Unity中Resources加载Prefab未实例化时添加组件的问题咨询
关于Unity Resources.Load()加载Prefab后修改原资源的问题解析
你观察到的这个现象太典型了,这绝对是Unity新手接触Resources系统时最容易踩的坑之一!
当你调用Resources.Load()加载Prefab时,你获取到的对象其实是直接指向Resources文件夹里原始Prefab的引用——根本不是什么独立副本,哪怕你完全没调用Instantiate()实例化到场景里。这就导致你对这个加载出来的testObj做的任何修改(比如添加TestScript组件),在编辑器运行模式下都会被同步回磁盘上的原始Prefab文件,关闭项目后这些修改就永久保留了。
就像你遇到的场景:
- 第一次运行时给
testObj加了TestScript,关闭项目后原始Prefab就带上了这个组件; - 第二次重复操作时,你加载的已经是带了一个
TestScript的Prefab,再添加一次自然就会出现两个相同组件。
要避免这种误改原始资源的情况,给你两个实用的解决方案:
- 方案1:加载后先创建内存副本再修改
哪怕你暂时不需要把对象放到场景里,也可以先用Instantiate()创建一个内存中的独立副本,之后所有修改都针对这个副本操作,完全不会影响原始Prefab:GameObject testObj = Resources.Load<GameObject>("testPrefab"); GameObject tempCopy = Instantiate(testObj); // 创建仅存在于内存的副本 tempCopy.AddComponent<TestScript>(); // 修改副本,原始Prefab不受影响 - 方案2:编辑器脚本专用——用
PrefabUtility.InstantiatePrefab()
如果是在编辑器扩展脚本里操作,可以借助UnityEditor的PrefabUtility类来生成脱离原始Prefab的实例,同样不会改动源资源:using UnityEditor; GameObject testObj = Resources.Load<GameObject>("testPrefab"); GameObject editorCopy = PrefabUtility.InstantiatePrefab(testObj) as GameObject; editorCopy.AddComponent<TestScript>();
最后提个小建议:现在Unity官方其实已经不太推荐使用Resources系统了,更建议用Addressable Assets系统来管理资源,它不仅能从根源上避免这类误改原始资源的问题,还能更灵活地处理资源的加载、卸载和打包。
内容的提问来源于stack exchange,提问作者Matthew Wang
相关产品推荐
相关产品推荐

