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

Unity通过字符串动态实例化对应建筑GameObject的技术问题咨询

解决方案

问题说明

你当前写的Instantiate("building" + menu.buildingNumber)属于错误用法:Unity的Instantiate()方法不支持直接传入字符串形式的变量名,来获取你在Inspector面板中绑定的GameObject预设,拼接出来的"buildingX"字符串无法自动映射到类里的building1/building2/building3字段。

实现方案

方案1:数组映射(最适配你的数字编号场景)

利用建筑编号的连续性,用数组存储所有建筑预设,直接通过下标读取,代码改动最小:

  1. 把原来单独声明的3个建筑变量替换为数组:
// 替换原来的public GameObject building1;public GameObject building2;public GameObject building3;
public GameObject[] buildings;
  1. 实例化代码调整为:
// 注意如果你的buildingNumber从1开始,需要减1匹配数组从0开始的下标
int buildingIndex = menu.buildingNumber - 1;
// 先做越界判断避免报错
if (buildingIndex >= 0 && buildingIndex < buildings.Length)
{
    Instantiate(buildings[buildingIndex]);
}
  1. 操作说明:在Inspector面板中按编号顺序把building1、2、3拖入数组对应的位置即可,后续新增建筑只需要往数组里加预设,不需要改逻辑代码。

方案2:字典映射(适合名称不规律的场景)

如果你的建筑编号不连续或者是自定义字符串名称,可以用字典做名称到预设的映射:

  1. 声明字典变量:
private Dictionary<string, GameObject> buildingDict = new Dictionary<string, GameObject>();
  1. 在Start()中初始化字典:
void Start()
{
    cash = changeCash;
    // 初始化建筑映射字典
    buildingDict.Add("1", building1);
    buildingDict.Add("2", building2);
    buildingDict.Add("3", building3);
    // 后续加新建筑,直接在这里加一行记录即可
}
  1. 实例化代码调整为:
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:27:00