diff options
Diffstat (limited to 'Erika/Assets/Scripts/Unit/Components')
13 files changed, 410 insertions, 16 deletions
diff --git a/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitMotion.cs b/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitMotion.cs index b211dc41..f8744f8e 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitMotion.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitAnimation/UnitMotion.cs @@ -38,6 +38,8 @@ public class UnitMotion : UnitComponent // 动画帧事件 private TimelineEventProxy m_TimelineEventProxy; + private const bool kForceUpdateAnimatorWhenTranslate = true; + #region 动作状态 // 当前动作 @@ -239,6 +241,24 @@ public class UnitMotion : UnitComponent } } + private float m_lastPlayingSpeed = 1; + private bool m_Playing = true; + + public bool playing + { + get + { + //return playbackSpeed != 0; + return m_Playing; + } + set + { + m_Playing = value; + if (!value) m_lastPlayingSpeed = playbackSpeed; + playbackSpeed = value ? m_lastPlayingSpeed : 0; + } + } + #endregion public override void OnUpdate() @@ -248,7 +268,7 @@ public class UnitMotion : UnitComponent m_TimelineEventProxy.ExecuteAnimationEvents(animationData, playbackClampedTimeInSeconds * TimelineEventProxy.FPS); // 播放速度控制 - if(animationData != null) + if(animationData != null && playing) { if(!animationData.actionSettings.disableTimeCurve) { @@ -303,6 +323,9 @@ public class UnitMotion : UnitComponent m_Animator = param.animator; m_OverrideController = param.overrideController; } + + m_Playing = true; + m_lastPlayingSpeed = 1; } public override void OnPostInitialize() @@ -442,6 +465,8 @@ public class UnitMotion : UnitComponent string trigger = "To" + stateName; m_Animator.SetTrigger(trigger); currentMotionID = motion.uid; + + OnPlayMotion(motion); } public void Trigger(int targetMotionId) @@ -460,6 +485,8 @@ public class UnitMotion : UnitComponent string trigger = "To" + stateName; m_Animator.SetTrigger(trigger); currentMotionID = motion.uid; + + OnPlayMotion(motion); } /// <summary> @@ -520,9 +547,11 @@ public class UnitMotion : UnitComponent { rm.OnAnimationChange(); } + + OnPlayMotion(motion); } - public void Play(EAnimationType animType) + public void Play(EAnimationType animType) { if (!m_MotionData.HasMotionAnimationType(animType)) return; @@ -563,12 +592,61 @@ public class UnitMotion : UnitComponent { rm.OnAnimationChange(); } + OnPlayMotion(motion); + } + + /// <summary> + /// 直接播放某动画的某一帧 + /// </summary> + /// <param name="motionId"></param> + /// <param name="normalizedClampedTime"></param> + public void PlayMotionFrame(int motionId, float normalizedClampedTime) + { + MotionData motion = m_MotionData.GetMotionDataById(motionId); + string stateName = motion.animatorState.ToString(); + bool overrideAnim = SyncOverrideAnim(stateName, motion.animationData.animationPath); + if (!overrideAnim) + return; + + ClearAllTriggers(); + + m_Animator.Play(stateName, 0, normalizedClampedTime); + + currentMotionID = motion.uid; + m_TimelineEventProxy.ResetPrevAnimationData(); + UnitRootMotion rm = m_Owner.GetComponent<UnitRootMotion>(); + if (rm) + { + rm.OnAnimationChange(); + } + OnPlayMotion(motion); + } + + #endregion + + #region 回调函数 + + void OnPlayMotion(MotionData motion) + { + if(kForceUpdateAnimatorWhenTranslate) + { + ForceUpdateAnimator(); + } + + owner.isInAir = motion.extraData.isInAir; + //if (motion.extraData.isInAir) + //{ + // owner.isInAir = true; + //} } #endregion #region Animator + /// <summary> + /// 强制调用一下animator.update + /// </summary> public void ForceUpdateAnimator() { float speed = m_Animator.speed; @@ -577,6 +655,20 @@ public class UnitMotion : UnitComponent m_Animator.speed = speed; } + public void ForceStopAnimator() + { + //m_Animator.StopPlayback(); + //m_Animator.speed = 0; + playing = false; + } + + public void ForceStartAnimator() + { + //m_Animator.StartPlayback(); + //m_Animator.speed = 1; + playing = true; + } + #endregion } diff --git a/Erika/Assets/Scripts/Unit/Components/UnitSkill.cs b/Erika/Assets/Scripts/Unit/Components/UnitSkill.cs index 485a49fb..f64eacf6 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitSkill.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitSkill.cs @@ -34,9 +34,11 @@ public class UnitSkill : UnitComponent #region 技能状态 // 连击池 private int m_CurrentCombo = 0; - private int m_CurrentComboIndex = 0; private List<int> m_AttackPool = new List<int>(); + private int m_PendingSkillIndexInCombo = 0; // 当前待播放的技能索引 + private int m_CurrentPlayingSkillIndexInCombo = -1; // 当前播放中的技能索引 + #endregion public override void Initialize(object obj = null) @@ -54,6 +56,8 @@ public class UnitSkill : UnitComponent if (m_AttackPool.Count != 0 && owner.unitMotion.IsChangeAble()) { + m_CurrentPlayingSkillIndexInCombo = m_PendingSkillIndexInCombo; + int skillId = m_AttackPool[0]; m_AttackPool.RemoveAt(0); @@ -88,7 +92,8 @@ public class UnitSkill : UnitComponent /// <returns></returns> public bool IsLink() { - return false; + return m_CurrentPlayingSkillIndexInCombo == m_PendingSkillIndexInCombo + || m_CurrentPlayingSkillIndexInCombo == -1; } public bool IsSkillMoveAble() @@ -96,6 +101,11 @@ public class UnitSkill : UnitComponent return false; } + public bool CanCastSkill() + { + return true; + } + public bool CanSkillMove() { return false; @@ -112,16 +122,17 @@ public class UnitSkill : UnitComponent if (m_CurrentCombo != comboId) { m_CurrentCombo = comboId; - m_CurrentComboIndex = 0; + m_PendingSkillIndexInCombo = 0; + m_CurrentPlayingSkillIndexInCombo = -1; int skillId = combo.skills[0]; m_AttackPool.Add(skillId); } else { - if (++m_CurrentComboIndex < combo.skills.Count) + if (++m_PendingSkillIndexInCombo < combo.skills.Count) { - int skillId = combo.skills[m_CurrentComboIndex]; + int skillId = combo.skills[m_PendingSkillIndexInCombo]; if (skillId != 0) { m_AttackPool.Add(skillId); @@ -145,7 +156,8 @@ public class UnitSkill : UnitComponent public void ClearCombo() { m_CurrentCombo = 0; - m_CurrentComboIndex = 0; + m_PendingSkillIndexInCombo = 0; + m_CurrentPlayingSkillIndexInCombo = -1; m_AttackPool.Clear(); } diff --git a/Erika/Assets/Scripts/Unit/Components/UnitState/UnitState.cs b/Erika/Assets/Scripts/Unit/Components/UnitState/UnitState.cs index c9a39513..8de093de 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitState/UnitState.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitState/UnitState.cs @@ -25,9 +25,10 @@ public class UnitState : UnitComponent {
get
{
- if (!owner.unitMotion.animationData.HasProperty(EAnimationProperty.Endpoint))
- return false;
- return owner.unitMotion.playbackClampedNormalizedTime >= owner.unitMotion.animationData.GetProperty(EAnimationProperty.Endpoint);
+ //if (!owner.unitMotion.animationData.HasProperty(EAnimationProperty.Endpoint))
+ // return false;
+ //return owner.unitMotion.playbackClampedNormalizedTime >= owner.unitMotion.animationData.GetProperty(EAnimationProperty.Endpoint);
+ return false;
}
} diff --git a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/IdleState.cs b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/IdleState.cs index e7763708..7eb4f67f 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/IdleState.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/IdleState.cs @@ -12,6 +12,8 @@ namespace UnitStates.Common { } + public bool bCrossfade; + public override void ModifyNextState(EUnitState state, UnitStateBase nextState) { } @@ -21,11 +23,26 @@ namespace UnitStates.Common if(m_Owner.isInAir) { //m_Owner.unitStatemachine.ChangeState(EUnitState.Landing); + UnitStates.Common.LandingState.Param landingParam = new LandingState.Param(); + landingParam.height = m_Owner.height; + landingParam.process = LandingState.EProcess.Landing_Loop; + landingParam.useLastMotion = false; + landingParam.lastMotion = unitMotion.currentMotionData; + fsm.ChangeState(EUnitState.Landing, landingParam); } else { - m_Motion.Trigger(EAnimationType.Idle); + if (bCrossfade) + { + MotionData motion = m_Motion.GetMotionDataByAnimationType(EAnimationType.Idle); + m_Motion.CrossFade(motion.uid, 1f, motion.extraData.crossfadeNormalizedTimeOffset); + } + else + { + m_Motion.Trigger(EAnimationType.Idle); + } } + bCrossfade = false; } public override void OnExit() diff --git a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/JumpState.cs b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/JumpState.cs index a5f3bc36..7677d69b 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/JumpState.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/JumpState.cs @@ -40,6 +40,10 @@ namespace UnitStates.Common { (nextState as MoveState).useCrossfade = true; } + else if(state == EUnitState.Idle) + { + (nextState as IdleState).bCrossfade = true; + } } public override void OnEnter(IStateParam obj) diff --git a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/LandingState.cs b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/LandingState.cs new file mode 100644 index 00000000..0c43d684 --- /dev/null +++ b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/LandingState.cs @@ -0,0 +1,194 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace UnitStates.Common +{ + + public class LandingState : UnitStateBase + { + // 下落的子步骤 + // 4: Rising-> Loop-> Landing-> Ground + // 3: Rising-> Loop-> (Landing+Ground) + // 2: (Rising+Loop+Landing)-> Ground + // 2: (Rising+Loop)-> (Landing+Ground) + public enum EProcess + { + None = 0, + + Landing_Loop = 1, // 滞空 + Landing_Landing = 2, // 下降 + Landing_Ground = 3, // 着陆 + } + + private EProcess m_Process; + private Coroutine m_coProcess; + private bool m_UseLastMotion; + private MotionData m_LastMotion; + + private float m_XSpeed; + + public struct Param : IStateParam + { + public EProcess process; // + public float height; // 下落高度 + + // 使用上一个动作的最后一帧作为下落动作 + public bool useLastMotion; + public MotionData lastMotion; + } + + public override void ModifyNextState(EUnitState state, UnitStateBase nextState) + { + if (state == EUnitState.Move) + { + (nextState as MoveState).useCrossfade = true; + } + else if (state == EUnitState.Idle) + { + (nextState as IdleState).bCrossfade = true; + } + } + + public override void OnEnter(IStateParam obj) + { + Param param = (Param)obj; + + m_Process = param.process; + m_UseLastMotion = param.useLastMotion; + m_LastMotion = param.lastMotion; + + GoToProcess(m_Process); + + m_Owner.isGrounding = false; + } + + public override void OnExit() + { + if(m_Process == EProcess.Landing_Loop && m_UseLastMotion) + { + m_Owner.unitMotion.ForceStartAnimator(); + } + if (m_coProcess != null) + { + fsm.StopCoroutine(m_coProcess); + } + m_Process = EProcess.None; + m_XSpeed = 0; + } + + public override void OnFixedUpdate() + { + } + + public override void OnUpdate() + { + if (m_Process != EProcess.Landing_Ground) + { + EUnitDirection unitDir = InputManager.Instance.inputDir; + if (unitDir != EUnitDirection.None) + { + m_XSpeed = unitDir == EUnitDirection.Right ? 10f : -10f; + } + m_Owner.unitCharacterController.Move(new Vector3(m_XSpeed, 0, 0) * Time.deltaTime); + if (m_XSpeed != 0) + { + m_XSpeed = Mathf.Lerp(m_XSpeed, 0, 0.005f); + } + } + } + + void GoToProcess(EProcess nextProcess) + { + if (m_coProcess != null) + { + fsm.StopCoroutine(m_coProcess); + } + m_Process = nextProcess; + IEnumerator coroutine = null; + switch (m_Process) + { + case EProcess.None: + break; + case EProcess.Landing_Loop: + coroutine = Landing_Loop(); + break; + case EProcess.Landing_Landing: + coroutine = Landing_Landing(); + break; + case EProcess.Landing_Ground: + coroutine = Landing_Ground(); + break; + default: + break; + } + m_coProcess = fsm.StartCoroutine(coroutine); + } + + IEnumerator Landing_Loop() + { + if(m_UseLastMotion) + { + //m_Owner.unitMotion.CrossFade(m_LastMotion.uid, 0, 0.8f); + m_Owner.unitMotion.ForceStopAnimator(); + } + else + { + MotionData motion = m_Owner.unitMotion.GetMotionDataByAnimationType(EAnimationType.Jump_Loop); + m_Owner.unitMotion.CrossFade(motion.uid, motion.extraData.crossfadeNormalizedTransitionDuration, motion.extraData.crossfadeNormalizedTimeOffset); + } + + yield return null;// Animator.Update()一次 + + // 下落,用公式或预定义曲线都可以 + + float gravityMagnifier = 5f; + float g = -9.8f * gravityMagnifier; + float speed = -3; + + while (true) + { + speed += Time.deltaTime * g; + Vector3 deltaPos = new Vector3(0, speed * Time.deltaTime, 0); + m_Owner.unitCharacterController.Move(deltaPos); + float y = m_Owner.transform.position.y; + if (y <= 0.1f) + { + m_Owner.unitCharacterController.Move(new Vector3(0, -y, 0)); + + if (m_UseLastMotion) + { + m_Owner.unitMotion.ForceStartAnimator(); + } + + GoToProcess(EProcess.Landing_Ground); + } + yield return null; + } + } + + IEnumerator Landing_Landing() + { + while (true) + { + yield return null; + } + } + + IEnumerator Landing_Ground() + { + MotionData motion = m_Owner.unitMotion.GetMotionDataByAnimationType(EAnimationType.Jump_Ground); + m_Owner.unitMotion.CrossFade(motion.uid, motion.extraData.crossfadeNormalizedTransitionDuration, motion.extraData.crossfadeNormalizedTimeOffset); + yield return null;// Animator.Update()一次 + //m_Owner.unitMotion.ForceUpdateAnimator(); + m_Owner.isGrounding = true; + while (m_Owner.unitMotion.IsCurrent(motion.uid) && !m_Owner.unitMotion.IsReachEnd()) + { + yield return null; + } + m_Owner.isInAir = false; + ChangeState(EUnitState.Idle); + } + } + +}
\ No newline at end of file diff --git a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/LandingState.cs.meta b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/LandingState.cs.meta new file mode 100644 index 00000000..af880add --- /dev/null +++ b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/LandingState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c85e92adf42cce745ac2289ecdc2f003 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/SkillState.cs b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/SkillState.cs index f20d0c6d..459b7e35 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/SkillState.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/SkillState.cs @@ -28,7 +28,11 @@ namespace UnitStates.Common SkillData skill = m_Owner.unitSkill.GetSkillById(m_SkillId); m_MotionId = skill.motionId; - m_Owner.unitMotion.Trigger(m_MotionId); + MotionData motion = unitMotion.GetMotionDataById(m_MotionId); + + m_Owner.unitMotion.CrossFade(m_MotionId, 0, 0); + //, motion.extraData.crossfadeNormalizedTransitionDuration + //, motion.extraData.crossfadeNormalizedTimeOffset); } public override void OnExit() diff --git a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/TurnState.cs b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/TurnState.cs index 769e8fda..cade08ce 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/TurnState.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Common/TurnState.cs @@ -34,6 +34,7 @@ namespace UnitStates.Common public override void OnExit() { + m_Owner.DirectTurn(dir); } public override void OnFixedUpdate() @@ -46,7 +47,6 @@ namespace UnitStates.Common { if(unitMotion.IsReachEnd()) { - m_Owner.DirectTurn(dir); ChangeState(EUnitState.Idle); } } diff --git a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Erika/UltimateImpactState.cs b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Erika/UltimateImpactState.cs new file mode 100644 index 00000000..cd07bfa1 --- /dev/null +++ b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Erika/UltimateImpactState.cs @@ -0,0 +1,39 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace UnitStates.Erika +{ + + // https://dragonballfighterz.fandom.com/wiki/Gogeta_(SS4)/Move_List + // https://www.youtube.com/watch?v=A-Eb1tAczEk&ab_channel=BANDAINAMCOEurope + + public class UltimateImpactState : UnitStateBase + { + public override void ModifyNextState(EUnitState state, UnitStateBase nextState) + { + throw new System.NotImplementedException(); + } + + public override void OnEnter(IStateParam param) + { + throw new System.NotImplementedException(); + } + + public override void OnExit() + { + throw new System.NotImplementedException(); + } + + public override void OnFixedUpdate() + { + throw new System.NotImplementedException(); + } + + public override void OnUpdate() + { + throw new System.NotImplementedException(); + } + } + +} diff --git a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Erika/UltimateImpactState.cs.meta b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Erika/UltimateImpactState.cs.meta new file mode 100644 index 00000000..4dcea475 --- /dev/null +++ b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/Erika/UltimateImpactState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fdc4578bd6a45c64085c90a5f19a735d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/UnitStateBase.cs b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/UnitStateBase.cs index da5a900f..ed2fa60e 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/UnitStateBase.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/UnitStateBase.cs @@ -40,5 +40,6 @@ public abstract class UnitStateBase public abstract void OnUpdate(); public abstract void OnFixedUpdate(); public abstract void ModifyNextState(EUnitState state, UnitStateBase nextState); + public virtual void OnPrevStateExit(EUnitState fromStateE, UnitStateBase fromState){} }
\ No newline at end of file diff --git a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/UnitStatemachine.cs b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/UnitStatemachine.cs index fdaf2979..36dbfe8c 100644 --- a/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/UnitStatemachine.cs +++ b/Erika/Assets/Scripts/Unit/Components/UnitStatemachine/UnitStatemachine.cs @@ -43,6 +43,7 @@ public enum EUnitState // Unit State Preset Jump = 1 << 27, Turn = 1 << 28, // 转身 + Landing = 1 << 29, // 下落 _MAX_, } @@ -52,6 +53,8 @@ public enum EUnitState // Unit State Preset /// </summary> public sealed class UnitStatemachine : UnitComponent { + public bool DebugLog = false; + //public Dictionary<EUnitState, UnitStateBase> allStates //{ // get @@ -137,7 +140,7 @@ public sealed class UnitStatemachine : UnitComponent /// <param name="state"></param> public bool ChangeState(EUnitState state, UnitStateBase.IStateParam param = null, bool bForce = false) { - if(!IsChange(m_CurrentState, state, bForce)) + if (!IsChange(m_CurrentState, state, bForce)) return false; UnitStateBase currentState = GetState(m_CurrentState); @@ -147,9 +150,14 @@ public sealed class UnitStatemachine : UnitComponent currentState.ModifyNextState(state, nextState); currentState.OnExit(); } - m_CurrentState = state; + if (DebugLog) + { + Debug.Log(m_CurrentState + "->" + state); + } if (nextState != null) { + nextState.OnPrevStateExit(m_CurrentState, currentState); + m_CurrentState = state; nextState.OnEnter(param); } return true; |