Last active
April 23, 2020 00:09
-
-
Save jeffvella/c8bcd49ee29fb2c85ab21aca9f5a9734 to your computer and use it in GitHub Desktop.
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 UnityEngine; | |
| [CreateAssetMenu(menuName = "Data/" + nameof(Ingredient))] | |
| public unsafe class Ingredient : ScriptableObjectDataProvider<Ingredient.IngredientData> | |
| { | |
| public enum Id | |
| { | |
| None = 0, | |
| Carrot, | |
| Potato, | |
| ChickenThigh, | |
| ChickenStock, | |
| } | |
| [Serializable] | |
| public struct IngredientData : IScriptableObjectData | |
| { | |
| public Id Id; | |
| public int Quantity; | |
| public float Tastyness; | |
| } | |
| } |
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.Generic; | |
| using Unity.Collections; | |
| using Unity.Entities; | |
| using UnityEngine; | |
| public enum RecipeId | |
| { | |
| None = 0, | |
| Stew, | |
| StuffedPotatoes | |
| } | |
| [CreateAssetMenu(menuName = "Data/" + nameof(Recipe))] | |
| public unsafe class Recipe : ScriptableObjectDataProvider | |
| { | |
| public RecipeId Id; | |
| public string Description; | |
| public List<Ingredient> Ingredients; | |
| public int Value; | |
| protected override IEnumerable<IComponentDataContainer> DeclareChildren() | |
| { | |
| return Ingredients; | |
| } | |
| public override void Convert(EntityManager em, Entity entity) | |
| { | |
| em.AddComponent<RecipeData>(entity); | |
| em.SetComponentData(entity, new RecipeData | |
| { | |
| Id = Id, | |
| Description = Description, | |
| SomeValue = Value, | |
| }); | |
| } | |
| public override ComponentType GetDataComponentType() | |
| => ComponentType.ReadWrite<RecipeData>(); | |
| } | |
| public struct RecipeData : IScriptableObjectData | |
| { | |
| public RecipeId Id; | |
| public FixedString64 Description; | |
| public int SomeValue; | |
| } |
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; | |
| using System.Collections.Generic; | |
| using Unity.Entities; | |
| using UnityEngine; | |
| using Object = UnityEngine.Object; | |
| public class ScriptableObjectAdapter : MonoBehaviour | |
| { | |
| public List<ScriptableObject> Data; | |
| } | |
| public class ScriptableObjectConversionSystem : GameObjectConversionSystem | |
| { | |
| private Dictionary<Guid, ConvertablesEntry> _entityByGuid = new Dictionary<Guid, ConvertablesEntry>(); | |
| private List<IComponentDataContainer> _convertables = new List<IComponentDataContainer>(); | |
| internal struct ConvertablesEntry | |
| { | |
| public Guid Id; | |
| public Entity Entity; | |
| public int ChildStartIndex; | |
| public int ChildCount; | |
| public int Depth; | |
| public int Index; | |
| } | |
| protected override void OnUpdate() | |
| { | |
| _entityByGuid.Clear(); | |
| _convertables.Clear(); | |
| Entities.ForEach(delegate (ScriptableObjectAdapter adapter) | |
| { | |
| AddHybridComponent(adapter); | |
| Entity adapterEntity = GetPrimaryEntity(adapter); | |
| DstEntityManager.RemoveComponent<Transform>(adapterEntity); | |
| for (int i = 0; i < adapter.Data.Count; i++) | |
| { | |
| if (adapter.Data[i] is IComponentDataContainer convertable) | |
| { | |
| _convertables.Add(convertable); | |
| CollectRecursively(adapter, convertable, _entityByGuid.Count); | |
| } | |
| } | |
| foreach (var item in _entityByGuid.Values) | |
| { | |
| var container = _convertables[item.Index]; | |
| var componentType = container.GetDataComponentType(); | |
| DeclareAssetDependency(adapter.gameObject, container.AsObject()); | |
| DstEntityManager.AddComponentData(item.Entity, new ScriptableObjectComponent | |
| { | |
| Id = item.Id, | |
| Type = componentType | |
| }); | |
| container.Convert(DstEntityManager, item.Entity); | |
| if (item.ChildCount > 0) | |
| { | |
| var buffer = DstEntityManager.AddBuffer<LinkedChild>(item.Entity); | |
| var len = item.ChildStartIndex + item.ChildCount; | |
| for (int i = item.ChildStartIndex; i < len; i++) | |
| { | |
| var childContainer = _convertables[i]; | |
| var childItem = _entityByGuid[childContainer.Id]; | |
| buffer.Add(new LinkedChild | |
| { | |
| Id = childContainer.Id, | |
| Entity = childItem.Entity | |
| }); | |
| } | |
| } | |
| DstEntityManager.SetName(item.Entity, container.Name); | |
| } | |
| }); | |
| } | |
| public struct LinkedChild : IBufferElementData | |
| { | |
| public Guid Id; | |
| public Entity Entity; | |
| } | |
| private void CollectRecursively(ScriptableObjectAdapter adapter, IComponentDataContainer convertable, int index, int depth = 0) | |
| { | |
| if (depth > 5) | |
| throw new InvalidOperationException(); | |
| var id = convertable.Id; | |
| var previousCount = _convertables.Count; | |
| if (!_entityByGuid.ContainsKey(id)) | |
| { | |
| var children = convertable.DeclareChildren(); | |
| if (children == null) | |
| { | |
| _entityByGuid[id] = new ConvertablesEntry | |
| { | |
| Id = id, | |
| Index = index, | |
| Entity = CreateAdditionalEntity(adapter.gameObject), | |
| Depth = depth | |
| }; | |
| return; | |
| } | |
| _convertables.AddRange(children); | |
| _entityByGuid[id] = new ConvertablesEntry | |
| { | |
| Id = id, | |
| Index = index, | |
| Entity = CreateAdditionalEntity(adapter.gameObject), | |
| ChildStartIndex = previousCount, | |
| ChildCount = _convertables.Count - previousCount, | |
| Depth = depth | |
| }; | |
| var i = 1; | |
| foreach (var child in children) | |
| { | |
| CollectRecursively(adapter, child, index + i++, ++depth); | |
| } | |
| } | |
| } | |
| } | |
| public struct ScriptableObjectComponent : IComponentData | |
| { | |
| public ComponentType Type; | |
| public Guid Id; | |
| public Entity Parent; | |
| } | |
| public interface IComponentDataContainer<T> : IComponentDataContainer where T : struct, IScriptableObjectData | |
| { | |
| T Data { get; } | |
| } | |
| public interface IComponentDataContainer | |
| { | |
| Guid Id { get; } | |
| string Name { get; } | |
| ComponentType GetDataComponentType(); | |
| void Convert(EntityManager em, Entity entity); | |
| IEnumerable<IComponentDataContainer> DeclareChildren(); | |
| Object AsObject(); | |
| } | |
| public unsafe abstract class ScriptableObjectDataProvider<T> : ScriptableObjectDataProvider, IComponentDataContainer<T> where T : unmanaged, IScriptableObjectData | |
| { | |
| public T Data; | |
| T IComponentDataContainer<T>.Data => Data; | |
| public override ComponentType GetDataComponentType() | |
| => ComponentType.ReadWrite<T>(); | |
| public override void Convert(EntityManager em, Entity entity) | |
| { | |
| em.AddComponent(entity, typeof(T)); | |
| em.SetComponentData(entity, Data); | |
| } | |
| } | |
| public unsafe abstract class ScriptableObjectDataProvider : ScriptableObject, IComponentDataContainer | |
| { | |
| [HideInInspector, SerializeField] | |
| protected Guid _id = Guid.NewGuid(); | |
| string IComponentDataContainer.Name => name; | |
| Guid IComponentDataContainer.Id => _id; | |
| public abstract ComponentType GetDataComponentType(); | |
| protected virtual IEnumerable<IComponentDataContainer> DeclareChildren() => default; | |
| IEnumerable<IComponentDataContainer> IComponentDataContainer.DeclareChildren() => DeclareChildren(); | |
| Object IComponentDataContainer.AsObject() => this; | |
| public abstract void Convert(EntityManager em, Entity entity); | |
| } | |
| public interface IScriptableObjectData : IComponentData | |
| { | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment