Creating commands
This section walks you through creating your own commands. First, create a new C# script in the Unity editor.
Creating the class
Add the following using statement at the top of your class: using TMPEffects.TMPCommands;.
Then, make the created class derive from TMPCommand.
In order to be able to create the command object in the Unity editor and add it to your database, make sure to decorate the class with the CreateAssetMenu attribute.
Members
You will have errors due to TMPCommand's abstract members not being implemented. Auto-implement them using your IDE, or add them manually. When you are done, your class should look something like this:
using UnityEngine;
using TMPEffects.TMPCommands;
[CreateAssetMenu(fileName="new YourFirstCommand", menuName="Your/Path/YourFirstCommand")]
public class YourFirstCommand : TMPCommand
{
public override TagType TagType => throw new System.NotImplementedException();
public override bool ExecuteInstantly => throw new System.NotImplementedException();
public override bool ExecuteOnSkip => throw new System.NotImplementedException();
public override void ExecuteCommand(TMPCommandArgs args)
{
throw new System.NotImplementedException();
}
public override bool ValidateParameters(IDictionary<string, string> parameters)
{
throw new System.NotImplementedException();
}
}
Let's go over each member individually.
Properties
TagType: Defines whether the tags for this command should operate on an index, a text block, or either option. For example, the built-in wait command operates on an index, and the built-in command show operates on a text block (see Built-in commands).
ExecuteInstantly: Commands where this property is true are executed the moment the TMPWriter begins the writing process, instead of when their opening tag index is reached. From the built-in tags, only show is executed instantly.
ExecuteOnSkip: Commands where this property is true are executed even when their index is skipped over by the writer (i.e., when TMPWriter.SkipWriter() is called). This should be true for commands that need to ensure they are being called even if skipped over, for example a command that starts a quest or adds an item to the player's inventory.
Optional properties
There are a few optional properties. If you don't override them, they are set to false by default. In both cases, this is to protect you from yourself 😉
Only set these to true if you are sure it is safe for your case!
ExecuteRepeatable: Commands where this property is true may be executed multiple times, specifically if the writer is reset / restarted at any point (i.e., when TMPWriter.ResetWriter() is called). This should be false for commands that need to ensure they are only ever raised once, for example a command that starts a quest or adds an item to the player's inventory.
ExecuteInPreview: Commands where this property is true are executed in the editor preview.
Warning
Note that you must wrap this property in a #if UNITY_EDITOR preprocessor directive if you want to override it; otherwise your builds will fail.
Methods
ValidateParameters(IDictionary<string, string> parameters): This method is called during tag processing. It allows you to specify whether a given tag for this command has valid parameters. ParameterUtility will come in handy here. Return true if the parameters are valid, return false if not. If false, the tag will not be processed.
ExecuteCommand(TMPCommandArgs args): The meat of your command. This executes the actual command you are implementing.
TMPCommandArgs
The sole argument for the ExecuteCommand method. It's kept relatively simple: it provides access to the actual EffectTag, through which you may get the tag's parameters, the EffectTagIndices, and the executing TMPWriter.
Full example
As complete example, the class below is the implementation of the built-in delay command.
using System.Collections.Generic;
using UnityEngine;
namespace TMPEffects.TMPCommands.Commands
{
[CreateAssetMenu(fileName = "new DelayCommand", menuName = "TMPEffects/Commands/Delay")]
public class DelayCommand : TMPCommand
{
public override TagType TagType => TagType.Index;
public override bool ExecuteInstantly => false;
public override bool ExecuteOnSkip => true;
public override bool ExecuteRepeatable => true;
#if UNITY_EDITOR
public override bool ExecuteInPreview => true;
#endif
public override void ExecuteCommand(TMPCommandArgs args)
{
if (ParameterUtility.TryGetFloatParameter(out float delay, args.tag.Parameters, ""))
{
args.writer.SetDelay(delay);
return;
}
// Since validate parameters ensures the parameter is present and float,
// this state should be impossible to reach
throw new System.InvalidOperationException();
}
public override bool ValidateParameters(IDictionary<string, string> parameters)
{
if (parameters == null) return false;
if (!parameters.ContainsKey(""))
return false;
return ParameterUtility.HasFloatParameter(parameters, "");
}
}
}
Adding the command to a database
To actually use the command in your text, you will have to follow these steps:
- Create a command object: Right click in your project view and create it (it will be in the path you specified in the CreateAssetMenu attribute).
- Add that object to the database you want to use and give it a name
- Use that database in the TMPWriter component
Done! You can now use your custom command like any of the built-in ones.
Creating scene commands
See Scene commands on how to add scene commands.