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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:14:51