角色与动画

总体链路

角色动画由四层数据共同决定:

Yarn 台词 / <<SetNPCState>>
        ↓ TechName
CharacterAnimationManager
        ↓ 找到角色 Controller 与 CharacterState
CharacterAnimationController
        ↓
Spine Skin + PixelAnimation + Background

相关运行时脚本:

  • Assets/Resources/Scripts/Core/AnimationSystem/CharacterAnimationManager.cs
  • Assets/Resources/Scripts/Core/AnimationSystem/CharacterAnimationController.cs
  • Assets/Resources/Scripts/Core/AnimationSystem/CharacterState.cs
  • Assets/Resources/Scripts/Core/AnimationSystem/PixelAnimation.cs
  • Assets/Resources/Scripts/Core/AnimationSystem/PixelAnimationPlayer.cs

角色和状态的当前完整索引见 f.角色索引。

角色定义

角色定义资产位于 Assets/Define/Character/,运行时路径为 Define/Character。

CharacterDefinition 主要包含:

  • techName:角色技术名称;
  • 名称、描述、Portrait 和邮件头像;
  • dialogueEmotionTags:对话标注工具允许尝试的状态名称;
  • initialCharacterStates:创建角色时依次应用的初始状态;
  • 默认 Body、Eyes、Mouth Skin;
  • targetSpinePrefab:角色的 Spine 预制体;
  • 直播资料、弹幕类型和语音频率。

initialCharacterStates 是默认外观,不是“角色全部可用状态列表”。真正应用状态时,目标 Spine SkeletonData 必须能找到状态引用的 Skin 或其他资源。

状态定义

CharacterState 位于 Assets/Define/Animation/CharacterState/,运行时从 Define/Animation/CharacterState 自动发现,并且可以合并 Mod 注册的状态。

一个状态包含:

字段作用
techNameYarn 和运行时代码使用的状态名。
skins要合并到角色 Skeleton 的 Skin,格式是 Skin 组和 Skin 值。
enablePixelAnimations应用状态时启动的 PixelAnimation。
disablePixelAnimations应用状态时停止的 PixelAnimation。
backgroundPrefab可选的背景预制体。

状态应用时会:

  1. 合并当前 Skin 与状态 Skin;
  2. 停止 LoopState 类型 PixelAnimation;
  3. 停用状态指定的 PixelAnimation;
  4. 播放状态指定的 PixelAnimation;
  5. 恢复持久化 Slot Attachment;
  6. 应用背景;
  7. 将状态记录为当前状态。

#state: 和 SetNPCState

对话行可以使用:

Aistalt: 我们先冷静一下。 #state:Cold

代码也可以显式调用:

<<SetNPCState Aistalt Sad>>

ApplyNPCState 支持更宽松的 selector:

<<ApplyNPCState Aistalt state:Happy>>
<<ApplyNPCState Aistalt #Happy>>

状态选择器会去掉 #、state:、state= 和 state_ 前缀,并按注册表查找状态。查找是全局的,但应用成功与否仍取决于目标角色的 Spine 资源。

当前内置状态分类

通用面部状态

这些状态主要通过 Eyes/<Value> 和 Mouth/<Value> Skin 改变表情,适合拥有对应 Skin 命名的角色:

Ahegao
Angry
Bored
Cold
Complex
Confused
Ero
Fear
Funny
Happy
Hate
Horray
Horror
Idle
Idle_Clear
Idle_BodyShape3
MiaEro
Naughty
Sad
Shy
Suprised

注意:它们是全局注册状态,不代表每个角色都支持。某角色缺少对应 Skin 时,ApplyCharacterState 可能无法成功应用,或状态只应用其中可用部分。

角色专属状态

Aistalt:
  Idol_1, Idol_2, Salute01, Salute02, TailLoop
 
BotChecker:
  BotChecker_Arid, BotChecker_Wild
 
Gothic:
  Gothic_Idle, Gothic_Lit, Gothic_Unlit
 
Greenguard:
  Green, Riot
 
Greta:
  Greta_Angry_1, Greta_Angry_2, Greta_Formal,
  Greta_Vomit_1, Greta_Vomit_2, Greta_Vomit_3
 
Soldier:
  Soldier_Salute_1, Soldier_Salute_2,
  Soldier_Smoke_1, Soldier_Smoke_2,
  Soldier_Smoke_3, Soldier_Smoke_4, Soldier_Smoke_Idle
 
Veteran:
  Vt_Die, Vt_Drink, Vt_Hand_2, Vt_Hand_3,
  Vt_Hand_4, Vt_Hand_5, Vt_UnDrink

这些状态通常包含角色专用 Skin、PixelAnimation、Spine 动画或身体形态,不能直接套给其他角色。

背景状态

以 BG_ 开头的状态主要用于切换角色背景,例如:

BG_BG_A_A
BG_BG_A_Empathy
BG_BG_A_Tech
BG_BG_A_Troll
BG_BG_BotChecker
BG_BG_Gothic
BG_BG_Greta2
BG_BG_MaoGirl_export
BG_BG_Masturbator
BG_BG_Nerd
BG_BG_Snow
BG_BG_Street_Day
BG_BG_Street_Night
BG_BG_Veteran

项目中还有更多场景、地点和剧情专用背景状态。它们没有 Eyes/Mouth Skin,通常不应被当作角色表情状态使用。

PixelAnimation 资产

项目中存在独立的 PixelAnimation 资产,例如:

Anim_Idol_1
Anim_Idol_2
Anim_Salute_1
Salute_2
Green_PA
Riot_PA
VT_Die
VT_Hand_1_PA
VT_Hand_2_PA
VT_Hand_3_PA
VT_Hand_4_PA
VT_Hand_5_PA
Vt_Idle_Drink_PA
Vt_Idle_Undrink_PA

PixelAnimation 不是 CharacterState。它是被状态启用,或由运行时代码直接播放的轨道资产。可包含:

  • Bone X/Y 轨道;
  • Physics 的 Wind/Gravity 轨道;
  • Slot Attachment 轨道;
  • Spine Animation 轨道;
  • 一次性、状态循环或持续循环行为;
  • 可选音频和参数随机化。