This commit is contained in:
CortexCore
2023-08-11 23:57:37 +08:00
parent 936a94c84b
commit 75889ec34f
149 changed files with 6524 additions and 1043 deletions

View File

@@ -3,16 +3,15 @@
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:a209c53514018594f9f482516f2a6781",
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:66d2ae14764cc7d49aad4b16930747c0",
"GUID:fd4f76a9ea9701445bfd4d132912acab",
"GUID:21b0c8d1703a94250bfac916590cea4f",
"GUID:be17a8778dbfe454890ed8279279e153",
"GUID:9e24947de15b9834991c9d8411ea37cf",
"GUID:84651a3751eca9349aac36a66bba901b",
"GUID:9400d40641bab5b4a9702f65bf5c6eb5",
"GUID:f51ebe6a0ceec4240a699833d6309b23"
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:517785bb4600a5140b47eac5fa49b8fc",
"GUID:be17a8778dbfe454890ed8279279e153"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -1,8 +1,7 @@
{
"name": "Entity.Component",
"name": "BITKit.Entities.Component",
"rootNamespace": "",
"references": [
"GUID:a209c53514018594f9f482516f2a6781",
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
"GUID:677cd05ca06c46b4395470200b1acdad",
"GUID:75469ad4d38634e559750d17036d5f7c",
@@ -12,11 +11,10 @@
"GUID:99a47d73d3ad3374b9d12c982228df71",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:274d4ecae4648e94c8b2cee7218378a0",
"GUID:1491147abca9d7d4bb7105af628b223e",
"GUID:28c2d6a6727d47442a24a353f0d37846",
"GUID:be17a8778dbfe454890ed8279279e153",
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:9400d40641bab5b4a9702f65bf5c6eb5"
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:be17a8778dbfe454890ed8279279e153"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections;
using System.Collections.Generic;
using BITKit.Entities;
using UnityEngine;
namespace BITKit
{
public class AutoHealComponent : EntityComponent,IHealthCallback,IDamageCallback
{
[SerializeField] private IntervalUpdate healDelayInterval;
[SerializeField] private IntervalUpdate healInterval;
[SerializeField] private int healIncrement;
private readonly ValidHandle allowHeal = new();
private IHealth _health;
public override void Initialize(IEntity _entity)
{
base.Initialize(_entity);
_entity.RegisterCallback<IHealthCallback>(this);
_entity.RegisterCallback<IDamageCallback>(this);
}
public override void OnStart()
{
_health = entity.Get<IHealth>();
}
private void Update()
{
if (!allowHeal.Allow || !healDelayInterval.AllowUpdateWithoutReset || !healInterval.AllowUpdate) return;
_health.HealthPoint= Mathf.Clamp(_health.HealthPoint+healIncrement,0,_health.MaxHealthPoint);
if (_health.HealthPoint == _health.MaxHealthPoint)
{
allowHeal.RemoveElement(this);
}
}
public void OnSetAlive(bool alive)
{
allowHeal.SetDisableElements(this,alive is false);
}
public void OnSetHP(int hp)
{
}
public void OnGetDamage(DamageMessage message)
{
allowHeal.AddElement(this);
healDelayInterval.Reset();
}
}
}

View File

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

View File

@@ -0,0 +1,130 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BITKit;
using BITKit.SubSystems;
using BITKit.Entities;
namespace BITKit.Entities
{
public interface IDamageType { }
public interface IDamageService
{
public event Action<DamageMessage> OnEntityDamaged;
public event Action<DamageMessage> OnEntityKilled;
void Execute(DamageMessage damageMessage);
ValidHandle AllowDamageHandle { get; }
}
[Serializable]
public class DamageServiceSingleton:IDamageService
{
private IDamageService _damageServiceImplementation => DamageService.Singleton;
public event Action<DamageMessage> OnEntityDamaged
{
add => _damageServiceImplementation.OnEntityDamaged += value;
remove => _damageServiceImplementation.OnEntityDamaged -= value;
}
public event Action<DamageMessage> OnEntityKilled
{
add => _damageServiceImplementation.OnEntityKilled += value;
remove => _damageServiceImplementation.OnEntityKilled -= value;
}
public void Execute(DamageMessage damageMessage)
{
_damageServiceImplementation.Execute(damageMessage);
}
public ValidHandle AllowDamageHandle => _damageServiceImplementation.AllowDamageHandle;
}
[Serializable]
public class DamageServiceMonoProxy:IDamageService
{
[SerializeField] private MonoBehaviour monoBehaviour;
private IDamageService _damageServiceImplementation=>monoBehaviour as IDamageService;
public event Action<DamageMessage> OnEntityDamaged
{
add => _damageServiceImplementation.OnEntityDamaged += value;
remove => _damageServiceImplementation.OnEntityDamaged -= value;
}
public event Action<DamageMessage> OnEntityKilled
{
add => _damageServiceImplementation.OnEntityKilled += value;
remove => _damageServiceImplementation.OnEntityKilled -= value;
}
public void Execute(DamageMessage damageMessage)
{
_damageServiceImplementation.Execute(damageMessage);
}
public ValidHandle AllowDamageHandle => _damageServiceImplementation.AllowDamageHandle;
}
public record DamageMessage
{
public IEntity initiator;
public IEntity target;
public int damage;
public IDamagable hit;
public Location location;
public IDamageType damageType;
}
public interface IDamageCallback
{
void OnGetDamage(DamageMessage message);
}
public interface IDamagable
{
IEntity Entity { get; }
Rigidbody Rigidbody { get; }
void GiveDamage(DamageMessage message);
}
public class DamageService:MonoBehaviour,IDamageService
{
internal static IDamageService Singleton { get; set; }
public ValidHandle AllowDamageHandle { get; }= new();
private readonly Queue<DamageMessage> Messages = new();
private void Awake()
{
Singleton = this;
}
private void FixedUpdate()
{
if (AllowDamageHandle.Allow is false)
{
Messages.Clear();
return;
}
while (Messages.TryDequeue(out var damageMessage))
{
var unityEntity = (Entity)damageMessage.target;
if (unityEntity is null || !unityEntity.TryGetComponent<IHealth>(out var heal) || !heal.IsAlive) continue;
damageMessage.initiator?.Invoke(damageMessage);
damageMessage.target?.Invoke(damageMessage);
foreach (var x in damageMessage.target?.GetCallbacks<IDamageCallback>()!)
{
x.OnGetDamage(damageMessage);
}
OnEntityDamaged?.Invoke(damageMessage);
if (heal.IsAlive is false)
{
OnEntityKilled?.Invoke(damageMessage);
}
}
}
public event Action<DamageMessage> OnEntityDamaged;
public event Action<DamageMessage> OnEntityKilled;
public void Execute(DamageMessage damageMessage)=>Messages.Enqueue(damageMessage);
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Remoting.Contexts;
@@ -10,33 +11,72 @@ namespace BITKit.Entities
void OnSetAlive(bool alive);
void OnSetHP(int hp);
}
[Serializable]
public class UnityEventHealthCallback : IHealthCallback
{
[SerializeField] private UnityEvent<int> onSetHP;
[SerializeField] private UnityEvent onSetAlive;
[SerializeField] private UnityEvent onSetDead;
public void OnSetAlive(bool alive)
{
if (alive)
{
onSetAlive.Invoke();
}
else
{
onSetDead.Invoke();
}
}
public void OnSetHP(int hp)
{
onSetHP.Invoke(hp);
}
}
public interface IHealth
{
public event Action<int> OnSetHealthPoint;
public event Action<bool> OnSetAlive;
int HealthPoint { get; set; }
int MaxHealthPoint { get; set; }
bool IsAlive { get; }
}
public class EntityHealth : EntityComponent, IHealth
{
[Header(Constant.Header.Settings)] [SerializeField]
private int healthPoint = 100;
[Header(Constant.Header.Settings)]
[SerializeField] private int healthPoint = 100;
[SerializeField] private int maxHealthPoint = 100;
[Header(Constant.Header.Events)] public UnityEvent<bool> onSetAlive = new();
[Header(Constant.Header.Events)]
[SerializeField] private UnityEvent<bool> onSetAlive = new();
[Header(Constant.Header.Providers)] [SerializeField, SerializeReference, SubclassSelector]
private IHealthCallback[] additiveCallback;
[Header(Constant.Header.InternalVariables)]
bool isAlive;
public event Action<int> OnSetHealthPoint;
public event Action<bool> OnSetAlive;
public int HealthPoint
{
get => healthPoint;
set => OnHealthPointChanged(healthPoint, value);
set => OnHealthPointChangedInternal(healthPoint, value);
}
public int MaxHealthPoint
{
get => maxHealthPoint;
set => maxHealthPoint = value;
}
public bool IsAlive { get; private set; }
bool IHealth.IsAlive => isAlive;
public override void Initialize(IEntity _entity)
{
base.Initialize(_entity);
_entity.Set<IHealth>(this);
_entity.Set(this);
}
public override void OnAwake()
{
@@ -45,18 +85,18 @@ namespace BITKit.Entities
public override void OnStart()
{
isAlive = healthPoint >= 0;
OnSetAlive(isAlive);
OnHealthPointChanged(0, healthPoint);
IsAlive = healthPoint >= 0;
OnSetAliveInternal(IsAlive);
OnHealthPointChangedInternal(0, healthPoint);
}
private void OnHealthPointChanged(int old, int newHP)
private void OnHealthPointChangedInternal(int old, int newHP)
{
healthPoint = newHP;
var _isAlive = newHP >= 0;
if (_isAlive != isAlive)
if (_isAlive != IsAlive)
{
OnSetAlive(isAlive = _isAlive);
OnSetAliveInternal(IsAlive = _isAlive);
}
//entity.Invoke<int>(_onSetHP, newHP);
@@ -70,9 +110,11 @@ namespace BITKit.Entities
{
x.OnSetHP(newHP);
}
OnSetHealthPoint?.Invoke(newHP);
}
private void OnSetAlive(bool alive)
private void OnSetAliveInternal(bool alive)
{
foreach (var x in entity.GetCallbacks<IHealthCallback>())
{
@@ -87,11 +129,12 @@ namespace BITKit.Entities
//entity.Invoke<bool>(_onSetAlive, alive);
//entity.Set<bool>(_isAlive, alive);
onSetAlive.Invoke(alive);
OnSetAlive?.Invoke(alive);
}
private void AddHP(int hp)
{
OnHealthPointChanged(healthPoint, healthPoint += hp);
OnHealthPointChangedInternal(healthPoint, healthPoint += hp);
}
private void OnDamage(DamageMessage damageMessage)
@@ -104,14 +147,14 @@ namespace BITKit.Entities
public void SetAlive()
{
BITAppForUnity.ThrowIfNotPlaying();
OnHealthPointChanged(-1, 100);
OnHealthPointChangedInternal(-1, 100);
}
[BIT]
public void SetDead()
{
BITAppForUnity.ThrowIfNotPlaying();
OnHealthPointChanged(100, -1);
OnHealthPointChangedInternal(100, -1);
}
#endif

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using BITKit.Entities;
using UnityEngine;
using UnityEngine.Events;
namespace BITKit.Entities
{
public class GetDamageComponent : EntityComponent
{
private readonly Queue<DamageMessage> DamageMessages = new();
[SerializeField] private UnityEvent<DamageMessage> onGetDamage;
[SerializeField, SerializeReference, SubclassSelector]
private IDamageCallback[] callbacks;
public override void OnAwake()
{
entity.AddListener<DamageMessage>(OnGetDamage);
}
private void OnGetDamage(DamageMessage obj)
{
if (obj.target != entity) return;
DamageMessages.Enqueue(obj);
onGetDamage?.Invoke(obj);
foreach (var x in callbacks)
{
x.OnGetDamage(obj);
}
}
}
}

View File

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

View File

@@ -6,8 +6,7 @@ namespace BITKit.Entities
{
public class EntityHitbox : EntityComponent,IDamagable
{
public IEntity Entity => entity;
IEntity IDamagable.Entity => entity;
public Rigidbody Rigidbody => m_rigidbody;
public void GiveDamage(DamageMessage message)
{

View File

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

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit.Entities
{
public class LocalPlayerComponent : EntityComponent
{
public override Type BaseType => typeof(LocalPlayerComponent);
}
}

View File

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

View File

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

View File

@@ -0,0 +1,12 @@
using System.Collections;
using System.Collections.Generic;
using AYellowpaper.SerializedCollections;
using UnityEngine;
namespace BITKit.Entities
{
public class SlotComponent : EntityComponent
{
public SerializedDictionary<string,Transform> slots;
}
}

View File

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

View File

@@ -1,46 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BITKit;
using BITKit.SubSystems;
using BITKit.Entities;
namespace BITKit.Entities
{
public interface IDamageType { }
public record DamageMessage
{
public IEntity initiator;
public IEntity target;
public int damage;
public IDamagable hit;
public Location location;
public IDamageType damageType;
}
public interface IDamageCallback
{
void OnGetDamage(DamageMessage message);
}
public interface IDamagable
{
IEntity Entity { get; }
Rigidbody Rigidbody { get; }
void GiveDamage(DamageMessage message);
}
public class DamageService:MonoBehaviour
{
static Queue<DamageMessage> Messages = new();
public static void Excute(DamageMessage damageMessage)
{
Messages.Enqueue(damageMessage);
}
private void FixedUpdate()
{
while (Messages.TryDequeue(out var damageMessage))
{
damageMessage.hit?.GiveDamage(damageMessage);
damageMessage.initiator?.Invoke(damageMessage);
}
}
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
@@ -7,13 +8,13 @@ using UnityEngine;
namespace BITKit.Entities
{
public interface IEntityComponent
public interface IEntityComponent:BITKit.Core.Entites.IEntityComponent
{
bool isLocalPlayer { get; }
IEntity entity { get; }
void Initialize(IEntity entity);
void OnAwake();
void OnStart();
void Initialize(IEntity _entity);
//void OnAwake();
//void OnStart();
void OnUpdate(float deltaTime);
void OnFixedUpdate(float deltaTime);
void OnLateUpdate(float deltaTime);
@@ -30,7 +31,7 @@ namespace BITKit.Entities
public bool isLocalPlayer => entity.Get<bool>(nameof(isLocalPlayer));
public bool isSpawned=> entity.Get<bool>(nameof(isSpawned));
private IEntity mEntity;
public virtual void Initialize(IEntity entity) { this.entity = entity; }
public virtual void Initialize(IEntity _entity) { this.entity = _entity; }
public virtual void OnAwake() { }
public virtual void OnStart() { }
public virtual void OnUpdate(float deltaTime) { }
@@ -42,6 +43,8 @@ namespace BITKit.Entities
public virtual void UnRegisterCallback() { }
public virtual void OnSpawn() { }
public virtual void OnDespawn() { }
public virtual Type BaseType => GetType();
public Core.Entites.IEntity Entity { get; set; }
}
#if UNITY_EDITOR

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit.Entities
{
public class EntityIdComponent : EntityComponent
{
public ulong Id;
public string Name;
public override void Initialize(IEntity _entity)
{
if (Id is 0) Id = (ulong)Guid.NewGuid().GetHashCode();
base.Initialize(_entity);
_entity.Set(this);
}
}
}

View File

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

View File

@@ -1,12 +1,67 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using BITKit;
using BITKit.Core.Entites;
using BITKit.Entities;
using UnityEngine;
using Cysharp.Threading.Tasks;
using UnityEngine.Pool;
using IEntity = BITKit.Core.Entites.IEntity;
using IEntityComponent = BITKit.Core.Entites.IEntityComponent;
[Serializable]
public class UnityEntitiesServiceSingleton:IEntitiesService
{
private static IEntitiesService _entitiesServiceImplementation=>DI.Get<IEntitiesService>();
public event Action<IEntity> OnAdd
{
add => _entitiesServiceImplementation.OnAdd += value;
remove => _entitiesServiceImplementation.OnAdd -= value;
}
public event Action<IEntity> OnRemove
{
add => _entitiesServiceImplementation.OnRemove += value;
remove => _entitiesServiceImplementation.OnRemove -= value;
}
public IEntity[] Entities => _entitiesServiceImplementation.Entities;
public bool Register(IEntity entity)
{
return _entitiesServiceImplementation.Register(entity);
}
public bool UnRegister(IEntity entity)
{
return _entitiesServiceImplementation.UnRegister(entity);
}
public CancellationToken CancellationToken => _entitiesServiceImplementation.CancellationToken;
public IEntity Get(ulong id) => _entitiesServiceImplementation.Get(id);
public IEntity[] Query<T>() where T : IEntityComponent
{
return _entitiesServiceImplementation.Query<T>();
}
public T[] QueryComponents<T>() where T : IEntityComponent
{
return _entitiesServiceImplementation.QueryComponents<T>();
}
public (T, T1)[] QueryComponents<T, T1>() where T : IEntityComponent where T1 : IEntityComponent
{
return _entitiesServiceImplementation.QueryComponents<T, T1>();
}
public (T, T1, T2)[] QueryComponents<T, T1, T2>() where T : IEntityComponent where T1 : IEntityComponent where T2 : IEntityComponent
{
return _entitiesServiceImplementation.QueryComponents<T, T1, T2>();
}
}
public class UnityEntitiesService : MonoBehaviour,IEntitiesService
{
private readonly Dictionary<ulong,IEntity> _dictionary=new();
@@ -18,6 +73,9 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
DI.Register<IEntitiesService>(this);
_cancellationToken = gameObject.GetCancellationTokenOnDestroy();
}
public event Action<IEntity> OnAdd;
public event Action<IEntity> OnRemove;
public IEntity[] Entities => _dictionary.Values.ToArray();
public bool Register(IEntity entity)
{
@@ -35,16 +93,76 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
while (RegisterQueue.TryDequeue(out var entity))
{
_dictionary.Add(entity.Id,entity);
OnAdd?.Invoke(entity);
}
while (UnRegisterQueue.TryDequeue(out var entity))
{
_dictionary.Remove(entity.Id);
if (_dictionary.TryRemove(entity.Id))
{
OnRemove?.Invoke(entity);
}
}
}
public CancellationToken CancellationToken => _cancellationToken;
public IEntity Get(ulong id)=>_dictionary[id];
public IEntity[] Query<T>() where T : IEntityComponent
{
throw new System.NotImplementedException();
return Entities.Where(x => ((Entity)x).TryGetComponentAny<T>(out _)).ToArray();
}
public T[] QueryComponents<T>() where T : IEntityComponent
{
var list = ListPool<T>.Get();
foreach (var iEntity in Entities)
{
switch (iEntity as Entity)
{
case { } x when x.TryGetComponentAny<T>(out var t):
list.Add((t));
break;
}
}
var value = list.ToArray();
list.Clear();
ListPool<T>.Release(list);
return value;
}
public (T, T1)[] QueryComponents<T, T1>() where T : IEntityComponent where T1 : IEntityComponent
{
var list = ListPool<(T t, T1 t1)>.Get();
foreach (var iEntity in Entities)
{
switch (iEntity as Entity)
{
case var x when x != null && x.TryGetComponentAny<T>(out var t) && x.TryGetComponentAny<T1>(out var t1):
list.Add((t, t1));
break;
}
}
var value = list.ToArray();
list.Clear();
ListPool<(T t, T1 t1)>.Release(list);
return value;
}
public (T, T1, T2)[] QueryComponents<T, T1, T2>() where T : IEntityComponent where T1 : IEntityComponent where T2 : IEntityComponent
{
var list = ListPool<(T t, T1 t1, T2 t2)>.Get();
foreach (var iEntity in Entities)
{
switch (iEntity as Entity)
{
case var x when x != null && x.TryGetComponentAny<T>(out var t) && x.TryGetComponentAny<T1>(out var t1) && x.TryGetComponentAny<T2>(out var t2):
list.Add((t, t1, t2));
break;
}
}
var value = list.ToArray();
list.Clear();
ListPool<(T t, T1 t1, T2 t2)>.Release(list);
return value;
}
}