> For the complete documentation index, see [llms.txt](https://docs.febucci.com/text-animator-unity/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.febucci.com/text-animator-unity/2.x-zh/xiao-guo/chuang-jian-ni-zi-ji-de-xiao-guo/bian-xie-zi-ding-yi-xiao-guo-c.md).

# 编写自定义效果（C#）

除了使用内置效果和通过检视器创建自定义效果外，你还可以通过 C# 轻松编程自定义效果。

***

## 1. 效果基类 <a href="#id-1-effect-base-class" id="id-1-effect-base-class"></a>

你需要做的就是继承于基类 `Febucci.UI.Effects.AnimationScriptableBase` 类 ([脚本 API](https://www.api.febucci.com/tools/text-animator-unity/api/Febucci.UI.Effects.AnimationScriptableBase.html)).

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

还有一些已为你准备好的有用类，你可以在 API 中查看，例如“BehaviorScriptableBase”或“AppearanceScriptableBase”（分别用于各自的效果类别）以及“BehaviorSineBase”，它已经处理了诸如 “a、f、w” 等修饰符等功能。

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

既然你在创建一个 ScriptableObject，就像 Actions 一样，确保也添加所需的属性以便实例化和序列化它们：

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

这样你就可以从项目窗口中创建它们。

***

通过继承自 `AnimationScriptableBase`，你会发现一些需要重写的方法，其中有一些是必须的（抽象的），还有一些是可选的（虚拟的），这取决于你的需求和你所继承的上层类，在文档中（包括脚本 API 和 IDE 中）你也会找到更多示例和关于新方法的信息。

## 3. 修饰符方法 <a href="#id-3-modifier-methods" id="id-3-modifier-methods"></a>

由于效果可以被“[修饰符](about:/text-animator-unity/docs/how-to-add-effects-to-your-texts/#modifiers)”影响，你可以重写以下方法来在你的动画中处理它们：

这些方法将在动画之前按顺序应用。

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

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

你可以使用此方法将动画的变量重置为初始状态。\
例如，在检视器中你可以公开暴露一个名为 `baseSpeed`的变量，但在你的效果中只使用 `currentSpeed` 并在该方法中使该变量为 `currentSpeed=baseSpeed` 。

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

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

你可以使用此方法将修饰符应用到你的变量中。

例如这会将 `currentSpeed` 值乘以 `s` 修饰符（如果存在）。

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

👍🏻 如果你想创建一个具有三个修饰符（例如“振幅”、“频率”和“波形大小”）的 Behavior 效果，你可以创建一个继承自 `BehaviorSineBase` 的类，它会为你处理这些修饰符。

## 4. 动画方法 <a href="#id-4-animation-methods" id="id-4-animation-methods"></a>

下面是一些你可以重写以创建自定义动画的方法。<br>

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

效果的最大持续时间。它用于计算动画的总持续时间并实现平滑过渡，但如果你有一个永不结束的效果，应返回 -1；

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

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

用于检查该效果是否可以应用到当前字母。例如如果你正在创建一个外观效果，该效果仅在字符经过的时间位于效果持续时间内时才应用（但在这种情况下你可以继承自 “AppearanceScriptableBase” 并让它为你处理）。

你可以更进一步，例如检查字符是数字还是字母、它们的单词索引等等。

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

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

将动画应用到字母的主方法，当 “CanApplyEffectTo” 返回 true 时调用。

* `character.current` 会在每帧被重置（与 `character.source`相匹配），因此你需要修改其值以对字母进行动画处理。
* `character.source` 是字母的原始位置和颜色，这意味着如果修改它你实际上是在永久改变该字母（直到设置新的文本）。建议仅将其用作基础，改为修改 `character.current` 。

## ✅ 完成！ <a href="#done" id="done"></a>

**你已经完成了所有必要的步骤，耶！**\
你添加的效果越多，这个过程就会越熟悉、越简单。

{% hint style="warning" %}
记得在项目视图中创建你的效果 ScriptableObject，并将其添加到数据库中。

你可以在这里阅读更多内容： [数据库](/text-animator-unity/2.x-zh/xiao-guo/wei-ni-de-wen-ben-tian-jia-xiao-guo/shu-ju-ku.md)
{% endhint %}

{% hint style="success" %}
👍🏻 你也可以随时查看内置效果类，看看它们是如何实现的。
{% endhint %}

**祝你玩得开心，尽情应用你的效果！**
