# Writing Custom Effects (C#)

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

***

## 1. Effect Base Class <a href="#id-1-effect-base-class" id="id-1-effect-base-class"></a>

All you need to do is inherit from the base `Febucci.UI.Effects.AnimationScriptableBase` class ([Scripting Api](https://www.api.febucci.com/tools/text-animator-unity/api/Febucci.UI.Effects.AnimationScriptableBase.html)).

```csharp
public class CustomEffect : AnimationScriptableBase
{
    //[...]
```

There are also some useful classes already available for you that you can view from the API, like the “BehaviorScriptableBase” or “AppearanceScriptableBase” which are intended for each effect category, “BehaviorSineBase” which already handles modifiers such as “a, f, w” and more.

## 2. Attributes <a href="#id-2-attributes" id="id-2-attributes"></a>

Since you’re creating a ScriptableObject, just like Actions, make sure to add the needed attributes as well in order to instance and serialize them:

```csharp
[CreateAssetMenu(fileName = "YourCustomEffect", menuName = "Text Animator/Custom/YourCustomEffect")]
[System.Serializable]
public class CustomEffect : AnimationScriptableBase
{
    //[...]
```

This way you’ll be able to create them from your Project Window.

***

By inheriting from `AnimationScriptableBase`, you’ll find some methods to override, a few obligatory (abstracts) and others optional (virtual) based on your needs and the upper class that you’re inheriting from, and in the docs (both Scripting API and in IDE) you’ll find more examples and info about new ones as well.

## 3. Modifier Methods <a href="#id-3-modifier-methods" id="id-3-modifier-methods"></a>

Since effects can be affected by “[Modifiers](about:/text-animator-unity/docs/how-to-add-effects-to-your-texts/#modifiers)”, you can override the following methods to handle them in your animations:

These methods will be applied, in order, before the animation.

### 3.1 ResetContext <a href="#id-31-resetcontext" id="id-31-resetcontext"></a>

```csharp
void ResetContext(TAnimCore animator)
```

You can use this method to reset your animation’s variables to their initial state.\
For example, in the inspector you can publicly expose a variable called `baseSpeed`, but in your effect only use `currentSpeed` and have that variable be `currentSpeed=baseSpeed` inside this method.

### 3.2 SetModifierTo <a href="#id-32-setmodifierto" id="id-32-setmodifierto"></a>

```csharp
void SetModifier(ModifierInfo modifier)
```

You can use this method to apply a modifier to your variables.

For example this will multiply the `currentSpeed` value by the `s` modifier (if there is any).

```csharp
public override void SetModifier(ModifierInfo modifier)
{
    switch (modifier.name)
    {
        case "s": currentSpeed *= modifier.value; break;
    }
}
```

👍🏻 If you want to create a Behavior effect that has three modifiers such as “amplitude”, “frequency” and “waveSize”, you can create a class that inherits from `BehaviorSineBase` which will handle them for you.

## 4. Animation Methods <a href="#id-4-animation-methods" id="id-4-animation-methods"></a>

Here are a few methods that you can override to create your custom animations.<br>

### 4.1 GetMaxDuration <a href="#id-41-getmaxduration" id="id-41-getmaxduration"></a>

The max duration of the effect. This is used to calculate the total duration of an animation and have smooth transitions, but if you have an effect that never ends you should return -1;

### 4.2 CanApplyEffectTo <a href="#id-42-canapplyeffectto" id="id-42-canapplyeffectto"></a>

```csharp
bool CanApplyEffectTo(CharacterData character, TAnimCore animator)
```

Used to check if the effect can be applied to the current letter. For example if you’re creating an appearance effect, which only applies if a character passed time is within the effect’s durattion (but in that case you can inherit from “AppearanceScriptableBase” and have it handle that for you).

You can go beyond that, for example check if the character is a number or a letter, or their word index and much more.

### 4.3 ApplyEffect <a href="#id-43-applyeffect" id="id-43-applyeffect"></a>

```csharp
void ApplyEffectTo(ref CharacterData character, TAnimCore animator)
```

Main method to apply an animation to a letter, called if “CanApplyEffectTo” returned true.

* `character.current` is reset every frame (matching `character.source`), so you’re expected to modify its values in order to animate a letter.
* `character.source` is the original placement and color of a letter, meaning that if modified you’re basically changing the letter permanently (until a new text is set). It is recommended that you only use this as a base, modifying `character.current` instead.

## ✅ Done! <a href="#done" id="done"></a>

**You’ve completed all the steps necessary, yay!**\
The more effects you add, the more this process will sound familiar and simpler.

{% hint style="warning" %}
Remember to create your effect ScriptableObject in the ProjectView, and add it to a database.

You can read more here: [Databases](/text-animator-unity/2.x/effects/add-effects-to-your-texts/databases.md)
{% endhint %}

{% hint style="success" %}
👍🏻 You can always take a look at the  built-in effects classes and see how they’re implemented.
{% endhint %}

**Have fun applying your effects!**


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.febucci.com/text-animator-unity/2.x/effects/create-your-own-effects/writing-custom-effects-c.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
