Unless you want to create an animation that dynamically reacts to external events, or an animation that includes randomness, like <shake> you can use Custom Animations instead of Custom C# Animations.
To create a custom animation you need 3 steps:
Create a class inheriting from TextAnimation. It will be responsible for animating the text.
Create a class inheriting from TextAnimationTagParser. It will parse the tag and create a TextAnimation object with the right parameters.
Register the parser.
Text Animation
In this example we'll create a simple animation that moves opacity between 0 and 1.
public class OpacityPingPong : TextAnimation
{
// The frequency of the animation with a default value.
// The default value is going to be used if no parameter is specified in the tag
public float frequency = 1;
// The construction takes the tag used to create the animation object.
// In case of our simple animation that wouldn't be necessary,
// but it's useful for animations that have different variants (fade-in / fade-out)
public OpacityPingPong(string creatorTag) : base(creatorTag) { }
// Here's where the animation happens.
// This function is called every frame for every single letter,
// even if they are invisible, so try not to do anything crazy in here.
public override void Animate(
Letter letter, // The current letter being animated
int letterIndex, // The index of the currently animated letter
float time, // The current time of the animation
AnimationResult result // Contains all modified animation properties
)
{
// Calculate a triangle wave between 0 and 1, that's our opacity!
var opacity = Mathf.PingPong(time * frequency, 1);
// Multiply the current opacity with our new value.
// It's important to always modify properties in a way that doesn't overwrite
// the changes set by other animations.
// If we wrote `result.opacity = opacity;` here, this animation would break
// all other animations that use opacity.
result.MultiplyOpacity(opacity);
}
// Optimization hints for UI Toolkit.
public override bool animatesColor => false;
public override bool animatesTransform => false;
}
Text Animation Tag Parser
public class OpacityPingPongParser : SimpleTextAnimationTagParser
{
public override IEnumerable<string> GetTagNames()
{
// This animation parser only supports a single tag
return new[] { "ping-pong" };
}
public override TextAnimation CreateAnimation(string tag, Parameters parameters)
{
// Create a new object of our new animation class.
var pingPong = new OpacityPingPong(tag);
// Check if the animation tag has the parameter "f" set.
// If yes, set the value in our ping pong class
if (parameters.TryGetFloatValue("f", out var frequency))
{
pingPong.frequency = frequency;
}
// Return the animation object with the right parameters.
// The animation will be applied to all letters within the tag.
return pingPong;
}
}
Registering the parser
There are two ways to register an AnimationParser for your text elements:
// Register the parser for a single text element
animatedText.AddAnimationParser(new OpacityPingPongParser());
// Register the parser globally
TextAnimator.AddGlobalAnimationParser(new OpacityPingPongParser());
How to use the new animations
Now everything is set up, you can use the animations like any other:
Hello, let's try our new <ping-pong>animation</ping-pong>!
You can also look at the code of all built-in animations for inspiration.
If you need help developing custom animations or want to share your creations, join my Discord and start a discussion!