Unity学习记录-2D角色移动跳跃
角色移动
角色移动是一个持久性的动作,放在FixedUpdate中处理
- 获取输入
- 设置刚体的速度
- 根据需要调整角色贴图的朝向
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
void PlayerMove() { if (!isHited) { float movement = Input.GetAxisRaw("Horizontal"); playerRb.velocity = new Vector2(movement * moveSpeed * Time.fixedDeltaTime, playerRb.velocity.y); if (movement != 0) { this.gameObject.transform.localScale = new Vector3(movement, 1, 1); } } }
|
角色跳跃
- 如何解决多段跳中,跳跃次数刷新的问题?
- 多段跳中,跳跃次数的BUG主要原因是:角色在起跳的一瞬间,还是和地面层接触,在此瞬间跳跃次数会刷新
- 使用射线检测和Rigidbody的
IsTouchingLayers方法来检测是否接触地面
- 在落地的一瞬间(y轴速度小于0且触地)恢复跳跃次数
- 如何优化角色的跳跃手感?
- 在角色跳跃后下降的过程,将下落速度增大,让角色更快下落以优化手感
- 在角色向上跳跃时先将Rigidbody的y轴速度赋为0,再施加向上的力可以保证每次跳跃高度相同
- 角色向上跳跃时限制最大速度
整体代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
| using System.Collections; using System.Collections.Generic; using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))] public class PlayerMovement : MonoBehaviour { [Header("移动速度")] public float moveSpeed; [Header("跳跃力度")] public float jumpForce; [Header("跳跃次数")] public int jumpCount = 2; [Header("最大跳跃速度")] public float maxJumpSpeed;
private Rigidbody2D playerRb; private BoxCollider2D playerCollider; private int jumpTime; private bool isOnGround = false; private GameObject currentGround;
[SerializeField][Header("左侧检查点")] private GameObject leftCheckPoint; [SerializeField][Header("右侧检查点")] private GameObject rightCheckPoint;
[SerializeField]private bool isHited = false; [SerializeField] private LayerMask ground;
void Start() { playerRb = gameObject.GetComponent<Rigidbody2D>(); playerCollider = gameObject.GetComponent<BoxCollider2D>(); anim = GetComponent<Animator>(); if(GetComponent<PlayerInfo>().getSkillNum() == 1) { jumpCount = 3; } jumpTime = jumpCount; }
void FixedUpdate() { PlayerMove(); }
void Update() { PlayerJump(); BetterFalling(); CheckIsGround(); }
void PlayerMove() { if (!isHited) { float movement = Input.GetAxisRaw("Horizontal"); playerRb.velocity = new Vector2(movement * moveSpeed * Time.fixedDeltaTime, playerRb.velocity.y); if (movement != 0) { this.gameObject.transform.localScale = new Vector3(movement, 1, 1); } } }
void PlayerJump() { if(jumpTime>0) { if(Input.GetButtonDown("Jump")) { jumpTime--; playerRb.velocity = new Vector2(playerRb.velocity.x, 0); playerRb.AddForce(Vector2.up*jumpForce); anim.SetBool("isJumping", true); isOnGround = false; } } if(playerRb.velocity.y>maxJumpSpeed) { playerRb.velocity = new Vector2(playerRb.velocity.x, maxJumpSpeed); } }
void BetterFalling() { if(playerRb.velocity.y<0) { playerRb.velocity += Vector2.up * Physics2D.gravity.y * (3.0f)*Time.deltaTime; } }
void CheckIsGround() { RaycastHit2D left = Physics2D.Raycast(leftCheckPoint.transform.position, Vector2.down*0.03f, 0.03f,ground); RaycastHit2D right = Physics2D.Raycast(rightCheckPoint.transform.position, Vector2.down*0.03f, 0.03f,ground); bool rayCheckResult = left||right;
if (playerRb.IsTouchingLayers(ground) || rayCheckResult) { isOnGround = true; } else { isOnGround = false; }
if (playerRb.velocity.y<0 && (playerRb.IsTouchingLayers(ground)||rayCheckResult)) { jumpTime = jumpCount; } } }
|
多段跳——跳跃次数bug解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
void CheckIsGround() { RaycastHit2D left = Physics2D.Raycast(leftCheckPoint.transform.position, Vector2.down*0.03f, 0.03f,ground); RaycastHit2D right = Physics2D.Raycast(rightCheckPoint.transform.position, Vector2.down*0.03f, 0.03f,ground); bool rayCheckResult = left||right;
if (playerRb.IsTouchingLayers(ground) || rayCheckResult) { isOnGround = true; } else { isOnGround = false; }
if (playerRb.velocity.y<0 && (playerRb.IsTouchingLayers(ground)||rayCheckResult)) { jumpTime = jumpCount; } }
|
跳跃手感优化
1 2 3 4 5 6 7 8 9 10 11
|
void BetterFalling() { if(playerRb.velocity.y<0) { playerRb.velocity += Vector2.up * Physics2D.gravity.y * (3.0f)*Time.deltaTime; } }
|
也可以通过增加角色的重力来实现更快的起跳和落地,优化手感