重构Ecs系统

重构Ecs系统
This commit is contained in:
ALEXTANG
2022-08-05 11:15:14 +08:00
parent b107157232
commit 5184f1d677
30 changed files with 0 additions and 1195 deletions

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: d941eb2d2cbae294bb5d2788bb724e80
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,113 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace TEngine
{
public interface IIndex
{
int Index { get; set; }
}
internal class HashSetDebugView<T> where T : IIndex
{
private readonly ArrayPool<T> m_Set;
public HashSetDebugView(ArrayPool<T> set)
{
m_Set = set ?? throw new ArgumentNullException(nameof(set));
}
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public T[] Items
{
get
{
return m_Set.ToArray();
}
}
}
[DebuggerTypeProxy(typeof(HashSetDebugView<>))]
[DebuggerDisplay("Count = {Count}")]
public class ArrayPool<T> where T:IIndex
{
internal T[] m_Items = new T[256];
internal bool[] Buckets = new bool[256];
private int m_Index;
private int count;
public T this[int index]
{
get
{
return m_Items[index];
}
set
{
m_Items[index] = value;
}
}
public int Count
{
get
{
return count;
}
}
public T[] ToArray()
{
List<T> elements = new List<T>();
for (int i = 0; i < m_Items.Length; i++)
{
if (Buckets[i])
{
elements.Add(m_Items[i]);
}
}
return elements.ToArray();
}
public void Remove(T item)
{
lock (this)
{
m_Items[item.Index] = default;
Buckets[item.Index] = false;
}
}
public void Add(T item)
{
lock (this)
{
if (item.Index != -1)
{
if (!Buckets[item.Index])
{
m_Items[item.Index] = item;
Buckets[item.Index] = true;
return;
}
}
m_Items[m_Index] = item;
Buckets[m_Index] = true;
item.Index = m_Index;
m_Index++;
if (m_Index >= m_Items.Length)
{
T[] newItems = new T[m_Items.Length * 2];
bool[] newBuckets = new bool[m_Items.Length * 2];
Array.Copy(m_Items,0,newItems,0,m_Items.Length);
Array.Copy(Buckets, 0, newBuckets, 0, Buckets.Length);
m_Items = newItems;
Buckets = newBuckets;
}
count = m_Index;
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 1abd052a77e45b44ebcde5803fb36afd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 385b1863dab169f4fa291611477e106c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,25 +0,0 @@
using TEngine;
using UnityEngine;
public class ECSDemoApp : MonoBehaviour
{
public ECSGameSystem EcsGameSystem = new ECSGameSystem();
public GameObject @object;
void Start()
{
var entity = EcsGameSystem.Create<Entity>();
ECSActor actor = entity.AddComponent<ECSActor>();
actor.Name = typeof(ECSActor).ToString();
actor.gameObject = Instantiate(@object);
actor.transform = actor.gameObject.GetComponent<Transform>();
entity.AddComponent<ECSComponent>();
Debug.Log(entity.ToString());
}
void Update()
{
EcsGameSystem.OnUpdate();
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: fb5cf3287e9bf3949820b50049e4bd8c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,9 +0,0 @@
using TEngine;
public class ECSGameSystem : ECSSystem
{
public void OnUpdate()
{
Update();
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d9d458a85873d744ab382e86008b89a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,13 +0,0 @@
namespace TEngine
{
/// <summary>
/// ECS Actor
/// </summary>
public class ECSActor : ECSComponent
{
public string Name;
public UnityEngine.GameObject gameObject;
public UnityEngine.Transform transform;
public uint ActorID;
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 34a977c48d3bdb144b7c923a702164b0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,14 +0,0 @@
namespace TEngine
{
/// <summary>
/// ECS构架可以将此组件从Entity上移除这个组件并丢入对象池给其他此刻需要此组件的Entity使用
/// 因此可以节省大量的内存反复创建和释放, 这也是ECS的特性可以大量重复使用组件
/// </summary>
public class ECSComponent:ECSObject
{
#pragma warning disable IDE1006
public Entity Entity { get; set; }
#pragma warning restore IDE1006
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: e93d874e10ffedf488c413fd5bbc012f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,72 +0,0 @@
using System;
using System.Collections.Generic;
namespace TEngine
{
public enum ECSDebugType
{
Entity,
System,
Component
}
[Serializable]
public class ECSCmptDebugKeyInfo
{
public string m_name;
public string val;
}
[Serializable]
public class ECSCmptDebugInfo
{
public string m_name;
public ECSDebugType Type = ECSDebugType.Component;
public List<ECSCmptDebugKeyInfo> m_info = new List<ECSCmptDebugKeyInfo>();
}
public class ECSDebugBehaviour : UnityEngine.MonoBehaviour
{
public List<ECSCmptDebugInfo> m_ECSInfo = new List<ECSCmptDebugInfo>();
public ECSCmptDebugInfo AddDebugCmpt(string cmptName)
{
var cmptInfo = m_ECSInfo.Find((item) => { return item.m_name == cmptName; });
if (cmptInfo == null)
{
cmptInfo = new ECSCmptDebugInfo();
cmptInfo.m_name = cmptName;
m_ECSInfo.Add(cmptInfo); ;
}
return cmptInfo;
}
public void RmvDebugCmpt(string cmptName)
{
m_ECSInfo.RemoveAll((item) => { return item.m_name == cmptName; });
}
public void SetDebugInfo(string cmptName, string key, string val)
{
var cmptInfo = AddDebugCmpt(cmptName);
var entry = cmptInfo.m_info.Find((t) => { return t.m_name == key; });
if (entry == null)
{
entry = new ECSCmptDebugKeyInfo();
entry.m_name = key;
cmptInfo.m_info.Add(entry);
}
entry.val = val;
}
public void RemoveAllDebugInfo(string cmpName)
{
var cmpInfo = m_ECSInfo.Find((item) => { return item.m_name == cmpName; });
if (cmpInfo != null)
{
cmpInfo.m_info.Clear();
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 2dc3e456c545c0c419624e068b9249dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,96 +0,0 @@
using System;
using System.Collections.Generic;
namespace TEngine
{
public class ECSEventCmpt : ECSComponent
{
private GameEvent _gameEvent;
#region AddEventListener
public void AddEventListener<T>(int eventId, Action<T> action)
{
_gameEvent.AddEventListener(eventId, action);
}
public void AddEventListener<T, U>(int eventId, Action<T, U> action)
{
_gameEvent.AddEventListener(eventId, action);
}
public void AddEventListener<T, U, W>(int eventId, Action<T, U, W> action)
{
_gameEvent.AddEventListener(eventId, action);
}
public void AddEventListener(int eventId, Action action)
{
_gameEvent.AddEventListener(eventId, action);
}
#endregion
#region RemoveEventListener
public void RemoveEventListener<T>(int eventId, Action<T> action)
{
_gameEvent.RemoveEventListener(eventId, action);
}
public void RemoveEventListener<T, U>(int eventId, Action<T, U> action)
{
_gameEvent.RemoveEventListener(eventId, action);
}
public void RemoveEventListener<T, U, W>(int eventId, Action<T, U, W> action)
{
_gameEvent.RemoveEventListener(eventId, action);
}
public void RemoveEventListener(int eventId, Action action)
{
_gameEvent.RemoveEventListener(eventId, action);
}
#endregion
#region Send
public void Send<T>(int eventId, T info)
{
_gameEvent.Send(eventId, info);
}
public void Send<T, U>(int eventId, T info, U info2)
{
_gameEvent.Send(eventId, info, info2);
}
public void Send<T, U, W>(int eventId, T info, U info2, W info3)
{
_gameEvent.Send(eventId, info, info2, info3);
}
public void Send(int eventId)
{
_gameEvent.Send(eventId);
}
#endregion
#region Clear
public void Clear()
{
GameMemPool<GameEvent>.Free(_gameEvent);
}
#endregion
#region
public override void OnDestroy()
{
Clear();
}
public override void Awake()
{
_gameEvent = GameMemPool<GameEvent>.Alloc();
Entity.Event = this;
}
#endregion
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: af343da6b3090a24b92fc12aaa638411
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,112 +0,0 @@
using System;
using System.Collections.Generic;
namespace TEngine
{
/// <summary>
/// ECS架构基类Object
/// </summary>
public class ECSObject
{
internal int HashCode;
internal ECSSystem System;
public ECSObject()
{
HashCode = GetType().GetHashCode();
}
public virtual void Awake() { }
public virtual void OnDestroy() { }
/// <summary>
/// Remove The ECSEntity or Component And Throw the ECSObject to ArrayPool When AddComponent Or Create Can Use Again
/// </summary>
/// <param name="ecsObject"></param>
/// <param name="reuse">此对象是否可以复用复用会将对象丢入System对象池中 等待再次使用如果是Entity对象并且不复用的话则把Entity所使用的组件也不复用</param>
public static void Destroy(ECSObject ecsObject, bool reuse = true)
{
if (ecsObject is ECSComponent ecsComponent)
{
ecsComponent.Entity.Components.Remove(ecsComponent);
if (ecsComponent is IUpdate update)
{
ecsComponent.Entity.Updates.Remove(update);
}
if (reuse)
{
ecsComponent.Entity.System.Push(ecsComponent);
}
ecsObject.OnDestroy();
return;
}
else if (ecsObject is Entity entity)
{
entity.System.RemoveEntity(entity);
entity.OnDestroy();
while (entity.Components.Count > 0)
{
ECSComponent ecsComponentTemp = entity.Components[0];
entity.Components.RemoveAt(0);
ecsComponentTemp.OnDestroy();
if (reuse)
{
entity.System.Push(ecsComponentTemp);
}
}
entity.Updates.Clear();
entity.CanUpdate = false;
if (reuse)
{
entity.System.Push(entity);
}
}
}
public T FindObjectOfType<T>() where T : ECSObject
{
Type type = typeof(T);
var elements = System.Entities.ToArray();
for (int i = 0; i < elements.Length; i++)
{
if (elements[i].GetType() == type)
{
return elements[i] as T;
}
for (int n = 0; n < elements[i].Components.Count; n++)
{
if (elements[i].Components[n].GetType() == type)
{
return elements[i].Components[n] as T;
}
}
}
return null;
}
public T[] FindObjectsOfType<T>() where T : ECSObject
{
Type type = typeof(T);
var items = System.Entities.ToArray();
List<T> elements = new List<T>();
for (int i = 0; i < items.Length; i++)
{
if (items[i].GetType() == type)
{
elements.Add(items[i] as T);
}
for (int n = 0; n < items[i].Components.Count; n++)
{
if (items[i].Components[n].GetType() == type)
{
elements.Add(items[i].Components[n] as T);
}
}
}
return elements.ToArray();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 003794832e9179348a633bdafe92ff3c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,233 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace TEngine
{
/// <summary>
/// ECS系统 管理Entity、ECSComponent复用对象池
/// </summary>
[Serializable]
public class ECSSystem : IDisposable
{
private static ECSSystem instance = new ECSSystem();
public static ECSSystem Instance => instance;
private readonly Dictionary<int,Stack<ECSObject>> m_ObjectPool = new Dictionary<int, Stack<ECSObject>>();
internal readonly ArrayPool<Entity> Entities = new ArrayPool<Entity>();
private bool m_IsDispose = false;
public void AddEntity(Entity entity)
{
entity.System = this;
entity.Awake();
Entities.Add(entity);
}
public void RemoveEntity(Entity entity)
{
Entities.Remove(entity);
}
/// <summary>
/// Get Object From ECSSystem
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Get<T>() where T : ECSObject, new()
{
int type = typeof(T).GetHashCode();
if (m_ObjectPool.TryGetValue(type,out Stack<ECSObject> stack))
{
if (stack.Count > 0)
{
return (T) stack.Pop();
}
goto Instantiate;
}
stack = new Stack<ECSObject>();
m_ObjectPool.Add(type,stack);
Instantiate: T ecsObject = new T();
return ecsObject;
}
/// <summary>
/// Push Object To ECSSystem
/// </summary>
public void Push(ECSObject ecsObject)
{
int type = ecsObject.HashCode;
if (m_ObjectPool.TryGetValue(type,out Stack<ECSObject> stack))
{
stack.Push(ecsObject);
return;
}
stack = new Stack<ECSObject>();
m_ObjectPool.Add(type,stack);
stack.Push(ecsObject);
}
public T Create<T>() where T : Entity, new()
{
T entity = Get<T>();
AddEntity(entity);
return entity;
}
public T Create<T>(T entity) where T : Entity, new()
{
AddEntity(entity);
return entity;
}
/// <summary>
/// 更新ECS系统
/// </summary>
/// <param name="worker">线程池是否并行</param>
public void Update(bool worker = false)
{
Run(worker);
}
/// <summary>
/// 更新ECS物理系统
/// </summary>
/// <param name="worker">线程池是否并行</param>
public void FixedUpdate(bool worker = false)
{
RunFixed(worker);
}
/// <summary>
/// 运行ECS系统
/// </summary>
/// <param name="worker">线程池是否并行</param>
public void Run(bool worker = false)
{
int count = Entities.Count;
if (!worker)
{
for (int i = 0; i < count; i++)
{
if (!Entities.Buckets[i])
{
continue;
}
if (!Entities[i].CanUpdate)
{
continue;
}
Entities[i].Execute();
}
}
else
{
Parallel.For(0, count, i =>
{
if (!Entities.Buckets[i])
{
return;
}
if (!Entities[i].CanUpdate)
{
return;
}
Entities[i].Execute();
});
}
}
public void RunFixed(bool worker = false)
{
int count = Entities.Count;
if (!worker)
{
for (int i = 0; i < count; i++)
{
if (!Entities.Buckets[i])
{
continue;
}
if (!Entities[i].CanFixedUpdate)
{
continue;
}
Entities[i].FixedUpdate();
}
}
else
{
Parallel.For(0, count, i =>
{
if (!Entities.Buckets[i])
{
return;
}
if (!Entities[i].CanFixedUpdate)
{
return;
}
Entities[i].FixedUpdate();
});
}
}
public void Dispose()
{
if (m_IsDispose)
{
return;
}
m_IsDispose = true;
}
public T FindObjectOfType<T>() where T : ECSObject
{
Type type = typeof(T);
var elements = Entities.ToArray();
for (int i = 0; i < elements.Length; i++)
{
if (elements[i].GetType() == type)
{
return elements[i] as T;
}
for (int j = 0; j < elements[i].Components.Count; j++)
{
if (elements[i].Components[j].GetType() == type)
{
return elements[i].Components[j] as T;
}
}
}
return null;
}
public T[] FindObjectsOfType<T>() where T : ECSObject
{
Type type = typeof(T);
var entities = Entities.ToArray();
List<T> elements = new List<T>();
for (int i = 0; i < entities.Length; i++)
{
if (entities[i].GetType() == type)
{
elements.Add(entities[i] as T);
}
for (int n = 0; n < entities[i].Components.Count; n++)
{
if (entities[i].Components[n].GetType() == type)
{
elements.Add(entities[i].Components[n] as T);
}
}
}
return elements.ToArray();
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d2bd4af51a518164c8da0dff296b2bb1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,273 +0,0 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace TEngine
{
public class Entity : ECSObject, IIndex
{
[SerializeField]
internal List<ECSComponent> Components = new List<ECSComponent>();
internal List<IUpdate> Updates = new List<IUpdate>();
internal List<IFixedUpdate> FixedUpdates = new List<IFixedUpdate>();
internal bool InActive;
internal bool CanUpdate;
internal bool CanFixedUpdate;
public int Index { get; set; } = -1;
public ECSEventCmpt Event { get; set; }
public Entity()
{
InActive = true;
System = ECSSystem.Instance;
}
~Entity()
{
InActive = false;
}
internal void Execute()
{
for (int i = 0; i < Updates.Count; i++)
{
Updates[i].Update();
}
}
internal void FixedUpdate()
{
for (int i = 0; i < FixedUpdates.Count; i++)
{
FixedUpdates[i].FixedUpdate();
}
}
public void RmvComponent<T>() where T : ECSComponent, new()
{
for (int i = 0; i < Components.Count; i++)
{
if (Components[i] is T component)
{
if (component is IUpdate update)
{
Updates.Remove(update);
}
else if (component is IFixedUpdate fixedUpdate)
{
FixedUpdates.Remove(fixedUpdate);
}
System.Push(component);
CanUpdate = Updates.Count > 0;
CanFixedUpdate = FixedUpdates.Count > 0;
}
}
#if UNITY_EDITOR
CheckDebugInfo();
#endif
}
public void RmvComponent(Type componentType)
{
for (int i = 0; i < Components.Count; i++)
{
if (Components[i].GetType() == componentType)
{
if (componentType is IUpdate update)
{
Updates.Remove(update);
CanUpdate = Updates.Count > 0;
}
else if (componentType is IFixedUpdate fixedUpdate)
{
FixedUpdates.Remove(fixedUpdate);
CanFixedUpdate = FixedUpdates.Count > 0;
}
//if (componentType is ECSComponent component)
//{
// System.Push(component);
//}
}
}
#if UNITY_EDITOR
CheckDebugInfo();
#endif
}
public T AddComponent<T>() where T : ECSComponent, new()
{
#if UNITY_EDITOR
CheckDebugInfo();
#endif
T component = System.Get<T>();
component.Entity = this;
component.System = System;
Components.Add(component);
component.Awake();
if (component is IUpdate update)
{
Updates.Add(update);
}
else if (component is IFixedUpdate fixedUpdate)
{
FixedUpdates.Add(fixedUpdate);
}
CanUpdate = Updates.Count > 0;
CanFixedUpdate = FixedUpdates.Count > 0;
return component;
}
public ECSComponent AddComponent(ECSComponent component)
{
#if UNITY_EDITOR
CheckDebugInfo();
#endif
component.Entity = this;
component.System = System;
Components.Add(component);
component.Awake();
if (component is IUpdate update)
{
Updates.Add(update);
}
else if (component is IFixedUpdate fixedUpdate)
{
FixedUpdates.Add(fixedUpdate);
}
CanUpdate = Updates.Count > 0;
CanFixedUpdate = FixedUpdates.Count > 0;
return component;
}
public T GetComponent<T>() where T : ECSComponent
{
for (int i = 0; i < Components.Count; i++)
{
if (Components[i] is T type)
{
return type;
}
}
return null;
}
public ECSComponent GetComponent(Type componentType)
{
for (int i = 0; i < Components.Count; i++)
{
if (Components[i].GetType() == componentType)
{
return Components[i];
}
}
return null;
}
public T[] GetComponents<T>() where T : ECSComponent
{
List<T> elements = new List<T>();
for (int i = 0; i < Components.Count; i++)
{
if (Components[i] is T type)
{
elements.Add(type);
}
}
return elements.ToArray();
}
public List<T> GetComponentsList<T>() where T : ECSComponent
{
List<T> elements = new List<T>();
for (int i = 0; i < Components.Count; i++)
{
if (Components[i] is T type)
{
elements.Add(type);
}
}
return elements;
}
public ECSComponent[] GetComponents(Type comType)
{
List<ECSComponent> elements = new List<ECSComponent>();
for (int i = 0; i < Components.Count; i++)
{
{
if (Components[i].GetType() == comType)
{
elements.Add(Components[i]);
}
}
}
return elements.ToArray();
}
public override string ToString()
{
string str = "[";
for (int i = 0; i < Components.Count; i++)
{
str += Components[i].GetType().Name + ",";
}
str = str.TrimEnd(',');
str += "]";
return $"{GetType().Name} Components: {str}";
}
public void CheckDebugInfo(GameObject gameObject)
{
#if UNITY_EDITOR
if (gameObject == null)
{
return;
}
var debugBehaviour = UnityUtil.AddMonoBehaviour<ECSDebugBehaviour>(gameObject);
debugBehaviour.m_ECSInfo.Clear();
for (int i = 0; i < this.Components.Count; i++)
{
var component = this.Components[i];
var cmptName = component.GetType().Name;
debugBehaviour.SetDebugInfo(cmptName, "", "");
}
#endif
}
public void CheckDebugInfo()
{
#if UNITY_EDITOR
//var actorEntity = this as Entity;
//if (actorEntity == null)
//{
// return;
//}
//if (actorEntity.gameObject == null)
//{
// return;
//}
//var debugBehaviour = UnityUtil.AddMonoBehaviour<ECSDebugBehaviour>(actorEntity.gameObject);
//debugBehaviour.m_ECSInfo.Clear();
//for (int i = 0; i < this.Components.Count; i++)
//{
// var component = this.Components[i];
// var cmptName = component.GetType().Name;
// debugBehaviour.SetDebugInfo(cmptName, "", "");
//}
#endif
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 9f5bc14d7a4aee34695c39d02ae1c71f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,32 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace TEngine
{
public class HotfixComponent : ECSComponent,IUpdate
{
public object[] Values;
public Action OnAwake, OnUpdate, OnDestroyExt;
public override void Awake()
{
OnAwake?.Invoke();
}
void IUpdate.Update()
{
OnUpdate?.Invoke();
}
public override void OnDestroy()
{
OnDestroyExt?.Invoke();
OnAwake = null;
OnUpdate = null;
OnDestroyExt = null;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c0ac8b7fabe2bae499a568608191eb57
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,10 +0,0 @@
namespace TEngine
{
/// <summary>
/// ECS组件更新接口减少组件for循环开销
/// </summary>
public interface IFixedUpdate
{
void FixedUpdate();
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 7fb8a7b6d364a024e8a49a0a731de201
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,10 +0,0 @@
namespace TEngine
{
/// <summary>
/// ECS组件更新接口减少组件for循环开销
/// </summary>
public interface IUpdate
{
void Update();
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: e7918afae3870234391c6e6f521e9ca7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,13 +0,0 @@
namespace TEngine
{
/// <summary>
/// 热更层由此组件进行更新ILRuntime不支持多继承, 接口继承)
/// </summary>
public class UpdateComponent :ECSComponent, IUpdate
{
public virtual void Update()
{
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 02463b27b6971f0408bb517c32c66553
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: