using System; using System.Collections.Generic; using UnityEngine; using XGame; using XGame.Database; using XGame.Framework.Components; using XGame.Framework.Interfaces; using XGame.Framework.Time; namespace FL.Battle.Components { public interface IAnimatorContext { Animator Animator { get; } ITimeModule Time { get; } } public class AnimatorComponent : Component, IAnimator, IReset { /// /// Animator参数名 /// int类型,数值参考EActionName /// private string STATE_VAL = "StateVal"; private ITimer _actionTimer; /// /// 触发器的定时器 /// private ITimer _triggerTimer; private Dictionary _nameToClipMap; private float _baseSpeed = 1; protected override void OnEnable(object intent) { _baseSpeed = Context.Animator.speed; RefreshClips(); } protected override void OnDisable() { _nameToClipMap?.Clear(); Context.Animator.speed = _baseSpeed; ClearTimers(); } protected override void OnDispose() { ClearTimers(); } private void ClearTimers() { _actionTimer?.Cancel(); _actionTimer = null; _triggerTimer?.Cancel(); _triggerTimer = null; } public void Play(EAnimationName aniName) { Play(new AnimationPlayArgs { aniName = aniName }); } public void Play(AnimationPlayArgs args) { var animator = Context.Animator; if (!_nameToClipMap.TryGetValue(args.aniName, out var clip)) { Log.Error($"找不到动作配置. Animator:{animator.name} ActionName:{args.aniName}"); return; } //if (_actionTimer != null) //{ // Log.Debug($"Animator Name:{animator.name} Now:{animator.GetInteger(STATE_VAL)} Next:{args.aniName}"); //} animator.SetInteger(STATE_VAL, (int)args.aniName); ClearTimers(); var duration = Mathf.CeilToInt(clip.length * 1000); if (args.onTrigger != null && args.triggerFrame > 0 && args.triggerFrame < duration) { _triggerTimer = Context.Time.AddDelayTimer(args.triggerFrame, () => { _triggerTimer = null; args.onTrigger.SafeInvoke(); }); } if (!clip.isLooping) { // 非循环动作才有回调 //Log.Debug($"Animator Start name:{args.aniName} clip:{clip.name} duration:{duration} time:{Time.realtimeSinceStartup} rotation:{animator.transform.localRotation}"); _actionTimer = Context.Time.AddDelayTimer(duration, () => { //Log.Debug($"Animator End name:{args.aniName} clip:{clip.name} duration:{duration} time:{Time.realtimeSinceStartup} rotation:{animator.transform.localRotation}"); _actionTimer = null; animator.SetInteger(STATE_VAL, (int)args.fallback); args.onCompleted.SafeInvoke(); }); } //state.Complete += (_) => //{ // callback?.Invoke(); //}; } private void RefreshClips() { if (_nameToClipMap == null) { _nameToClipMap = new Dictionary(); } var controller = Context.Animator.runtimeAnimatorController; if (controller != null && controller.animationClips != null) { foreach (var clip in controller.animationClips) { if (Enum.TryParse(clip.name, out var actionName)) { _nameToClipMap.Add(actionName, clip); } else { Log.Error($"AnimationClip 命名错误. Animator:{Context.Animator.name} Clip:{clip.name}"); } } } //foreach (var parameter in Context.Animator.parameters) //{ // var id = parameter.nameHash; // Context.Animator.SetBool(id, true); //} } void IReset.Reset() { ClearTimers(); } } }