# 编写自定义效果（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 %}

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


---

# 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-zh/xiao-guo/chuang-jian-ni-zi-ji-de-xiao-guo/bian-xie-zi-ding-yi-xiao-guo-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.
