You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity:Player碰撞Capsule后无法销毁对象并提升速度问题求助

问题排查与解决方案

我来帮你梳理下代码里可能导致碰撞后速度不增加的问题,一步步来解决:

1. 先确认碰撞检测是否真的触发了

首先要排查OnCollisionEnter有没有被调用——如果碰撞逻辑根本没触发,后面的速度修改自然不会生效。你可以先在方法里加个日志测试:

void OnCollisionEnter(Collision other) {
    Debug.Log("碰撞到物体:" + other.gameObject.name);
    // 原有代码...
}

如果没看到日志输出,检查这几个关键点:

  • Player和Capsule都必须有碰撞体组件(比如BoxCollider/CapsuleCollider),且Is Trigger都不能勾选(如果用了Trigger,要改用OnTriggerEnter方法)。
  • 至少其中一个物体要有Rigidbody组件:如果Player的Rigidbody勾选了Is Kinematic,那Capsule必须有非Kinematic的Rigidbody才能触发碰撞。
  • 确认Capsule的名称是严格的"Capsule"(Unity物体名称区分大小写),或者更稳妥的是给Capsule加个专属标签(比如SpeedBoost),用标签判断比名称更可靠:
    if (other.gameObject.CompareTag("SpeedBoost")) {
        // 执行逻辑
    }
    

2. 速度赋值的优化与修正

你的代码里每次Update都会直接覆盖Rigidbody的速度,这里有两个小问题:

  • 不要每次都调用GetComponent<Rigidbody>(),既浪费性能也可能出意外,建议在Start里缓存组件:
    private Rigidbody rb;
    
    void Start() {
        rb = GetComponent<Rigidbody>();
    }
    
  • 速度修改要在原有基础上累加,而不是直接赋值为10(你试过+=10但没效果,大概率是因为碰撞没触发),比如speed += 10f;

3. 修改后的完整代码示例

结合上面的优化,调整后的代码如下:

public class PlayerController : MonoBehaviour { 
    public KeyCode moveL; 
    public KeyCode moveR; 
    public float horizontal = 0; 
    public int laneNum = 2; 
    public bool isControlLocked = false; // 把字符串改成布尔类型,更高效可靠
    public float speed;
    private Rigidbody rb;

    void Start() {
        rb = GetComponent<Rigidbody>(); // 缓存Rigidbody
    }

    void Update () { 
        rb.velocity = new Vector3(horizontal, GM.verticalVelocity, speed); 

        if (Input.GetKeyDown(moveL) && laneNum > 1 && !isControlLocked) { 
            horizontal = -2; 
            StartCoroutine(StopSlide()); 
            laneNum--; 
            isControlLocked = true; 
        } else if (Input.GetKeyDown(moveR) && laneNum < 3 && !isControlLocked) { 
            horizontal = 2; 
            laneNum++; 
            StartCoroutine(StopSlide()); 
            isControlLocked = true; 
        } 
    } 

    void OnCollisionEnter(Collision other) { 
        if(other.gameObject.tag == "lethal") { 
            Destroy(gameObject); 
        } 
        // 用标签判断Capsule,记得给Capsule设置对应标签
        if (other.gameObject.CompareTag("SpeedBoost")) { 
            Destroy(other.gameObject); 
            speed += 10f; // 累加速度
            Debug.Log("当前速度:" + speed); // 打印日志确认速度变化
        } 
    } 

    IEnumerator StopSlide() { 
        yield return new WaitForSeconds(.5f); 
        horizontal = 0; 
        isControlLocked = false; 
    } 
}

额外小建议

  • 可以给速度加个上限,防止无限增长导致游戏失衡,比如speed = Mathf.Min(speed + 10f, 50f);(限制最大速度为50)。
  • 布尔类型的isControlLocked比字符串判断更直观,也不容易因为拼写错误出问题。

内容的提问来源于stack exchange,提问作者user9727936

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:18:34