当前位置:   article > 正文

类银河恶魔城学习记录1-7-DashState源代码 P34

类银河恶魔城学习记录1-7-DashState源代码 P34
Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili

Player.cs
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using Unity.VisualScripting;
  4. using UnityEngine;
  5. public class Player : MonoBehaviour
  6. {
  7. [Header("Move Info")]
  8. public float moveSpeed;//定义速度,与xInput相乘控制速度的大小
  9. public float jumpForce;
  10. public float dashSpeed;//冲刺速度
  11. public float dashDuration;//持续时间
  12. [Header("Collision Info")]
  13. [SerializeField] private Transform groundCheck;//transform类,代表的时物体的位置,后面会来定位子组件的位置
  14. [SerializeField] private float groundCheckDistance;
  15. [SerializeField] private Transform wallCheck;//transform类,代表的时物体的位置,后面会来定位子组件的位置
  16. [SerializeField] private float wallCheckDistance;
  17. [SerializeField] private LayerMask whatIsGround;//LayerMask类,与Raycast配合,https://docs.unity3d.com/cn/current/ScriptReference/Physics.Raycast.html
  18. public int facingDir { get; private set; } = 1;
  19. private bool facingRight = true;//判断是否朝右
  20. #region 定义Unity组件
  21. public Animator anim { get; private set; }//这样才能配合着拿到自己身上的animator的控制权
  22. public Rigidbody2D rb { get; private set; }//配合拿到身上的Rigidbody2D组件控制权
  23. #endregion
  24. #region 定义States
  25. public PlayerStateMachine stateMachine { get; private set; }
  26. public PlayerIdleState idleState { get; private set; }
  27. public PlayerMoveState moveState { get; private set; }
  28. public PlayerJumpState jumpState { get; private set; }
  29. public PlayerAirState airState { get; private set; }
  30. public PlayerDashState dashState { get; private set; }
  31. #endregion
  32. private void Awake()
  33. {
  34. stateMachine = new PlayerStateMachine();
  35. //通过构造函数,在构造时传递信息
  36. idleState = new PlayerIdleState(this, stateMachine, "Idle");
  37. moveState = new PlayerMoveState(this, stateMachine, "Move");
  38. jumpState = new PlayerJumpState(this, stateMachine, "Jump");
  39. airState = new PlayerAirState(this, stateMachine, "Jump");
  40. dashState = new PlayerDashState(this, stateMachine, "Dash");
  41. //this 就是 Player这个类本身
  42. }//Awake初始化所以State,为所有State传入各自独有的参数,及animBool,以判断是否调用此动画(与animatoin配合完成)
  43. private void Start()
  44. {
  45. anim = GetComponentInChildren<Animator>();//拿到自己身上的animator的控制权
  46. rb = GetComponent<Rigidbody2D>();
  47. stateMachine.Initialize(idleState);
  48. }
  49. #region 定时器设置
  50. public float timer;
  51. public float cooldown;
  52. #endregion
  53. private void Update()//在mano中update会自动刷新但其他没有mano的不会故,需要在这个updata中调用其他脚本中的函数stateMachine.currentState.update以实现 //stateMachine中的update
  54. {
  55. stateMachine.currentState.Update();//反复调用CurrentState的Update函数
  56. timer -= Time.deltaTime;
  57. }
  58. public void SetVelocity(float _xVelocity,float _yVelocity)
  59. {
  60. rb.velocity = new Vector2(_xVelocity, _yVelocity);//将rb的velocity属性设置为对应的想要的二维向量。因为2D游戏的速度就是二维向量
  61. FlipController(_xVelocity);//在其他设置速度的时候调用翻转控制器
  62. }//控制速度的函数,此函数在其他State中可能会使用,但仅能通过player.SeVelocity调用
  63. public bool IsGroundDetected()
  64. {
  65. return Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckDistance, whatIsGround);
  66. }//通过RayCast检测是否挨着地面,https://docs.unity3d.com/cn/current/ScriptReference/Physics.Raycast.html
  67. //xxxxxxxx() => xxxxxxxx == xxxxxxxxxx() return xxxxxxxxx;
  68. private void OnDrawGizmos()
  69. {
  70. Gizmos.DrawLine(groundCheck.position, new Vector3(groundCheck.position.x, groundCheck.position.y - groundCheckDistance));//绘制一条从 from(前面的) 开始到 to(后面的) 的线。
  71. Gizmos.DrawLine(wallCheck.position, new Vector3(wallCheck.position.x + wallCheckDistance, wallCheck.position.y ));//绘制一条从 from(前面的) 开始到 to(后面的) 的线。
  72. }//画线函数
  73. public void Flip()
  74. {
  75. facingDir = facingDir * -1;
  76. facingRight = !facingRight;
  77. transform.Rotate(0, 180, 0);//旋转函数,transform不需要额外定义,因为他是自带的
  78. }//翻转函数
  79. public void FlipController(float _x)//目前设置x,目的时能在空中时也能转身
  80. {
  81. if(_x > 0 &&!facingRight)//当速度大于0且没有朝右时,翻转
  82. {
  83. Flip();
  84. }
  85. else if(_x < 0 && facingRight)
  86. {
  87. Flip();
  88. }
  89. }
  90. }

