Created
October 9, 2019 18:08
-
-
Save jeffvella/aaa4f8faf7bf384c85079343868eb32b to your computer and use it in GitHub Desktop.
Experiment with ScriptableObject entity conversion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Concurrent; | |
using System.Collections.Generic; | |
using Unity.Collections; | |
using Unity.Collections.LowLevel.Unsafe; | |
using Unity.Entities; | |
using Unity.Mathematics; | |
using UnityEngine; | |
public struct LevelDataComponent : IComponentData | |
{ | |
public int Id; | |
public NativeString512 Text; | |
} | |
[CreateAssetMenu] | |
public class LevelData : EcsScriptableObject<LevelDataComponent> | |
{ | |
public int Id; | |
public string Text; | |
public override LevelDataComponent Convert(EntityManager dstEntityManager, Entity entity) | |
{ | |
return new LevelDataComponent | |
{ | |
Id = Id, | |
Text = new NativeString512(Text) | |
}; | |
} | |
} | |
[Serializable] | |
public struct SomeGameData : IComponentData | |
{ | |
public UnsafeList Stuff; | |
public NativeString512 Text; | |
public bool GodMode; | |
} | |
[CreateAssetMenu] | |
public class GameData : EcsScriptableObject<SomeGameData> | |
{ | |
public List<int> ManagedStuff; | |
public string Text; | |
public bool GodMode; | |
public override SomeGameData Convert(EntityManager dstEntityManager, Entity entity) | |
{ | |
var unmanagedStuff = new UnsafeList(Allocator.Persistent); // yummy leaks | |
for (int i = 0; i < ManagedStuff.Count; i++) | |
unmanagedStuff.Add(ManagedStuff[i]); | |
return new SomeGameData | |
{ | |
Stuff = unmanagedStuff, | |
Text = new NativeString512(Text), | |
GodMode = GodMode, | |
}; | |
} | |
} | |
public abstract class EcsScriptableObject : ScriptableObject | |
{ | |
public static Dictionary<int, ScriptableObjectAccessor> ByInstanceId = new Dictionary<int, ScriptableObjectAccessor>(); | |
public static ConcurrentQueue<ScriptableObjectAccessor> PendingConversion = new ConcurrentQueue<ScriptableObjectAccessor>(); | |
public abstract void Convert(EntityManager dstEntityManager, ScriptableObjectAccessor accessor); | |
public abstract string GetComponentTypeName(); | |
} | |
public class ScriptableObjectAccessor | |
{ | |
public Entity Entity; | |
public EcsScriptableObject Instance; | |
} | |
public abstract class EcsScriptableObject<TComponentData> : EcsScriptableObject where TComponentData : unmanaged, IComponentData | |
{ | |
protected EcsScriptableObject() | |
{ | |
var accessor = new ScriptableObjectAccessor | |
{ | |
Instance = this, | |
Entity = Entity.Null, | |
}; | |
PendingConversion.Enqueue(accessor); | |
ByInstanceId.Add(GetInstanceID(), accessor); | |
} | |
public override void Convert(EntityManager dstEntityManager, ScriptableObjectAccessor accessor) | |
{ | |
var component = Convert(dstEntityManager, accessor.Entity); | |
dstEntityManager.AddComponentData(accessor.Entity, component); | |
} | |
public override string GetComponentTypeName() => typeof(TComponentData).Name; | |
public abstract TComponentData Convert(EntityManager dstEntityManager, Entity entity); | |
} | |
public class ScriptableObjectConversion : GameObjectConversionSystem | |
{ | |
protected override void OnUpdate() | |
{ | |
while (EcsScriptableObject.PendingConversion.Count > 0) | |
{ | |
if (EcsScriptableObject.PendingConversion.TryDequeue(out var so)) | |
{ | |
so.Entity = DstEntityManager.CreateEntity(); | |
so.Instance.Convert(DstEntityManager, so); | |
DstEntityManager.SetName(so.Entity, $"SO: {so.Instance.GetType().Name}<{so.Instance.GetComponentTypeName()}>"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment