Unity报错CS0165:未赋值局部变量'BoxPrefab'的解决方法
3D扫雷游戏开发问题:未赋值局部变量错误及预制体赋值修复
问题说明
我在Unity开发首个项目——3D扫雷游戏,需要在3D网格的每个单元格实例化Box预制体,但触发报错:
Assets\BoxGrid.cs(26,67): error CS0165: Use of unassigned local variable 'BoxPrefab'
尝试用private GameObject BoxPrefab = GameObject.Find("Box");给变量赋值预制体无效,求仅通过脚本为BoxPrefab赋值并修复错误的方法。
我的代码
BoxGrid类代码
public class BoxGrid { private GameObject BoxPrefab = GameObject.Find("Box"); private int width; private int height; private int length; private float CellSize; private int[,,] BoxGridArray; public BoxGrid(int width, int height, int length, float CellSize) { this.width = width; this.height = height; this.length = length; this.CellSize = CellSize; BoxGridArray = new int[width, height, length]; for (int x = 0; x < BoxGridArray.GetLength(0); x++) { for (int y = 0; y < BoxGridArray.GetLength(1); y++) { for (int z = 0; z < BoxGridArray.GetLength(2); z++) { GameObject BoxPrefab = GameObject.Instantiate(BoxPrefab, GetPosition(x, y, z) + new Vector3(CellSize, CellSize, CellSize) * .5f, Quaternion.identity) as GameObject; Debug.DrawLine(GetPosition(x, y, z), GetPosition(x, y, z + 1), Color.white, 100f); Debug.DrawLine(GetPosition(x, y, z), GetPosition(x, y + 1, z), Color.white, 100f); Debug.DrawLine(GetPosition(x, y, z), GetPosition(x + 1, y, z), Color.white, 100f); } } } } private Vector3 GetPosition(int x, int y, int z) { return new Vector3(x, y, z) * CellSize; } }
GridCreate脚本代码
public class GridCreate : MonoBehaviour { public void Start() { BoxGrid Grid = new BoxGrid(4, 4, 4, 25f); } }
解决方案
错误根源
- 局部变量遮蔽成员变量:在实例化代码行,重新声明了局部变量
GameObject BoxPrefab,覆盖了类的成员变量,导致编译器判定你在使用未赋值的局部变量。 GameObject.Find时机错误:在类成员变量初始化阶段调用GameObject.Find无效——此时Unity对象还未完成初始化,而且预制体如果不在场景中,Find根本找不到目标。
修复方案
方案1:通过Resources加载预制体(纯脚本实现)
把Box预制体放到项目内的Resources文件夹(需手动创建),用Resources.Load加载:
public class BoxGrid { private GameObject BoxPrefab; private int width; private int height; private int length; private float CellSize; private int[,,] BoxGridArray; public BoxGrid(int width, int height, int length, float CellSize) { this.width = width; this.height = height; this.length = length; this.CellSize = CellSize; // 加载Resources文件夹下的Box预制体,路径为相对于Resources的路径 BoxPrefab = Resources.Load<GameObject>("Box"); if (BoxPrefab == null) { Debug.LogError("找不到Box预制体,请检查是否放在Resources文件夹下"); return; } BoxGridArray = new int[width, height, length]; for (int x = 0; x < BoxGridArray.GetLength(0); x++) { for (int y = 0; y < BoxGridArray.GetLength(1); y++) { for (int z = 0; z < BoxGridArray.GetLength(2); z++) { // 移除局部变量声明,直接使用成员变量 GameObject boxInstance = GameObject.Instantiate(BoxPrefab, GetPosition(x, y, z) + new Vector3(CellSize, CellSize, CellSize) * .5f, Quaternion.identity); Debug.DrawLine(GetPosition(x, y, z), GetPosition(x, y, z + 1), Color.white, 100f); Debug.DrawLine(GetPosition(x, y, z), GetPosition(x, y + 1, z), Color.white, 100f); Debug.DrawLine(GetPosition(x, y, z), GetPosition(x + 1, y, z), Color.white, 100f); } } } } private Vector3 GetPosition(int x, int y, int z) { return new Vector3(x, y, z) * CellSize; } }
方案2:通过构造函数传递预制体引用(更符合Unity规范)
虽然要求纯脚本,但这种方式更可靠,避免依赖Resources:
// GridCreate脚本修改 public class GridCreate : MonoBehaviour { // 在Inspector面板拖拽Box预制体到此处 public GameObject boxPrefab; public void Start() { BoxGrid Grid = new BoxGrid(4, 4, 4, 25f, boxPrefab); } } // BoxGrid类修改 public class BoxGrid { private GameObject BoxPrefab; private int width; private int height; private int length; private float CellSize; private int[,,] BoxGridArray; // 新增参数接收预制体引用 public BoxGrid(int width, int height, int length, float CellSize, GameObject boxPrefab) { this.width = width; this.height = height; this.length = length; this.CellSize = CellSize; this.BoxPrefab = boxPrefab; if (BoxPrefab == null) { Debug.LogError("Box预制体引用为空,请检查GridCreate中的赋值"); return; } BoxGridArray = new int[width, height, length]; for (int x = 0; x < BoxGridArray.GetLength(0); x++) { for (int y = 0; y < BoxGridArray.GetLength(1); y++) { for (int z = 0; z < BoxGridArray.GetLength(2); z++) { GameObject boxInstance = GameObject.Instantiate(BoxPrefab, GetPosition(x, y, z) + new Vector3(CellSize, CellSize, CellSize) * .5f, Quaternion.identity); Debug.DrawLine(GetPosition(x, y, z), GetPosition(x, y, z + 1), Color.white, 100f); Debug.DrawLine(GetPosition(x, y, z), GetPosition(x, y + 1, z), Color.white, 100f); Debug.DrawLine(GetPosition(x, y, z), GetPosition(x + 1, y, z), Color.white, 100f); } } } } private Vector3 GetPosition(int x, int y, int z) { return new Vector3(x, y, z) * CellSize; } }
核心修复点
- 删除实例化代码行中的局部变量声明
GameObject BoxPrefab,直接使用类的成员变量。 - 不要在成员变量初始化阶段调用
GameObject.Find,改用Resources.Load(需预制体在Resources文件夹)或构造函数传递引用的方式获取预制体。
内容的提问来源于stack exchange,提问作者rekted off
相关产品推荐
相关产品推荐