PlayerState.cs
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Security.Authentication.ExtendedProtection;
  4. using UnityEngine;
  5. //被继承的总类,后面的所以state都需要继承它
  6. //实际上Player并没有进入过这个状态,没有调用此脚本,所有的调用均属于此脚本的子脚本
  7. public class PlayerState
  8. {
  9. protected PlayerStateMachine stateMachine;//创建PlayerStateMachine类,以承接来自Player.cs传过来的东西
  10. protected Player player;//创建Player类,以承接来自Player.cs传过来的东西
  11. protected float stateTimer;
  12. #region Unity组件
  13. protected Rigidbody2D rb;//纯简化,将player.rb --> rb
  14. #endregion
  15. private string animBoolName;//控制此时的anim的BOOL值
  16. protected float xInput;//设置一个可以保存当前是否在按移动键的变量
  17. public PlayerState(Player _player,PlayerStateMachine _stateMachine,string _animBoolName)
  18. {
  19. this.player = _player;
  20. this.stateMachine = _stateMachine;
  21. this.animBoolName = _animBoolName;
  22. }//构造函数,用于传递信息
  23. public virtual void Enter()
  24. {
  25. player.anim.SetBool(animBoolName, true);//通过animator自带的函数,将animator里的Bool值改变为想要的值
  26. rb = player.rb;//纯简化,将player.rb --> rb
  27. }
  28. public virtual void Update()
  29. {
  30. stateTimer -= Time.deltaTime;//https://docs.unity3d.com/cn/current/ScriptReference/Time-deltaTime.html
  31. //从上一帧到当前帧的间隔(以秒为单位)(只读)。这个表达式就是表示每一帧都不断的减少时间
  32. player.anim.SetFloat("yVelocity", rb.velocity.y);//通过animator自带的函数,将animator里的Float值改变为想要的值,改变yVelocity以控制Jump与Fall动画的切换
  33. xInput = Input.GetAxisRaw("Horizontal");//对于键盘和游戏杆输入,该值将处于 -1...1 的范围内。 由于未对输入进行平滑处理,键盘输入将始终为 -1、0 或 1。 如果您想自己完成键盘输入的所有平滑处理,这非常有用。
  34. }
  35. public virtual void Exit()
  36. {
  37. player.anim.SetBool(animBoolName, false);//通过animator自带的函数,将animator里的Bool值改变为想要的值
  38. }
  39. }

PlayerStateMachine.cs
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class PlayerStateMachine
  5. {
  6. public PlayerState currentState { get; private set; }
  7. public void Initialize(PlayerState _startState)
  8. {
  9. currentState = _startState;
  10. currentState.Enter();
  11. }//初始化状态函数,及通过将idleState传送进来,以便于调用idleState中的Enter函数
  12. public void ChangeState(PlayerState _newState)
  13. {
  14. currentState.Exit();
  15. currentState = _newState;
  16. currentState.Enter();
  17. }//更改状态函数
  18. //1.调用当前状态的Exit函数,使动画为false
  19. //2.传入新的状态,替换原来的状态
  20. //3.调用新的状态的Enter函数
  21. }

