Trying eliminating statics

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?

Any though?
How should I bite this problem?

Yes. You can attach pretty much anything you like to a singleton entity. (comps, buffers)

var cachedSystem = World.GetExistingSystem();
var hashMap = cachedSystem.hashMap;

1 Like

Right, I shall do that then.

Ah, this is simpler than I thought :slight_smile:

1 Like

class IComponentData 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)

3 Likes

@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);
        }
1 Like

Oh these are indeed clever. How did you even come up with that? :smile:

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 :roll_eyes:
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.

Thank you guys for assistance, I think I got decent results so far.
Here is my outcome.
Sorry for quotations from other thread.

Any further thoughts, are more than welcome.

You could also have an editor play mode changed event hook that kills/resets/shutdown any singletons or static data manually.

So, if for some reason your singleton entities are not being killed on ECS shutdown, you can always tap into ECS directly and murder them yourself.

Take a look at this:
https://github.com/joshcamas/unity-domain-reload-helper

Some cases were too difficult to get rid of the static. As I don’t want to waste any time on this, this script and attribute takes care of it.

1 Like