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

Unity 2D C#问题:不应实例化的Prefab被错误实例化

背景

我正在搭建一个系统,会根据主场景加载前菜单中用户输入的数量,在游戏里生成指定数量的GameObject。通过3个for循环,按照菜单输入的对象数量执行循环,每次循环实例化一个Prefab副本。

问题

每当从菜单加载主场景时,就算数量设为0或者null,每种Prefab总会至少生成1个。这会导致生成的副本超出用户定义的数量,引发问题。

我已经在处理数值解析并传递给生成脚本的所有脚本(数据管理器、Scriptable Object等)以及生成脚本内部添加了多个Debug.Log();,所有日志返回值均为0,理论上应该不会生成任何对象。

生成器脚本代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PawnSpawner : MonoBehaviour
{
    [SerializeField] VarManager VarManager;

    [SerializeField] GameObject Pawn;
    [SerializeField] GameObject InfPawn;
    [SerializeField] GameObject VaxPawn;

    private int? totPawns;
    private int? defPawns;
    private int? infPawns;
    private int? vaxPawns;

    private void Awake()
    {
        VarManager = GameObject.Find("GameManager").GetComponent<VarManager>();

        totPawns = VarManager.totalPawns;

        defPawns = VarManager.uninfectedPawnAmount;
        infPawns = VarManager.infectedPawnAmount;
        vaxPawns = VarManager.vaccinatedPawnAmount;
    }

    // Start is called before the first frame update
    void Start()
    {
        if(defPawns != 0 || defPawns != null)
        {
            for (int i = 0; i <= defPawns; i++)
            {
                int x = UnityEngine.Random.Range(-300, 301);
                int y = UnityEngine.Random.Range(-300, 301);

                GameObject D_Pawn = Instantiate(Pawn, new Vector3(x, y, 0), Quaternion.identity);
            }
        }

        if(infPawns != 0 || infPawns != null)
        {
            for (int i = 0; i <= infPawns; i++)
            {
                int x = UnityEngine.Random.Range(-300, 301);
                int y = UnityEngine.Random.Range(-300, 301);

                GameObject I_Pawn = Instantiate(InfPawn, new Vector3(x, y, 0), Quaternion.identity);
            }
        }

        if (vaxPawns != 0 || vaxPawns != null)
        {
            for (int i = 0; i <= vaxPawns; i++)
            {
                int x = UnityEngine.Random.Range(-300, 301);
                int y = UnityEngine.Random.Range(-300, 301);

                GameObject V_Pawn = Instantiate(VaxPawn, new Vector3(x, y, 0), Quaternion.identity);
            }
        }
    }

    // Update is called once per frame
    void Update()
    {
        Destroy(this);
    }

    private void OnDestroy()
    {
        Debug.Log("---PAWN SPAWNER HAS FULLY EXECUTED SPAWNING SEQUENCE---");
        Debug.Log("TOTAL PAWNS SPAWNED:" + totPawns);
        Debug.Log("Default Pawns:" + defPawns);
        Debug.Log("Infected Pawns:" + infPawns);
        Debug.Log("Vaccinated Pawns:" + vaxPawns);
        Debug.Log("---REMOVING SELF---");
    }
}
问题原因与修复方案

错误1:条件判断逻辑错误

代码里的if(defPawns != 0 || defPawns != null)用了逻辑或||,这个条件永远为真:

  • 如果defPawns是0,那么defPawns != null成立;
  • 如果defPawns是null,那么defPawns != 0成立。
    所以不管数值是0还是null,都会进入循环。

应改为逻辑与&&,同时判断数量大于0:

if(defPawns != null && defPawns > 0)

错误2:循环边界错误

for (int i = 0; i <= defPawns; i++)用了<=,会导致循环次数比输入数量多1:

  • 当defPawns是0时,i=0满足0<=0,执行1次循环;
  • 当defPawns是n时,会执行n+1次循环。

应改为<,让循环次数等于输入的数量:

for (int i = 0; i < defPawns; i++)

修正后的Start方法代码

void Start()
{
    if(defPawns != null && defPawns > 0)
    {
        for (int i = 0; i < defPawns; i++)
        {
            int x = UnityEngine.Random.Range(-300, 301);
            int y = UnityEngine.Random.Range(-300, 301);

            GameObject D_Pawn = Instantiate(Pawn, new Vector3(x, y, 0), Quaternion.identity);
        }
    }

    if(infPawns != null && infPawns > 0)
    {
        for (int i = 0; i < infPawns; i++)
        {
            int x = UnityEngine.Random.Range(-300, 301);
            int y = UnityEngine.Random.Range(-300, 301);

            GameObject I_Pawn = Instantiate(InfPawn, new Vector3(x, y, 0), Quaternion.identity);
        }
    }

    if (vaxPawns != null && vaxPawns > 0)
    {
        for (int i = 0; i < vaxPawns; i++)
        {
            int x = UnityEngine.Random.Range(-300, 301);
            int y = UnityEngine.Random.Range(-300, 301);

            GameObject V_Pawn = Instantiate(VaxPawn, new Vector3(x, y, 0), Quaternion.identity);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 23:00:27