Creature Visuals And Animation

Pick The Smallest Hook

Choose the lightest visual hook that matches the job:

NeedUse
Swap a packaged visuals sceneCharacterAssetProfile.Scenes.VisualsPath or MonsterAssetProfile.VisualsScenePath
Use static frame cuesVisualCueSet on CharacterAssetProfile
Build the node tree in codeOverride TryCreateCreatureVisuals()
Drive combat animations yourselfOverride SetupCustomCombatAnimationStateMachine(...)
Drive merchant / rest-site visualsOverride SetupCustomMerchantAnimationStateMachine(...) or WorldProceduralVisuals

Start with paths and profiles. Move to factories only when static resources cannot express the behavior.

选择最小 Hook

按需求选择最轻的视觉接入点:

需求使用
替换打包好的视觉场景CharacterAssetProfile.Scenes.VisualsPathMonsterAssetProfile.VisualsScenePath
使用静态帧 cueCharacterAssetProfile 上的 VisualCueSet
用代码构建节点树覆写 TryCreateCreatureVisuals()
自己驱动战斗动画覆写 SetupCustomCombatAnimationStateMachine(...)
驱动商店 / 篝火视觉覆写 SetupCustomMerchantAnimationStateMachine(...) 或使用 WorldProceduralVisuals

从路径和 profile 开始。只有静态资源表达不了行为时,再使用 factory。

Visual Cues

VisualCueSet is useful for non-Spine characters that can be described by named stills or frame sequences.

csharp
public override CharacterAssetProfile AssetProfile => new()
{
    VisualCues = new VisualCueSet(
        texturePathByCue: new Dictionary<string, string>
        {
            ["idle"] = "res://MyMod/images/character/idle.png",
            ["hit"] = "res://MyMod/images/character/hit.png",
        })
};

For a still frame that should hold briefly and then let the state machine return to idle, use the builder:

csharp
public override CharacterAssetProfile AssetProfile => new()
{
    VisualCues = VisualCueSetBuilder.Create()
        .Single("idle", "res://MyMod/images/character/idle.png")
        .Single("attack", "res://MyMod/images/character/attack.png", 0.5f)
        .Build()
};

Keep cue names aligned with the animation states your model or state machine will request.

Visual Cue

VisualCueSet 适合可用命名静态图或帧序列表达的非 Spine 角色。

csharp
public override CharacterAssetProfile AssetProfile => new()
{
    VisualCues = new VisualCueSet(
        texturePathByCue: new Dictionary<string, string>
        {
            ["idle"] = "res://MyMod/images/character/idle.png",
            ["hit"] = "res://MyMod/images/character/hit.png",
        })
};

如果某个静态帧需要短暂停留,然后让状态机回到 idle,可以用 builder:

csharp
public override CharacterAssetProfile AssetProfile => new()
{
    VisualCues = VisualCueSetBuilder.Create()
        .Single("idle", "res://MyMod/images/character/idle.png")
        .Single("attack", "res://MyMod/images/character/attack.png", 0.5f)
        .Build()
};

cue 名称应与模型或状态机请求的动画状态一致。

State Machines

Use ModAnimStateMachines or ModAnimStateMachineBuilder when you need explicit animation state transitions.

csharp
protected override ModAnimStateMachine? SetupCustomCombatAnimationStateMachine(
    Node visualsRoot,
    CharacterModel character)
{
    return ModAnimStateMachines.Standard(
        CompositeBackendFactory.FromNode(visualsRoot));
}

Return null when the normal vanilla animation path should run.

状态机

需要明确控制动画状态切换时,使用 ModAnimStateMachinesModAnimStateMachineBuilder

csharp
protected override ModAnimStateMachine? SetupCustomCombatAnimationStateMachine(
    Node visualsRoot,
    CharacterModel character)
{
    return ModAnimStateMachines.Standard(
        CompositeBackendFactory.FromNode(visualsRoot));
}

返回 null 表示继续使用普通原版动画路径。

Practical Notes

  • Keep visual resources in the mod PCK and reference them with res://.
  • Register Godot scripts before any scene is instantiated.
  • Use one visible fallback pose for every non-Spine creature.
  • Test death, hit, attack, cast, idle, and relaxed states before release.
  • For merchant and rest-site visuals, verify both normal UI entry and reload-from-save paths.

实用注意点

  • 视觉资源放进 Mod PCK,并用 res:// 引用。
  • 任何场景实例化前先注册 Godot 脚本。
  • 非 Spine 生物至少准备一个可见回退姿势。
  • 发布前测试死亡、受击、攻击、施放、待机和 relaxed 状态。
  • 商店与篝火视觉需要同时验证正常进入和读档恢复路径。