PlayerGroundState.cs
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. //GroundState用于保证只有在Idle和Move这两个地面状态下才能调用某些函数,并且稍微减少一点代码量
  5. public class PlayerGroundState : PlayerState
  6. {
  7. public PlayerGroundState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
  8. {
  9. }
  10. public override void Enter()
  11. {
  12. base.Enter();
  13. }
  14. public override void Update()
  15. {
  16. base.Update();
  17. if(Input.GetKeyDown(KeyCode.LeftShift))
  18. {
  19. stateMachine.ChangeState(player.dashState);
  20. }
  21. if (Input.GetKeyDown(KeyCode.Space)&&player.IsGroundDetected())
  22. {
  23. stateMachine.ChangeState(player.jumpState);
  24. }//空格切换为跳跃状态
  25. }
  26. public override void Exit()
  27. {
  28. base.Exit();
  29. }
  30. }

PlayerIdleState.cs
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class PlayerIdleState : PlayerGroundState//继承函数,获得PlayerState里的所有函数和参数
  5. {
  6. public PlayerIdleState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
  7. {
  8. }//构造函数,用于传递信息。
  9. //当外补New出对象时,New出的对象里传入参数
  10. public override void Enter()
  11. {
  12. base.Enter();
  13. }
  14. public override void Exit()
  15. {
  16. base.Exit();
  17. }
  18. public override void Update()
  19. {
  20. base.Update();
  21. if(xInput != 0)
  22. {
  23. stateMachine.ChangeState(player.moveState);//在这里我们能使用Player里的东西,主要是因为我们通过构造函数传过来Player实体,如果不传,则无法使用已经存在了的Player实体。
  24. }
  25. }
  26. }

PlayerMoveState.cs
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class PlayerMoveState : PlayerGroundState
  5. {
  6. public PlayerMoveState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
  7. {
  8. }//构造函数,用于传递信息。
  9. //当外补New出对象时,New出的对象里传入参数
  10. public override void Enter()
  11. {
  12. base.Enter();
  13. }
  14. public override void Exit()
  15. {
  16. base.Exit();
  17. }
  18. public override void Update()
  19. {
  20. base.Update();
  21. player.SetVelocity(xInput*player.moveSpeed, rb.velocity.y);//player.rb.velocity.y默认的为0,player.moveSpeed在player中定义,但可以在Unity引擎中更改
  22. if (xInput==0)
  23. {
  24. stateMachine.ChangeState(player.idleState);//在这里我们能使用Player里的东西,主要是因为我们通过构造函数传过来Player实体,如果不传,则无法使用已经存在了的Player实体。
  25. }
  26. }
  27. }

PlayerJumpState.cs
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class PlayerJumpState : PlayerState
  5. {
  6. public PlayerJumpState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
  7. {
  8. }
  9. public override void Enter()
  10. {
  11. base.Enter();
  12. rb.velocity = new Vector2(rb.velocity.x, player.jumpForce);//将y轴速度改变
  13. }
  14. public override void Update()
  15. {
  16. base.Update();
  17. if (rb.velocity.y < 0)//当速度小于0时切换为airState
  18. {
  19. stateMachine.ChangeState(player.airState);//与其说是airState,不如说是FallState
  20. }
  21. }
  22. public override void Exit()
  23. {
  24. base.Exit();
  25. }
  26. }

PlayerAirState.cs
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class PlayerAirState : PlayerState
  5. {
  6. public PlayerAirState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
  7. {
  8. }
  9. public override void Enter()
  10. {
  11. base.Enter();
  12. }
  13. public override void Update()
  14. {
  15. base.Update();
  16. if (player.IsGroundDetected())
  17. {
  18. stateMachine.ChangeState(player.idleState);
  19. }
  20. }
  21. public override void Exit()
  22. {
  23. base.Exit();
  24. }
  25. }

PlayerDashState.cs
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class PlayerDashState : PlayerState
  5. { //由Ground进入
  6. public PlayerDashState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
  7. {
  8. }
  9. public override void Enter()
  10. {
  11. base.Enter();
  12. stateTimer = player.dashDuration;设置Dash可以保持的值
  13. player.SetVelocity(player.dashSpeed * player.facingDir, rb.velocity.y);
  14. }
  15. public override void Exit()
  16. {
  17. base.Exit();
  18. player.SetVelocity(0, rb.velocity.y);//当退出时使速度为0防止动作结束后速度不变导致的持续移动
  19. }
  20. public override void Update()
  21. {
  22. base.Update();
  23. if (stateTimer < 0)当timer小于0,切换
  24. {
  25. stateMachine.ChangeState(player.idleState);
  26. }
  27. }
  28. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/57313
推荐阅读
相关标签
  

闽ICP备14008679号