mirror of
https://github.com/DCFApixels/DragonECS-Unity.git
synced 2025-09-18 18:14:35 +08:00
Update
This commit is contained in:
parent
0862067ddd
commit
ebfaf5bc98
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37d966ee996491b4d923ae68af4b67cd
|
||||
guid: f2b9c91714b4752468a3a5691cbf5237
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
21
src/Buildin/EcsDefaultWorldProvider.cs
Normal file
21
src/Buildin/EcsDefaultWorldProvider.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
[CreateAssetMenu(fileName = nameof(EcsDefaultWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsDefaultWorldProvider), order = 1)]
|
||||
public class EcsDefaultWorldProvider : EcsWorldProvider<EcsDefaultWorld>
|
||||
{
|
||||
//private static EcsDefaultWorldProvider _singleInstance;
|
||||
//public static EcsDefaultWorldProvider SingletonInstance
|
||||
//{
|
||||
// get
|
||||
// {
|
||||
// if (_singleInstance == null)
|
||||
// {
|
||||
// _singleInstance = FindOrCreateSingleton<EcsDefaultWorldProvider>();
|
||||
// }
|
||||
// return _singleInstance;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
23
src/Buildin/EcsDefaultWorldSingletonProvider.cs
Normal file
23
src/Buildin/EcsDefaultWorldSingletonProvider.cs
Normal file
@ -0,0 +1,23 @@
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public class EcsDefaultWorldSingletonProvider : EcsWorldProvider<EcsDefaultWorld>
|
||||
{
|
||||
private static EcsDefaultWorldSingletonProvider _instance;
|
||||
public static EcsDefaultWorldSingletonProvider Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = FindOrCreateSingleton<EcsDefaultWorldSingletonProvider>("DefaultSingletonProvider");
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
protected override EcsDefaultWorld BuildWorld()
|
||||
{
|
||||
return new EcsDefaultWorld();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54d84d8749e68c044b4f13a512808a67
|
||||
guid: 7592c6e5a68845c4abeac089e561d8c7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@ -6,89 +6,93 @@ using UnityEngine;
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
[Serializable]
|
||||
[DebugColor(255 / 3, 255, 0)]
|
||||
[MetaColor(255 / 3, 255, 0)]
|
||||
public struct UnityComponent<T> : IEcsComponent, IEnumerable<T>//IntelliSense hack
|
||||
where T : Component
|
||||
{
|
||||
public T obj;
|
||||
public UnityComponent(T obj) => this.obj = obj;
|
||||
public UnityComponent(T obj)
|
||||
{
|
||||
this.obj = obj;
|
||||
}
|
||||
IEnumerator<T> IEnumerable<T>.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack
|
||||
IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); //IntelliSense hack
|
||||
}
|
||||
|
||||
|
||||
public class UnityComponentInitializer<T> : TemplateComponentInitializer<UnityComponent<T>> where T : Component
|
||||
#region Unity Component Templates
|
||||
public class UnityComponentTemplate<T> : ComponentTemplateBase<UnityComponent<T>> where T : Component
|
||||
{
|
||||
public override string Name => "UnityComponent/" + typeof(T).Name;
|
||||
public sealed override void Add(EcsWorld w, int e) => w.GetPool<UnityComponent<T>>().Add(e) = component;
|
||||
public override void OnValidate(GameObject gameObject)
|
||||
public sealed override void Apply(int worldID, int entityID)
|
||||
{
|
||||
EcsWorld.GetPool<EcsPool<UnityComponent<T>>>(worldID).TryAddOrGet(entityID) = component;
|
||||
}
|
||||
public override void OnValidate(UnityEngine.Object obj)
|
||||
{
|
||||
if (component.obj == null)
|
||||
component.obj = gameObject.GetComponent<T>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Serializable]
|
||||
public sealed class UnityComponentRigitBodyInitializer : UnityComponentInitializer<Rigidbody>
|
||||
{
|
||||
if (obj is GameObject go)
|
||||
{
|
||||
component.obj = go.GetComponent<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class UnityComponentAnimatorInitializer : UnityComponentInitializer<Animator>
|
||||
{
|
||||
}
|
||||
public sealed class UnityComponentRigitBodyInitializer : UnityComponentTemplate<Rigidbody> { }
|
||||
[Serializable]
|
||||
public sealed class UnityComponentCharacterControllerInitializer : UnityComponentInitializer<CharacterController>
|
||||
{
|
||||
}
|
||||
public sealed class UnityComponentAnimatorInitializer : UnityComponentTemplate<Animator> { }
|
||||
[Serializable]
|
||||
public sealed class UnityComponentCharacterControllerInitializer : UnityComponentTemplate<CharacterController> { }
|
||||
#endregion
|
||||
|
||||
#region Colliders
|
||||
#region Collider Templates
|
||||
[Serializable]
|
||||
public sealed class UnityComponentColliderInitializer : UnityComponentInitializer<Collider>
|
||||
public sealed class UnityComponentColliderTemplate : UnityComponentTemplate<Collider>
|
||||
{
|
||||
public override string Name => "UnityComponent/Collider/" + nameof(Collider);
|
||||
}
|
||||
[Serializable]
|
||||
public sealed class UnityComponentBoxColliderInitializer : UnityComponentInitializer<BoxCollider>
|
||||
public sealed class UnityComponentBoxColliderTemplate : UnityComponentTemplate<BoxCollider>
|
||||
{
|
||||
public override string Name => "UnityComponent/Collider/" + nameof(BoxCollider);
|
||||
}
|
||||
[Serializable]
|
||||
public sealed class UnityComponentSphereColliderInitializer : UnityComponentInitializer<SphereCollider>
|
||||
public sealed class UnityComponentSphereColliderTemplate : UnityComponentTemplate<SphereCollider>
|
||||
{
|
||||
public override string Name => "UnityComponent/Collider/" + nameof(SphereCollider);
|
||||
}
|
||||
[Serializable]
|
||||
public sealed class UnityComponentCapsuleColliderInitializer : UnityComponentInitializer<CapsuleCollider>
|
||||
public sealed class UnityComponentCapsuleColliderTemplate : UnityComponentTemplate<CapsuleCollider>
|
||||
{
|
||||
public override string Name => "UnityComponent/Collider/" + nameof(CapsuleCollider);
|
||||
}
|
||||
[Serializable]
|
||||
public sealed class UnityComponentMeshColliderInitializer : UnityComponentInitializer<MeshCollider>
|
||||
public sealed class UnityComponentMeshColliderTemplate : UnityComponentTemplate<MeshCollider>
|
||||
{
|
||||
public override string Name => "UnityComponent/Collider/" + nameof(MeshCollider);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Joints
|
||||
#region Joint Templates
|
||||
[Serializable]
|
||||
public sealed class UnityComponentJointInitializer : UnityComponentInitializer<Joint>
|
||||
public sealed class UnityComponentJointTemplate : UnityComponentTemplate<Joint>
|
||||
{
|
||||
public override string Name => "UnityComponent/Joint/" + nameof(Joint);
|
||||
}
|
||||
[Serializable]
|
||||
public sealed class UnityComponentFixedJointInitializer : UnityComponentInitializer<FixedJoint>
|
||||
public sealed class UnityComponentFixedJointTemplate : UnityComponentTemplate<FixedJoint>
|
||||
{
|
||||
public override string Name => "UnityComponent/Joint/" + nameof(FixedJoint);
|
||||
}
|
||||
[Serializable]
|
||||
public sealed class UnityComponentCharacterJointInitializer : UnityComponentInitializer<CharacterJoint>
|
||||
public sealed class UnityComponentCharacterJointTemplate : UnityComponentTemplate<CharacterJoint>
|
||||
{
|
||||
public override string Name => "UnityComponent/Joint/" + nameof(CharacterJoint);
|
||||
}
|
||||
[Serializable]
|
||||
public sealed class UnityComponentConfigurableJointInitializer : UnityComponentInitializer<ConfigurableJoint>
|
||||
public sealed class UnityComponentConfigurableJointTemplate : UnityComponentTemplate<ConfigurableJoint>
|
||||
{
|
||||
public override string Name => "UnityComponent/Joint/" + nameof(ConfigurableJoint);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 47a8547ed46c26e4bb6a68651ad40be0
|
||||
guid: 637d69c48b6c0164abe654cd7f5ceb07
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@ -1,4 +1,5 @@
|
||||
using DCFApixels.DragonECS.RunnersCore;
|
||||
using DCFApixels.DragonECS.Internal;
|
||||
using DCFApixels.DragonECS.RunnersCore;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
@ -10,7 +11,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
public static void DrawGizmos(this EcsPipeline systems)
|
||||
{
|
||||
systems.GetRunner<IEcsGizmosProcess>().DrawGizmos(systems);
|
||||
systems.GetRunnerInstance<EcsLateGizmosRunner>().DrawGizmos(systems);
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,9 +21,9 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public static class IEcsLateRunSystemExtensions
|
||||
{
|
||||
public static void LateRun(this EcsPipeline systems)
|
||||
public static void LateRun(this EcsPipeline pipeline)
|
||||
{
|
||||
systems.GetRunner<IEcsLateRunProcess>().LateRun(systems);
|
||||
pipeline.GetRunnerInstance<EcsLateRunRunner>().LateRun(pipeline);
|
||||
}
|
||||
}
|
||||
public interface IEcsFixedRunProcess : IEcsProcess
|
||||
@ -33,14 +34,14 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
public static void FixedRun(this EcsPipeline pipeline)
|
||||
{
|
||||
pipeline.GetRunner<IEcsFixedRunProcess>().FixedRun(pipeline);
|
||||
pipeline.GetRunnerInstance<EcsFixedRunRunner>().FixedRun(pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
[DebugColor(DebugColor.Orange)]
|
||||
public class EcsLateGizmosSystemRunner : EcsRunner<IEcsGizmosProcess>, IEcsGizmosProcess
|
||||
[MetaColor(MetaColor.Orange)]
|
||||
public class EcsLateGizmosRunner : EcsRunner<IEcsGizmosProcess>, IEcsGizmosProcess
|
||||
{
|
||||
#if DEBUG && !DISABLE_DEBUG
|
||||
private EcsProfilerMarker[] _markers;
|
||||
@ -48,10 +49,10 @@ namespace DCFApixels.DragonECS
|
||||
public void DrawGizmos(EcsPipeline pipeline)
|
||||
{
|
||||
#if DEBUG && !DISABLE_DEBUG
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
for (int i = 0; i < Process.Length; i++)
|
||||
{
|
||||
using (_markers[i].Auto())
|
||||
targets[i].DrawGizmos(pipeline);
|
||||
Process[i].DrawGizmos(pipeline);
|
||||
}
|
||||
#else
|
||||
foreach (var item in targets) item.DrawGizmos(pipeline);
|
||||
@ -61,17 +62,17 @@ namespace DCFApixels.DragonECS
|
||||
#if DEBUG && !DISABLE_DEBUG
|
||||
protected override void OnSetup()
|
||||
{
|
||||
_markers = new EcsProfilerMarker[targets.Length];
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
_markers = new EcsProfilerMarker[Process.Length];
|
||||
for (int i = 0; i < Process.Length; i++)
|
||||
{
|
||||
_markers[i] = new EcsProfilerMarker($"{targets[i].GetType().Name}.{nameof(DrawGizmos)}");
|
||||
_markers[i] = new EcsProfilerMarker($"{Process[i].GetType().Name}.{nameof(DrawGizmos)}");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[DebugColor(DebugColor.Orange)]
|
||||
public class EcsLateRunSystemRunner : EcsRunner<IEcsLateRunProcess>, IEcsLateRunProcess
|
||||
[MetaColor(MetaColor.Orange)]
|
||||
public class EcsLateRunRunner : EcsRunner<IEcsLateRunProcess>, IEcsLateRunProcess
|
||||
{
|
||||
#if DEBUG && !DISABLE_DEBUG
|
||||
private EcsProfilerMarker[] _markers;
|
||||
@ -79,10 +80,12 @@ namespace DCFApixels.DragonECS
|
||||
public void LateRun(EcsPipeline pipeline)
|
||||
{
|
||||
#if DEBUG && !DISABLE_DEBUG
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
for (int i = 0; i < Process.Length; i++)
|
||||
{
|
||||
using (_markers[i].Auto())
|
||||
targets[i].LateRun(pipeline);
|
||||
{
|
||||
Process[i].LateRun(pipeline);
|
||||
}
|
||||
}
|
||||
#else
|
||||
foreach (var item in targets) item.LateRun(pipeline);
|
||||
@ -92,16 +95,16 @@ namespace DCFApixels.DragonECS
|
||||
#if DEBUG && !DISABLE_DEBUG
|
||||
protected override void OnSetup()
|
||||
{
|
||||
_markers = new EcsProfilerMarker[targets.Length];
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
_markers = new EcsProfilerMarker[Process.Length];
|
||||
for (int i = 0; i < Process.Length; i++)
|
||||
{
|
||||
_markers[i] = new EcsProfilerMarker($"EcsRunner.{targets[i].GetType().Name}.{nameof(LateRun)}");
|
||||
_markers[i] = new EcsProfilerMarker($"EcsRunner.{Process[i].GetType().Name}.{nameof(LateRun)}");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
[DebugColor(DebugColor.Orange)]
|
||||
public class EcsFixedRunSystemRunner : EcsRunner<IEcsFixedRunProcess>, IEcsFixedRunProcess
|
||||
[MetaColor(MetaColor.Orange)]
|
||||
public class EcsFixedRunRunner : EcsRunner<IEcsFixedRunProcess>, IEcsFixedRunProcess
|
||||
{
|
||||
#if DEBUG && !DISABLE_DEBUG
|
||||
private EcsProfilerMarker[] _markers;
|
||||
@ -109,10 +112,12 @@ namespace DCFApixels.DragonECS
|
||||
public void FixedRun(EcsPipeline pipeline)
|
||||
{
|
||||
#if DEBUG && !DISABLE_DEBUG
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
for (int i = 0; i < Process.Length; i++)
|
||||
{
|
||||
using (_markers[i].Auto())
|
||||
targets[i].FixedRun(pipeline);
|
||||
{
|
||||
Process[i].FixedRun(pipeline);
|
||||
}
|
||||
}
|
||||
#else
|
||||
foreach (var item in targets) item.FixedRun(pipeline);
|
||||
@ -122,10 +127,10 @@ namespace DCFApixels.DragonECS
|
||||
#if DEBUG && !DISABLE_DEBUG
|
||||
protected override void OnSetup()
|
||||
{
|
||||
_markers = new EcsProfilerMarker[targets.Length];
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
_markers = new EcsProfilerMarker[Process.Length];
|
||||
for (int i = 0; i < Process.Length; i++)
|
||||
{
|
||||
_markers[i] = new EcsProfilerMarker($"EcsRunner.{targets[i].GetType().Name}.{nameof(FixedRun)}");
|
||||
_markers[i] = new EcsProfilerMarker($"EcsRunner.{Process[i].GetType().Name}.{nameof(FixedRun)}");
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ce52308e352f734e8a21c5ae282c246
|
||||
guid: 9b692b77d059ff445912bada1712ccab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@ -6,7 +6,7 @@ using UnityEditor;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
[DebugColor(DebugColor.Cyan)]
|
||||
[MetaColor(MetaColor.Cyan)]
|
||||
public readonly struct UnityGameObject : IEcsComponent
|
||||
{
|
||||
public readonly GameObject gameObject;
|
||||
@ -60,12 +60,11 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
public static class GameObjectRefExt
|
||||
{
|
||||
public static entlong NewEntityWithGameObject(this EcsWorld self, string name = "EcsEntity", GameObjectIcon icon = GameObjectIcon.NONE)
|
||||
public static entlong NewEntityWithGameObject(this EcsWorld self, string name = "Entity", GameObjectIcon icon = GameObjectIcon.NONE)
|
||||
{
|
||||
entlong result = self.GetEntityLong(self.NewEmptyEntity());
|
||||
entlong result = self.NewEntityLong();
|
||||
GameObject newGameObject = new GameObject(name);
|
||||
newGameObject.AddComponent<EcsEntityConnect>().ConnectWith(result);
|
||||
// self.GetPool<UnityGameObject>().Add(result.id) =
|
||||
#if UNITY_EDITOR
|
||||
if (icon != GameObjectIcon.NONE)
|
||||
{
|
||||
@ -84,7 +83,6 @@ namespace DCFApixels.DragonECS
|
||||
EditorGUIUtility.SetIconForObject(newGameObject, (Texture2D)iconContent.image);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 909b2b01fa1e58b4e9e739827e36cff4
|
||||
guid: 398c78166eea90647a60b91b2b9a0f0b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@ -1,19 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
[CreateAssetMenu(fileName = nameof(EcsDefaultWorldProvider), menuName = EcsConsts.FRAMEWORK_NAME + "/WorldProviders/" + nameof(EcsDefaultWorldProvider), order = 1)]
|
||||
public class EcsDefaultWorldProvider : EcsWorldProvider<EcsDefaultWorld>
|
||||
{
|
||||
private static EcsDefaultWorldProvider _single;
|
||||
public static EcsDefaultWorldProvider Single
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_single == null)
|
||||
_single = FindOrCreateSingle<EcsDefaultWorldProvider>();
|
||||
return _single;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -18,13 +18,13 @@ namespace DCFApixels.DragonECS
|
||||
private EcsWorld _world;
|
||||
|
||||
[SerializeField]
|
||||
private EntityTemplatePreset[] _entityTemplatePresets;
|
||||
private ScriptableEntityTemplate[] _scriptableTemplates;
|
||||
[SerializeField]
|
||||
private EntityTemplate[] _entityTemplates;
|
||||
private MonoEntityTemplate[] _monoTemplates;
|
||||
|
||||
internal void SetTemplates_Editor(EntityTemplate[] tempaltes)
|
||||
internal void SetTemplates_Editor(MonoEntityTemplate[] tempaltes)
|
||||
{
|
||||
_entityTemplates = tempaltes;
|
||||
_monoTemplates = tempaltes;
|
||||
}
|
||||
|
||||
#region Properties
|
||||
@ -38,7 +38,7 @@ namespace DCFApixels.DragonECS
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _world;
|
||||
}
|
||||
public bool IsAlive
|
||||
public bool IsConected
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _entity.IsAlive;
|
||||
@ -69,70 +69,157 @@ namespace DCFApixels.DragonECS
|
||||
_entity = entlong.NULL;
|
||||
}
|
||||
}
|
||||
public void ApplyTemplates() => ApplyTemplatesFor(_entity.ID);
|
||||
public void ApplyTemplates()
|
||||
{
|
||||
ApplyTemplatesFor(_entity.ID);
|
||||
}
|
||||
public void ApplyTemplatesFor(int entityID)
|
||||
{
|
||||
foreach (var t in _entityTemplatePresets)
|
||||
t.Apply(_world, entityID);
|
||||
foreach (var t in _entityTemplates)
|
||||
t.Apply(_world, entityID);
|
||||
foreach (var t in _scriptableTemplates)
|
||||
{
|
||||
t.Apply(_world.id, entityID);
|
||||
}
|
||||
foreach (var t in _monoTemplates)
|
||||
{
|
||||
t.Apply(_world.id, entityID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
namespace DCFApixels.DragonECS.Editors
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
[CustomEditor(typeof(EcsEntityConnect))]
|
||||
[CanEditMultipleObjects]
|
||||
public class EcsEntityEditor : Editor
|
||||
{
|
||||
private EcsEntityConnect Target => (EcsEntityConnect)target;
|
||||
|
||||
private bool _isInit = false;
|
||||
private EcsEntityConnect Target => (EcsEntityConnect)target;
|
||||
private bool IsMultipleTargets => targets.Length > 1;
|
||||
|
||||
private void Init()
|
||||
{
|
||||
if (_isInit)
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
_isInit = true;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
Init();
|
||||
EcsGUI.Layout.DrawConnectStatus(Target.IsAlive);
|
||||
EcsEntityConnect[] targets = new EcsEntityConnect[this.targets.Length];
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
{
|
||||
targets[i] = (EcsEntityConnect)this.targets[i];
|
||||
}
|
||||
DrawTop();
|
||||
|
||||
if (Target.Entity.TryGetID(out int id))
|
||||
EditorGUILayout.IntField(id);
|
||||
DrawConnectStatus(targets);
|
||||
DrawEntityInfo();
|
||||
|
||||
DrawTemplates();
|
||||
|
||||
DrawButtons();
|
||||
DrawComponents();
|
||||
}
|
||||
private void DrawTop()
|
||||
{
|
||||
var iterator = serializedObject.GetIterator();
|
||||
iterator.NextVisible(true);
|
||||
using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath))
|
||||
{
|
||||
EditorGUILayout.PropertyField(iterator, true);
|
||||
}
|
||||
}
|
||||
private void DrawConnectStatus(EcsEntityConnect[] targets)
|
||||
{
|
||||
bool isConnected = Target.IsConected;
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
{
|
||||
if (isConnected != targets[i].IsConected)
|
||||
{
|
||||
isConnected = !Target.IsConected;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isConnected == Target.IsConected)
|
||||
{
|
||||
EcsGUI.Layout.DrawConnectStatus(Target.IsConected);
|
||||
}
|
||||
else
|
||||
EditorGUILayout.IntField(0);
|
||||
GUILayout.Label(Target.Entity.ToString());
|
||||
{
|
||||
EcsGUI.Layout.DrawUndeterminedConnectStatus();
|
||||
}
|
||||
}
|
||||
|
||||
base.OnInspectorGUI();
|
||||
private void DrawEntityInfo()
|
||||
{
|
||||
GUILayout.Label(string.Empty);
|
||||
Rect entityRect = GUILayoutUtility.GetLastRect();
|
||||
Rect idRect = entityRect;
|
||||
idRect.xMax -= idRect.width / 2f;
|
||||
Rect genRect = entityRect;
|
||||
genRect.xMin = idRect.xMax;
|
||||
genRect.xMax -= genRect.width / 2f;
|
||||
Rect worldRect = genRect;
|
||||
worldRect.x += worldRect.width;
|
||||
|
||||
if (IsMultipleTargets == false && Target.Entity.TryUnpack(out int id, out short gen, out short world))
|
||||
{
|
||||
EditorGUI.IntField(idRect, id);
|
||||
EditorGUI.IntField(genRect, gen);
|
||||
EditorGUI.IntField(worldRect, world);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.TextField(idRect, "-");
|
||||
EditorGUI.TextField(genRect, "-");
|
||||
EditorGUI.TextField(worldRect, "-");
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawTemplates()
|
||||
{
|
||||
var iterator = serializedObject.GetIterator();
|
||||
iterator.NextVisible(true);
|
||||
bool enterChildren = true;
|
||||
while (iterator.NextVisible(enterChildren))
|
||||
{
|
||||
using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath))
|
||||
{
|
||||
EditorGUILayout.PropertyField(iterator, true);
|
||||
}
|
||||
enterChildren = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawButtons()
|
||||
{
|
||||
if (GUILayout.Button("Autoset Templates"))
|
||||
{
|
||||
Target.SetTemplates_Editor(Target.GetComponents<EntityTemplate>());
|
||||
|
||||
Target.SetTemplates_Editor(Target.GetComponents<MonoEntityTemplate>());
|
||||
EditorUtility.SetDirty(target);
|
||||
}
|
||||
if (GUILayout.Button("Autoset Templates Cascade"))
|
||||
{
|
||||
foreach (var item in Target.GetComponentsInChildren<EcsEntityConnect>())
|
||||
{
|
||||
item.SetTemplates_Editor(item.GetComponents<EntityTemplate>());
|
||||
item.SetTemplates_Editor(item.GetComponents<MonoEntityTemplate>());
|
||||
EditorUtility.SetDirty(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Target.IsAlive)
|
||||
private void DrawComponents()
|
||||
{
|
||||
if (Target.IsConected)
|
||||
{
|
||||
List<object> comps = new List<object>();
|
||||
Target.World.GetComponents(Target.Entity.ID, comps);
|
||||
|
@ -9,43 +9,50 @@ namespace DCFApixels.DragonECS
|
||||
[Serializable]
|
||||
public abstract class EcsWorldProviderBase : ScriptableObject
|
||||
{
|
||||
public abstract EcsWorld WorldRaw { get; }
|
||||
public abstract EcsWorld GetRaw(Func<EcsWorld> builder = null);
|
||||
public abstract bool IsEmpty { get; }
|
||||
public abstract void SetRaw(EcsWorld world);
|
||||
public abstract EcsWorld GetRaw();
|
||||
}
|
||||
[Serializable]
|
||||
public abstract class EcsWorldProvider<TWorld> : EcsWorldProviderBase where TWorld : EcsWorld
|
||||
{
|
||||
private static TWorld _world;
|
||||
public sealed override EcsWorld WorldRaw => _world;
|
||||
public override EcsWorld GetRaw(Func<EcsWorld> builder = null)
|
||||
{
|
||||
if (_world == null || _world.IsDestroyed)
|
||||
{
|
||||
if (builder != null)
|
||||
_world = (TWorld)builder();
|
||||
else
|
||||
_world = (TWorld)Activator.CreateInstance(typeof(TWorld));
|
||||
OnWorldCreated(_world);
|
||||
}
|
||||
return _world;
|
||||
}
|
||||
public TWorld Get(Func<TWorld> builder = null)
|
||||
{
|
||||
if (_world == null || _world.IsDestroyed)
|
||||
{
|
||||
if(builder != null)
|
||||
_world = builder();
|
||||
else
|
||||
_world = (TWorld)Activator.CreateInstance(typeof(TWorld));
|
||||
OnWorldCreated(_world);
|
||||
}
|
||||
return _world;
|
||||
}
|
||||
protected virtual void OnWorldCreated(TWorld world) { }
|
||||
private TWorld _world;
|
||||
|
||||
protected static TProvider FindOrCreateSingle<TProvider>() where TProvider : EcsWorldProvider<TWorld>
|
||||
#region Properties
|
||||
public sealed override bool IsEmpty
|
||||
{
|
||||
get { return _world == null; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
public sealed override void SetRaw(EcsWorld worldRaw)
|
||||
{
|
||||
Set((TWorld)worldRaw);
|
||||
}
|
||||
public void Set(TWorld world)
|
||||
{
|
||||
_world = world;
|
||||
}
|
||||
public sealed override EcsWorld GetRaw()
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
public TWorld Get()
|
||||
{
|
||||
if (_world == null || _world.IsDestroyed)
|
||||
{
|
||||
_world = BuildWorld();
|
||||
OnWorldCreated(_world);
|
||||
}
|
||||
return _world;
|
||||
}
|
||||
protected static TProvider FindOrCreateSingleton<TProvider>() where TProvider : EcsWorldProvider<TWorld>
|
||||
{
|
||||
return FindOrCreateSingleton<TProvider>(typeof(TProvider).Name + "Singleton");
|
||||
}
|
||||
protected static TProvider FindOrCreateSingleton<TProvider>(string name) where TProvider : EcsWorldProvider<TWorld>
|
||||
{
|
||||
string name = typeof(TProvider).Name + "Single";
|
||||
TProvider instance = Resources.Load<TProvider>(name);
|
||||
if (instance == null)
|
||||
{
|
||||
@ -62,5 +69,42 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
protected virtual TWorld BuildWorld()
|
||||
{
|
||||
return (TWorld)Activator.CreateInstance(typeof(TWorld), new object[] { null, -1 });
|
||||
}
|
||||
protected virtual void OnWorldCreated(TWorld world) { }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
[CustomEditor(typeof(EcsWorldProviderBase), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class EcsWorldProviderBaseEditor : Editor
|
||||
{
|
||||
private EcsWorldProviderBase Target => (EcsWorldProviderBase)target;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
if (Target.IsEmpty)
|
||||
{
|
||||
var style = EcsEditor.GetStyle(new Color32(255, 0, 75, 100));
|
||||
GUILayout.Box("Is Empty", style, GUILayout.ExpandWidth(true));
|
||||
}
|
||||
else
|
||||
{
|
||||
var style = EcsEditor.GetStyle(new Color32(75, 255, 0, 100));
|
||||
EcsWorld world = Target.GetRaw();
|
||||
GUILayout.Box($"{world.GetMeta().Name} ( {world.id} )", style, GUILayout.ExpandWidth(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -18,6 +18,7 @@ namespace DCFApixels.DragonECS
|
||||
if (v is Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
return;
|
||||
}
|
||||
|
||||
bool hasTag = string.IsNullOrEmpty(tag) == false;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
|
||||
namespace DCFApixels.DragonECS.Editors
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
[FilePath("DragonECS/DebugMonitorPrefs.prefs", FilePathAttribute.Location.ProjectFolder)]
|
||||
public class DebugMonitorPrefs : ScriptableSingleton<DebugMonitorPrefs>
|
||||
|
@ -1,48 +1,83 @@
|
||||
#if UNITY_EDITOR
|
||||
using DCFApixels.DragonECS.Unity.Internal;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UI;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS.Editors
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
public static class EcsGUI
|
||||
{
|
||||
private static GUIStyle _grayStyle;
|
||||
private static GUIStyle _greenStyle;
|
||||
private static GUIStyle _redStyle;
|
||||
private static GUILayoutOption[] _defaultParams;
|
||||
|
||||
private static bool _isInit = false;
|
||||
private static void Init()
|
||||
{
|
||||
if (_isInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_defaultParams = new GUILayoutOption[] { GUILayout.ExpandWidth(true) };
|
||||
_grayStyle = EcsEditor.GetStyle(new Color32(100, 100, 100, 100));
|
||||
_greenStyle = EcsEditor.GetStyle(new Color32(75, 255, 0, 100));
|
||||
_redStyle = EcsEditor.GetStyle(new Color32(255, 0, 75, 100));
|
||||
_isInit = true;
|
||||
}
|
||||
|
||||
|
||||
private const string CONNECTED = "Connected";
|
||||
private const string NOT_CONNECTED = "Not connected";
|
||||
private const string UNDETERMINED_CONNECTED = "---";
|
||||
public static void DrawConnectStatus(Rect position, bool status)
|
||||
{
|
||||
Init();
|
||||
if (status)
|
||||
GUI.Box(position, "Connected", _greenStyle);
|
||||
{
|
||||
GUI.Box(position, CONNECTED, _greenStyle);
|
||||
}
|
||||
else
|
||||
GUI.Box(position, "Not connected", _redStyle);
|
||||
{
|
||||
GUI.Box(position, NOT_CONNECTED, _redStyle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void DrawUndeterminedConnectStatus(Rect position)
|
||||
{
|
||||
Init();
|
||||
GUI.Box(position, UNDETERMINED_CONNECTED, _grayStyle);
|
||||
}
|
||||
public static class Layout
|
||||
{
|
||||
public static void DrawConnectStatus(bool status, params GUILayoutOption[] options)
|
||||
{
|
||||
Init();
|
||||
if(options == null || options.Length <= 0)
|
||||
{
|
||||
options = _defaultParams;
|
||||
}
|
||||
if (status)
|
||||
GUILayout.Box("Connected", _greenStyle, GUILayout.ExpandWidth(true));
|
||||
{
|
||||
GUILayout.Box(CONNECTED, _greenStyle, options);
|
||||
}
|
||||
else
|
||||
GUILayout.Box("Not connected", _redStyle, GUILayout.ExpandWidth(true));
|
||||
{
|
||||
GUILayout.Box(NOT_CONNECTED, _redStyle, options);
|
||||
}
|
||||
}
|
||||
public static void DrawUndeterminedConnectStatus(params GUILayoutOption[] options)
|
||||
{
|
||||
Init();
|
||||
if (options == null || options.Length <= 0)
|
||||
{
|
||||
options = _defaultParams;
|
||||
}
|
||||
GUILayout.Box(UNDETERMINED_CONNECTED, _grayStyle, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,30 @@
|
||||
using DCFApixels.DragonECS.Unity.Debug;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
[DebugHide, DebugColor(DebugColor.Gray)]
|
||||
public class PipelineDebugSystem : IEcsPreInitProcess
|
||||
[MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)]
|
||||
public class PipelineDebugSystem : IEcsPreInit, IEcsPipelineMember
|
||||
{
|
||||
public EcsPipeline Pipeline { get; set; }
|
||||
private string _monitorName;
|
||||
public PipelineDebugSystem(string monitorName = "Pipeline")
|
||||
{
|
||||
_monitorName = monitorName;
|
||||
}
|
||||
|
||||
void IEcsPreInitProcess.PreInit(EcsPipeline pipeline)
|
||||
void IEcsPreInit.PreInit()
|
||||
{
|
||||
PipelineDebugMonitor monitor = new GameObject(EcsConsts.DEBUG_PREFIX + _monitorName).AddComponent<PipelineDebugMonitor>();
|
||||
monitor.source = this;
|
||||
monitor.pipeline = pipeline;
|
||||
monitor.pipeline = Pipeline;
|
||||
monitor.monitorName = _monitorName;
|
||||
|
||||
PipelineProcessesDebugMonitor processesMonitor = new GameObject(EcsConsts.DEBUG_PREFIX + "Processes Matrix").AddComponent<PipelineProcessesDebugMonitor>();
|
||||
processesMonitor.transform.parent = monitor.transform;
|
||||
processesMonitor.source = this;
|
||||
processesMonitor.pipeline = pipeline;
|
||||
processesMonitor.pipeline = Pipeline;
|
||||
processesMonitor.monitorName = "Processes Matrix";
|
||||
|
||||
//foreach (var item in pipeline.AllSystems) //Вырезано пока не сделаю TODO в SystemDebugMonitor
|
||||
@ -46,22 +47,23 @@ namespace DCFApixels.DragonECS
|
||||
internal PipelineDebugSystem source;
|
||||
internal EcsPipeline pipeline;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace Editors
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
using DCFApixels.DragonECS.Internal;
|
||||
using DCFApixels.DragonECS.RunnersCore;
|
||||
using DCFApixels.DragonECS.Unity.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
[CustomEditor(typeof(PipelineDebugMonitor))]
|
||||
public class PipelineDebugMonitorEditor : Editor
|
||||
{
|
||||
private DebugColorAttribute _fakeDebugColorAttribute = new DebugColorAttribute(190, 190, 190);
|
||||
private Type _debugColorAttributeType = typeof(DebugColorAttribute);
|
||||
private MetaColorAttribute _fakeDebugColorAttribute = new MetaColorAttribute(190, 190, 190);
|
||||
private Type _debugColorAttributeType = typeof(MetaColorAttribute);
|
||||
private GUIStyle _headerStyle;
|
||||
private GUIStyle _interfacesStyle;
|
||||
private Color _interfaceColor = new Color(0.96f, 1f, 0.16f);
|
||||
@ -156,7 +158,7 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
GUILayout.BeginVertical(EcsEditor.GetStyle(color, 0.2f));
|
||||
GUILayout.Label(EcsEditor.GetGenericName(type), EditorStyles.boldLabel);
|
||||
GUILayout.Label(string.Join(", ", runner.Targets.Cast<object>().Select(o => o.GetType().Name)), systemsListStyle);
|
||||
GUILayout.Label(string.Join(", ", runner.ProcessRaw.Cast<object>().Select(o => o.GetType().Name)), systemsListStyle);
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
@ -337,4 +339,3 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
using DCFApixels.DragonECS.Unity.Debug;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
[DebugHide, DebugColor(DebugColor.Gray)]
|
||||
public class WorldDebugSystem : IEcsRunProcess
|
||||
[MetaTags(MetaTags.HIDDEN), MetaColor(MetaColor.Gray)]
|
||||
public class WorldDebugSystem : IEcsRun
|
||||
{
|
||||
private string _monitorName;
|
||||
private EcsWorld _ecsWorld;
|
||||
@ -27,7 +28,7 @@ namespace DCFApixels.DragonECS
|
||||
poolsmonitor.monitorName = "pools";
|
||||
}
|
||||
|
||||
public void Run(EcsPipeline pipeline)
|
||||
public void Run()
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -65,12 +66,11 @@ namespace DCFApixels.DragonECS
|
||||
internal WorldDebugSystem source;
|
||||
internal EcsWorld world;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace Editors
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
|
||||
[CustomEditor(typeof(WorldPoolsMonitor))]
|
||||
@ -111,9 +111,12 @@ namespace DCFApixels.DragonECS
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
|
||||
/// Äåôîëòíûé öâåò äëÿ ïóëà: new Color(0.3f, 1f, 0f, 1f);
|
||||
|
||||
private void DrawPoolBlock(IEcsPool pool, Rect position)
|
||||
{
|
||||
var meta = pool.GetMeta();
|
||||
|
||||
int count = pool.Count;
|
||||
int capacity = pool.Capacity < 0 ? count : pool.Capacity;
|
||||
|
||||
@ -128,13 +131,7 @@ namespace DCFApixels.DragonECS
|
||||
progressBar.width = position.width;
|
||||
progressBar.center = position.center - Vector2.up * _poolBlockMinSize.y * 0.09f;
|
||||
|
||||
|
||||
Color mainColor = new Color(0.3f, 1f, 0f, 1f);
|
||||
var debugColor = pool.ComponentType.GetCustomAttribute<DebugColorAttribute>();
|
||||
if (debugColor != null)
|
||||
{
|
||||
mainColor = debugColor.GetUnityColor();
|
||||
}
|
||||
Color mainColor = meta.Color.ToUnityColor();
|
||||
Color backgroundColor = mainColor * 0.3f + Color.white * 0.2f;
|
||||
|
||||
EditorGUI.DrawRect(progressBar, backgroundColor);
|
||||
@ -177,4 +174,4 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
8
src/EntityTemplate/Editor.meta
Normal file
8
src/EntityTemplate/Editor.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8c6da13649cc094e80f3ec624bad02b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
251
src/EntityTemplate/Editor/EntityTemplateEditor.cs
Normal file
251
src/EntityTemplate/Editor/EntityTemplateEditor.cs
Normal file
@ -0,0 +1,251 @@
|
||||
using DCFApixels.DragonECS.Unity.Internal;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public abstract class EntityTemplateEditorBase : Editor
|
||||
{
|
||||
private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 15f, 15f);
|
||||
private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 15f, 15f);
|
||||
|
||||
private GUIStyle removeButtonStyle;
|
||||
private GenericMenu genericMenu;
|
||||
private bool _isInit = false;
|
||||
|
||||
#region Init
|
||||
private void Init()
|
||||
{
|
||||
if (genericMenu == null)
|
||||
_isInit = false;
|
||||
if (_isInit)
|
||||
return;
|
||||
|
||||
var tmpstylebase = EcsEditor.GetStyle(new Color(0.9f, 0f, 0.22f), 0.5f);
|
||||
var tmpStyle = EcsEditor.GetStyle(new Color(1f, 0.5f, 0.7f), 0.5f);
|
||||
|
||||
removeButtonStyle = new GUIStyle(EditorStyles.linkLabel);
|
||||
removeButtonStyle.alignment = TextAnchor.MiddleCenter;
|
||||
|
||||
removeButtonStyle.normal = tmpstylebase.normal;
|
||||
removeButtonStyle.hover = tmpStyle.normal;
|
||||
removeButtonStyle.active = tmpStyle.normal;
|
||||
removeButtonStyle.focused = tmpStyle.normal;
|
||||
|
||||
removeButtonStyle.padding = new RectOffset(0, 0, 0, 0);
|
||||
removeButtonStyle.margin = new RectOffset(0, 0, 0, 0);
|
||||
removeButtonStyle.border = new RectOffset(0, 0, 0, 0);
|
||||
|
||||
genericMenu = new GenericMenu();
|
||||
|
||||
var dummies = ComponentTemplateTypeCache.Dummies;
|
||||
foreach (var dummy in dummies)
|
||||
{
|
||||
string name = dummy.Name;
|
||||
string description = dummy.Description;
|
||||
if (string.IsNullOrEmpty(description) == false)
|
||||
{
|
||||
name = $"{name} {EcsUnityConsts.INFO_MARK}";
|
||||
}
|
||||
genericMenu.AddItem(new GUIContent(name, description), false, OnAddComponent, dummy);
|
||||
}
|
||||
|
||||
_isInit = true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Add/Remove
|
||||
private void OnAddComponent(object obj)
|
||||
{
|
||||
Type componentType = obj.GetType();
|
||||
if (this.target is ITemplateInternal target)
|
||||
{
|
||||
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
|
||||
for (int i = 0; i < componentsProp.arraySize; i++)
|
||||
{
|
||||
if (componentsProp.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType)
|
||||
return;
|
||||
}
|
||||
|
||||
componentsProp.InsertArrayElementAtIndex(0);
|
||||
|
||||
componentsProp.GetArrayElementAtIndex(0).managedReferenceValue = ((IComponentTemplate)obj).Clone();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(this.target);
|
||||
}
|
||||
}
|
||||
private void OnRemoveComponentAt(int index)
|
||||
{
|
||||
if (this.target is ITemplateInternal target)
|
||||
{
|
||||
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
|
||||
componentsProp.DeleteArrayElementAtIndex(index);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(this.target);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected void Draw(ITemplateInternal target)
|
||||
{
|
||||
Init();
|
||||
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
|
||||
if (componentsProp == null)
|
||||
return;
|
||||
|
||||
DrawTop(target);
|
||||
for (int i = 0; i < componentsProp.arraySize; i++)
|
||||
{
|
||||
DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i);
|
||||
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * 2);
|
||||
}
|
||||
DrawFooter(target);
|
||||
}
|
||||
private void DrawTop(ITemplateInternal target)
|
||||
{
|
||||
if (GUILayout.Button("Add Component", GUILayout.Height(24f)))
|
||||
{
|
||||
Init();
|
||||
genericMenu.ShowAsContext();
|
||||
}
|
||||
}
|
||||
private void DrawFooter(ITemplateInternal target)
|
||||
{
|
||||
if (GUILayout.Button("Clear", GUILayout.Height(24f)))
|
||||
{
|
||||
Init();
|
||||
serializedObject.FindProperty(target.ComponentsPropertyName).ClearArray();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
private void DrawComponentData(SerializedProperty componentRefProp, int index)
|
||||
{
|
||||
IComponentTemplate template = componentRefProp.managedReferenceValue as IComponentTemplate;
|
||||
if (template == null)
|
||||
{
|
||||
DrawDamagedComponent(componentRefProp, index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (componentRefProp.managedReferenceValue == null)
|
||||
{
|
||||
DrawDamagedComponent(componentRefProp, index);
|
||||
return;
|
||||
}
|
||||
|
||||
Type initializerType;
|
||||
Type componentType;
|
||||
SerializedProperty componentProperty = componentRefProp;
|
||||
ComponentTemplateBase customInitializer = componentProperty.managedReferenceValue as ComponentTemplateBase;
|
||||
if (customInitializer != null)
|
||||
{
|
||||
componentProperty = componentRefProp.FindPropertyRelative("component");
|
||||
initializerType = customInitializer.Type;
|
||||
componentType = customInitializer.GetType().GetField("component", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FieldType;
|
||||
}
|
||||
else
|
||||
{
|
||||
initializerType = componentProperty.managedReferenceValue.GetType();
|
||||
componentType = initializerType;
|
||||
}
|
||||
|
||||
string name = template.Name;
|
||||
string description = template.Description;
|
||||
Color panelColor = template.Color;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.22f));
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
GUIContent label = new GUIContent(name);
|
||||
if (componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0)
|
||||
{
|
||||
GUILayout.Label(label);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.PropertyField(componentProperty, label, true);
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
componentProperty.serializedObject.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
|
||||
}
|
||||
|
||||
Rect lastrect = GUILayoutUtility.GetLastRect();
|
||||
Rect removeButtonRect = RemoveButtonRect;
|
||||
removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f);
|
||||
|
||||
GUILayout.EndVertical();
|
||||
Rect lineRect = GUILayoutUtility.GetLastRect();
|
||||
lineRect.y = lineRect.yMax;
|
||||
lineRect.height = 3f;
|
||||
Color rectColor = panelColor;
|
||||
rectColor.a = 0.34f;
|
||||
EditorGUI.DrawRect(lineRect, rectColor);
|
||||
GUILayout.Label("", GUILayout.Width(removeButtonRect.width));
|
||||
|
||||
if (GUI.Button(removeButtonRect, "x", removeButtonStyle))
|
||||
OnRemoveComponentAt(index);
|
||||
|
||||
if (!string.IsNullOrEmpty(description))
|
||||
{
|
||||
Rect tooltipIconRect = TooltipIconRect;
|
||||
tooltipIconRect.center = new Vector2(lastrect.xMax - removeButtonRect.width / 2f, lastrect.yMin + removeButtonRect.height / 2f);
|
||||
GUIContent descriptionLabel = new GUIContent(EcsUnityConsts.INFO_MARK, description);
|
||||
GUI.Label(tooltipIconRect, descriptionLabel, EditorStyles.boldLabel);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void DrawDamagedComponent(SerializedProperty componentRefProp, int index)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
EditorGUILayout.HelpBox($"Damaged component. If the problem occurred after renaming a component or initializer. use MovedFromAttrubute", MessageType.Warning);
|
||||
|
||||
Rect lastrect = GUILayoutUtility.GetLastRect();
|
||||
Rect removeButtonRect = RemoveButtonRect;
|
||||
removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f);
|
||||
|
||||
GUILayout.Label("", GUILayout.Width(removeButtonRect.width));
|
||||
if (GUI.Button(removeButtonRect, "x", removeButtonStyle))
|
||||
OnRemoveComponentAt(index);
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
public string GetLastPathComponent(string input)
|
||||
{
|
||||
int lastSlashIndex = input.LastIndexOfAny(new char[] { '/', '\\' });
|
||||
if (lastSlashIndex == -1)
|
||||
return input;
|
||||
else
|
||||
return input.Substring(lastSlashIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(ScriptableEntityTemplate), true)]
|
||||
public class EntityTemplatePresetEditor : EntityTemplateEditorBase
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
Draw((ITemplateInternal)target);
|
||||
}
|
||||
}
|
||||
[CustomEditor(typeof(MonoEntityTemplate), true)]
|
||||
public class EntityTemplateEditor : EntityTemplateEditorBase
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
Draw((ITemplateInternal)target);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,49 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public class EntityTemplate : MonoBehaviour, ITemplateInternal
|
||||
{
|
||||
[SerializeReference]
|
||||
private ITemplateComponent[] _components;
|
||||
string ITemplateInternal.ComponentsPropertyName => nameof(_components);
|
||||
|
||||
public void Apply(EcsWorld world, int entityID)
|
||||
{
|
||||
foreach (var item in _components)
|
||||
item.Add(world, entityID);
|
||||
}
|
||||
private void OnValidate()
|
||||
{
|
||||
if (_components == null) return;
|
||||
foreach (var item in _components)
|
||||
{
|
||||
if (item is ITemplateComponentOnValidate g)
|
||||
g.OnValidate(gameObject);
|
||||
}
|
||||
|
||||
}
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
if (_components == null) return;
|
||||
foreach (var item in _components)
|
||||
{
|
||||
if (item is ITemplateComponentGizmos g)
|
||||
g.OnGizmos(transform, ITemplateComponentGizmos.Mode.Always);
|
||||
}
|
||||
}
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
if (_components == null) return;
|
||||
foreach (var item in _components)
|
||||
{
|
||||
if (item is ITemplateComponentGizmos g)
|
||||
g.OnGizmos(transform, ITemplateComponentGizmos.Mode.Selected);
|
||||
}
|
||||
}
|
||||
public void Clear()
|
||||
{
|
||||
_components = new ITemplateComponent[0];
|
||||
}
|
||||
}
|
||||
}
|
@ -1,260 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
namespace Editors
|
||||
{
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public abstract class EntityTemplateEditorBase : Editor
|
||||
{
|
||||
private static readonly Rect RemoveButtonRect = new Rect(0f, 0f, 15f, 15f);
|
||||
private static readonly Rect TooltipIconRect = new Rect(0f, 0f, 15f, 15f);
|
||||
|
||||
private GUIStyle removeButtonStyle;
|
||||
private GenericMenu genericMenu;
|
||||
private bool _isInit = false;
|
||||
|
||||
#region Init
|
||||
private void Init()
|
||||
{
|
||||
if (genericMenu == null)
|
||||
_isInit = false;
|
||||
if (_isInit)
|
||||
return;
|
||||
|
||||
var tmpstylebase = EcsEditor.GetStyle(new Color(0.9f, 0f, 0.22f), 0.5f);
|
||||
var tmpStyle = EcsEditor.GetStyle(new Color(1f, 0.5f, 0.7f), 0.5f);
|
||||
|
||||
removeButtonStyle = new GUIStyle(EditorStyles.linkLabel);
|
||||
removeButtonStyle.alignment = TextAnchor.MiddleCenter;
|
||||
|
||||
removeButtonStyle.normal = tmpstylebase.normal;
|
||||
removeButtonStyle.hover = tmpStyle.normal;
|
||||
removeButtonStyle.active = tmpStyle.normal;
|
||||
removeButtonStyle.focused = tmpStyle.normal;
|
||||
|
||||
removeButtonStyle.padding = new RectOffset(0, 0, 0, 0);
|
||||
removeButtonStyle.margin = new RectOffset(0, 0, 0, 0);
|
||||
removeButtonStyle.border = new RectOffset(0, 0, 0, 0);
|
||||
|
||||
genericMenu = new GenericMenu();
|
||||
|
||||
var dummies = TemplateBrowsableTypeCache.Dummies;
|
||||
foreach (var dummy in dummies)
|
||||
{
|
||||
string name, description;
|
||||
if (dummy is ITemplateComponentName browsableName)
|
||||
name = browsableName.Name;
|
||||
else
|
||||
name = EcsEditor.GetName(dummy.GetType());
|
||||
|
||||
if (dummy is TemplateComponentInitializerBase initializer)
|
||||
description = initializer.Description;
|
||||
else
|
||||
description = EcsEditor.GetDescription(dummy.GetType());
|
||||
|
||||
if (!string.IsNullOrEmpty(description))
|
||||
{
|
||||
name = $"{name} {EcsUnityConsts.INFO_MARK}";
|
||||
}
|
||||
|
||||
genericMenu.AddItem(new GUIContent(name, description), false, OnAddComponent, dummy);
|
||||
}
|
||||
|
||||
_isInit = true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Add/Remove
|
||||
private void OnAddComponent(object obj)
|
||||
{
|
||||
Type componentType = obj.GetType();
|
||||
if (this.target is ITemplateInternal target)
|
||||
{
|
||||
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
|
||||
for (int i = 0; i < componentsProp.arraySize; i++)
|
||||
{
|
||||
if (componentsProp.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType)
|
||||
return;
|
||||
}
|
||||
|
||||
componentsProp.InsertArrayElementAtIndex(0);
|
||||
|
||||
componentsProp.GetArrayElementAtIndex(0).managedReferenceValue = ((ITemplateComponent)obj).Clone();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(this.target);
|
||||
}
|
||||
}
|
||||
private void OnRemoveComponentAt(int index)
|
||||
{
|
||||
if (this.target is ITemplateInternal target)
|
||||
{
|
||||
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
|
||||
componentsProp.DeleteArrayElementAtIndex(index);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(this.target);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected void Draw(ITemplateInternal target)
|
||||
{
|
||||
Init();
|
||||
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
|
||||
if (componentsProp == null)
|
||||
return;
|
||||
|
||||
DrawTop(target);
|
||||
for (int i = 0; i < componentsProp.arraySize; i++)
|
||||
{
|
||||
DrawComponentData(componentsProp.GetArrayElementAtIndex(i), i);
|
||||
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing * 2);
|
||||
}
|
||||
DrawFooter(target);
|
||||
}
|
||||
private void DrawTop(ITemplateInternal target)
|
||||
{
|
||||
if (GUILayout.Button("Add Component", GUILayout.Height(24f)))
|
||||
{
|
||||
Init();
|
||||
genericMenu.ShowAsContext();
|
||||
}
|
||||
}
|
||||
private void DrawFooter(ITemplateInternal target)
|
||||
{
|
||||
if (GUILayout.Button("Clear", GUILayout.Height(24f)))
|
||||
{
|
||||
Init();
|
||||
serializedObject.FindProperty(target.ComponentsPropertyName).ClearArray();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
private void DrawComponentData(SerializedProperty componentRefProp, int index)
|
||||
{
|
||||
ITemplateComponent browsable = componentRefProp.managedReferenceValue as ITemplateComponent;
|
||||
if (browsable == null)
|
||||
{
|
||||
DrawDamagedComponent(componentRefProp, index);
|
||||
return;
|
||||
}
|
||||
ITemplateComponentName browsableName = browsable as ITemplateComponentName;
|
||||
|
||||
if (componentRefProp.managedReferenceValue == null)
|
||||
{
|
||||
DrawDamagedComponent(componentRefProp, index);
|
||||
return;
|
||||
}
|
||||
|
||||
Type initializerType;
|
||||
Type componentType;
|
||||
SerializedProperty componentProperty = componentRefProp;
|
||||
TemplateComponentInitializerBase customInitializer = componentProperty.managedReferenceValue as TemplateComponentInitializerBase;
|
||||
if (customInitializer != null)
|
||||
{
|
||||
componentProperty = componentRefProp.FindPropertyRelative("component");
|
||||
initializerType = customInitializer.Type;
|
||||
componentType = customInitializer.GetType().GetField("component", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FieldType;
|
||||
}
|
||||
else
|
||||
{
|
||||
initializerType = componentProperty.managedReferenceValue.GetType();
|
||||
componentType = initializerType;
|
||||
}
|
||||
|
||||
Type type = browsable.GetType();
|
||||
string name = browsableName == null ? type.Name : GetLastPathComponent(browsableName.Name);
|
||||
string description = customInitializer != null ? customInitializer.Description : initializerType.GetCustomAttribute<DebugDescriptionAttribute>()?.description;
|
||||
// Color panelColor = customInitializer != null ? customInitializer.Color : initializerType.GetCustomAttribute<DebugColorAttribute>()?.GetUnityColor() ?? Color.black;
|
||||
Color panelColor = customInitializer != null ? customInitializer.Color : EcsDebugUtility.GetColor(initializerType).ToUnityColor();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
GUILayout.BeginVertical(EcsEditor.GetStyle(panelColor, 0.2f));
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
GUIContent label = new GUIContent(name, $"{name} ");
|
||||
if (componentType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length <= 0)
|
||||
{
|
||||
GUILayout.Label(label);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.PropertyField(componentProperty, label, true);
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
componentProperty.serializedObject.ApplyModifiedProperties();
|
||||
EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
|
||||
}
|
||||
|
||||
Rect lastrect = GUILayoutUtility.GetLastRect();
|
||||
Rect removeButtonRect = RemoveButtonRect;
|
||||
removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f);
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.Label("", GUILayout.Width(removeButtonRect.width));
|
||||
|
||||
if (GUI.Button(removeButtonRect, "x", removeButtonStyle))
|
||||
OnRemoveComponentAt(index);
|
||||
|
||||
if (!string.IsNullOrEmpty(description))
|
||||
{
|
||||
Rect tooltipIconRect = TooltipIconRect;
|
||||
tooltipIconRect.center = new Vector2(lastrect.xMax - removeButtonRect.width / 2f, lastrect.yMin + removeButtonRect.height / 2f);
|
||||
GUIContent descriptionLabel = new GUIContent(EcsUnityConsts.INFO_MARK, description);
|
||||
GUI.Label(tooltipIconRect, descriptionLabel, EditorStyles.boldLabel);
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void DrawDamagedComponent(SerializedProperty componentRefProp, int index)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
EditorGUILayout.HelpBox($"Damaged component. If the problem occurred after renaming a component or initializer. use MovedFromAttrubute", MessageType.Warning);
|
||||
|
||||
Rect lastrect = GUILayoutUtility.GetLastRect();
|
||||
Rect removeButtonRect = RemoveButtonRect;
|
||||
removeButtonRect.center = new Vector2(lastrect.xMax + removeButtonRect.width, lastrect.yMin + removeButtonRect.height / 2f);
|
||||
|
||||
GUILayout.Label("", GUILayout.Width(removeButtonRect.width));
|
||||
if (GUI.Button(removeButtonRect, "x", removeButtonStyle))
|
||||
OnRemoveComponentAt(index);
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
public string GetLastPathComponent(string input)
|
||||
{
|
||||
int lastSlashIndex = input.LastIndexOfAny(new char[] { '/', '\\' });
|
||||
if (lastSlashIndex == -1)
|
||||
return input;
|
||||
else
|
||||
return input.Substring(lastSlashIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(EntityTemplatePreset), true)]
|
||||
public class EntityTemplatePresetEditor : EntityTemplateEditorBase
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
Draw((ITemplateInternal)target);
|
||||
}
|
||||
}
|
||||
[CustomEditor(typeof(EntityTemplate), true)]
|
||||
public class EntityTemplateEditor : EntityTemplateEditorBase
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
Draw((ITemplateInternal)target);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
[CreateAssetMenu(fileName = "EntityTemplatePreset", menuName = EcsConsts.FRAMEWORK_NAME + "/EntityTemplatePreset", order = 1)]
|
||||
public class EntityTemplatePreset : ScriptableObject, ITemplateInternal
|
||||
{
|
||||
[SerializeReference]
|
||||
private ITemplateComponent[] _components;
|
||||
string ITemplateInternal.ComponentsPropertyName => nameof(_components);
|
||||
|
||||
//ITemplateBrowsable[] ITemplateInternal.Components
|
||||
//{
|
||||
// get => _components;
|
||||
// set => _components = value;
|
||||
//}
|
||||
|
||||
public void Apply(EcsWorld world, int entityID)
|
||||
{
|
||||
foreach (var item in _components)
|
||||
item.Add(world, entityID);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_components = new ITemplateComponent[0];
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface ITemplate
|
||||
{
|
||||
public void Apply(EcsWorld world, int entityID);
|
||||
}
|
||||
|
||||
public interface ITemplateInternal : ITemplate
|
||||
{
|
||||
// internal ITemplateBrowsable[] Components { get; set; }
|
||||
internal string ComponentsPropertyName { get; }
|
||||
}
|
||||
|
||||
public static class ITemplateExt
|
||||
{
|
||||
public static int NewEntity(this ITemplate self, EcsWorld world)
|
||||
{
|
||||
int e = world.NewEmptyEntity();
|
||||
self.Apply(world, e);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
57
src/EntityTemplate/ITemplateNode.cs
Normal file
57
src/EntityTemplate/ITemplateNode.cs
Normal file
@ -0,0 +1,57 @@
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface ITemplateNode
|
||||
{
|
||||
void Apply(int worldID, int entityID);
|
||||
}
|
||||
public interface ITemplate : ITemplateNode
|
||||
{
|
||||
//void Add(ITemplateNode template);
|
||||
//void Remove(ITemplateNode template);
|
||||
}
|
||||
|
||||
public interface ITemplateInternal : ITemplate
|
||||
{
|
||||
string ComponentsPropertyName { get; }
|
||||
//EntityTemplateInheritanceMatrix InheritanceMatrix { get; }
|
||||
}
|
||||
|
||||
public static class ITemplateExtensions
|
||||
{
|
||||
public static int NewEntity(this EcsWorld world, ITemplateNode template)
|
||||
{
|
||||
int e = world.NewEntity();
|
||||
template.Apply(world.id, e);
|
||||
return e;
|
||||
}
|
||||
public static entlong NewEntityLong(this EcsWorld world, ITemplateNode template)
|
||||
{
|
||||
entlong e = world.NewEntityLong();
|
||||
template.Apply(world.id, e.ID);
|
||||
return e;
|
||||
}
|
||||
public static entlong NewEntityWithGameObject(this EcsWorld world, ITemplateNode template, string name = "Entity", GameObjectIcon icon = GameObjectIcon.NONE)
|
||||
{
|
||||
entlong e = world.NewEntityWithGameObject(name, icon);
|
||||
template.Apply(world.id, e.ID);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
//[Serializable]
|
||||
//public class EntityTemplateInheritanceMatrix
|
||||
//{
|
||||
// [SerializeReference]
|
||||
// private ITemplateNode[] _components;
|
||||
//
|
||||
// #region Methods
|
||||
// public void Apply(int worldID, int entityID)
|
||||
// {
|
||||
// foreach (var item in _components)
|
||||
// {
|
||||
// item.Apply(worldID, entityID);
|
||||
// }
|
||||
// }
|
||||
// #endregion
|
||||
//}
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface ITemplateComponent
|
||||
{
|
||||
public void Add(EcsWorld w, int e);
|
||||
}
|
||||
public interface ITemplateComponentName : ITemplateComponent
|
||||
{
|
||||
public string Name { get; }
|
||||
}
|
||||
public interface ITemplateComponentGizmos
|
||||
{
|
||||
public void OnGizmos(Transform transform, Mode mode);
|
||||
public enum Mode
|
||||
{
|
||||
Always,
|
||||
Selected
|
||||
}
|
||||
}
|
||||
public interface ITemplateComponentOnValidate
|
||||
{
|
||||
public void OnValidate(GameObject gameObject);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public abstract class TemplateComponentInitializerBase
|
||||
{
|
||||
public virtual string Name => string.Empty;
|
||||
public virtual Color Color => Color.black;
|
||||
public virtual string Description => string.Empty;
|
||||
public abstract Type Type { get; }
|
||||
|
||||
internal abstract object ComponentRef { get; }
|
||||
|
||||
#region Get meta
|
||||
internal static Color GetColor(Type type)
|
||||
{
|
||||
//var atr = type.GetCustomAttribute<DebugColorAttribute>();
|
||||
//if (atr == null) return Color.black;
|
||||
//return atr.GetUnityColor();
|
||||
return EcsDebugUtility.GetColor(type).ToUnityColor();
|
||||
}
|
||||
internal static string GetName(Type type)
|
||||
{
|
||||
string friendlyName = type.Name;
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
int iBacktick = friendlyName.IndexOf('`');
|
||||
if (iBacktick > 0)
|
||||
friendlyName = friendlyName.Remove(iBacktick);
|
||||
|
||||
friendlyName += "/" + friendlyName;
|
||||
friendlyName += "<";
|
||||
Type[] typeParameters = type.GetGenericArguments();
|
||||
for (int i = 0; i < typeParameters.Length; ++i)
|
||||
{
|
||||
string typeParamName = GetName(typeParameters[i]);
|
||||
friendlyName += (i == 0 ? typeParamName : "," + typeParamName);
|
||||
}
|
||||
friendlyName += ">";
|
||||
}
|
||||
return friendlyName;
|
||||
}
|
||||
|
||||
internal static string GetDescription(Type type)
|
||||
{
|
||||
var atr = type.GetCustomAttribute<DebugDescriptionAttribute>();
|
||||
if (atr == null) return string.Empty;
|
||||
return atr.description;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
[Serializable]
|
||||
public abstract class TemplateComponentInitializer<T> : TemplateComponentInitializerBase, ITemplateComponentName, ITemplateComponentGizmos, ITemplateComponentOnValidate
|
||||
{
|
||||
private static string _autoname = GetName(typeof(T));
|
||||
private static Color _autoColor = GetColor(typeof(T));
|
||||
private static string _autoDescription = GetDescription(typeof(T));
|
||||
|
||||
[SerializeField]
|
||||
protected T component;
|
||||
|
||||
#region Properties
|
||||
public override string Name => _autoname;
|
||||
public override Color Color => _autoColor;
|
||||
public override string Description => _autoDescription;
|
||||
public sealed override Type Type => typeof(T);
|
||||
|
||||
internal T Component => component;
|
||||
internal override object ComponentRef => component;
|
||||
#endregion
|
||||
|
||||
public abstract void Add(EcsWorld w, int e);
|
||||
public virtual void OnGizmos(Transform transform, ITemplateComponentGizmos.Mode mode) { }
|
||||
public virtual void OnValidate(GameObject gameObject) { }
|
||||
}
|
||||
|
||||
internal static class ITemplateBrowsableExt
|
||||
{
|
||||
private static MethodInfo memberwiseCloneMethdo = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
internal static ITemplateComponent Clone(this ITemplateComponent obj)
|
||||
{
|
||||
return (ITemplateComponent)memberwiseCloneMethdo.Invoke(obj, null);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace Editors
|
||||
{
|
||||
internal static class TemplateBrowsableTypeCache
|
||||
{
|
||||
private static Type[] _types;
|
||||
private static ITemplateComponent[] _dummies;
|
||||
internal static ReadOnlySpan<Type> Types => _types;
|
||||
internal static ReadOnlySpan<ITemplateComponent> Dummies => _dummies;
|
||||
|
||||
static TemplateBrowsableTypeCache()
|
||||
{
|
||||
List<Type> types = new List<Type>();
|
||||
Type interfaceType = typeof(ITemplateComponent);
|
||||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
var targetTypes = assembly.GetTypes().Where(type => !type.IsGenericType && (type.IsValueType || type.IsClass) && type.GetCustomAttribute<SerializableAttribute>() != null);
|
||||
|
||||
types.AddRange(targetTypes.Where(type => interfaceType.IsAssignableFrom(type)));
|
||||
|
||||
foreach (var t in targetTypes)
|
||||
{
|
||||
if (t.IsSubclassOf(typeof(TemplateComponentInitializer<>)))
|
||||
{
|
||||
if (t.HasAttribute<SerializableAttribute>())
|
||||
types.Add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
_types = types.ToArray();
|
||||
_dummies = new ITemplateComponent[_types.Length];
|
||||
|
||||
for (int i = 0; i < _types.Length; i++)
|
||||
_dummies[i] = (ITemplateComponent)Activator.CreateInstance(_types[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
8
src/EntityTemplate/Templates.meta
Normal file
8
src/EntityTemplate/Templates.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14555d6350df03d448d362de7b6a31c1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
157
src/EntityTemplate/Templates/ComponentTemplateBase.cs
Normal file
157
src/EntityTemplate/Templates/ComponentTemplateBase.cs
Normal file
@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using static DCFApixels.DragonECS.IComponentTemplate;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface IComponentTemplate : ITemplateNode
|
||||
{
|
||||
#region Properties
|
||||
Type Type { get; }
|
||||
string Name { get; }
|
||||
MetaGroup Group { get; }
|
||||
string Description { get; }
|
||||
IReadOnlyCollection<string> Tags { get; }
|
||||
Color Color { get; }
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
object GetRaw();
|
||||
void SetRaw(object raw);
|
||||
void OnGizmos(Transform transform, GizmosMode mode);
|
||||
void OnValidate(UnityEngine.Object obj);
|
||||
#endregion
|
||||
|
||||
public enum GizmosMode
|
||||
{
|
||||
Always,
|
||||
Selected
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public abstract class ComponentTemplateBase : IComponentTemplate
|
||||
{
|
||||
#region Properties
|
||||
public abstract Type Type { get; }
|
||||
public virtual string Name { get { return string.Empty; } }
|
||||
public virtual MetaGroup Group { get { return default; } }
|
||||
public virtual string Description { get { return string.Empty; } }
|
||||
public virtual IReadOnlyCollection<string> Tags { get { return Array.Empty<string>(); } }
|
||||
public virtual Color Color { get { return Color.black; } }
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
public abstract object GetRaw();
|
||||
public abstract void SetRaw(object raw);
|
||||
public virtual void OnGizmos(Transform transform, GizmosMode mode) { }
|
||||
public virtual void OnValidate(UnityEngine.Object obj) { }
|
||||
|
||||
public abstract void Apply(int worldID, int entityID);
|
||||
#endregion
|
||||
}
|
||||
[Serializable]
|
||||
public abstract class ComponentTemplateBase<T> : ComponentTemplateBase, IComponentTemplate
|
||||
{
|
||||
private static TypeMetaDataCached _meta = EcsDebugUtility.GetCachedTypeMeta<T>();
|
||||
[SerializeField]
|
||||
protected T component;
|
||||
|
||||
#region Properties
|
||||
public override Type Type { get { return typeof(T); } }
|
||||
public override string Name { get { return _meta.Name; } }
|
||||
public override MetaGroup Group { get { return _meta.Group; } }
|
||||
public override string Description { get { return _meta.Description; } }
|
||||
public override IReadOnlyCollection<string> Tags { get { return _meta.Tags; } }
|
||||
public override Color Color { get { return _meta.Color.ToUnityColor(); } }
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
public override object GetRaw()
|
||||
{
|
||||
return component;
|
||||
}
|
||||
public override void SetRaw(object raw)
|
||||
{
|
||||
component = (T)raw;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public abstract class ComponentTemplate<T> : ComponentTemplateBase<T>, IComponentTemplate
|
||||
where T : struct, IEcsComponent
|
||||
{
|
||||
public override void Apply(int worldID, int entityID)
|
||||
{
|
||||
EcsWorld.GetPool<EcsPool<T>>(worldID).TryAddOrGet(entityID) = component;
|
||||
}
|
||||
}
|
||||
public abstract class TagComponentTemplate<T> : ComponentTemplateBase<T>, IComponentTemplate
|
||||
where T : struct, IEcsTagComponent
|
||||
{
|
||||
public override void Apply(int worldID, int entityID)
|
||||
{
|
||||
EcsWorld.GetPool<EcsTagPool<T>>(worldID).Set(entityID, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Internal
|
||||
{
|
||||
internal static class ComponentTemplateExtensions
|
||||
{
|
||||
private static MethodInfo memberwiseCloneMethdo = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
internal static IComponentTemplate Clone(this IComponentTemplate obj)
|
||||
{
|
||||
return (IComponentTemplate)memberwiseCloneMethdo.Invoke(obj, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
internal static class ComponentTemplateTypeCache
|
||||
{
|
||||
private static Type[] _types;
|
||||
private static IComponentTemplate[] _dummies;
|
||||
internal static ReadOnlySpan<Type> Types => _types;
|
||||
internal static ReadOnlySpan<IComponentTemplate> Dummies => _dummies;
|
||||
|
||||
static ComponentTemplateTypeCache()
|
||||
{
|
||||
List<Type> types = new List<Type>();
|
||||
Type interfaceType = typeof(IComponentTemplate);
|
||||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
var targetTypes = assembly.GetTypes().Where(type => !type.IsGenericType && !(type.IsAbstract || type.IsInterface) && type.GetCustomAttribute<SerializableAttribute>() != null);
|
||||
|
||||
types.AddRange(targetTypes.Where(type => interfaceType.IsAssignableFrom(type)));
|
||||
|
||||
foreach (var t in targetTypes)
|
||||
{
|
||||
if (t.IsSubclassOf(typeof(ComponentTemplateBase<>)))
|
||||
{
|
||||
types.Add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
_types = types.ToArray();
|
||||
foreach (var type in _types)
|
||||
{
|
||||
EcsDebugUtility.GetCachedTypeMeta(type);
|
||||
}
|
||||
_dummies = new IComponentTemplate[_types.Length];
|
||||
|
||||
for (int i = 0; i < _types.Length; i++)
|
||||
{
|
||||
_dummies[i] = (IComponentTemplate)Activator.CreateInstance(_types[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c96e3aedd5a69443af75096e5561265
|
||||
guid: b532f9d8441035d49b9acb99ea23c231
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
65
src/EntityTemplate/Templates/MonoEntityTemplate.cs
Normal file
65
src/EntityTemplate/Templates/MonoEntityTemplate.cs
Normal file
@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public class MonoEntityTemplate : MonoBehaviour, ITemplateInternal
|
||||
{
|
||||
[SerializeReference]
|
||||
private IComponentTemplate[] _components;
|
||||
//[SerializeField]
|
||||
//private EntityTemplateInheritanceMatrix _inheritanceMatrix;
|
||||
|
||||
#region Properties
|
||||
string ITemplateInternal.ComponentsPropertyName
|
||||
{
|
||||
get { return nameof(_components); }
|
||||
}
|
||||
//EntityTemplateInheritanceMatrix ITemplateInternal.InheritanceMatrix
|
||||
//{
|
||||
// get { return _inheritanceMatrix; }
|
||||
//}
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
public void Apply(int worldID, int entityID)
|
||||
{
|
||||
foreach (var item in _components)
|
||||
{
|
||||
item.Apply(worldID, entityID);
|
||||
}
|
||||
}
|
||||
public void Clear()
|
||||
{
|
||||
_components = Array.Empty<IComponentTemplate>();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UnityEvents
|
||||
private void OnValidate()
|
||||
{
|
||||
if (_components == null) { return; }
|
||||
foreach (var item in _components)
|
||||
{
|
||||
item.OnValidate(gameObject);
|
||||
}
|
||||
}
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
if (_components == null) { return; }
|
||||
foreach (var item in _components)
|
||||
{
|
||||
item.OnGizmos(transform, IComponentTemplate.GizmosMode.Always);
|
||||
}
|
||||
}
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
if (_components == null) { return; }
|
||||
foreach (var item in _components)
|
||||
{
|
||||
item.OnGizmos(transform, IComponentTemplate.GizmosMode.Selected);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 385a6c66660032944ad2cce7130715d7
|
||||
guid: 351338ca92ace49499f450172d857af6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
50
src/EntityTemplate/Templates/ScriptableEntityTemplate.cs
Normal file
50
src/EntityTemplate/Templates/ScriptableEntityTemplate.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
[CreateAssetMenu(fileName = nameof(ScriptableEntityTemplate), menuName = EcsConsts.FRAMEWORK_NAME + "/" + nameof(ScriptableEntityTemplate), order = 1)]
|
||||
public class ScriptableEntityTemplate : ScriptableObject, ITemplateInternal
|
||||
{
|
||||
[SerializeReference]
|
||||
private IComponentTemplate[] _components;
|
||||
//[SerializeField]
|
||||
//private EntityTemplateInheritanceMatrix _inheritanceMatrix;
|
||||
|
||||
#region Properties
|
||||
string ITemplateInternal.ComponentsPropertyName
|
||||
{
|
||||
get { return nameof(_components); }
|
||||
}
|
||||
//EntityTemplateInheritanceMatrix ITemplateInternal.InheritanceMatrix
|
||||
//{
|
||||
// get { return _inheritanceMatrix; }
|
||||
//}
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
public void Apply(int worldID, int entityID)
|
||||
{
|
||||
foreach (var item in _components)
|
||||
{
|
||||
item.Apply(worldID, entityID);
|
||||
}
|
||||
}
|
||||
public void Clear()
|
||||
{
|
||||
_components = Array.Empty<IComponentTemplate>();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UnityEvents
|
||||
private void OnValidate()
|
||||
{
|
||||
if (_components == null) { return; }
|
||||
foreach (var item in _components)
|
||||
{
|
||||
item.OnValidate(this);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d2b62f9703592042befb46ac1fee09c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,42 +0,0 @@
|
||||
using DCFApixels.DragonECS.Internal;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
[DebugHide, DebugColor(DebugColor.Grey)]
|
||||
public class DeleteOneFrameComponentFixedSystem<TComponent> : IEcsFixedRunProcess, IEcsInject<EcsWorld>
|
||||
where TComponent : struct, IEcsComponent
|
||||
{
|
||||
private sealed class Aspect : EcsAspect
|
||||
{
|
||||
public EcsPool<TComponent> pool;
|
||||
public Aspect(Builder b) => pool = b.Include<TComponent>();
|
||||
}
|
||||
List<EcsWorld> _worlds = new List<EcsWorld>();
|
||||
public void Inject(EcsWorld obj) => _worlds.Add(obj);
|
||||
public void FixedRun(EcsPipeline pipeline)
|
||||
{
|
||||
for (int i = 0, iMax = _worlds.Count; i < iMax; i++)
|
||||
{
|
||||
EcsWorld world = _worlds[i];
|
||||
if (world.IsComponentTypeDeclared<TComponent>())
|
||||
{
|
||||
foreach (var e in world.Where(out Aspect a))
|
||||
a.pool.Del(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static class DeleteOneFrameComponentFixedSystemExtensions
|
||||
{
|
||||
private const string AUTO_DEL_LAYER = nameof(AUTO_DEL_LAYER);
|
||||
public static EcsPipeline.Builder AutoDelFixed<TComponent>(this EcsPipeline.Builder b, string layerName = AUTO_DEL_LAYER)
|
||||
where TComponent : struct, IEcsComponent
|
||||
{
|
||||
if (AUTO_DEL_LAYER == layerName)
|
||||
b.Layers.Insert(EcsConsts.POST_END_LAYER, AUTO_DEL_LAYER);
|
||||
b.AddUnique(new DeleteOneFrameComponentSystem<TComponent>(), layerName);
|
||||
return b;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e8c608fea9f3569409826ec54affa822
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace DCFApixels.DragonECS.Editors
|
||||
namespace DCFApixels.DragonECS.Unity.Internal
|
||||
{
|
||||
internal class BitMask
|
||||
{
|
||||
@ -21,21 +21,30 @@ namespace DCFApixels.DragonECS.Editors
|
||||
public bool this[int index]
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => (_data[index >> OFFSET] & (1 << (index & MOD_MASK))) != 0;
|
||||
get
|
||||
{
|
||||
return (_data[index >> OFFSET] & (1 << (index & MOD_MASK))) != 0;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
_data[index >> OFFSET] |= (1 << (index & MOD_MASK));
|
||||
}
|
||||
else
|
||||
{
|
||||
_data[index >> OFFSET] &= ~(1 << (index & MOD_MASK));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Resize(int newSize)
|
||||
{
|
||||
if (newSize <= _size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_size = newSize / DATA_BITS + 1;
|
||||
Array.Resize(ref _data, _size);
|
||||
|
@ -1,25 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public static class DebugColorAttributeExt
|
||||
{
|
||||
public static Color GetUnityColor(this DebugColorAttribute self)
|
||||
{
|
||||
return self.color.ToUnityColor();
|
||||
}
|
||||
public static Color32 GetUnityColor32(this DebugColorAttribute self)
|
||||
{
|
||||
return self.color.ToUnityColor32();
|
||||
}
|
||||
|
||||
public static Color ToUnityColor(this DebugColor self)
|
||||
{
|
||||
return new Color(self.r / 255f, self.g / 255f, self.b / 255f, self.a / 255f);
|
||||
}
|
||||
public static Color32 ToUnityColor32(this DebugColor self)
|
||||
{
|
||||
return new Color32(self.r, self.g, self.b, self.a);
|
||||
}
|
||||
}
|
||||
}
|
16
src/Utils/MetaColorExstensions.cs
Normal file
16
src/Utils/MetaColorExstensions.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public static class MetaColorExstensions
|
||||
{
|
||||
public static Color ToUnityColor<T>(this T self) where T : IMetaColor
|
||||
{
|
||||
return new Color(self.R / 255f, self.G / 255f, self.B / 255f, self.A / 255f);
|
||||
}
|
||||
public static Color32 ToUnityColor32<T>(this T self) where T : IMetaColor
|
||||
{
|
||||
return new Color32(self.R, self.G, self.B, self.A);
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace DCFApixels.DragonECS.Editors
|
||||
namespace DCFApixels.DragonECS.Unity.Internal
|
||||
{
|
||||
internal class SparseArray<TValue>
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user