using System.Collections.Generic; using Sirenix.OdinInspector; using SLSUtilities.FunctionalAnimation; using UnityEngine; namespace Cielonos.MainGame.Interactions { /// /// NPC 专属剧情动作子模块。 /// 继承通用播放器并实现 ISubmodule 接口,负责管理 NPC 数据化剧情动作集的注册与无条件播放。 /// public class NpcFuncAnimSubmodule : FuncAnimPlayer, ISubmodule { /// 该子模块的拥有者实例 public NpcBase Owner { get; set; } /// NPC 本地注册的动作数据集查找字典(直接指向基类的 collection 字段) public Dictionary Collection => collection; public NpcFuncAnimSubmodule(NpcBase owner) : base(owner, "FullBodyAction") { this.Owner = owner; } /// /// 将剧情动作资源注册进 NPC 的动作字典中,并将动画 Clip 强行重载至覆盖控制器(animatorOverride)中。 /// public override void Add(FuncAnimData animation) { if (animation == null) return; // 1. 调用通用基类完成基础的字典注册 base.Add(animation); // 2. 将动画 Clip 映射到对应的 Animator State 槽位上 if (Owner.animatorOverride != null) { Owner.animatorOverride[animation.animInfo.stateName] = animation.animationClip; } } /// /// 通过动作名播放 NPC 剧情动作(支持在 Inspector 中一键播放调试)。 /// [Button("播放动作")] public override bool Play(string animationName, float speedMultiplier = 1f, float transitionDuration = 0.1f, bool isNormalizedTransition = false, float normalizedStartTime = -1f, List runtimeStartEvents = null) { if (!Collection.TryGetValue(animationName, out FuncAnimData funcAnimData)) { Debug.LogWarning($"[NpcFuncAnimSubmodule] 在 NPC '{Owner.gameObject.name}' 的动作库中未找到名为 '{animationName}' 的动作。"); return false; } // NPC 播放动作采取无条件强制覆盖机制,直接委派给基类完成底层播放 return base.Play(funcAnimData, speedMultiplier, transitionDuration, isNormalizedTransition, normalizedStartTime, runtimeStartEvents); } } }