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

Unity进入Play Mode时冻结:WaveManager激活导致无响应问题排查

僵尸射击游戏Unity冻结无响应问题排查与解决

问题现象

  • 开发首款僵尸射击游戏,WaveManager脚本负责波次切换、每轮僵尸数量递增
  • 激活WaveManager组件后进入游戏,Unity直接冻结无响应;停用组件则恢复正常,且无任何报错信息
  • 设备配置:16GB内存 + M1芯片

初始代码与问题根源

WaveManager脚本(注:脚本实际名为TargetSpawner,代码中存在笔误)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WaveManager : MonoBehaviour
{
    public int targetsSpawned;
    public int targetsLeft;
    public int wave;
    public int firstWaveTargets;
    ZombieSoawner spawner;

    void Awake()
    {
        spawner = GameObject.FindGameObjectWithTag("TargetSpawner").GetComponent<ZombieSoawner>();
        wave = 1;
        targetsSpawned = firstWaveTargets;
        targetsLeft = targetsSpawned;
        spawner.SpawnZombies();
    }


    void Update()
    {
        if (targetsLeft <= 0)
        {
            nextWave();
        }
    }

    void nextWave()
    {
            wave += 1;
            targetsSpawned += 2;
            targetsLeft = targetsSpawned;
            spawner.SpawnZombies();
    }
}

ZombieSpawner脚本(问题核心所在)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ZombieSoawner : MonoBehaviour
{
    public WaveManager manager;
    int targetsPlaced;
    public GameObject target;

    public void SpawnZombies()
    {
        while (manager.targetsSpawned > targetsPlaced)
        {
            PlaceTargets();
            targetsPlaced += 1;
        }
    }

    public void PlaceTargets()
    {
        targetsPlaced = 0; // 此处是无限循环的根源
        Vector3 originalPos = transform.localPosition;
        transform.localPosition = originalPos;
        float randomOffset = Random.Range(-20f, 20f);
        Vector3 randomPos = new Vector3(originalPos.x + randomOffset, originalPos.y + 5f, originalPos.z + randomOffset);
        Instantiate(target, randomPos, Quaternion.identity);
    }
}

Target脚本(无问题)

using UnityEngine;
using UnityEngine.AI;
public class Target : MonoBehaviour
{
    public float health = 50f;
    public float lookRadius = 20f;
    Transform target;
    NavMeshAgent agent;
    WaveManager manager;

    private void Awake()
    {
        manager = GameObject.FindGameObjectWithTag("WaveManager").GetComponent<WaveManager>();
        target = PlayerManager.instance.player.transform;
        agent = GetComponent<NavMeshAgent>();
    }


    private void Update()
    {
        float distance = Vector3.Distance(target.position, transform.position);

        if ( distance <= lookRadius)
        {
            agent.SetDestination(target.position);

            if (distance <= agent.stoppingDistance)
            {
                FaceTarget();
            }
        }
    }

    void FaceTarget()
    {
        Vector3 direction = (target.position - transform.position).normalized;
        Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
        transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * 5f);
    }

    public void TakeDamage(float amount)
    {
        health -= amount;
        if (health <= 0f)
        {
            manager.targetsLeft -= 1;
            Destroy(gameObject);
        }
    }

    private void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, lookRadius);
    }

}

问题分析

SpawnZombies方法中的while循环本意是生成指定数量的僵尸,但每次调用PlaceTargets时,都会将targetsPlaced重置为0。这导致循环条件manager.targetsSpawned > targetsPlaced永远成立,进入无限循环,Unity主线程被阻塞,最终表现为冻结无响应。

解决方案

将targetsPlaced = 0;从PlaceTargets方法中移至SpawnZombies方法的开头,确保每轮生成僵尸前先重置计数,循环可以正常终止:

修正后的ZombieSpawner脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ZombieSoawner : MonoBehaviour
{
    public WaveManager manager;
    int targetsPlaced;
    public GameObject target;

    public void SpawnZombies()
    {
        targetsPlaced = 0; // 移至此处,每轮生成前重置计数
        while (manager.targetsSpawned > targetsPlaced)
        {
            PlaceTargets();
            targetsPlaced += 1;
        }
    }

    public void PlaceTargets()
    {
        Vector3 originalPos = transform.localPosition;
        transform.localPosition = originalPos;
        float randomOffset = Random.Range(-20f, 20f);
        Vector3 randomPos = new Vector3(originalPos.x + randomOffset, originalPos.y + 5f, originalPos.z + randomOffset);
        Instantiate(target, randomPos, Quaternion.identity);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 05:37:25