> 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/3.x-zh/bian-xie-zi-ding-yi-lei/bian-xie-zi-ding-yi-xiao-guo-c.md).

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

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

{% hint style="info" %}
P.S. 请确保你已经阅读了 [高级概念](/text-animator-unity/3.x-zh/bian-xie-zi-ding-yi-lei/gao-ji-gai-nian.md) 页面！
{% 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="/pages/fcf4f88b28b49780d39777586af51e7613cd2ba5">/pages/fcf4f88b28b49780d39777586af51e7613cd2ba5</a></td></tr><tr><td><strong>Scriptable 包装器</strong></td><td>将前面的元素统一在一起，并让你把内容保存到磁盘上。只需几行代码，就能让我们完成其余工作！</td></tr></tbody></table>

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

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

* 用于存储效果变量的东西
* 负责修改字母的结构体
* 把这两者粘合在一起并让你将信息保存到磁盘上的 Scriptable
  {% 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，它用于实现 
        //     各阶段之间的平滑过渡。
        }
}
```

### Scriptable Object 包装器

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

```csharp
[System.Serializable] // <-- 一定要可序列化！！
[CreateAssetMenu(fileName = "Your Custom Effect")]
class CustomEffectScriptable : ManagedEffectScriptable<CustomEffectState, CustomEffectParameters>
{
    // 只需根据参数创建一个新的 State（参数已由 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="/files/8ca187870ae1d1cb61e8da138ef9afe353e471d0" alt=""><figcaption></figcaption></figure>

***

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

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

**祝你愉快地应用这些效果！**

***

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