1
This commit is contained in:
24
Unity/Scripts/Entity/BITKit.Entites.asmdef
Normal file
24
Unity/Scripts/Entity/BITKit.Entites.asmdef
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Entity",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||
"GUID:a209c53514018594f9f482516f2a6781",
|
||||
"GUID:75469ad4d38634e559750d17036d5f7c",
|
||||
"GUID:66d2ae14764cc7d49aad4b16930747c0",
|
||||
"GUID:fd4f76a9ea9701445bfd4d132912acab",
|
||||
"GUID:21b0c8d1703a94250bfac916590cea4f",
|
||||
"GUID:be17a8778dbfe454890ed8279279e153",
|
||||
"GUID:9e24947de15b9834991c9d8411ea37cf",
|
||||
"GUID:84651a3751eca9349aac36a66bba901b"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
69
Unity/Scripts/Entity/Components/Animator/EntityAnimator.cs
Normal file
69
Unity/Scripts/Entity/Components/Animator/EntityAnimator.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Sirenix.OdinInspector;
|
||||
using Sirenix.Serialization;
|
||||
using UnityEngine.Events;
|
||||
using System.Linq;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
|
||||
public class EntityAnimator : EntityComponent
|
||||
{
|
||||
public Animator[] animators;
|
||||
[SerializeReference, SubclassSelector] public References[] animationKeyWords;
|
||||
[SerializeReference, SubclassSelector] public References _rootVelocity;
|
||||
[SerializeReference, SubclassSelector] public References[] boolParameters;
|
||||
[SerializeReference, SubclassSelector] public References[] floatParameters;
|
||||
List<string> keyWords;
|
||||
public override void OnAwake()
|
||||
{
|
||||
keyWords = animationKeyWords.Select(x => x.Get()).ToList();
|
||||
}
|
||||
public override void OnStart()
|
||||
{
|
||||
entity.AddListener<string>(Constant.Animation.Play, Play);
|
||||
}
|
||||
protected virtual void Play(string name)
|
||||
{
|
||||
if (animationKeyWords.Length is 0 || keyWords.Contains(name))
|
||||
{
|
||||
animators.ForEach(x =>
|
||||
{
|
||||
if (x.isActiveAndEnabled)
|
||||
{
|
||||
name = name.Replace(".", "_");
|
||||
x.SetTrigger(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
public override void OnFixedUpdate(float deltaTime)
|
||||
{
|
||||
foreach (var boolPar in boolParameters)
|
||||
{
|
||||
animators.ForEach(x =>
|
||||
{
|
||||
if (x.isActiveAndEnabled)
|
||||
x.SetBool(boolPar, entity.Get<bool>(boolPar));
|
||||
});
|
||||
}
|
||||
foreach (var floatPar in floatParameters)
|
||||
{
|
||||
animators.ForEach(x =>
|
||||
{
|
||||
if (x.isActiveAndEnabled)
|
||||
x.SetFloat(floatPar, entity.Get<float>(floatPar));
|
||||
});
|
||||
}
|
||||
}
|
||||
void OnAnimatorMove()
|
||||
{
|
||||
entity.Set(_rootVelocity, animators[0].velocity);
|
||||
}
|
||||
void AnimationEvent(string name)
|
||||
{
|
||||
entity.Invoke(Constant.Animation.OnEvent, name);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using BITKit.Sensors;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public class EntityAudioObject : EntityComponent, IAudioObject
|
||||
{
|
||||
float volume;
|
||||
public override void OnStart()
|
||||
{
|
||||
entity.AddListener<AudioSO>(OnAuioSO);
|
||||
}
|
||||
public override void OnFixedUpdate(float deltaTime)
|
||||
{
|
||||
volume = Mathf.Lerp(volume, 0, deltaTime);
|
||||
}
|
||||
public float GetVolume()
|
||||
{
|
||||
return volume;
|
||||
}
|
||||
void OnAuioSO(AudioSO so)
|
||||
{
|
||||
if (so.distance > volume)
|
||||
volume = so.distance;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "Entity.Component",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:a209c53514018594f9f482516f2a6781",
|
||||
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
|
||||
"GUID:677cd05ca06c46b4395470200b1acdad",
|
||||
"GUID:75469ad4d38634e559750d17036d5f7c",
|
||||
"GUID:66d2ae14764cc7d49aad4b16930747c0",
|
||||
"GUID:508392158bd966c4d9c21e19661a441d",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:99a47d73d3ad3374b9d12c982228df71",
|
||||
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
|
||||
"GUID:274d4ecae4648e94c8b2cee7218378a0",
|
||||
"GUID:1491147abca9d7d4bb7105af628b223e",
|
||||
"GUID:28c2d6a6727d47442a24a353f0d37846",
|
||||
"GUID:be17a8778dbfe454890ed8279279e153",
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [
|
||||
"RH_SerializedDictionary"
|
||||
],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
31
Unity/Scripts/Entity/Components/Camera/EntityCamera.cs
Normal file
31
Unity/Scripts/Entity/Components/Camera/EntityCamera.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public class EntityCamera : EntityComponent
|
||||
{
|
||||
[Header(Constant.Header.Components)]
|
||||
public Behaviour aliveCamera;
|
||||
public Behaviour deathCamera;
|
||||
[Header(Constant.Header.Reference)]
|
||||
[SerializeReference, SubclassSelector] public IReference _onSetAlive;
|
||||
public override void OnSpawn()
|
||||
{
|
||||
if (isLocalPlayer)
|
||||
{
|
||||
OnSetAlive(true);
|
||||
}
|
||||
}
|
||||
public override void OnDespawn()
|
||||
{
|
||||
aliveCamera.enabled = deathCamera.enabled = false;
|
||||
}
|
||||
void OnSetAlive(bool alive)
|
||||
{
|
||||
aliveCamera.enabled = alive;
|
||||
deathCamera.enabled = alive is false;
|
||||
}
|
||||
}
|
||||
}
|
61
Unity/Scripts/Entity/Components/Character/EntityCharacter.cs
Normal file
61
Unity/Scripts/Entity/Components/Character/EntityCharacter.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using Sirenix.OdinInspector;
|
||||
using DG.Tweening;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public class EntityCharacter : EntityComponent
|
||||
{
|
||||
[Header(Constant.Header.Components)]
|
||||
public List<Renderer> fpvRenderer = new();
|
||||
public List<Renderer> tpvRenderer = new();
|
||||
[Header(Constant.Header.Reference)]
|
||||
[SerializeReference, SubclassSelector] public References _isAlive;
|
||||
[SerializeReference, SubclassSelector] public References _getDamage;
|
||||
|
||||
public override void OnStart()
|
||||
{
|
||||
entity.AddListener<bool>(nameof(OnSetAlive), OnSetAlive);
|
||||
entity.AddListener<int>(nameof(OnSetHP), OnSetHP);
|
||||
}
|
||||
public override void OnSpawn()
|
||||
{
|
||||
if (isLocalPlayer)
|
||||
{
|
||||
OnSetAlive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFPV(false);
|
||||
}
|
||||
}
|
||||
public override void OnDespawn()
|
||||
{
|
||||
SetFPV(false);
|
||||
}
|
||||
void OnSetAlive(bool alive)
|
||||
{
|
||||
SetFPV(isLocalPlayer ? alive : false);
|
||||
}
|
||||
void OnSetHP(int hp)
|
||||
{
|
||||
entity.Invoke<string>(Constant.Animation.Play, _getDamage);
|
||||
}
|
||||
void SetFPV(bool isFpv)
|
||||
{
|
||||
var shadowMode = isFpv ?
|
||||
ShadowCastingMode.ShadowsOnly :
|
||||
ShadowCastingMode.On;
|
||||
foreach (var x in fpvRenderer)
|
||||
{
|
||||
x.enabled = isFpv;
|
||||
}
|
||||
foreach (var x in tpvRenderer)
|
||||
{
|
||||
x.shadowCastingMode = shadowMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
[System.Serializable]
|
||||
public struct ExpectState<T>
|
||||
{
|
||||
public T shouldBe;
|
||||
public T being;
|
||||
public T force;
|
||||
public static implicit operator T(ExpectState<T> value)
|
||||
{
|
||||
return value.being;
|
||||
}
|
||||
public void Reset()
|
||||
{
|
||||
shouldBe = being = force = default;
|
||||
}
|
||||
public void Release()
|
||||
{
|
||||
being = shouldBe;
|
||||
}
|
||||
public void Release(T value)
|
||||
{
|
||||
force = default;
|
||||
being = shouldBe = value;
|
||||
}
|
||||
}
|
||||
public interface IEntityMovement
|
||||
{
|
||||
void SyncMovement(Vector3 velocity, Vector3 position,Quaternion rotation,bool isGrounded);
|
||||
}
|
||||
public class EntityMovement : EntityInputComponent, IEntityMovement
|
||||
{
|
||||
Vector2 inputVector;
|
||||
public override void OnMovement(InputAction.CallbackContext context)
|
||||
{
|
||||
inputVector = context.ReadValue<Vector2>();
|
||||
inputVector = Vector2.ClampMagnitude(inputVector, 1);
|
||||
}
|
||||
public override void OnFixedUpdate(float deltaTime)
|
||||
{
|
||||
transform.position += (Vector3)inputVector * deltaTime;
|
||||
}
|
||||
|
||||
public void SyncMovement(Vector3 velocity, Vector3 position, Quaternion rotation, bool isGrounded)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public interface IMovementCallback { }
|
||||
public record MovementCallback : IMovementCallback
|
||||
{
|
||||
public bool started;
|
||||
public bool updated;
|
||||
public bool canceled;
|
||||
}
|
||||
public record OnRunCallback : MovementCallback { }
|
||||
public record OnClimbCallback : MovementCallback { }
|
||||
|
||||
public interface IMovementCancelAction { }
|
||||
public record MovementCancelAction : IMovementCancelAction { }
|
||||
public record CancelMovement : MovementCancelAction { }
|
||||
public record CancelMovementAction : MovementCancelAction { }
|
||||
public record CancelRunOrSprint : MovementCancelAction { }
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using BITKit.Entities;
|
||||
using BITKit.StateMachine;
|
||||
namespace BITKit
|
||||
{
|
||||
public interface IEntityMovementState : IState
|
||||
{
|
||||
|
||||
}
|
||||
}
|
61
Unity/Scripts/Entity/Components/Equipment/EntityEquipment.cs
Normal file
61
Unity/Scripts/Entity/Components/Equipment/EntityEquipment.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using BITKit;
|
||||
using BITKit.Animations;
|
||||
using BITKit.StateMachine;
|
||||
using System.Linq;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public interface IEquipBase : IEntryElement, IAwake, IStart, IUpdate
|
||||
{
|
||||
public const string _Equip = "Equip";
|
||||
string AddressablePath { get; }
|
||||
IEntity Entity { get; set; }
|
||||
void PlayAudio(string name);
|
||||
}
|
||||
public abstract class BITEquipBase<T> : MonoBehaviour, IEquipBase where T : IState
|
||||
{
|
||||
[Header(Constant.Header.Components)]
|
||||
public UnityAnimator animator;
|
||||
[Header(Constant.Header.InternalVariables)]
|
||||
protected IEntity entity;
|
||||
public IEntity Entity { get => entity; set => entity = value; }
|
||||
public virtual string AddressablePath => throw new System.NotImplementedException();
|
||||
public virtual void Entry() { }
|
||||
public virtual void Exit() { }
|
||||
public virtual void OnAwake() { }
|
||||
public virtual void OnStart() { }
|
||||
public virtual void OnUpdate(float deltaTime) { }
|
||||
public virtual void PlayAudio(string name) { }
|
||||
}
|
||||
public class EntityEquipment : EntityComponent
|
||||
{
|
||||
public EntryGroup<IEquipBase> equips = new();
|
||||
IEquipBase entrid;
|
||||
public override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
equips.list = GetComponentsInChildren<IEquipBase>(true).ToList();
|
||||
foreach (var x in equips.list)
|
||||
{
|
||||
x.Entity = entity;
|
||||
x.OnAwake();
|
||||
}
|
||||
foreach (var x in equips.list)
|
||||
{
|
||||
x.OnStart();
|
||||
}
|
||||
}
|
||||
public override void OnUpdate(float deltaTime)
|
||||
{
|
||||
if (isLocalPlayer)
|
||||
{
|
||||
if (equips.TryGetEntried(out entrid))
|
||||
{
|
||||
entrid.OnUpdate(deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
78
Unity/Scripts/Entity/Components/Health/EntityHealth.cs
Normal file
78
Unity/Scripts/Entity/Components/Health/EntityHealth.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public interface IHealthCallback
|
||||
{
|
||||
void OnSetAlive(bool alive);
|
||||
void OnSetHP(int hp);
|
||||
}
|
||||
public class EntityHealth : EntityComponent
|
||||
{
|
||||
[Header(Constant.Header.Settings)]
|
||||
public int healthPoint = 100;
|
||||
[Header(Constant.Header.Events)]
|
||||
public UnityEvent<bool> onSetAlive = new();
|
||||
[Header(Constant.Header.InternalVariables)]
|
||||
bool isAlive;
|
||||
public override void OnAwake()
|
||||
{
|
||||
entity.AddListener<DamageMessage>(OnDamage);
|
||||
}
|
||||
public override void OnStart()
|
||||
{
|
||||
isAlive = healthPoint >= 0;
|
||||
OnSetAlive(isAlive);
|
||||
OnHealthPointChanged(0, healthPoint);
|
||||
}
|
||||
void OnHealthPointChanged(int old, int newHP)
|
||||
{
|
||||
var _isAlive = newHP >= 0;
|
||||
if (_isAlive != isAlive)
|
||||
{
|
||||
OnSetAlive(isAlive = _isAlive);
|
||||
}
|
||||
//entity.Invoke<int>(_onSetHP, newHP);
|
||||
//entity.Set<int>("HP", newHP);
|
||||
foreach (var x in entity.GetCallbacks<IHealthCallback>())
|
||||
{
|
||||
x.OnSetHP(newHP);
|
||||
}
|
||||
}
|
||||
void OnSetAlive(bool alive)
|
||||
{
|
||||
foreach (var x in entity.GetCallbacks<IHealthCallback>())
|
||||
{
|
||||
x.OnSetAlive(alive);
|
||||
}
|
||||
//entity.Invoke<bool>(_onSetAlive, alive);
|
||||
//entity.Set<bool>(_isAlive, alive);
|
||||
onSetAlive.Invoke(alive);
|
||||
}
|
||||
void AddHP(int hp)
|
||||
{
|
||||
OnHealthPointChanged(healthPoint, healthPoint += hp);
|
||||
}
|
||||
void OnDamage(DamageMessage damageMessage)
|
||||
{
|
||||
if (damageMessage.target == entity)
|
||||
AddHP(-damageMessage.damage);
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
[BIT]
|
||||
public void SetAlive()
|
||||
{
|
||||
BITAppForUnity.ThrowIfNotPlaying();
|
||||
OnHealthPointChanged(-1, 100);
|
||||
}
|
||||
[BIT]
|
||||
public void SetDead()
|
||||
{
|
||||
BITAppForUnity.ThrowIfNotPlaying();
|
||||
OnHealthPointChanged(100, -1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
19
Unity/Scripts/Entity/Components/Hitbox/EntityHitbox.cs
Normal file
19
Unity/Scripts/Entity/Components/Hitbox/EntityHitbox.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using BITKit;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public class EntityHitbox : EntityComponent, IDamagable
|
||||
{
|
||||
public IEntity Entity => entity;
|
||||
|
||||
public Rigidbody Rigidbody => m_rigidbody;
|
||||
|
||||
public Rigidbody m_rigidbody;
|
||||
public void GiveDamage(DamageMessage message)
|
||||
{
|
||||
entity.Invoke<DamageMessage>(message);
|
||||
}
|
||||
}
|
||||
}
|
43
Unity/Scripts/Entity/Components/HotFix/EntityLocalPlayer.cs
Normal file
43
Unity/Scripts/Entity/Components/HotFix/EntityLocalPlayer.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using BITKit;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public class EntityLocalPlayer : EntityComponent
|
||||
{
|
||||
public override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
entity.Set<bool>(nameof(EntityComponent.isLocalPlayer), true);
|
||||
if (isSpawned is false)
|
||||
{
|
||||
foreach (var x in GetComponentsInChildren<IEntityComponent>(true))
|
||||
{
|
||||
x.OnSpawn();
|
||||
}
|
||||
entity.Set<bool>(nameof(isSpawned), true);
|
||||
}
|
||||
IEntity.LocalPlayer = entity;
|
||||
IEntity.OnSpawnLocalPlayer.Invoke(entity);
|
||||
}
|
||||
public override void OnDestroyComponent()
|
||||
{
|
||||
base.OnDestroyComponent();
|
||||
if (isSpawned)
|
||||
{
|
||||
foreach (var x in GetComponentsInChildren<IEntityComponent>(true))
|
||||
{
|
||||
x.OnDespawn();
|
||||
}
|
||||
entity.Set<bool>(nameof(isSpawned), false);
|
||||
}
|
||||
IEntity.LocalPlayer = null;
|
||||
}
|
||||
public override void OnSpawn()
|
||||
{
|
||||
BIT4Log.Log<EntityLocalPlayer>("已创建本地玩家");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
14
Unity/Scripts/Entity/Components/Impact/EntityImpact.cs
Normal file
14
Unity/Scripts/Entity/Components/Impact/EntityImpact.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public class EntityImpact : EntityComponent, IPhysicsImpact
|
||||
{
|
||||
public void AddImpact(Vector3 force)
|
||||
{
|
||||
var damage = (int)(-force.sqrMagnitude);
|
||||
entity.Invoke<int>("AddHP", damage);
|
||||
}
|
||||
}
|
||||
}
|
116
Unity/Scripts/Entity/Components/Interactive/EntityInteractive.cs
Normal file
116
Unity/Scripts/Entity/Components/Interactive/EntityInteractive.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.Interactions;
|
||||
using BITKit;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public class EntityInteractive : EntityInputComponent
|
||||
{
|
||||
[Header(Constant.Header.Settings)]
|
||||
public float distance;
|
||||
public LayerMask layerMask;
|
||||
[Header(Constant.Header.Input)]
|
||||
public InputActionReference interactiveAction;
|
||||
InputActionGroup inputActionGroup = new();
|
||||
[Header(Constant.Header.InternalVariables)]
|
||||
ISelectable selected;
|
||||
IntervalUpdate cd = new(0.08f);
|
||||
public override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
}
|
||||
public override void OnSpawn()
|
||||
{
|
||||
base.OnSpawn();
|
||||
if (isLocalPlayer)
|
||||
{
|
||||
inputActionGroup.RegisterCallback(interactiveAction, OnInteractive);
|
||||
}
|
||||
}
|
||||
public override void OnDespawn()
|
||||
{
|
||||
base.OnDespawn();
|
||||
if (isLocalPlayer)
|
||||
{
|
||||
inputActionGroup.UnRegisterCallback(interactiveAction, OnInteractive);
|
||||
}
|
||||
}
|
||||
public override void OnUpdate(float deltaTime)
|
||||
{
|
||||
if (isLocalPlayer)
|
||||
{
|
||||
var ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
|
||||
if (Physics.Raycast(ray, out var raycastHit, distance, layerMask))
|
||||
{
|
||||
if (raycastHit.transform.TryGetComponentAny<ISelectable>(out var _detected))
|
||||
{
|
||||
if (_detected == selected)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
TryDeSelected();
|
||||
|
||||
Detected(_detected);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TryDeSelected();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TryDeSelected();
|
||||
}
|
||||
}
|
||||
}
|
||||
void TryDeSelected()
|
||||
{
|
||||
if (selected is not null)
|
||||
{
|
||||
selected.SetSelectionState(SelectionState.None);
|
||||
foreach (var x in entity.GetCallbacks<ISelectableCallback>())
|
||||
{
|
||||
x.OnInactive(selected);
|
||||
}
|
||||
selected = null;
|
||||
}
|
||||
}
|
||||
void Detected(ISelectable detected)
|
||||
{
|
||||
selected = detected;
|
||||
detected.SetSelectionState(SelectionState.Hover);
|
||||
foreach (var x in entity.GetCallbacks<ISelectableCallback>())
|
||||
{
|
||||
x.OnHover(selected);
|
||||
}
|
||||
}
|
||||
public override void OnInteractive(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context.interaction is TapInteraction && context.performed)
|
||||
{
|
||||
var selected = this.selected;
|
||||
if (selected is not null)
|
||||
{
|
||||
|
||||
if (selected is MonoBehaviour monoBehaviour)
|
||||
{
|
||||
if (monoBehaviour.TryGetComponentAny<IAction>(out var action))
|
||||
{
|
||||
action.Excute();
|
||||
}
|
||||
foreach (var x in entity.GetCallbacks<ISelectableCallback>())
|
||||
{
|
||||
x.OnActive(selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Sirenix.OdinInspector;
|
||||
using System.Linq;
|
||||
using UnityEngine.Events;
|
||||
using Cysharp.Threading.Tasks;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public class EntityLocomotion : EntityComponent
|
||||
{
|
||||
[Header(Constant.Header.Settings)]
|
||||
|
||||
[Header(Constant.Header.Components)]
|
||||
public Animator animator;
|
||||
|
||||
}
|
||||
}
|
36
Unity/Scripts/Entity/Components/Melee/EntityMelee.cs
Normal file
36
Unity/Scripts/Entity/Components/Melee/EntityMelee.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public interface IEntityMelee
|
||||
{
|
||||
void Excute();
|
||||
}
|
||||
public class EntityMelee : EntityComponent
|
||||
{
|
||||
[Header(Constant.Header.Settings)]
|
||||
public int damage=50;
|
||||
public bool singleTarget;
|
||||
public override void OnStart()
|
||||
{
|
||||
entity.AddListener<int>("Melee", Melee);
|
||||
}
|
||||
public virtual void Excute()
|
||||
{
|
||||
Melee(damage);
|
||||
}
|
||||
public virtual void AIAction(string actionName)
|
||||
{
|
||||
switch (actionName)
|
||||
{
|
||||
case "Melee":
|
||||
Excute();
|
||||
break;
|
||||
}
|
||||
}
|
||||
protected virtual void Melee(int damage)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
32
Unity/Scripts/Entity/Components/Physics/EntityPhysics.cs
Normal file
32
Unity/Scripts/Entity/Components/Physics/EntityPhysics.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public class EntityPhysics : EntityComponent, IHealthCallback
|
||||
{
|
||||
public Animator animator;
|
||||
public Rigidbody[] rigidbodies;
|
||||
public Collider[] ragdollColliders;
|
||||
public override void OnStart()
|
||||
{
|
||||
entity.RegisterCallback<IHealthCallback>(this);
|
||||
}
|
||||
void IHealthCallback.OnSetAlive(bool alive)
|
||||
{
|
||||
if(animator)
|
||||
animator.enabled = alive;
|
||||
rigidbodies.ForEach(x =>
|
||||
{
|
||||
x.isKinematic = alive;
|
||||
});
|
||||
ragdollColliders.ForEach(x =>
|
||||
{
|
||||
x.enabled = !alive;
|
||||
});
|
||||
}
|
||||
public void OnSetHP(int hp)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
52
Unity/Scripts/Entity/Core/DamageSystem.cs
Normal file
52
Unity/Scripts/Entity/Core/DamageSystem.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using BITKit;
|
||||
using BITKit.SubSystems;
|
||||
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);
|
||||
}
|
||||
[SubSystemConfig(isMainThread = true)]
|
||||
public class DamageSystem : SubBITSystem
|
||||
{
|
||||
static Queue<DamageMessage> messages = new();
|
||||
public static void Excute(DamageMessage damageMessage)
|
||||
{
|
||||
messages.Enqueue(damageMessage);
|
||||
}
|
||||
public override void OnCreate()
|
||||
{
|
||||
messages.Clear();
|
||||
}
|
||||
public override void OnFixedUpdate(float deltaTime)
|
||||
{
|
||||
while (messages.TryDequeue(out var damageMessage))
|
||||
{
|
||||
damageMessage.hit?.GiveDamage(damageMessage);
|
||||
damageMessage.initiator?.Invoke(damageMessage);
|
||||
//damageMessage.initiator?.Invoke(damageMessage);
|
||||
//damageMessage.target?.Invoke(damageMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
Unity/Scripts/Entity/Core/EntitiesManager.cs
Normal file
36
Unity/Scripts/Entity/Core/EntitiesManager.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using BITKit;
|
||||
using System.Collections.Concurrent;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public class EntitiesManager
|
||||
{
|
||||
[RuntimeInitializeOnLoadMethod]
|
||||
static void Reload()
|
||||
{
|
||||
Dictionary.Clear();
|
||||
}
|
||||
public static ConcurrentDictionary<int, IEntity> Dictionary = new();
|
||||
public static Func<int, IEntity> CreateFactory;
|
||||
public static IEntity Get(int id)
|
||||
{
|
||||
if (Dictionary.TryGetValue(id, out var entity))
|
||||
{
|
||||
return entity;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NullReferenceException($"没有找到id为{id}的iEntity");
|
||||
}
|
||||
}
|
||||
public static IEntity GetOrAdd(int id)
|
||||
{
|
||||
return GetOrAdd(id, CreateFactory);
|
||||
}
|
||||
public static IEntity GetOrAdd(int id, Func<int, IEntity> createFacotry) => Dictionary.GetOrAdd(id, createFacotry);
|
||||
}
|
||||
}
|
147
Unity/Scripts/Entity/Core/Entity.cs
Normal file
147
Unity/Scripts/Entity/Core/Entity.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine.Events;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
|
||||
[Inspectable]
|
||||
public class Entity : MonoBehaviour, IEntity
|
||||
{
|
||||
public string addressablePath="Entity";
|
||||
GenericEvent genericEvent = new();
|
||||
Processor processor = new();
|
||||
public IEntityComponent[] entityComponents { get; set; }
|
||||
public int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
if (id is 0)
|
||||
{
|
||||
id = Guid.NewGuid().GetHashCode();
|
||||
}
|
||||
return id;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (id != value)
|
||||
{
|
||||
id = value;
|
||||
EntitiesManager.Dictionary.TryRemove(id, out var _);
|
||||
EntitiesManager.GetOrAdd(id, x => this);
|
||||
}
|
||||
}
|
||||
}
|
||||
int id;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
entityComponents = GetComponentsInChildren<IEntityComponent>(true);
|
||||
entityComponents.ForEach(x => x.Initialize(this));
|
||||
}
|
||||
protected virtual void Start()
|
||||
{
|
||||
entityComponents.ForEach(x => x.OnAwake());
|
||||
entityComponents.ForEach(x => x.OnStart());
|
||||
EntitiesManager.Dictionary.AddOrUpdate(id, (x) => this, (x1, x2) => this);
|
||||
}
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
entityComponents.ForEach(x => x.OnDestroyComponent());
|
||||
EntitiesManager.Dictionary.TryRemove(id, out var _);
|
||||
}
|
||||
protected virtual void Update()
|
||||
{
|
||||
entityComponents.ForEach(x => x.OnUpdate(Time.deltaTime));
|
||||
}
|
||||
protected virtual void FixedUpdate()
|
||||
{
|
||||
entityComponents.ForEach(x => x.OnFixedUpdate(Time.fixedDeltaTime));
|
||||
}
|
||||
protected virtual void LateUpdate()
|
||||
{
|
||||
entityComponents.ForEach(x => x.OnLateUpdate(Time.deltaTime));
|
||||
}
|
||||
public void AddListener<T>(Action<T> action) => genericEvent.AddListener<T>(action);
|
||||
public void Invoke<T>(T value) => genericEvent.Invoke<T>(value);
|
||||
public void RemoveListener<T>(Action<T> action) => genericEvent.RemoveListener<T>(action);
|
||||
public void AddListener<T>(string key, Action<T> action) => genericEvent.AddListener<T>(key, action);
|
||||
public void Invoke<T>(string key, T value) => genericEvent.Invoke<T>(key, value);
|
||||
public void Invoke<T>() where T : new() => genericEvent.Invoke<T>();
|
||||
public void RemoveListener<T>(string key, Action<T> action) => genericEvent.RemoveListener<T>(key, action);
|
||||
public T Get<T>(string key = Constant.System.Internal)
|
||||
{
|
||||
var value = genericEvent.Get<T>(key);
|
||||
if (value is null && typeof(T).IsAssignableFrom(typeof(Component)))
|
||||
{
|
||||
if (TryGetComponent<T>(out var component))
|
||||
{
|
||||
Set<T>(component);
|
||||
return component;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
public void Set<T>(T value) => genericEvent.Set<T>(value);
|
||||
public void Set<T>(string key = Constant.System.Internal, T value = default) => genericEvent.Set<T>(key, value);
|
||||
public T GetContext<T>(T value = default) => processor.GetContext<T>(value);
|
||||
public void AddProcessor<T>(Func<T, T> func) => processor.AddProcessor<T>(func);
|
||||
public void RemoveProcessor<T>(Func<T, T> func) => processor.RemoveProcessor<T>(func);
|
||||
public T GetContext<T>(string key, T value) => processor.GetContext<T>(value);
|
||||
public void AddProcessor<T>(string key, Func<T, T> func) => processor.AddProcessor<T>(key, func);
|
||||
public void RemoveProcessor<T>(string key, Func<T, T> func) => processor.RemoveProcessor<T>(key, func);
|
||||
|
||||
public void RegisterCallback<T>(T t)
|
||||
{
|
||||
var value = GetCallbacks<T>() as List<T>;
|
||||
value.Add(t);
|
||||
}
|
||||
|
||||
public void UnRegisterCallback<T>(T t)
|
||||
{
|
||||
var value = GetCallbacks<T>() as List<T>;
|
||||
value.Remove(t);
|
||||
}
|
||||
|
||||
public IEnumerable<T> GetCallbacks<T>()
|
||||
{
|
||||
var value = Get<List<T>>(nameof(ICallback)).CreateOrAddIfEmety(() =>
|
||||
{
|
||||
List<T> newList = new();
|
||||
Set<List<T>>(nameof(ICallback), newList);
|
||||
|
||||
return newList;
|
||||
});
|
||||
if (value is null)
|
||||
{
|
||||
Debug.LogWarning("List is Null");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public int[] GetInts() => new int[] { id };
|
||||
public float[] GetFloats() => null;
|
||||
public byte[] GetBytes() => null;
|
||||
|
||||
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.CustomEditor(typeof(Entity))]
|
||||
public class EntityInspector : BITInspector<Entity>
|
||||
{
|
||||
public override VisualElement CreateInspectorGUI()
|
||||
{
|
||||
FillDefaultInspector();
|
||||
var label = CreateSubTitle("Identity");
|
||||
var idLabel = root.Create<Label>();
|
||||
idLabel.text = agent.Id.ToString();
|
||||
return root;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
52
Unity/Scripts/Entity/Core/EntityComponent.cs
Normal file
52
Unity/Scripts/Entity/Core/EntityComponent.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Sirenix.OdinInspector;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public interface IEntityComponent
|
||||
{
|
||||
bool isLocalPlayer { get; }
|
||||
IEntity entity { get; }
|
||||
void Initialize(IEntity entity);
|
||||
void OnAwake();
|
||||
void OnStart();
|
||||
void OnUpdate(float deltaTime);
|
||||
void OnFixedUpdate(float deltaTime);
|
||||
void OnLateUpdate(float deltaTime);
|
||||
void OnSetOverride(bool value);
|
||||
void OnDestroyComponent();
|
||||
void OnSpawn();
|
||||
void OnDespawn();
|
||||
void RegisterCallback() { }
|
||||
void UnRegisterCallback() { }
|
||||
|
||||
}
|
||||
public abstract partial class EntityComponent : MonoBehaviour, IEntityComponent
|
||||
{
|
||||
public IEntity entity { get; set; }
|
||||
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 OnAwake() { }
|
||||
public virtual void OnStart() { }
|
||||
public virtual void OnUpdate(float deltaTime) { }
|
||||
public virtual void OnFixedUpdate(float deltaTime) { }
|
||||
public virtual void OnLateUpdate(float deltaTime) { }
|
||||
public virtual void OnSetOverride(bool value) { }
|
||||
public virtual void OnDestroyComponent() { }
|
||||
public virtual void RegisterCallback() { }
|
||||
public virtual void UnRegisterCallback() { }
|
||||
public virtual void OnSpawn() { }
|
||||
public virtual void OnDespawn() { }
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[UnityEditor.CustomEditor(typeof(EntityComponent), true)]
|
||||
public class EntityComponentInspector : BITInspector<EntityComponent>
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
34
Unity/Scripts/Entity/Core/EntityInputComponent.cs
Normal file
34
Unity/Scripts/Entity/Core/EntityInputComponent.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using BITKit.UniversalInputSystem;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public class EntityInputComponent : EntityComponent, BITController.IGameplayActions
|
||||
{
|
||||
public virtual void OnMovement(InputAction.CallbackContext context) { }
|
||||
public virtual void OnView(InputAction.CallbackContext context) { }
|
||||
public virtual void OnJump(InputAction.CallbackContext context) { }
|
||||
public virtual void OnCrouch(InputAction.CallbackContext context) { }
|
||||
public virtual void OnHoldCrouch(InputAction.CallbackContext context) { }
|
||||
public virtual void OnFire(InputAction.CallbackContext context) { }
|
||||
public virtual void OnAim(InputAction.CallbackContext context) { }
|
||||
public virtual void OnInteractive(InputAction.CallbackContext context) { }
|
||||
public virtual void OnAbility(InputAction.CallbackContext context) { }
|
||||
public virtual void OnMelee(InputAction.CallbackContext context) { }
|
||||
public virtual void OnRun(InputAction.CallbackContext context) { }
|
||||
public virtual void OnRunHold(InputAction.CallbackContext context) { }
|
||||
public virtual void OnReload(InputAction.CallbackContext context) { }
|
||||
public virtual void OnPrimary(InputAction.CallbackContext context) { }
|
||||
public virtual void OnSecondary(InputAction.CallbackContext context) { }
|
||||
public virtual void OnTertiary(InputAction.CallbackContext context) { }
|
||||
public virtual void OnQuaternary(InputAction.CallbackContext context) { }
|
||||
public virtual void OnQuinary(InputAction.CallbackContext context) { }
|
||||
public virtual void OnSenary(InputAction.CallbackContext context) { }
|
||||
public virtual void OnSeptenary(InputAction.CallbackContext context) { }
|
||||
public virtual void OnOctonary(InputAction.CallbackContext context) { }
|
||||
public virtual void OnNonary(InputAction.CallbackContext context) { }
|
||||
public virtual void OnDenary(InputAction.CallbackContext context) { }
|
||||
}
|
||||
}
|
22
Unity/Scripts/Entity/Core/EntityOverride.cs
Normal file
22
Unity/Scripts/Entity/Core/EntityOverride.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public class EntityOverride : EntityComponent
|
||||
{
|
||||
ValidHandle isOverriding = new();
|
||||
IEntityComponent[] components;
|
||||
public override void OnAwake()
|
||||
{
|
||||
components = GetComponentsInChildren<IEntityComponent>();
|
||||
isOverriding.AddListener(_isOverriding =>
|
||||
{
|
||||
components.ForEach(x =>
|
||||
{
|
||||
x.OnSetOverride(_isOverriding);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
42
Unity/Scripts/Entity/Core/IEntity.cs
Normal file
42
Unity/Scripts/Entity/Core/IEntity.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
/// <summary>Entity接口,用于复杂实体</summary>
|
||||
public interface IEntity : IGenericEvent<string>, IDatabase, IProcessor, ICallback
|
||||
{
|
||||
public static IEntity LocalPlayer;
|
||||
public static Action<IEntity> OnSpawnLocalPlayer;
|
||||
IEntityComponent[] entityComponents { get; set; }
|
||||
int Id { get; set; }
|
||||
string AddressablePath => nameof(IEntity);
|
||||
}
|
||||
public class IEntityReader : NetMessageReader<IEntity>
|
||||
{
|
||||
public override IEntity ReadBinary(BinaryReader reader)
|
||||
{
|
||||
var id = reader.ReadInt32();
|
||||
var path = reader.ReadString();
|
||||
var entity = EntitiesManager.GetOrAdd(id, _id => Create(id, path));
|
||||
return entity;
|
||||
}
|
||||
public override void WriteBinary(BinaryWriter writer, IEntity value)
|
||||
{
|
||||
writer.Write(value.Id);
|
||||
writer.Write(value.AddressablePath);
|
||||
}
|
||||
IEntity Create(int id, string path)
|
||||
{
|
||||
var entity = Addressables
|
||||
.LoadAssetAsync<GameObject>(path)
|
||||
.WaitForCompletion()
|
||||
.GetComponent<IEntity>();
|
||||
entity.Id = id;
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
}
|
21
Unity/Scripts/Entity/Editor/Editor.BITKit.Entity.asmdef
Normal file
21
Unity/Scripts/Entity/Editor/Editor.BITKit.Entity.asmdef
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "BITKit.Entity.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:a209c53514018594f9f482516f2a6781",
|
||||
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
|
||||
"GUID:30817c1a0e6d646d99c048fc403f5979"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [
|
||||
"UNITY_EDITOR",
|
||||
"MIRROR"
|
||||
],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
24
Unity/Scripts/Entity/Editor/EntityInspector.cs
Normal file
24
Unity/Scripts/Entity/Editor/EntityInspector.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
/* using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor.UIElements;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
[CanEditMultipleObjects]
|
||||
[CustomEditor(typeof(EntityComponent), true)]
|
||||
public class EntityComponentInspector : Editor
|
||||
{
|
||||
public override VisualElement CreateInspectorGUI()
|
||||
{
|
||||
VisualElement container = new();
|
||||
|
||||
container.Add(new Label("Entity"));
|
||||
|
||||
InspectorElement.FillDefaultInspector(container, serializedObject, this);
|
||||
return container;
|
||||
}
|
||||
}
|
||||
} */
|
Reference in New Issue
Block a user