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
相关产品推荐
相关产品推荐

