Unity中SpeedBoost无法取消,玩家持续保持加速状态求助
问题分析与修复方案
核心问题
- 触发SpeedBoost时直接修改了
moveSpeed的值为runSpeed,导致原本的基础移动速度被永久覆盖,后续无法正确恢复 - 计时器结束时的恢复逻辑完全错误,错误地将
runSpeed设置为已被修改的moveSpeed,等于没有恢复速度
修复步骤
- 新增默认速度存储变量:添加
private float defaultMoveSpeed;,专门保存Inspector中设置的初始基础移动速度,避免原数值被覆盖 - 初始化默认速度:在
Start()方法中记录初始基础速度:defaultMoveSpeed = moveSpeed; - 修正触发逻辑:触发SpeedBoost时,无需修改任何速度变量,只需开启
boosting状态并重置计时器 - 调整速度优先级:在Update中优先判断
boosting状态,再处理Shift键的奔跑逻辑,确保Boost期间强制使用奔跑速度 - 简化恢复逻辑:计时器结束时,仅关闭
boosting状态即可,无需修改速度变量
修改后的完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { public float moveSpeed; public Rigidbody2D rb; public float jumpForce; public float runSpeed; private float activeSpeed; private float defaultMoveSpeed; // 存储初始基础速度 public bool isGrounded; public Transform groundCheckPoint; public float groundCheckRadius; public LayerMask whatIsGround; public Animator ani; private float boostTimer; private bool boosting; // Start is called before the first frame update void Start() { boostTimer = 0; boosting = false; defaultMoveSpeed = moveSpeed; // 初始化默认基础速度 } // Update is called once per frame void Update() { isGrounded = Physics2D.OverlapCircle(groundCheckPoint.position, groundCheckRadius, whatIsGround); // 优先判断Boost状态,再处理Shift奔跑 activeSpeed = defaultMoveSpeed; if(boosting || Input.GetKey(KeyCode.LeftShift)) { activeSpeed = runSpeed; } rb.velocity = new Vector2 ( Input.GetAxisRaw("Horizontal") * activeSpeed, rb.velocity.y); if (Input.GetButtonDown("Jump")) { if(isGrounded == true) { rb.velocity = new Vector2(rb.velocity.x, jumpForce); } } if(rb.velocity.x > 0) { transform.localScale = Vector3.one; } if (rb.velocity.x < 0) { transform.localScale = new Vector3(-1f, 1f, 1f); } //动画控制 ani.SetFloat("speed", Mathf.Abs(rb.velocity.x)); ani.SetBool("isGrounded", isGrounded); ani.SetFloat("ySpeed", rb.velocity.y); if (boosting) { boostTimer += Time.deltaTime; if(boostTimer >= 3) { boostTimer = 0; boosting = false; // 仅关闭Boost状态 } } } void OnTriggerEnter2D(Collider2D other) { if (other.tag == "SpeedBoost") { boosting = true; boostTimer = 0; // 重置计时器 Destroy(other.gameObject); } } public void KnockBack() { rb.velocity = new Vector2(0f, jumpForce * .5f); ani.SetTrigger("isHit"); } }
内容的提问来源于stack exchange,提问作者Crexlo Dev
相关产品推荐
相关产品推荐

