Unity中释放输入轴后启用Rigidbody Kinematic的实现问题
解决方案
核心思路是通过检测输入轴的数值判断用户操作:当移动和转向轴的数值都为0时,启用刚体的isKinematic属性让坦克立刻停止滑行;只要任意一个轴有输入,就关闭该属性,允许坦克正常响应控制。
修改后的完整代码如下:
public class TankController : MonoBehaviour { public int m_PlayerNumber = 1; public float m_Speed = 12f; public float m_TurnSpeed = 180f; public AudioSource m_MovementAudio; public float m_PitchRange = 0.2f; private string m_MovementAxisName; private string m_TurnAxisName; private Rigidbody m_Rigidbody; private float m_MovementInputValue; private float m_TurnInputValue; private float m_OriginalPitch; private void Awake() { m_Rigidbody = GetComponent<Rigidbody>(); } private void OnEnable() { // 启用时默认关闭Kinematic,允许控制 m_Rigidbody.isKinematic = false; m_MovementInputValue = 0f; m_TurnInputValue = 0f; } private void OnDisable() { m_Rigidbody.isKinematic = true; } private void Start() { m_MovementAxisName = "CarroV" ; m_TurnAxisName = "CarroH"; // 初始化音频原始音调 m_OriginalPitch = m_MovementAudio.pitch; } private void Update() { m_MovementInputValue = Input.GetAxis(m_MovementAxisName); m_TurnInputValue = Input.GetAxis(m_TurnAxisName); EngineAudio(); // 核心判断:无任何输入时启用Kinematic,否则关闭 bool hasInput = Mathf.Abs(m_MovementInputValue) > 0.01f || Mathf.Abs(m_TurnInputValue) > 0.01f; m_Rigidbody.isKinematic = !hasInput; } private void FixedUpdate() { Move(); Turn(); } private void Move() { // 只有有移动输入时才执行移动逻辑 if (Mathf.Abs(m_MovementInputValue) > 0.01f) { Vector3 movement = transform.forward * m_MovementInputValue * m_Speed * Time.deltaTime; m_Rigidbody.MovePosition(m_Rigidbody.position + movement); } } private void Turn() { // 只有有转向输入时才执行转向逻辑 if (Mathf.Abs(m_TurnInputValue) > 0.01f) { float turn = m_TurnInputValue * m_TurnSpeed * Time.deltaTime; Quaternion turnRotation = Quaternion.Euler(0f, turn, 0f); m_Rigidbody.MoveRotation(m_Rigidbody.rotation * turnRotation); } } // 补全原代码未实现的引擎音频逻辑 private void EngineAudio() { if (Mathf.Abs(m_MovementInputValue) < 0.1f && Mathf.Abs(m_TurnInputValue) < 0.1f) { if (m_MovementAudio.isPlaying) { m_MovementAudio.Stop(); } } else { if (!m_MovementAudio.isPlaying) { m_MovementAudio.Play(); } float pitch = m_OriginalPitch + Random.Range(-m_PitchRange, m_PitchRange); m_MovementAudio.pitch = pitch; } } }
关键改动说明:
- 在
Update中添加输入检测:用Mathf.Abs过滤输入轴的微小波动,无输入时设置isKinematic = true锁住刚体,彻底解决滑行问题;有输入时关闭该属性,保证正常控制。 - 在
Move和Turn方法中增加输入判断,避免无操作时执行无效的移动/转向调用。 - 补全了原代码遗漏的音频初始化和播放逻辑,保持功能完整性(不需要可直接删除)。
内容的提问来源于stack exchange,提问作者Ricardo Mendoza
相关产品推荐
相关产品推荐

