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

Unity项目运行卡顿无报错,求排查触发检测脚本问题

问题分析与修复

卡顿根源

  • Update()每帧调用AddScore(),当touching为true时,while (touching == true)是死循环:循环内没有任何修改touching的逻辑,CPU会被这个循环完全占用,直接导致卡顿。
  • 同时每次循环都会启动wait()协程,短时间内会生成海量协程,进一步加剧性能问题。

其他逻辑问题

  • 缺少OnTriggerExit2D方法,玩家离开碰撞体后touching不会被重置为false,逻辑永远停留在触发状态。
  • 分数增加逻辑错误:用while循环+协程无法实现"每秒加1分"的效果,反而会瞬间刷爆分数。
  • 销毁对象的逻辑错误:else分支每帧都会启动waiter()协程,会同时运行上百个销毁倒计时协程,导致重复销毁或性能浪费。

修复后的代码

using System.Collections;
using UnityEngine;

public class Trigger : MonoBehaviour
{
    public GameObject targetToDestroy;
    bool isTouching = false;
    int score = 0;
    Coroutine scoreCoroutine;
    Coroutine destroyCoroutine;

    private void OnTriggerStay2D(Collider2D other)
    {
        Debug.Log("Touching");
        isTouching = true;

        // 启动分数增加协程(确保同一时间只有一个协程运行)
        if (scoreCoroutine == null)
        {
            scoreCoroutine = StartCoroutine(IncreaseScorePerSecond());
        }

        // 如果有销毁倒计时协程,立即停止
        if (destroyCoroutine != null)
        {
            StopCoroutine(destroyCoroutine);
            destroyCoroutine = null;
        }
    }

    private void OnTriggerExit2D(Collider2D other)
    {
        Debug.Log("Not Touching");
        isTouching = false;

        // 停止分数增加协程
        if (scoreCoroutine != null)
        {
            StopCoroutine(scoreCoroutine);
            scoreCoroutine = null;
        }

        // 启动销毁倒计时协程(确保同一时间只有一个)
        if (destroyCoroutine == null)
        {
            destroyCoroutine = StartCoroutine(DestroyAfterDelay());
        }
    }

    IEnumerator IncreaseScorePerSecond()
    {
        while (isTouching)
        {
            score++;
            Debug.Log($"当前分数: {score}");
            yield return new WaitForSecondsRealtime(1);
        }
    }

    IEnumerator DestroyAfterDelay()
    {
        yield return new WaitForSecondsRealtime(2);
        Destroy(targetToDestroy);
    }
}

修改说明

  • 重命名变量提高可读性(比如other改为targetToDestroy,避免和碰撞参数重名;touching改为isTouching)。
  • 新增OnTriggerExit2D方法,在玩家离开碰撞体时重置触发状态。
  • 用Coroutine变量管理协程,确保同一时间只有一个分数增加/销毁倒计时协程运行,避免重复启动。
  • 将分数逻辑移到独立协程IncreaseScorePerSecond中,通过协程的yield实现每秒加1分的效果,替代原有的死循环。
  • 优化销毁逻辑:只有当玩家离开时才启动一次销毁倒计时,且如果玩家再次触发碰撞体,会立即停止销毁协程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 09:24:22