Unity中复制ScriptableObject数据时如何解除与原对象的关联?
问题原因
ScriptableObject是引用类型,当你执行playingStructure = pattern.structures[index];时,并没有生成新的Structures实例,只是让playingStructure变量指向了原ScriptableObject在内存中的同一个对象。因此,对playingStructure的Cards、x、y列表进行修改,本质就是直接操作原ScriptableObject的数据,会同步影响原始资源文件。
实现无关联复制的方案
可以通过以下几种方式创建Structures的独立实例,确保修改操作不会影响原数据:
方案1:在Structures类中实现Clone方法
在ScriptableObject类内添加克隆方法,手动复制所有数据:
public class Structures : ScriptableObject { public List<Card> Cards; public List<int> x; public List<int> y; // 生成深拷贝实例 public Structures Clone() { Structures clone = CreateInstance<Structures>(); // 为每个列表创建新实例并复制元素 clone.Cards = Cards != null ? new List<Card>(Cards) : new List<Card>(); clone.x = x != null ? new List<int>(x) : new List<int>(); clone.y = y != null ? new List<int>(y) : new List<int>(); return clone; } }
修改PlayPrepare中的赋值逻辑:
if (index >= 0) { playingStructure = pattern.structures[index].Clone(); }
方案2:通用序列化深拷贝工具
利用序列化实现通用的深拷贝,适合结构复杂的ScriptableObject:
using UnityEngine; using System.IO; using System.Runtime.Serialization.Formatters.Binary; public static class ScriptableObjectCopyUtility { public static T DeepCopy<T>(this T source) where T : ScriptableObject { if (source == null) return null; BinaryFormatter formatter = new BinaryFormatter(); using (MemoryStream stream = new MemoryStream()) { formatter.Serialize(stream, source); stream.Position = 0; return formatter.Deserialize(stream) as T; } } }
使用方式:
playingStructure = pattern.structures[index].DeepCopy();
注意:如果Card类包含Unity特有引用类型(如GameObject、Texture),需确保该类支持序列化,或单独处理这些引用的复制。
方案3:手动创建实例并复制数据
如果不想扩展类,可直接在逻辑中手动生成新实例并复制元素:
if (index >= 0) { Structures original = pattern.structures[index]; playingStructure = ScriptableObject.CreateInstance<Structures>(); playingStructure.Cards = new List<Card>(original.Cards); playingStructure.x = new List<int>(original.x); playingStructure.y = new List<int>(original.y); }
内容的提问来源于stack exchange,提问作者kryakva
相关产品推荐
相关产品推荐

