0

你好 :)

我希望将可编写脚本的对象类的每一个实例添加到 HashSet(它位于单独脚本中的静态类中)。

我通过创建一个将所述类添加到哈希集中的方法来做到这一点,并在我正在实例化的类的构造函数中调用了这个方法。事情是这样的……它有效,但并非总是如此?这是代码,我将在最后进一步探讨问题:

//first script where the hashset is:
public static class Record
{
    private static HashSet<MyClassToInstantiate> MyHashSet = new HashSet<MyClassToInstantiate>();

    public static void AddToMyHashSet(MyClassToInstantiate obj)
    {                
        MyHashSet.Add(obj);                
    }

}       

//the other script:
[CreateAssetMenu(menuName = "X")]
public class MyClassToInstantiate : ScriptableObject
{
    [SerializeField] string someRandomData1;
    [SerializeField] int someRandomData2;

    public MyClassToInstantiate()
    {
        Record.AddToMyHashSet(this);
    }
}

除了我第一次打开 Unity 之外,这一切都很好。第一次我总是必须进入我的“MyClassToInstantiate”的任何实例并改变一些东西(任何东西),它才开始工作(我正在使用 [createAssetMenu] 属性顺便说一句)。

附言。我敢肯定我没有看到明显的理论问题!提前感谢任何让我了解正在发生的事情的人

4

1 回答 1

1

所以这里是主要问题。scriptableObject 实例是永久存在于您的统一项目中的资产。带有哈希集的静态类是仅在统一运行时存在的数据。一旦您离开应用程序,它就消失了,因此您需要重新生成数据。现在我“不是 100% 确定为什么统一调用 scriptableObject 的构造函数,它似乎在验证(当你选择它/进行更改时)但依赖类似的东西肯定会导致问题;)。

您可以在访问数据时获取所有实例。

 public static class Record

{

private static HashSet<MyClassToInstantiate> MyHashet;

public static HashSet<MyClassToInstantiate> GetHashSet() 
{
    RefreshHash();

    return MyHashet;
}

public static void RefreshHash() 
{
    MyClassToInstantiate[] allInstances = GetAllInstances<MyClassToInstantiate>();
    MyHashet = new HashSet<MyClassToInstantiate>();
    for (int i = 0; i < allInstances.Length; ++i)
    {
        MyHashet.Add(allInstances[i]);
    }
}

private static T[] GetAllInstances<T>() where T : ScriptableObject
{
    string[] guids = UnityEditor.AssetDatabase.FindAssets("t:" + typeof(T).Name);  //FindAssets uses tags check documentation for more info
    T[] a = new T[guids.Length];
    for (int i = 0; i < guids.Length; i++)         //probably could get optimized 
    {
        string path = UnityEditor.AssetDatabase.GUIDToAssetPath(guids[i]);
        a[i] = UnityEditor.AssetDatabase.LoadAssetAtPath<T>(path);
    }

    return a;
}

}

GetHashSet() 函数将返回您的可编写脚本对象的所有实例。

但是,如果您想要一个更简洁的解决方案,拥有一个包含指向您想要的所有 MyClassToIntanctiate 实例的链接的其他 scriptableObject 可能会更好。它可以让您编辑列表,因此默认情况下不会全部添加。

于 2020-05-30T13:16:54.200 回答