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

除了使用 [内置效果](https://docs.febucci.com/text-animator-unity/3.x-zh/xiao-guo/nei-zhi-xiao-guo-lie-biao) 或 [从检查器创建自定义效果](https://docs.febucci.com/text-animator-unity/3.x-zh/zi-ding-yi/chuang-jian-nin-zi-ji-de-xiao-guo), <mark style="color:默认;background-color:$warning;">**你也可以通过 C# 轻松编写自定义效果**</mark>.

{% hint style="info" %}
附注：确保你已阅读 [gao-ji-gai-nian](https://docs.febucci.com/text-animator-unity/3.x-zh/bian-xie-zi-ding-yi-lei/gao-ji-gai-nian "mention") 页面！
{% endhint %}

效果有三个关键部分（可以写在同一个文件中）。

<table data-view="cards"><thead><tr><th></th><th></th></tr></thead><tbody><tr><td><strong>参数类/结构体</strong></td><td>包含有关你将在效果中使用的数据/值的信息（<strong>状态）</strong> </td></tr><tr><td><strong>状态</strong> 结构体</td><td>主效果类。根据参数和字符，随时间修改它。同时处理 <a data-mention href="../xiao-guo/ru-he-bian-ji-xiao-guo/xiu-shi-fu">xiu-shi-fu</a></td></tr><tr><td><strong>可脚本化封装</strong></td><td>将前面的元素统一在一起并让你将内容保存到磁盘。只需几行代码让我们完成其余工作！</td></tr></tbody></table>

{% hint style="success" %}
这些名称只是约定，但 **你可以按自己喜欢的方式命名它们**!

只要知道你需要：&#x20;

* 用于存储效果变量的东西
* 负责修改字母的结构体
* 将这两者黏合并允许你将信息保存到磁盘的可脚本化对象
  {% endhint %}

## 编写你的自定义脚本

{% hint style="info" %}
在本示例中，我们制作了一个使字符按可变量上升的效果。
{% endhint %}

首先，确保导入必要的命名空间（你的 IDE 无论如何都会提示你 <3）

<pre class="language-csharp"><code class="lang-csharp">using UnityEngine;

// 导入 Text Animator 的命名空间
<strong>using Febucci.TextAnimatorCore;
</strong>using Febucci.TextAnimatorCore.Text;
<strong>using Febucci.Parsing;
</strong><strong>using Febucci.TextAnimatorForUnity.Effects;
</strong></code></pre>

### 参数

创建你将用来修改字符的数据（这就是你将在检查器中看到并编辑的内容）。

```csharp
// 可以是 struct 或 class
// 后者允许你拥有默认值
[System.Serializable]
class CustomEffectParameters
{
    public float amount = 1.5f;
}
```

### 状态

效果的“核心”部分。根据参数和预先计算的 Text Animator 数据修改字母。

* 该结构体必须继承自 **IEffectState**.

```csharp
// 必须是 struct！
struct CustomEffectState : IEffectState
{
    readonly float defaultAmount;
    float amount;


    public CustomEffectState(CustomEffectParameters data)
    {
        // 从参数类获取默认量
        this.defaultAmount = data.amount;
        this.amount = defaultAmount;
    }

    public void UpdateParameters(RegionParameters parameters)
    {
        // 自动处理用户在富文本标签中写入的情况， 
        // 在此例中为 "a"
        //（例如 <tagID a=5> 会将 "amount" 设为 5，而 
        // a*2 会使 "amount" 成为 defaultAmount 的两倍）
        amount = parameters.ModifyFloat("a", defaultAmount);
    }

    public void Apply(ref CharacterData character, in ManagedEffectContext context)
    {
        // 使用 "amount" 将字符向上移动
        // 使用清晰且易用的 API
        character.MovePosition(
            Vector3.Up * amount * context.progressionRange * context.intensity,
            context.isUpPositive
            );
        // 1. 注意 context.progressionRange -> 它是 
        //     你在编辑器中分配的曲线！
        //     允许你得到阶跃、正弦、弹跳等效果
        // 2. 还要注意 context.intensity，需用于实现 
        //     阶段之间的平滑过渡。
        }
}
```

### 可脚本化对象封装

创建将你的自定义效果挂接到 Text Animator 所需的逻辑，并将其保存在 Assets 文件夹中。

```csharp
[System.Serializable] // <-- 使其可序列化！！
[CreateAssetMenu(fileName = "Your Custom Effect")]
class CustomEffectScriptable : ManagedEffectScriptable<CustomEffectState, CustomEffectParameters>
{
    // 简单地根据参数（已由 text animator 管理）创建一个新状态
    protected override CustomEffectState CreateState(CustomEffectParameters parameters)
        => new CustomEffectState(parameters);
}
```

{% hint style="info" %}
还有另一个接受更多类型的 "ManagedEffectScriptable" 版本，以及 "Referenced" 效果的实现，但我们将在未来的版本中介绍！
{% endhint %}

{% hint style="success" %}
这些脚本是 Text Animator 确保你获得以下内容所需的全部：

* 自动管理的曲线、播放、修饰符
* 无竞态条件的优化效果
* 兼容 AOT 平台的效果（无需使用反射）
* 我们强大的预览编辑器
* 在 UI Toolkit 和 Text Mesh Pro 上表现一致的效果，包括动态缩放

还有更多！<3
{% endhint %}

<figure><img src="https://1326131491-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXuXUTa2X5PYuYL6yRvl1%2Fuploads%2FpaXEW0rl1anhoSBUK719%2FClipboard-20251116-235502-613.gif?alt=media&#x26;token=72885c85-f75f-43db-969c-ab4a72c28803" alt=""><figcaption></figcaption></figure>

***

{% hint style="success" %}
完成！  **你已完成所有必要步骤，耶！**\
你添加的效果越多，这个过程就越熟悉、越简单。
{% endhint %}

{% hint style="warning" %}
记得为你的效果在检查器中设置标签并将其添加到数据库！否则它将无法被识别。你可以在这里阅读更多： [xiao-guo-shu-ju-ku](https://docs.febucci.com/text-animator-unity/3.x-zh/xiao-guo/ru-he-tian-jia-xiao-guo/xiao-guo-shu-ju-ku "mention")
{% endhint %}

**祝你在应用效果时玩得开心！**

***

{% hint style="info" %}
关于创建 “Referenced” 效果的指南即将推出，因为我们仍在调整 UX/API 部分。
{% endhint %}
