Unity中奔跑状态仅瞬现:无法稳定切换至running状态的问题求助
解决Unity 2D平台游戏奔跑仅触发一瞬间的问题
嘿,我一眼就看出问题所在啦——你误用了Unity的输入检测API,导致奔跑状态只能在按键按下的第一帧生效,没法持续触发。咱们一步步来修复:
问题根源
GetKeyDown 和 GetButtonDown 这两个方法只在按键被按下的那单一帧返回true,而奔跑是需要按住Shift+方向键持续生效的操作,所以得换成检测「按键是否处于按住状态」的API:GetKey 和 GetButton。
具体修改点
1. 移动逻辑的奔跑判断
你原来的奔跑代码只在同时按下方向键和Shift的瞬间执行一次,之后每一帧都会被上面的走路速度覆盖。应该调整逻辑,先判断是否处于奔跑状态,再统一设置速度:
把原来的:
// WALKING MOVEMENT rb.velocity = new Vector2(dirX * walkSpeed, rb.velocity.y); // RUNNING MOVEMENT if (Input.GetButtonDown("Horizontal") && Input.GetKeyDown(KeyCode.LeftShift)) { rb.velocity = new Vector2(dirX * runSpeed, rb.velocity.y); }
改成:
// 先判断是否处于奔跑状态 float currentSpeed = walkSpeed; if (Input.GetButton("Horizontal") && Input.GetKey(KeyCode.LeftShift)) { currentSpeed = runSpeed; } // 统一设置速度 rb.velocity = new Vector2(dirX * currentSpeed, rb.velocity.y);
2. 动画状态的奔跑判断
动画部分同样用了GetKeyDown,导致只有按下Shift的那帧会切换到奔跑动画,之后立刻变回走路。把两处Input.GetKeyDown(KeyCode.LeftShift)换成Input.GetKey(KeyCode.LeftShift):
修改后的UpdateAnimationState里的判断:
if (dirX > 0f) { if (Input.GetKey(KeyCode.LeftShift)) // 这里改成GetKey { state = MovementState.running; } else { state = MovementState.walking; } sprite.flipX = false; } else if (dirX < 0f) { if (Input.GetKey(KeyCode.LeftShift)) // 这里也改成GetKey { state = MovementState.running; } else { state = MovementState.walking; } sprite.flipX = true; }
修改后的完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerMovement : MonoBehaviour { private Rigidbody2D rb; private SpriteRenderer sprite; private Animator anim; private float dirX = 0f; [SerializeField] private float walkSpeed = 3f; [SerializeField] private float runSpeed = 7f; [SerializeField] private float jumpForce = 14f; private enum MovementState { idle, walking, running, jumping, falling } void Start() { rb = GetComponent<Rigidbody2D>(); sprite = GetComponent<SpriteRenderer>(); anim = GetComponent<Animator>(); } void Update() { dirX = Input.GetAxisRaw("Horizontal"); // 移动逻辑:先判断奔跑状态,再设置速度 float currentSpeed = walkSpeed; if (Input.GetButton("Horizontal") && Input.GetKey(KeyCode.LeftShift)) { currentSpeed = runSpeed; } rb.velocity = new Vector2(dirX * currentSpeed, rb.velocity.y); // 跳跃逻辑保持不变 if (Input.GetButtonDown("Jump")) { rb.velocity = new Vector2(rb.velocity.x, jumpForce); } UpdateAnimationState(); } private void UpdateAnimationState() { MovementState state; // 奔跑、走路、 idle 动画判断 if (dirX > 0f) { if (Input.GetKey(KeyCode.LeftShift)) { state = MovementState.running; } else { state = MovementState.walking; } sprite.flipX = false; } else if (dirX < 0f) { if (Input.GetKey(KeyCode.LeftShift)) { state = MovementState.running; } else { state = MovementState.walking; } sprite.flipX = true; } else { state = MovementState.idle; } // 跳跃、下落动画保持不变 if (rb.velocity.y > .1f) { state = MovementState.jumping; } else if (rb.velocity.y < -.1f) { state = MovementState.falling; } anim.SetInteger("state", (int)state); } }
额外小建议
如果你想让控制更灵活(比如允许玩家在Unity输入设置里自定义奔跑键),可以在「Edit > Project Settings > Input Manager」里添加一个名为Run的输入轴,然后把代码里的Input.GetKey(KeyCode.LeftShift)换成Input.GetButton("Run"),这样以后改按键不用改代码啦~
内容的提问来源于stack exchange,提问作者Guapelididoo
相关产品推荐
相关产品推荐

