unity-game-engine - 复制可编写脚本的对象

标签 unity-game-engine

有没有办法在 ScriptableObjects 中模仿 MonoBehaviour 复制语义?

假设我有一个像这样的 MonoBehaviour:

public class DummyClassBehaviour : MonoBehaviour {
    public DummyClass           DummyClassTest;     //ScriptableObject
    public DummyClassBehaviour  DummyBehaviourTest; //Another DummyClassBehaviour
}

还有一个 ScriptableObject:

public class DummyClass : ScriptableObject {
    public string Text = "";
}

当我复制(CTRL+D)附加了 DummyClassBehaviour 的 GameObject 时,“DummyBehaviourTest”会按照您的预期进行复制:如果它引用我正在复制的 GameObject 中的 MonoBehaviour,则复制机制会更新对同一 MonoBehaviour 的引用输入新的游戏对象。如果它引用另一个 GameObject 中的 MonoBehaviour,则该引用保持不变。

另一方面,ScriptableObject 始终引用原始对象。因此,我最终得到 N 个游戏对象,它们都共享原始游戏对象中的相同 ScriptableObject (DummyClass)。我使用 ScriptableObjects 来允许非 Monobehaviour 数据类的序列化。

最佳答案

据我所知,如果我错了,请纠正我,您无法修改 ScriptableObject 的序列化行为以匹配 MonoBehaviour 的序列化行为。也就是说,如果重复,它应该更新引用文献。

相反,我选择了一个不太理想的解决方案,但它有效。我的类被分配了一个唯一的标识符,它像其他所有东西一样被序列化。我在 DummyBehaviour.Awake() 中使用此 ID 创建一个查找表,然后用它来重新分配我的 DummyClass。

我不会接受我自己的答案,因为我觉得它没有完全回答我原来的问题,但它是相关的:

[System.Serializable]
public class DummyClass {
// Unique id is assigned by DummyBehaviour and is unique to the game object
    // that DummyBehaviour is attached to.
public int UniqueID = -1;
public string Text = "";

// Override GetHashCode so Dictionary lookups 
public override int GetHashCode(){
    int hash = 17;
        hash = hash * 31 + UniqueID;
    return hash;
}

    // override equality function, allows dictionary to do comparisons.
public override bool Equals(object obj)
{
    if (object.ReferenceEquals(obj, null))return false;

    DummyClass item = obj as DummyClass;
    return item.UniqueID == this.UniqueID;
}

    // Allow checks of the form 'if(dummyClass)'
public static implicit operator bool(DummyClass a) 
{
    if (object.ReferenceEquals(a, null)) return false;
    return (a.UniqueID==-1)?false:true;
}


public static bool operator ==(DummyClass a, DummyClass b)
{
    if (object.ReferenceEquals(a, null))
    {
         return object.ReferenceEquals(b, null);
    }

    return a.Equals(b);
}
public static bool operator !=(DummyClass a, DummyClass b)
{
    if (object.ReferenceEquals(a, null))
    {
         return object.ReferenceEquals(b, null);
    }
    return !a.Equals(b);
}
}

还有我的 MonoBehaviour:

[ExecuteInEditMode]
public class DummyBehaviour : MonoBehaviour {
    public List<DummyClass> DummyClasses = new List<DummyClass>();

    // reassign references based on uniqueid.
    void Awake(){   
        Dictionary<DummyClass,DummyClass> dmap = new Dictionary<DummyClass,DummyClass>();
        // iterate over all dummyclasses, reassign references.
        for(int i = 0; i < DummyClasses.Count; i++){
            DummyClass2 d = DummyClasses[i];
            if(dmap.ContainsKey(d)){
                DummyClasses[i] = dmap[d];
            } else {
                dmap[d] = d;
            }
        }
        DummyClasses[0].Text = "All items same";
    }

    // helper function, for inspector contextmenu, to add more classes from Editor
    [ContextMenu ("AddDummy")]
    void AddDummy(){
        if(DummyClasses.Count==0)DummyClasses.Add(new DummyClass{UniqueID = 1});
        else {
            // Every item after 0 points to zero, serialization will remove refs during deep copy.
            DummyClasses.Add(DummyClasses[0]);
        }
        UnityEditor.EditorUtility.SetDirty(this);
    }
}

关于unity-game-engine - 复制可编写脚本的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15318425/

相关文章:

android - 将 Unity IAP 从 1.23.5 更新到 2.2.4 时出现构建错误, list 合并失败

c# - 保存和加载音频

java - 如何从 Java 调用正在运行的 C# 应用程序中的方法?

css - 如何在 unity3d 上加载 png 图像并使用加载场景

c# - 如何使 RectTransform 跟随位于不同父级下的另一个 RectTransform?

ios - Xcode clang : error: linker command failed with exit code 1 (UNITY used for creation)

c# - Unity 访问非静态成员需要对象引用 C#

c# - Unity C# 数组 - 如何克隆

Azure 空间 anchor - 在 HoloLens 上获取云空间异常

unity-game-engine - 为什么我对 OnCollisionEnter() 的定义没有被使用?