So here is my little problem, which I would like resolve.
I want to eliminate static in fields (not for methods), to be able utilize Entrer Play Mode Settings
Mind, it all works at the current state, but using statics.
I got following:
Monobehaviour inspector, in which I can adjust properties at runtime, to generate and modify my hex planet.
DOTS systems and jobs, which are responsible for generating planet.
And some static data, which are common for both MB and Systems.
So in terms of eliminating static fields, as my next goal, I started using singleton entities.
The thing is, I have also UnityEngine.Collection List, which I set in MB inspector, and read in the system on main thread. Of course it is none blitable. And I can not store list in singleton, as far I am aware.
But I could convert that lists into Dynamic buffer in MB script. And I think that could resolve that part of the problem, as I could read settings data, across different systems. Can I actually use IBufferElementData in singleton entity? I assume that I can (haven’t tested yet).
Whether this is most appropriate solution, I am uncertain.
However, I have also NativeHasMap. And my question is, what is the current most appropriate approach, to read for example NativeHashMap across multiple systems, without using static?
classIComponentData can store managed things and it can be singleton entity without problems - lists, native containers etc. Of course with only main thread usage limitation, but as you told you will use it on the main thread. And in case of native containers, you just get singleton entity in system and just pass native container from this singleton to job.
(but for class singletons use extension methods on systems - this.GetSingleton<t> this.SetSingleton<T> instead of just GetSingleton<t> SetSingleton<T> because last one has struct restriction and extension hasn’t)
@eizenhorn this is really nice info.
This just reminds me, I have seen somewhere very recently the discussion, which was mentioning class IComponentData.
Even weirder. you can use any class derived from UnityEngine.Object as ComponentObject (without IComponentData).
public struct SingletonTag : IComponentData { }
public class MyClassComponent : IComponentData
{
public NativeList<int> Data = new NativeList<int>(Allocator.Persistent);
}
public class MyObjectComponent : UnityEngine.Object
{
public NativeList<int> Data = new NativeList<int>(Allocator.Persistent);
private void OnDestroy()
{
Data.Dispose();
}
}
protected override void OnCreate()
{
var entity = EntityManager.CreateEntity();
EntityManager.AddComponentObject(entity, new MyObjectComponent());
EntityManager.AddComponentObject(entity, new MyClassComponent());
EntityManager.AddComponent<SingletonTag>(entity);
}
protected override void OnUpdate()
{
var objComp = GetSingleton<MyObjectComponent>();//not working
var clsComp = GetSingleton<MyClassComponent>();//not working
var objComp2 = this.GetSingleton<MyObjectComponent>();//not working
var clsComp2 = this.GetSingleton<MyClassComponent>();//working
//but this works
var e = GetSingletonEntity<SingletonTag>();
EntityManager.GetComponentObject<MyObjectComponent>(e);
EntityManager.GetComponentObject<MyClassComponent>(e);
}
Oh these are indeed clever. How did you even come up with that?
But on other hand, it make me think, is it right to use classes in Dots?
Are this approaches not invalidate dots principles, or some sort things like that?
I am probably wrong, but I feel, these are like kind of hacks / work arounds
Shouldn’t we be avoiding mixing entities and classes as components together, as the principle?
UnityEngine.Object support is for HybridComponent.
It’s there and will be there as long as GameObject exists.
It’s part of DOTS principle.
Say you have a UnityEngine. Object designed for GameObject.
But you also want to use it in ECS.
You can either choose to simply add it to entity as ObjectComponent or shared component if you want.
or convert it to unmanaged IComponentData or BlobAsset.