Writing Custom Effects (C#)

Other than using built-in effects or creating custom ones from the Inspector, you can easily program custom Effects via C#.

P.S. Make sure you have read the Advanced Concepts page!

Effects have three key parts (which can be written in the same file).

Parameters class/struct

Contains information about the data/values you will use in your effect (state)

State struct

Main effect class. Given the parameters and a Character, modifies it through time. Also handles Modifiers

Scriptable Wrapper

Unifies the previous elements together and lets you save things on disk. A few of line of code to let us do the rest!

Writing your Custom Script

For this example, we're making an effect that makes a character go up by a variable amount.

First, make sure to import the necessary namespaces (your IDE will tell you anyways <3)

using UnityEngine;

// import Text Animator's namespaces
using Febucci.TextAnimatorCore;
using Febucci.TextAnimatorCore.Text;
using Febucci.Parsing;
using Febucci.TextAnimatorForUnity.Effects;

Parameters

Create the data you will need to modify the characters (it's the same one you will see and edit in the Inspector).

// can be either struct or class
// the latter allows you to have default values
[System.Serializable]
class CustomEffectParameters
{
    public float amount = 1.5f;
}

State

The "core" part of an effect. Modifies the letter given the parameters and pre-calculated Text Animator data.

  • The struct must inherit from IEffectState.

// must be struct!
struct CustomEffectState : IEffectState
{
    readonly float defaultAmount;
    float amount;


    public CustomEffectState(CustomEffectParameters data)
    {
        // gets the default amount from the parameters class
        this.defaultAmount = data.amount;
        this.amount = defaultAmount;
    }

    public void UpdateParameters(RegionParameters parameters)
    {
        // automatically handles cases where the user wrote 
        // modifiers in the rich text tag, "a" in this case
        // (e.g. <tagID a=5> will set "amount" to 5, while 
        // a*2 will make "amount" two times defaultAmount)
        amount = parameters.ModifyFloat("a", defaultAmount);
    }

    public void Apply(ref CharacterData character, in ManagedEffectContext context)
    {
        // uses "amount" to move the character up
        // with a clear and easy to use API
        character.MovePosition(
            Vector3.Up * amount * context.progressionRange * context.intensity,
            context.isUpPositive
            );
        // 1. note context.progressionRange -> it's the 
        //     curve you have assigned in the editor!
        //     allowing you for a step, a sine, bounce etc. result
        // 2. note also the context.intensity, needed to have 
        //     smooth transitions between stages.
        }
}

Scriptable Object Wrapper

Creates the logic necessary to hook your custom effect into Text Animator, also saving it in the Assets folder.

[System.Serializable] // <-- make it serializable!!
[CreateAssetMenu(fileName = "Your Custom Effect")]
class CustomEffectScriptable : ManagedEffectScriptable<CustomEffectState, CustomEffectParameters>
{
    // simply creates a new State, given the Parameters (already managed by text animator)
    protected override CustomEffectState CreateState(CustomEffectParameters parameters)
        => new CustomEffectState(parameters);
}

There is another version of "ManagedEffectScriptable" which accepts more types, as well as the "Referenced" effect implementation, but we will cover than from future versions!


Have fun applying your effects!


A guide for creating "Referenced" effects is coming soon, as we're still tinkering the UX/API part.