Unity通过字符串动态实例化对应建筑GameObject的技术问题咨询
解决方案
问题说明
你当前写的Instantiate("building" + menu.buildingNumber)属于错误用法:Unity的Instantiate()方法不支持直接传入字符串形式的变量名,来获取你在Inspector面板中绑定的GameObject预设,拼接出来的"buildingX"字符串无法自动映射到类里的building1/building2/building3字段。
实现方案
方案1:数组映射(最适配你的数字编号场景)
利用建筑编号的连续性,用数组存储所有建筑预设,直接通过下标读取,代码改动最小:
- 把原来单独声明的3个建筑变量替换为数组:
// 替换原来的public GameObject building1;public GameObject building2;public GameObject building3; public GameObject[] buildings;
- 实例化代码调整为:
// 注意如果你的buildingNumber从1开始,需要减1匹配数组从0开始的下标 int buildingIndex = menu.buildingNumber - 1; // 先做越界判断避免报错 if (buildingIndex >= 0 && buildingIndex < buildings.Length) { Instantiate(buildings[buildingIndex]); }
- 操作说明:在Inspector面板中按编号顺序把building1、2、3拖入数组对应的位置即可,后续新增建筑只需要往数组里加预设,不需要改逻辑代码。
方案2:字典映射(适合名称不规律的场景)
如果你的建筑编号不连续或者是自定义字符串名称,可以用字典做名称到预设的映射:
- 声明字典变量:
private Dictionary<string, GameObject> buildingDict = new Dictionary<string, GameObject>();
- 在
Start()中初始化字典:
void Start() { cash = changeCash; // 初始化建筑映射字典 buildingDict.Add("1", building1); buildingDict.Add("2", building2); buildingDict.Add("3", building3); // 后续加新建筑,直接在这里加一行记录即可 }
- 实例化代码调整为:
string buildingKey = menu.buildingNumber.ToString(); if (buildingDict.ContainsKey(buildingKey)) { Instantiate(buildingDict[buildingKey]); }
修改后的完整示例代码(数组方案)
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class main : MonoBehaviour { public Text cashText; public static float cash = 0f; public float changeCash = 0f; // 替换原来的三个单独建筑变量为数组 public GameObject[] buildings; void Start() { cash = changeCash; // 帧率设置放在Start里即可,不需要每帧重复赋值 Application.targetFrameRate = 60; } void Update() { cashText.text = "cash: " + cash.ToString(); if (Input.GetKeyDown("r")) { Destroy(GameObject.FindGameObjectWithTag("building")); GameObject[] projectiles = GameObject.FindGameObjectsWithTag("projectile"); foreach(GameObject projectile in projectiles) { Destroy(projectile); } int buildingIndex = menu.buildingNumber - 1; if (buildingIndex >=0 && buildingIndex < buildings.Length) { Instantiate(buildings[buildingIndex]); } } } }
额外优化说明
- 不推荐使用
Resources.Load("building" + menu.buildingNumber)的方式实现,这种方式需要把所有建筑预设放到Resources文件夹下,打包时会强制打包所有Resources内的资源,占用包体空间,且加载效率低于直接在Inspector赋值的方式。
内容的提问来源于stack exchange,提问作者coolmanreebro
相关产品推荐
相关产品推荐

