如何将可编写脚本的对象的每个实例添加到集合中?
How can I add each instance of a scriptable object to a collection?
你好:)
我希望将可编写脚本的对象 class 的每个实例添加到 HashSet(它位于单独脚本中的静态 class 中)。
我通过创建一个方法来做到这一点,该方法将 class 添加到哈希集,我在我正在实例化的 class 的构造函数中调用了这个方法。事情是这样的……它有效,但并非总是如此?这是代码,我会在最后进一步探讨问题:
//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] 属性 btw)。
ps。我确定我有一个我没有看到的明显的理论问题!预先感谢任何让我了解正在发生的事情的人
所以这是主要问题。 ScriptableObject 实例是永久存在于您的统一项目中的资产。带有哈希集的静态 class 是仅在统一为 运行 时才存在的数据。一旦您离开应用程序,它就消失了,因此您需要重新生成数据。现在我不是 100% 确定为什么 unity 在验证时调用 scriptableObject 的构造函数(当您 select it/make 更改时),但依赖类似的东西肯定会导致问题;)。
您可以在访问数据时get all instances。
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() 函数将 return 您的脚本化对象的所有实例。
但是,如果您想要一个更简洁的解决方案,那么使用另一个带有指向您想要的所有 MyClassToIntanctiate 实例的链接的 scriptableObject 可能会更好。它可以让您编辑列表,因此默认情况下不会全部添加它们。
你好:)
我希望将可编写脚本的对象 class 的每个实例添加到 HashSet(它位于单独脚本中的静态 class 中)。
我通过创建一个方法来做到这一点,该方法将 class 添加到哈希集,我在我正在实例化的 class 的构造函数中调用了这个方法。事情是这样的……它有效,但并非总是如此?这是代码,我会在最后进一步探讨问题:
//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] 属性 btw)。
ps。我确定我有一个我没有看到的明显的理论问题!预先感谢任何让我了解正在发生的事情的人
所以这是主要问题。 ScriptableObject 实例是永久存在于您的统一项目中的资产。带有哈希集的静态 class 是仅在统一为 运行 时才存在的数据。一旦您离开应用程序,它就消失了,因此您需要重新生成数据。现在我不是 100% 确定为什么 unity 在验证时调用 scriptableObject 的构造函数(当您 select it/make 更改时),但依赖类似的东西肯定会导致问题;)。
您可以在访问数据时get all instances。
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() 函数将 return 您的脚本化对象的所有实例。
但是,如果您想要一个更简洁的解决方案,那么使用另一个带有指向您想要的所有 MyClassToIntanctiate 实例的链接的 scriptableObject 可能会更好。它可以让您编辑列表,因此默认情况下不会全部添加它们。