diff options
Diffstat (limited to 'Assets/Scripts/Avatar/States')
18 files changed, 841 insertions, 0 deletions
diff --git a/Assets/Scripts/Avatar/States/AbilityBase.cs b/Assets/Scripts/Avatar/States/AbilityBase.cs new file mode 100644 index 00000000..4932a3de --- /dev/null +++ b/Assets/Scripts/Avatar/States/AbilityBase.cs @@ -0,0 +1,66 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +/// <summary> +/// 同一个角色同一个时间只能有一个state +/// </summary> +public abstract class StateBase +{ + protected int m_StateID; + public int ID + { + get + { + return m_StateID; + } + } + + public StateBase() + { + m_StateID = UIDManager.Acquire(); + } + + public virtual void OnInit() { } + + /// <summary> + /// 进入当前state的回调 + /// </summary> + public virtual void OnEnter() { } + + /// <summary> + /// 退出当前state的回调 + /// </summary> + public virtual void OnExit() { } + + /// <summary> + /// 当前state的update函数 + /// </summary> + public virtual void OnUpdate() { } + + /// <summary> + /// 在物理模拟之后更新 + /// </summary> + public virtual void OnPhysicsUpdate() { } + + /// <summary> + /// 过渡到下一个state的回调 + /// </summary> + /// <param name="to"></param> + public virtual void OnTranslate(StateBase to) { } + + /// <summary> + /// 检测到hitbox碰撞时的回调 + /// </summary> + public virtual void OnHit(HitInfo info) { } + + /// <summary> + /// 检测到hurtbox碰撞时的回调 + /// </summary> + public virtual void OnHurt(HurtInfo info) { } + + /// <summary> + /// 检测到defendbox碰撞时的回调 + /// </summary> + public virtual void OnDefend() { } +} diff --git a/Assets/Scripts/Avatar/States/AbilityBase.cs.meta b/Assets/Scripts/Avatar/States/AbilityBase.cs.meta new file mode 100644 index 00000000..79a6b7eb --- /dev/null +++ b/Assets/Scripts/Avatar/States/AbilityBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a3b3cfab4bd1dd74bb539687535b58f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Avatar/States/AttackState.cs b/Assets/Scripts/Avatar/States/AttackState.cs new file mode 100644 index 00000000..ae8f3b66 --- /dev/null +++ b/Assets/Scripts/Avatar/States/AttackState.cs @@ -0,0 +1,175 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public struct AttackStateConfig +{ + public Vector3 velocity; // velocity setup + public int motion; + public Animator animator; + public PhysicsBody body; +} + +// 单独的一个招式 +public class AttackState : StateBase +{ + AttackStateConfig m_Config = new AttackStateConfig(); + + private List<Trigger> m_Triggers = new List<Trigger>(); + + private List<Trigger> m_PhysicsTriggers = new List<Trigger>(); + + /// <summary> + /// 这个招式配置的hit + /// </summary> + private List<Hit> m_Hits = new List<Hit>(); + + /// <summary> + /// 从动画结束开始计时 + /// </summary> + float m_TimeCount; + public float ExpireTime + { + get + { + return m_TimeCount; + } + } + + /// <summary> + /// 这个招式的hit个数 + /// </summary> + public int HitCount + { + get + { + return m_Hits != null ? m_Hits.Count : 0; + } + } + + + public AttackState(Animator animator, int animation, PhysicsBody body = null) + { + m_Config.animator = animator; + m_Config.motion = animation; + m_Config.velocity = Vector3.zero; + m_Config.body = body; + } + + public AttackState(AttackStateConfig config) + { + m_Config = config; + } + + public override void OnInit() + { + } + + public override void OnDefend() + { + throw new System.NotImplementedException(); + } + + public override void OnEnter() + { + m_TimeCount = 0; + + m_Config.animator.CrossFade(m_Config.motion, 0); + + if(m_Config.body != null) + { + m_Config.body.LocalVelocity = m_Config.velocity; + } + + foreach(var hit in m_Hits) + { + hit.WipeRecords(); + } + + foreach(var trigger in m_Triggers) + { + trigger.Reset(); + } + } + + public override void OnExit() + { + m_TimeCount = 0; + } + + public override void OnHit(HitInfo info) + { + } + + public override void OnHurt(HurtInfo info) + { + } + + public override void OnTranslate(StateBase to) + { + } + + public override void OnUpdate() + { + AnimatorStateInfo info = m_Config.animator.GetCurrentAnimatorStateInfo(0); + if(info.shortNameHash == m_Config.motion && info.normalizedTime >= 0.99f) + { + m_TimeCount += Time.deltaTime; + } + foreach (var stateTrigger in m_Triggers) + { + if (stateTrigger.Update() && stateTrigger.Swallow) + break; + } + } + + // 在物理模拟之后 + public override void OnPhysicsUpdate() + { + foreach (var trigger in m_PhysicsTriggers) + { + if (trigger.Update() && trigger.Swallow) + break; + } + } + + public void AddTrigger(Trigger trigger) + { + if (trigger == null || m_Triggers.Contains(trigger)) + return; + m_Triggers.Add(trigger); + } + + public void AddPhysicsTrigger(Trigger trigger) + { + if (trigger == null || m_PhysicsTriggers.Contains(trigger)) + return; + m_PhysicsTriggers.Add(trigger); + } + + public void AddHitDefination(HitDefination defination) + { + Hit info = new Hit(); + info.defination = defination; + m_Hits.Add(info); + } + + // 获得当前时间点产生的hit + public Hit GetHit() + { + AnimatorStateInfo info = m_Config.animator.GetCurrentAnimatorStateInfo(0); + float normalizeTime = info.normalizedTime; + for (int i = 0; i< m_Hits.Count; ++i) + { + Hit hit = m_Hits[i]; + float start = hit.defination.start; + float end = hit.defination.end; + if(normalizeTime >= start && normalizeTime <= end) + { + return hit; + } + } + return null; + } + +} diff --git a/Assets/Scripts/Avatar/States/AttackState.cs.meta b/Assets/Scripts/Avatar/States/AttackState.cs.meta new file mode 100644 index 00000000..4159d2bc --- /dev/null +++ b/Assets/Scripts/Avatar/States/AttackState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eefcc728a2660c0459b0d79230cc4dec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Avatar/States/DashState.cs b/Assets/Scripts/Avatar/States/DashState.cs new file mode 100644 index 00000000..c9237d4c --- /dev/null +++ b/Assets/Scripts/Avatar/States/DashState.cs @@ -0,0 +1,18 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class DashState : MonoBehaviour +{ + // Start is called before the first frame update + void Start() + { + + } + + // Update is called once per frame + void Update() + { + + } +} diff --git a/Assets/Scripts/Avatar/States/DashState.cs.meta b/Assets/Scripts/Avatar/States/DashState.cs.meta new file mode 100644 index 00000000..c246c665 --- /dev/null +++ b/Assets/Scripts/Avatar/States/DashState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d5a31f4a65fbba429d0a2ff3b3a49a4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Avatar/States/DodgeState.cs b/Assets/Scripts/Avatar/States/DodgeState.cs new file mode 100644 index 00000000..58bc9301 --- /dev/null +++ b/Assets/Scripts/Avatar/States/DodgeState.cs @@ -0,0 +1,16 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +/// <summary> +/// Dodge state +/// </summary> +public class DodgeState : StateBase +{ + public DodgeState() + { + + } + +} diff --git a/Assets/Scripts/Avatar/States/DodgeState.cs.meta b/Assets/Scripts/Avatar/States/DodgeState.cs.meta new file mode 100644 index 00000000..e7297a88 --- /dev/null +++ b/Assets/Scripts/Avatar/States/DodgeState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 838e30895704e13479bfb0f5c06229e5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Avatar/States/HurtState.cs b/Assets/Scripts/Avatar/States/HurtState.cs new file mode 100644 index 00000000..db48d1a4 --- /dev/null +++ b/Assets/Scripts/Avatar/States/HurtState.cs @@ -0,0 +1,70 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +/// <summary> +/// 将伤害类型进行分类,决定不同的motion类型 +/// </summary> +public enum HurtType +{ + Light = 0, // 轻击 + Medium, // 中击 + Hard, // 重击 + Back, + Up, + Diagup +} + + +public class HurtState : StateBase +{ + Animator m_Animator; + + int m_AnimHash; + + /// <summary> + /// 在Idle状态时可以切换的state + /// </summary> + private List<Trigger> m_Triggers = new List<Trigger>(); + + public HurtState(Animator animator, int animation) + : base() + { + m_Animator = animator; + m_AnimHash = animation; + } + + public override void OnEnter() + { + m_Animator.CrossFadeInFixedTime(m_AnimHash, 0.25f); + + foreach (var trigger in m_Triggers) + { + trigger.Reset(); + } + } + + public override void OnInit() + { + base.OnInit(); + } + + public override void OnUpdate() + { + foreach (var trigger in m_Triggers) + { + if (trigger.Update() && trigger.Swallow) + break; + } + + base.OnUpdate(); + } + + public void AddTrigger(Trigger trigger) + { + if (trigger == null || m_Triggers.Contains(trigger)) + return; + m_Triggers.Add(trigger); + } + +} diff --git a/Assets/Scripts/Avatar/States/HurtState.cs.meta b/Assets/Scripts/Avatar/States/HurtState.cs.meta new file mode 100644 index 00000000..ba24ef88 --- /dev/null +++ b/Assets/Scripts/Avatar/States/HurtState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a7f21d9eef4527249a00204754fbff5b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Avatar/States/IdleState.cs b/Assets/Scripts/Avatar/States/IdleState.cs new file mode 100644 index 00000000..8b46b904 --- /dev/null +++ b/Assets/Scripts/Avatar/States/IdleState.cs @@ -0,0 +1,57 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +public class IdleState : StateBase +{ + Animator m_Animator; + + int m_AnimHash; + + /// <summary> + /// 在Idle状态时可以切换的state + /// </summary> + private List<Trigger> m_Triggers = new List<Trigger>(); + + public IdleState(Animator animator, int animation) + : base() + { + m_Animator = animator; + m_AnimHash = animation; + } + + public override void OnEnter() + { + m_Animator.CrossFadeInFixedTime(m_AnimHash, 0.25f); + + foreach (var trigger in m_Triggers) + { + trigger.Reset(); + } + } + + public override void OnInit() + { + base.OnInit(); + } + + public override void OnUpdate() + { + foreach(var trigger in m_Triggers) + { + if (trigger.Update() && trigger.Swallow) + break; + } + + base.OnUpdate(); + } + + public void AddTrigger(Trigger trigger) + { + if (trigger == null || m_Triggers.Contains(trigger)) + return; + m_Triggers.Add(trigger); + } + +} diff --git a/Assets/Scripts/Avatar/States/IdleState.cs.meta b/Assets/Scripts/Avatar/States/IdleState.cs.meta new file mode 100644 index 00000000..f872a5a6 --- /dev/null +++ b/Assets/Scripts/Avatar/States/IdleState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5761f8b5c41ec014381b1bd33ad42f1d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Avatar/States/JumpState.cs b/Assets/Scripts/Avatar/States/JumpState.cs new file mode 100644 index 00000000..1e172358 --- /dev/null +++ b/Assets/Scripts/Avatar/States/JumpState.cs @@ -0,0 +1,263 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public struct JumpStateConfig +{ + public PhysicsBody body; + public PhysicsPrimitive collider; + public Animator animator; + + public float neutralJumpSpeedY; // 垂直跳跃的基础速度 + public float fowardJumpSpeedX; // 向前跳跃的水平速度 + public float backwardJumpSpeedX; // 向后跳跃的水平速度(一般来说是负值) + + public int animJump; + public int animNU; + public int animFU; + public int animBU; + public int animND; + public int animFD; + public int animBD; + public int animJumpEnd; + + public bool skipStart; //没有准备动作 +} + +public class JumpState : StateBase +{ + public enum Direction + { + None, + Neutral, + Forward, + Backward + } + + public enum Stage + { + None, + Ready, + Up, + Down, + End, + } + + Direction m_Dir; + + PhysicsBody m_Body; + PhysicsPrimitive m_Collider; + + Animator m_Animator; + + public float m_NeutralJumpSpeedY; // 垂直跳跃的基础速度 + public float m_FowardJumpSpeedX; // 向前跳跃的水平速度 + public float m_BackwardJumpSpeedX; // 向后跳跃的水平速度(一般来说是负值) + + // jump motions + int m_AnimJumpStart; // on ground + int m_AnimJumpNeutralUpwards; + int m_AnimJumpNeutralDownwards; + int m_AnimJumpFwdUpwards; + int m_AnimJumpFwdDownwards; + int m_AnimJumpBackUpwards; + int m_AnimJumpBackDownwards; + int m_AnimJumpEnd; // on ground again + + int m_CurAnim; + Stage m_CurStage; + int m_CurUpMotion; + int m_CurDownMotion; + Vector3 m_CurInitVelocity; + + public Stage CurStage + { + get + { + return m_CurStage; + } + } + + public Direction CurDirection + { + get + { + return m_Dir; + } + } + + private List<Trigger> m_Triggers = new List<Trigger>(); + + bool m_SkipStart; + + public JumpState(JumpStateConfig config) + { + m_Body = config.body; + m_Collider = config.collider; + m_Animator = config.animator; + m_NeutralJumpSpeedY = config.neutralJumpSpeedY; + m_FowardJumpSpeedX = config.fowardJumpSpeedX; + m_BackwardJumpSpeedX = config.backwardJumpSpeedX; + m_AnimJumpStart = config.animJump; + m_AnimJumpNeutralUpwards = config.animNU; + m_AnimJumpNeutralDownwards = config.animND; + m_AnimJumpFwdUpwards = config.animFU; + m_AnimJumpFwdDownwards = config.animFD; + m_AnimJumpBackUpwards = config.animBU; + m_AnimJumpBackDownwards = config.animBD; + m_AnimJumpEnd = config.animJumpEnd; // on ground again + m_SkipStart = config.skipStart; + } + + public void SetDir(Direction dir) + { + m_Dir = dir; + } + + public override void OnEnter() + { + base.OnEnter(); + + m_CurAnim = 0; + + switch(m_Dir) + { + case Direction.Neutral: + m_CurUpMotion = m_AnimJumpNeutralUpwards; + m_CurDownMotion = m_AnimJumpNeutralDownwards; + m_CurInitVelocity = new Vector3(0, m_NeutralJumpSpeedY, 0); + break; + case Direction.Forward: + m_CurUpMotion = m_AnimJumpFwdUpwards; + m_CurDownMotion = m_AnimJumpFwdDownwards; + m_CurInitVelocity = new Vector3(m_FowardJumpSpeedX, m_NeutralJumpSpeedY, 0); + break; + case Direction.Backward: + m_CurUpMotion = m_AnimJumpBackUpwards; + m_CurDownMotion = m_AnimJumpBackDownwards; + m_CurInitVelocity = new Vector3(m_BackwardJumpSpeedX, m_NeutralJumpSpeedY, 0); + break; + } + + bool isOnGround = m_Collider.IsOnGround; + bool isUp = m_Body.Velocity.y > 0; + bool isDown = m_Body.Velocity.y < 0; + bool isFreeFall = Mathf.Approximately(m_Body.Velocity.y, 0); + + if (isOnGround && !m_SkipStart) + m_CurStage = Stage.Ready; + else if (isUp || isOnGround && m_SkipStart) + m_CurStage = Stage.Up; + else if (isDown || isFreeFall) + m_CurStage = Stage.Down; + } + + public override void OnUpdate() + { + foreach (var stateTrigger in m_Triggers) + { + if (stateTrigger.Update() && stateTrigger.Swallow) + return; + } + + AnimatorStateInfo motionInfo = m_Animator.GetCurrentAnimatorStateInfo(0); + + switch (m_CurStage) + { + case Stage.Ready: + if(m_CurAnim != m_AnimJumpStart) + { + m_Animator.CrossFade(m_AnimJumpStart, 0.2f); + m_CurAnim = m_AnimJumpStart; + } + if(motionInfo.shortNameHash == m_AnimJumpStart && motionInfo.normalizedTime >= 1f) + { + m_CurStage = Stage.Up; + } + break; + case Stage.Up: + if(m_CurAnim != m_CurUpMotion) + { + m_Body.LocalVelocity = m_CurInitVelocity; + m_Animator.CrossFade(m_CurUpMotion, 0.05f); + m_CurAnim = m_CurUpMotion; + } + if(m_Body.Velocity.y < 0) + { + m_CurStage = Stage.Down; + } + break; + case Stage.Down: + if(m_CurAnim != m_CurDownMotion) + { + m_Animator.CrossFade(m_CurDownMotion, 0.5f); + m_CurAnim = m_CurDownMotion; + } + if(m_Collider.IsOnGround) + { + m_CurStage = Stage.End; + } + break; + case Stage.End: + if(m_CurAnim != m_AnimJumpEnd) + { + m_Animator.CrossFade(m_AnimJumpEnd, 0.2f); + m_CurAnim = m_AnimJumpEnd; + } + break; + } + } + + public override void OnPhysicsUpdate() + { + base.OnPhysicsUpdate(); + } + + /// <summary> + /// 跳跃准备动作已经完毕 + /// </summary> + /// <returns></returns> + public bool IsJumpReady() + { + if (m_CurAnim != m_AnimJumpStart) + return false; + + AnimatorStateInfo state = m_Animator.GetCurrentAnimatorStateInfo(0); + if (state.shortNameHash == m_CurAnim && state.normalizedTime >= 1f) + return true; + + return false; + } + + /// <summary> + /// 结束 + /// </summary> + /// <returns></returns> + public bool IsJumpDone(float t = 1f) + { + if (m_CurStage == Stage.End) + { + AnimatorStateInfo state = m_Animator.GetCurrentAnimatorStateInfo(0); + return state.shortNameHash == m_AnimJumpEnd && state.normalizedTime >= t; + } + + return false; + } + + /// <summary> + /// 着地 + /// </summary> + /// <returns></returns> + public bool IsJumpGround() + { + return m_CurStage == Stage.End && m_Collider.IsOnGround; + } + + public void AddTrigger(Trigger trigger) + { + if (trigger == null || m_Triggers.Contains(trigger)) + return; + m_Triggers.Add(trigger); + } + +}
\ No newline at end of file diff --git a/Assets/Scripts/Avatar/States/JumpState.cs.meta b/Assets/Scripts/Avatar/States/JumpState.cs.meta new file mode 100644 index 00000000..3d18db1c --- /dev/null +++ b/Assets/Scripts/Avatar/States/JumpState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b3175c1ee1042e144b77c298e7b61eeb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Avatar/States/MoveState.cs b/Assets/Scripts/Avatar/States/MoveState.cs new file mode 100644 index 00000000..0fbfcddb --- /dev/null +++ b/Assets/Scripts/Avatar/States/MoveState.cs @@ -0,0 +1,65 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class MoveState : StateBase +{ + Animator m_Animator; + int m_AnimHash; + + /// <summary> + /// 在跑动状态时可以切换的state + /// </summary> + private List<Trigger> m_Triggers = new List<Trigger>(); + + public MoveState(Animator animator, int animation) + { + m_Animator = animator; + m_AnimHash = animation; + } + + public override void OnInit() + { + + } + + public override void OnDefend() + { + throw new System.NotImplementedException(); + } + + public override void OnEnter() + { + m_Animator.CrossFadeInFixedTime(m_AnimHash, 0.1f); + + foreach (var trigger in m_Triggers) + { + trigger.Reset(); + } + } + + public override void OnExit() + { + } + + public override void OnTranslate(StateBase to) + { + } + + public override void OnUpdate() + { + foreach (var stateTrigger in m_Triggers) + { + if (stateTrigger.Update() && stateTrigger.Swallow) + break; + } + } + + public void AddTrigger(Trigger trigger) + { + if (trigger == null || m_Triggers.Contains(trigger)) + return; + m_Triggers.Add(trigger); + } + +} diff --git a/Assets/Scripts/Avatar/States/MoveState.cs.meta b/Assets/Scripts/Avatar/States/MoveState.cs.meta new file mode 100644 index 00000000..eb1dbbd7 --- /dev/null +++ b/Assets/Scripts/Avatar/States/MoveState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae20739ccc918064dbe538d303d4be99 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Avatar/States/UberState.cs b/Assets/Scripts/Avatar/States/UberState.cs new file mode 100644 index 00000000..a0b6d940 --- /dev/null +++ b/Assets/Scripts/Avatar/States/UberState.cs @@ -0,0 +1,12 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +// 一个角色只能有一个uber state,用来处理状态的自动切换 +public abstract class UberState : StateBase +{ + public abstract void OnUpdate(); + + public abstract void OnPhysicsUpdate(); + +} diff --git a/Assets/Scripts/Avatar/States/UberState.cs.meta b/Assets/Scripts/Avatar/States/UberState.cs.meta new file mode 100644 index 00000000..b36ffc94 --- /dev/null +++ b/Assets/Scripts/Avatar/States/UberState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eafda132ea825cc46b32edfe09ebdecc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |