From 3b0c221d3de4f89721e00b02e8142e68906af32d Mon Sep 17 00:00:00 2001 From: chai <215380520@qq.com> Date: Tue, 15 Nov 2022 11:32:55 +0800 Subject: * motion --- Documents/_TODO.xlsx | Bin 1971860 -> 1971860 bytes .../PC/Erika/MotionData/motion_data_erika.asset | 22 +- .../Scripts/Unit/Action/WaitForActionReachEnd.cs | 4 +- .../Scripts/Unit/Action/WaitForTransitionDone.cs | 4 +- Erika/Assets/Scripts/Unit/AnimationType.cs | 39 +++ Erika/Assets/Scripts/Unit/AnimationType.cs.meta | 11 + Erika/Assets/Scripts/Unit/AnimatorLayerInfo.cs | 6 +- .../Components/UnitAnimation/MonsterAnimation.cs | 12 +- .../Unit/Components/UnitAnimation/PCAnimation.cs | 2 +- .../Unit/Components/UnitAnimation/UnitAction.cs | 238 ---------------- .../Components/UnitAnimation/UnitAction.cs.meta | 11 - .../Unit/Components/UnitAnimation/UnitMotion.cs | 302 +++++++++++++++++++++ .../Components/UnitAnimation/UnitMotion.cs.meta | 11 + Erika/Assets/Scripts/Unit/Components/UnitSkill.cs | 18 ++ .../Components/UnitState/Erika/PCState_States.cs | 2 +- .../Unit/Components/UnitState/MonsterState.cs | 2 +- .../Scripts/Unit/Controller/UnitController.cs | 2 +- Erika/Assets/Scripts/Unit/TimelineEventProxy.cs | 2 +- Erika/Assets/Scripts/Unit/UnitMotionData.cs | 67 ++++- Erika/Assets/Scripts/Unit/UnitRootMotion.cs | 2 +- Erika/Assets/Scripts/Utils/LogTag.cs | 2 +- 21 files changed, 486 insertions(+), 273 deletions(-) create mode 100644 Erika/Assets/Scripts/Unit/AnimationType.cs create mode 100644 Erika/Assets/Scripts/Unit/AnimationType.cs.meta delete mode 100644 Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitAction.cs delete mode 100644 Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitAction.cs.meta create mode 100644 Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitMotion.cs create mode 100644 Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitMotion.cs.meta diff --git a/Documents/_TODO.xlsx b/Documents/_TODO.xlsx index 7726c2e2..7828a718 100644 Binary files a/Documents/_TODO.xlsx and b/Documents/_TODO.xlsx differ diff --git a/Erika/Assets/Bundle/Unit/PC/Erika/MotionData/motion_data_erika.asset b/Erika/Assets/Bundle/Unit/PC/Erika/MotionData/motion_data_erika.asset index 64b03a27..30bb1eed 100644 --- a/Erika/Assets/Bundle/Unit/PC/Erika/MotionData/motion_data_erika.asset +++ b/Erika/Assets/Bundle/Unit/PC/Erika/MotionData/motion_data_erika.asset @@ -19,101 +19,121 @@ MonoBehaviour: note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} - animatorState: 0 + animatorState: 85 + animationType: 1 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 82 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 - hide: 0 uid: 1 note: animationData: {fileID: 0} animatorState: 0 + animationType: 0 overrideTransitions: - enabled: 0 fromId: 1 diff --git a/Erika/Assets/Scripts/Unit/Action/WaitForActionReachEnd.cs b/Erika/Assets/Scripts/Unit/Action/WaitForActionReachEnd.cs index e4dd7bb3..394601e2 100644 --- a/Erika/Assets/Scripts/Unit/Action/WaitForActionReachEnd.cs +++ b/Erika/Assets/Scripts/Unit/Action/WaitForActionReachEnd.cs @@ -8,10 +8,10 @@ using UnityEngine; /// public class WaitForActionReachEnd : IEnumerator { - UnitAction m_UnitAnimation; + UnitMotion m_UnitAnimation; int m_Layer; - public WaitForActionReachEnd(UnitAction unitAnim, int layer = 0) + public WaitForActionReachEnd(UnitMotion unitAnim, int layer = 0) { m_UnitAnimation = unitAnim; m_Layer = layer; diff --git a/Erika/Assets/Scripts/Unit/Action/WaitForTransitionDone.cs b/Erika/Assets/Scripts/Unit/Action/WaitForTransitionDone.cs index 1e59b75d..da3005c4 100644 --- a/Erika/Assets/Scripts/Unit/Action/WaitForTransitionDone.cs +++ b/Erika/Assets/Scripts/Unit/Action/WaitForTransitionDone.cs @@ -8,9 +8,9 @@ using UnityEngine; /// public class WaitForTransitionDone : IEnumerator { - UnitAction m_UnitAnimation; + UnitMotion m_UnitAnimation; - public WaitForTransitionDone(UnitAction unitAnim) + public WaitForTransitionDone(UnitMotion unitAnim) { m_UnitAnimation = unitAnim; } diff --git a/Erika/Assets/Scripts/Unit/AnimationType.cs b/Erika/Assets/Scripts/Unit/AnimationType.cs new file mode 100644 index 00000000..eb57168a --- /dev/null +++ b/Erika/Assets/Scripts/Unit/AnimationType.cs @@ -0,0 +1,39 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +/// +/// 按照类型分类动作,部分动作如locomotion应该具有唯一性 +/// 不要修改枚举值,扩展 +/// +public enum EAnimationType +{ + _BEGIN = 0, + + /// + /// locomotion + /// + Idle = 1, + Stun_Idle = 2, + Move = 3, + Run = 4, + + /// + /// 受击 + /// + Hit_Up = 20, + Hit_Knockdown = 21, + Hit_Knockdown_Loop = 22, + Hit_Knockdown_Hit = 23, + Hit_Knockdown_Die = 24, + Hit_Air = 25, + Hit_Air_Hit = 26, + + /// + /// 特殊动作 + /// + Throw = 40, + Block = 41, + + _END +} diff --git a/Erika/Assets/Scripts/Unit/AnimationType.cs.meta b/Erika/Assets/Scripts/Unit/AnimationType.cs.meta new file mode 100644 index 00000000..b3511b3f --- /dev/null +++ b/Erika/Assets/Scripts/Unit/AnimationType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3430979c52222f4f8c29728bb868f1d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Erika/Assets/Scripts/Unit/AnimatorLayerInfo.cs b/Erika/Assets/Scripts/Unit/AnimatorLayerInfo.cs index 97af086a..0cada209 100644 --- a/Erika/Assets/Scripts/Unit/AnimatorLayerInfo.cs +++ b/Erika/Assets/Scripts/Unit/AnimatorLayerInfo.cs @@ -32,7 +32,7 @@ public class AnimatorLayerInfo AnimatorClipInfo[] clipInfos = clipsInfo; if (clipInfos == null || clipInfos.Length == 0) { - LogHelper.LogError(LogTag.UnitAction, "No current animation."); + LogHelper.LogError(LogTag.UnitMotion, "No current animation."); return null; } var clip = clipInfos[0]; //选第一个 @@ -173,7 +173,7 @@ public class AnimatorLayerInfo public bool applySpeedCurve { get; set; } - UnitAction m_UnitAnimation; + UnitMotion m_UnitAnimation; Coroutine m_CalcPlaybackTimeCoroutine; @@ -181,7 +181,7 @@ public class AnimatorLayerInfo public string m_CurrentState; - public AnimatorLayerInfo(UnitAction unitAnimation, Animator animator, int layer) + public AnimatorLayerInfo(UnitMotion unitAnimation, Animator animator, int layer) { this.m_UnitAnimation = unitAnimation; this.m_Animator = animator; diff --git a/Erika/Assets/Scripts/Unit/Components/UnitAnimation/MonsterAnimation.cs b/Erika/Assets/Scripts/Unit/Components/UnitAnimation/MonsterAnimation.cs index b0b34924..2ead987d 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitAnimation/MonsterAnimation.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitAnimation/MonsterAnimation.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; -public class MonsterAnimation : UnitAction +public class MonsterAnimation : UnitMotion { public enum ELayer { @@ -96,12 +96,12 @@ public class MonsterAnimation : UnitAction private void Play(EActionState animState, float normalizedTime = float.NegativeInfinity) { - base.Play(animState.ToString(), normalizedTime); - } - - public void CrossFade(EActionState animState, float normalizedTransitionDuration, float normalizedTimeOffset = float.NegativeInfinity, float normalizedTransitionTime = 0.0f) + //base.Play(animState.ToString(), normalizedTime); + } + + public void CrossFade(EActionState animState, float normalizedTransitionDuration, float normalizedTimeOffset = float.NegativeInfinity, float normalizedTransitionTime = 0.0f) { - base.CrossFade(animState.ToString(), normalizedTransitionDuration, normalizedTimeOffset, normalizedTransitionTime); + //base.CrossFade(animState.ToString(), normalizedTransitionDuration, normalizedTimeOffset, normalizedTransitionTime); } } diff --git a/Erika/Assets/Scripts/Unit/Components/UnitAnimation/PCAnimation.cs b/Erika/Assets/Scripts/Unit/Components/UnitAnimation/PCAnimation.cs index f6d19495..30dba3eb 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitAnimation/PCAnimation.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitAnimation/PCAnimation.cs @@ -4,7 +4,7 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; -public class PCAnimation : UnitAction +public class PCAnimation : UnitMotion { #if !ANIM_CROSS_FADE diff --git a/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitAction.cs b/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitAction.cs deleted file mode 100644 index 9a398404..00000000 --- a/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitAction.cs +++ /dev/null @@ -1,238 +0,0 @@ -#define ANIM_CROSS_FADE -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -#if UNITY_EDITOR -using UnityEditor; -#endif - -//https://docs.unity3d.com/ScriptReference/AnimatorOverrideController.html -//https://docs.unity3d.com/ScriptReference/AnimatorOverrideController.ApplyOverrides.html - -/// -/// 角色动作管理 -/// http://unitylore.org/wiki/doku.php?id=l3y0gj -/// -[DisallowMultipleComponent] -public class UnitAction : UnitComponent -{ - // 角色的所有动作数据,包括(动画、事件、RM) - //public UnitActionData m_ActionData; - - // 当前动作,和AnimatorState不同,忽略过渡,即时切换 - protected string m_CurrentAction = "Idle"; - public string currentAction - { - get - { - return m_CurrentAction; - } - set - { - m_CurrentAction = value; - m_Dirty = true; - } - } - - private bool m_Dirty = true; - - public Animator animator { get { return m_Animator; } } - protected Animator m_Animator; - - public bool isInTransition - { - get - { - return m_Animator.IsInTransition(0); - } - } - - // 当前动作的AnimationData - private AnimationData m_CachedAnimationData; - public AnimationData animationData - { - get - { - if (m_Dirty) - { - //m_CachedAnimationData = m_ActionData.GetAnimationData(currentAction); - m_Dirty = false; - } - return m_CachedAnimationData; - } - } - - // 当前动作的动画片段 - public AnimationClip animationClip - { - get - { - if(animationData != null) - { - AnimationClip clip = ResourceManager.Instance.LoadAsset(animationData.animationPath); - return clip; - } - return null; - } - } - - public float playbackNormalizedTime - { - get - { - AnimatorStateInfo state = stateInfo; - if (!state.loop && state.normalizedTime > 1) - return 1; - return state.normalizedTime % 1f; - } - } - - public AnimatorStateInfo stateInfo - { - get - { - AnimatorStateInfo stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); - if (isInTransition) // 过渡中的动作认为当前动作是下一个动作 - { - stateInfo = m_Animator.GetNextAnimatorStateInfo(0); - } - return stateInfo; - } - } - - public int stateHash - { - get - { - return stateInfo.shortNameHash; - } - } - - // 并非准确的播放时间,只是逻辑时间,因为动画会加速减速 - public float playbackTimeInSeconds - { - get - { - return playbackNormalizedTime * animationClip.length; - } - } - - TimelineEventProxy m_TimelineEventProxy; - - public float playbackSpeed - { - get - { - return m_Animator.GetFloat("PlaybackSpeed" + 0); - } - set - { - float v = Mathf.Clamp(value, 0, 10); - m_Animator.SetFloat("PlaybackSpeed" + 0, v); - } - } - - public override void OnUpdate() - { - base.OnUpdate(); - // 执行事件 - m_TimelineEventProxy.ExecuteAnimationEvents(animationData, playbackTimeInSeconds * TimelineEventProxy.FPS); - - // 播放速度控制 - if (/*applySpeedCurve && */animationData != null && animationData.speedCurve != null) - { - playbackSpeed = animationData.speedCurve.Evaluate(playbackNormalizedTime); - } - } - - public bool IsToggleOpen(EAnimationToogle toggle) - { - return animationData.IsToggleOpen(toggle, playbackNormalizedTime); - } - - public override void Initialize() - { - base.Initialize(); - - } - - public override void OnPostInitialize() - { - base.OnPostInitialize(); - - m_TimelineEventProxy = new TimelineEventProxy(this.owner); - playbackSpeed = 1f; - } - - /// - /// 直接播放动作 - /// - /// - /// - /// - public void Play(string targetAction, float normalizedTime = float.NegativeInfinity) - { - currentAction = targetAction; - - m_Animator.Play(targetAction, 0, normalizedTime); - m_TimelineEventProxy.ResetPrevAnimationData(); - - UnitRootMotion rm = m_Owner.GetComponent(); - if(rm) - { - rm.OnAnimationChange(); - } - } - - /// - /// CrossFade - /// - /// - /// - /// - /// - /// - public void CrossFade(string targetAction, float normalizedTransitionDuration, float normalizedTimeOffset = float.NegativeInfinity, float normalizedTransitionTime = 0.0f) - { - //TransitionData transition = m_ActionData.GetTransitionData(currentAction, targetAction); - //if(transition != null) - //{ - // if(transition.type == TransitionData.TransitionType.NormalizedTime) - // { - // m_Animator.CrossFade(targetAction, transition.duration, 0, normalizedTimeOffset, normalizedTransitionTime); - // } - // else if(transition.type == TransitionData.TransitionType.FixedTime) - // { - // m_Animator.CrossFadeInFixedTime(targetAction, transition.duration, 0, normalizedTimeOffset, normalizedTransitionTime); - // } - //} - //else - //{ - // m_Animator.CrossFade(targetAction, normalizedTransitionDuration, 0, normalizedTimeOffset, normalizedTransitionTime); - //} - //currentAction = targetAction; - - //m_TimelineEventProxy.ResetPrevAnimationData(); - - //UnitRootMotion rm = m_Owner.GetComponent(); - //if (rm) - //{ - // rm.OnAnimationChange(); - //} - } - - /// - /// 切换动作 - /// - /// - public void SwitchAction(string targetAction) - { - - } - - public void PlayMotion(int motionId) - { - } - -} diff --git a/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitAction.cs.meta b/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitAction.cs.meta deleted file mode 100644 index d9a25bcd..00000000 --- a/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitAction.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e99a41ae04c2aca428c3f0d1bda239c4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitMotion.cs b/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitMotion.cs new file mode 100644 index 00000000..49995d19 --- /dev/null +++ b/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitMotion.cs @@ -0,0 +1,302 @@ +#define ANIM_CROSS_FADE +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + +//https://docs.unity3d.com/ScriptReference/AnimatorOverrideController.html +//https://docs.unity3d.com/ScriptReference/AnimatorOverrideController.ApplyOverrides.html + +/// +/// 角色动画管理 +/// http://unitylore.org/wiki/doku.php?id=l3y0gj +/// +[DisallowMultipleComponent] +public class UnitMotion : UnitComponent +{ + public Animator animator { get { return m_Animator; } } + protected Animator m_Animator; + + protected AnimatorOverrideController m_OverrideController; + + // 角色的所有动作数据,包括(动画、事件、RM) + public UnitMotionData m_MotionData; + + // 当前动作 + protected int m_currentMotionIDID; + public int currentMotionID + { + get + { + return m_currentMotionIDID; + } + set + { + m_currentMotionIDID = value; + m_Dirty = true; + } + } + + private bool m_Dirty = true; + + public bool isInTransition + { + get + { + return m_Animator.IsInTransition(0); + } + } + + // 当前动作的AnimationData + private AnimationData m_CachedAnimationData; + public AnimationData animationData + { + get + { + if (m_Dirty) + { + //m_CachedAnimationData = m_ActionData.GetAnimationData(currentAction); + m_Dirty = false; + } + return m_CachedAnimationData; + } + } + + // 当前动作的动画片段 + public AnimationClip animationClip + { + get + { + if(animationData != null) + { + AnimationClip clip = ResourceManager.Instance.LoadAsset(animationData.animationPath); + return clip; + } + return null; + } + } + + public float playbackNormalizedTime + { + get + { + AnimatorStateInfo state = stateInfo; + if (!state.loop && state.normalizedTime > 1) + return 1; + return state.normalizedTime % 1f; + } + } + + public AnimatorStateInfo stateInfo + { + get + { + AnimatorStateInfo stateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); + if (isInTransition) // 过渡中的动作认为当前动作是下一个动作 + { + stateInfo = m_Animator.GetNextAnimatorStateInfo(0); + } + return stateInfo; + } + } + + public int stateHash + { + get + { + return stateInfo.shortNameHash; + } + } + + // 并非准确的播放时间,只是逻辑时间,因为动画会加速减速 + public float playbackTimeInSeconds + { + get + { + return playbackNormalizedTime * animationClip.length; + } + } + + TimelineEventProxy m_TimelineEventProxy; + + public float playbackSpeed + { + get + { + return m_Animator.GetFloat("PlaybackSpeed" + 0); + } + set + { + float v = Mathf.Clamp(value, 0, 10); + m_Animator.SetFloat("PlaybackSpeed" + 0, v); + } + } + + public override void OnUpdate() + { + base.OnUpdate(); + // 执行事件 + m_TimelineEventProxy.ExecuteAnimationEvents(animationData, playbackTimeInSeconds * TimelineEventProxy.FPS); + + // 播放速度控制 + if (/*applySpeedCurve && */animationData != null && animationData.speedCurve != null) + { + playbackSpeed = animationData.speedCurve.Evaluate(playbackNormalizedTime); + } + } + + public bool IsToggleOpen(EAnimationToogle toggle) + { + return animationData.IsToggleOpen(toggle, playbackNormalizedTime); + } + + public override void Initialize() + { + base.Initialize(); + + } + + public override void OnPostInitialize() + { + base.OnPostInitialize(); + + m_TimelineEventProxy = new TimelineEventProxy(this.owner); + playbackSpeed = 1f; + } + + /// + /// 用uid拿motion数据 + /// + /// + /// + public MotionData GetMotionDataById(int id) + { + return m_MotionData.GetMotionDataById(id); + } + + /// + /// 用逻辑类型拿motion数据,返回第一个符合type的motion + /// + /// + /// + public MotionData GetMotionDataByAnimationType(EAnimationType type) + { + return m_MotionData.GetMotionDataByAnimationType(type); + } + + #region 播放动作,对外屏蔽Animator + + /// + /// CrossFade过渡到目标动作 + /// + /// + /// + /// + /// + /// + public void CrossFade(int targetMotionId, float normalizedTransitionDuration, float normalizedTimeOffset = float.NegativeInfinity, float normalizedTransitionTime = 0.0f) + { + TransitionData transition = m_MotionData.GetTransitionData(currentMotionID, targetMotionId); + MotionData motion = m_MotionData.GetMotionDataById(targetMotionId); + string stateName = motion.animatorState.ToString(); + bool overrideAnim = SyncOverrideAnim(stateName, motion.animationData.animationPath); + if (!overrideAnim) + return; + + if (transition != null) + { + if (transition.type == TransitionData.TransitionType.NormalizedTime) + { + m_Animator.CrossFade(stateName, transition.duration, 0, normalizedTimeOffset, normalizedTransitionTime); + } + else if (transition.type == TransitionData.TransitionType.FixedTime) + { + m_Animator.CrossFadeInFixedTime(stateName, transition.duration, 0, normalizedTimeOffset, normalizedTransitionTime); + } + } + else + { + m_Animator.CrossFade(stateName, normalizedTransitionDuration, 0, normalizedTimeOffset, normalizedTransitionTime); + } + + currentMotionID = targetMotionId; + m_TimelineEventProxy.ResetPrevAnimationData(); + UnitRootMotion rm = m_Owner.GetComponent(); + if (rm) + { + rm.OnAnimationChange(); + } + } + + /// + /// 直接播放目标动作 + /// + /// + public void PlayMotion(int motionId) + { + MotionData motion = m_MotionData.GetMotionDataById(motionId); + PlayMotion(motion); + } + + /// + /// 直接播放目标动作 + /// + /// + public void PlayMotion(MotionData motion) + { + string stateName = motion.animatorState.ToString(); + bool overrideAnim = SyncOverrideAnim(stateName, motion.animationData.animationPath); + if (!overrideAnim) + return; + + m_Animator.Play(stateName); + + currentMotionID = motion.uid; + m_TimelineEventProxy.ResetPrevAnimationData(); + UnitRootMotion rm = m_Owner.GetComponent(); + if (rm) + { + rm.OnAnimationChange(); + } + } + + #endregion + + #region 覆盖动画状态机片段 + + /// + /// 设置override controller对应片段的覆盖片段 + /// + /// 原placeholder片段名(也可以认为是状态名) + /// + private bool SyncOverrideAnim(string target, AnimationClip clip) + { + if(m_Animator != null) + { + m_OverrideController[target] = clip != null ? clip : null; + return true; + } + return false; + } + + private bool SyncOverrideAnim(string target, string path) + { + AnimationClip clip = ResourceManager.Instance.LoadAsset(path); + if (clip == null) + return false; + return SyncOverrideAnim(target, clip); + } + + private bool SyncOverrideAnim(MotionData motion) + { + string state = motion.animatorState.ToString(); + string path = motion.animationData.animationPath; + return SyncOverrideAnim(state, path); + } + + #endregion + +} diff --git a/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitMotion.cs.meta b/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitMotion.cs.meta new file mode 100644 index 00000000..962972c8 --- /dev/null +++ b/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitMotion.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 62ade175c9b245544bf8a20842c2cbfb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Erika/Assets/Scripts/Unit/Components/UnitSkill.cs b/Erika/Assets/Scripts/Unit/Components/UnitSkill.cs index 92676e73..7acf8e5f 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitSkill.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitSkill.cs @@ -8,7 +8,25 @@ using UnityEngine; [DisallowMultipleComponent] public class UnitSkill : UnitComponent { + //角色所有技能数据 + protected List m_AllSkills; + //所有连击数据 + protected List m_AllCombos; + protected UnitMotion m_UnitMotion + { + get + { + return owner.unitAnimation; + } + } + protected UnitStatemachine m_UnitStatemachine + { + get + { + return owner.unitStatemachine; + } + } } diff --git a/Erika/Assets/Scripts/Unit/Components/UnitState/Erika/PCState_States.cs b/Erika/Assets/Scripts/Unit/Components/UnitState/Erika/PCState_States.cs index d81abc50..e445ef92 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitState/Erika/PCState_States.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitState/Erika/PCState_States.cs @@ -93,7 +93,7 @@ public partial class PCState : UnitState if (m_Owner.isTowardRight && !param.isRight || !m_Owner.isTowardRight && param.isRight) { - //m_Owner.pcAnimation.Play(UnitAction.EActionState.Turn); + //m_Owner.pcAnimation.Play(UnitMotion.EActionState.Turn); //yield return new WaitForActionReachEnd(m_Owner.pcAnimation); //if (param.isRight) // m_Owner.transform.rotation = Quaternion.Euler(0, 0, 0); diff --git a/Erika/Assets/Scripts/Unit/Components/UnitState/MonsterState.cs b/Erika/Assets/Scripts/Unit/Components/UnitState/MonsterState.cs index fd2251b1..a4a31bde 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitState/MonsterState.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitState/MonsterState.cs @@ -29,7 +29,7 @@ public class MonsterState : UnitState [SerializeField] private EUnitState m_State; public EUnitState CurrentState { get { return m_State; } } - UnitAction unitAnimation { get { return m_Owner.unitAnimation; } } + UnitMotion unitAnimation { get { return m_Owner.unitAnimation; } } public override void Initialize() { diff --git a/Erika/Assets/Scripts/Unit/Controller/UnitController.cs b/Erika/Assets/Scripts/Unit/Controller/UnitController.cs index df587f85..d038831b 100644 --- a/Erika/Assets/Scripts/Unit/Controller/UnitController.cs +++ b/Erika/Assets/Scripts/Unit/Controller/UnitController.cs @@ -34,7 +34,7 @@ public class UnitController : MonoBehaviour/*, Interactable*/ public MonsterState monsterState { get { return unitState as MonsterState; } } - public UnitAction unitAnimation; + public UnitMotion unitAnimation; public PCAnimation pcAnimation { get { return unitAnimation as PCAnimation; } } public MonsterAnimation monsterAnimation { get { return unitAnimation as MonsterAnimation; } } diff --git a/Erika/Assets/Scripts/Unit/TimelineEventProxy.cs b/Erika/Assets/Scripts/Unit/TimelineEventProxy.cs index 61981620..21a474cb 100644 --- a/Erika/Assets/Scripts/Unit/TimelineEventProxy.cs +++ b/Erika/Assets/Scripts/Unit/TimelineEventProxy.cs @@ -97,7 +97,7 @@ public partial class TimelineEventProxy public UnitController owner { get; private set; } - private UnitAction m_UnitAnimation { get { return owner.unitAnimation; } } + private UnitMotion m_UnitAnimation { get { return owner.unitAnimation; } } private AnimationData m_PrevAnimationData; diff --git a/Erika/Assets/Scripts/Unit/UnitMotionData.cs b/Erika/Assets/Scripts/Unit/UnitMotionData.cs index 5dc01498..851c0d3b 100644 --- a/Erika/Assets/Scripts/Unit/UnitMotionData.cs +++ b/Erika/Assets/Scripts/Unit/UnitMotionData.cs @@ -7,13 +7,17 @@ using UnityEngine; /// 动作元数据 /// [Serializable] -public struct MotionData +public class MotionData { [SerializeField] public bool hide; [SerializeField] public int uid; // 动作在角色作用域下的唯一编号 [SerializeField] public string note; - [SerializeField, Tooltip("理论上是角色能够访问动作数据的唯一一个入口")] public AnimationData animationData; // 理论上是角色能够访问动作数据的唯一一个入口,其他地方通过uid拿这里的数据 - [SerializeField] public EAnimatorState animatorState; + [SerializeField, Tooltip("理论上是角色能够访问动作数据的唯一一个入口, 其他地方通过uid拿这里的数据")] + public AnimationData animationData; + [SerializeField, Tooltip("在Animator Override Controller中替换的动画")] + public EAnimatorState animatorState; + [SerializeField, Tooltip("动画类型,用来嵌入gameplay逻辑")] + public EAnimationType animationType; } [Serializable] @@ -64,4 +68,61 @@ public class UnitMotionData : ScriptableObject [Space(5)] [Tooltip("设置动作间过渡时间")] public List overrideTransitions; + + #region 方法 + + /// + /// 用uid拿motion数据 + /// + /// + /// + public MotionData GetMotionDataById(int id) + { + if (allMotions == null || allMotions.Count == 0) + return null; + var motion = allMotions.Find(m => m.uid == id); + return motion; + } + + /// + /// 用逻辑类型拿motion数据,返回第一个符合type的motion + /// + /// + /// + public MotionData GetMotionDataByAnimationType(EAnimationType type) + { + if (allMotions == null || allMotions.Count == 0) + return null; + var motion = allMotions.Find(m => m.animationType == type); + return motion; + } + + /// + /// 根据uid拿到animation data + /// + /// + /// + public AnimationData GetAnimationData(int uid) + { + MotionData motion = GetMotionDataById(uid); + if (motion != null) + { + return motion.animationData; + } + return null; + } + + /// + /// 过渡时间Override + /// + /// + /// + /// + public TransitionData GetTransitionData(int from, int to) + { + var transition = overrideTransitions.Find(t => t.fromId == from && t.toId == to); + return transition; + } + + #endregion } diff --git a/Erika/Assets/Scripts/Unit/UnitRootMotion.cs b/Erika/Assets/Scripts/Unit/UnitRootMotion.cs index 4af74c9d..20562920 100644 --- a/Erika/Assets/Scripts/Unit/UnitRootMotion.cs +++ b/Erika/Assets/Scripts/Unit/UnitRootMotion.cs @@ -28,7 +28,7 @@ public class UnitRootMotion : UnitComponent private float m_PrevNormalTime; - Dictionary m_RootMotionDic = new Dictionary(); + Dictionary m_RootMotionDic = new Dictionary(); public void Reset() { diff --git a/Erika/Assets/Scripts/Utils/LogTag.cs b/Erika/Assets/Scripts/Utils/LogTag.cs index 7a735ee1..ff38cd25 100644 --- a/Erika/Assets/Scripts/Utils/LogTag.cs +++ b/Erika/Assets/Scripts/Utils/LogTag.cs @@ -6,7 +6,7 @@ public enum LogTag { Resources, - UnitAction, + UnitMotion, UnitState, } -- cgit v1.1-26-g67d0