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

Unity中该ScriptableObject脚本是否正确?求修正或优化方案

Unity实例化预制体脚本修正与优化

原脚本存在的问题

  • DestroyObjectInScene仅销毁第一个找到的Respawn标签物体,无法清理所有旧实例(包括生成的文本)
  • 新实例化的物体未添加Respawn标签,导致下次点击按钮时无法被销毁
  • 缺少空值校验,数组越界、预制体为空时会直接报错
  • Button1/2/3方法重复度高,可复用性差
  • 生成的文本没有标记,无法被统一清理

优化后的脚本

using TMPro;
using UnityEngine;

public class InstanziaOggetti : MonoBehaviour
{
    [Header("配置项")]
    public ObjectScriptable[] objectConfigs; // 物体配置数组
    public TMP_Text nameTextPrefab; // 物体名称文本预制体
    public TMP_Text[] buttonNameTexts; // 按钮上的名称文本

    private const string RespawnTag = "Respawn";

    void Start()
    {
        UpdateButtonNames();
    }

    // 通用按钮点击方法,通过参数指定要实例化的物体索引
    public void OnButtonClick(int objectIndex)
    {
        // 边界校验
        if (objectIndex < 0 || objectIndex >= objectConfigs.Length)
        {
            Debug.LogError($"物体索引{objectIndex}超出数组范围");
            return;
        }

        DestroyAllOldInstances();
        SpawnObject(objectIndex);
    }

    // 生成指定索引的物体和名称文本
    private void SpawnObject(int objectIndex)
    {
        var config = objectConfigs[objectIndex];
        if (config == null || config.objectPrefab == null)
        {
            Debug.LogError($"索引{objectIndex}的配置或预制体为空");
            return;
        }

        // 实例化物体
        GameObject spawnedObject = Instantiate(config.objectPrefab);
        spawnedObject.transform.position = new Vector3(0, 0.5f, 0);
        spawnedObject.tag = RespawnTag; // 添加标签,方便后续销毁

        // 实例化名称文本
        if (nameTextPrefab != null)
        {
            TMP_Text spawnedText = Instantiate(nameTextPrefab);
            spawnedText.transform.position = new Vector3(0, 2.5f, 0);
            spawnedText.text = config.objectName;
            spawnedText.tag = RespawnTag; // 文本也加标签,统一销毁
        }
    }

    // 销毁所有带Respawn标签的物体
    private void DestroyAllOldInstances()
    {
        GameObject[] oldObjects = GameObject.FindGameObjectsWithTag(RespawnTag);
        foreach (var obj in oldObjects)
        {
            Destroy(obj);
        }
    }

    // 更新按钮上的物体名称
    private void UpdateButtonNames()
    {
        if (buttonNameTexts == null) return;

        for (int i = 0; i < buttonNameTexts.Length; i++)
        {
            if (buttonNameTexts[i] == null) continue;

            if (i < objectConfigs.Length && objectConfigs[i] != null)
            {
                buttonNameTexts[i].text = objectConfigs[i].objectName;
            }
            else
            {
                buttonNameTexts[i].text = string.Empty;
            }
        }
    }
}

Unity设置检查项

  • 确保ObjectScriptable类中objectPrefab和objectName字段已正确定义,且每个配置项都赋值了预制体和名称
  • 按钮的OnClick事件绑定:选择脚本所在物体,找到OnButtonClick方法,传入对应索引(比如第一个按钮传0,第二个传1)
  • 预制体需添加Respawn标签,否则无法被销毁
  • 确保场景中存在EventSystem(UI按钮必须依赖它)
  • 检查nameTextPrefab的TMP字体是否正确赋值,避免文本无法显示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 15:28:12