This commit is contained in:
CortexCore
2023-10-24 23:38:22 +08:00
parent 2c4710bc5d
commit bd40165ade
152 changed files with 3681 additions and 1531 deletions

View File

@@ -5,10 +5,12 @@ namespace BITKit
{
public class AnimatorHelper : MonoBehaviour
{
public Transform root;
void OnAnimatorMove()
[SerializeField] private Transform root;
private void OnAnimatorMove()
{
root?.SendMessage(nameof(OnAnimatorMove));
if (root is not null)
root.SendMessage(nameof(OnAnimatorMove));
}
}
}

View File

@@ -10,17 +10,12 @@ namespace BITKit.Animations
{
public class UnityAnimator : MonoBehaviour, IAnimator
{
[System.Serializable]
public record AnimatorPlayEvent
{
public string stateName;
public int index;
}
[System.Serializable]
[Serializable]
public class AnimatorLayerInfo
{
public string stateName;
public string fullStateName;
internal string entryName;
public AnimatorStateInfo currentState = new();
public event Action<string> onStateEnter;
public event Action<string> onStateExit;
@@ -33,6 +28,10 @@ namespace BITKit.Animations
onStateExit?.Invoke(name);
}
}
[Header(Constant.Header.Settings)]
[SerializeField] private bool debug;
[Header(Constant.Header.Components)]
public Animator animator;
public AnimatorLayerInfo this[int index]
@@ -54,13 +53,27 @@ namespace BITKit.Animations
return layerInfos[index];
}
}
public List<AnimatorLayerInfo> layerInfos = new();
[SerializeField] private List<AnimatorLayerInfo> layerInfos = new();
[Header(Constant.Header.InternalVariables)]
private readonly Dictionary<string,UnityAnimatorStateInfo> _registryStates=new ();
private void OnEnable()
{
animator.enabled = true;
}
private void OnDisable()
{
animator.enabled = false;
foreach (var x in layerInfos)
{
x.entryName = null;
}
}
public void CrossFade(string name, float duration, int index = 0, float normalizedTimeOffset = 0)
{
animator.CrossFade(name, duration, index);
name = name.Replace(".", "_");
animator.CrossFade(name, duration, index, normalizedTimeOffset);
}
public void Play(string name, int index = -1, float normalizedTimeOffset = 0)
@@ -82,17 +95,29 @@ namespace BITKit.Animations
public void OnStateEnter(int index, string name)
{
if (debug)
{
BIT4Log.Log<UnityAnimator>($"OnEntry:{name}");
}
this[index].fullStateName = name;
foreach (var item in name.Split("."))
{
name = item;
break;
}
this[index].stateName = name;
this[index].stateName = this[index].entryName = name;
this[index].OnStateEnter(name);
}
public void OnStateExit(int index, string name)
{
if (string.IsNullOrEmpty(this[index].entryName))
{
return;
}
if (debug)
{
BIT4Log.Log<UnityAnimator>($"OnExit:{name}");
}
this[index].OnStateExit(name);
}
public float3 GetRootVelocity()

View File

@@ -12,12 +12,27 @@ namespace BITKit
HalfOpen,
Locked,
}
public Transform root;
public Vector3 openEuler;
public Vector3 closeEuler;
public State state;
[SerializeField] private bool allowPhysics = true;
[SerializeField] private Rigidbody root;
[SerializeField] private Vector3 openEuler;
[SerializeField] private Vector3 closeEuler;
[SerializeField] private State state;
[SerializeField] private Collider[] ignoreColliders;
private void Start()
{
var selfColliders = GetComponentsInChildren<Collider>(true);
var parentCollider = GetComponentInParent<Collider>(true);
foreach (var self in selfColliders)
{
foreach (var ignore in ignoreColliders)
{
Physics.IgnoreCollision(self, ignore, true);
}
if (parentCollider is not null)
Physics.IgnoreCollision(self, parentCollider, true);
}
Set();
}
public void Execute()
@@ -34,11 +49,15 @@ namespace BITKit
break;
}
}
public void Set(bool isClosed)
{
state = isClosed ? State.Close : State.Open;
root.localEulerAngles = isClosed ? closeEuler : openEuler;
root.transform.localEulerAngles = isClosed ? closeEuler : openEuler;
if (allowPhysics)
root.isKinematic = isClosed;
}
private void Set()
{
var isClosed = state switch

View File

@@ -6,12 +6,12 @@ namespace BITKit.Entities
public sealed 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;
[SerializeField] private Animator[] animators;
[SerializeReference, SubclassSelector] private References[] animationKeyWords;
[SerializeReference, SubclassSelector] private References _rootVelocity;
[SerializeReference, SubclassSelector] private References[] boolParameters;
[SerializeReference, SubclassSelector] private References[] floatParameters;
private List<string> keyWords;
public override void OnAwake()
{
keyWords = animationKeyWords.Select(x => x.Get()).ToList();

View File

@@ -4,7 +4,6 @@
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
"GUID:a45ea9d98164db34f9c3c360d07b4ab2",
"GUID:f822dbf6fdfd4a5469cccaa2e4eed3b6",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:7efac18f239530141802fb139776f333"

View File

@@ -62,6 +62,9 @@ namespace BITKit.Entities
/// </summary>
public interface IEntityMovement:IStateMachine<IEntityMovementState>
{
Vector3 Position { get; set; }
Quaternion Rotation { get; set; }
Vector3 Forward { get; }
/// <summary>
/// 视角中心,通常是摄像机的位置
/// </summary>

View File

@@ -6,14 +6,47 @@ using UnityEngine.InputSystem;
namespace BITKit
{
public class NavAgentMovement: StateBasedComponent<IEntityMovementState>,IEntityMovement,IHealthCallback
public class NavAgentMovement: StateBasedComponent<IEntityMovementState>,IEntityMovement
{
#region
[SerializeField] private NavMeshAgent agent;
[SerializeField] private new Rigidbody rigidbody;
[Inject] private IHealth _health;
[Inject(true)] private IEntityOverride _override;
#endregion
public override void OnStart()
{
if (_override is not null)
{
_override.OnOverride += (x) =>
{
agent.isStopped = x;
};
}
_health.OnSetAlive += OnSetAlive;
_health.OnSetHealthPoint += OnSetHP;
}
#region
public Vector3 Position
{
get=>transform.position;
set=>transform.position=value;
}
public Quaternion Rotation
{
get=>transform.rotation;
set=>transform.rotation=value;
}
public Vector3 Forward => transform.forward;
public Vector3 ViewCenter { get; set; }
public Quaternion ViewRotation { get; set; }
public Vector3 LocomotionBasedVelocity { get; private set; }
@@ -34,6 +67,9 @@ namespace BITKit
GroundVelocity = _groundVelocity;
IsGrounded = agent.isOnOffMeshLink is false;
entity.Set<bool>("IsMoving",Velocity.sqrMagnitude>=0.16f);
entity.Set<float>("SqrMagnitude",Velocity.sqrMagnitude);
if (!isDead) return;
recordPosition = rigidbody.position;

View File

@@ -0,0 +1,52 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
namespace BITKit.Entities.Movement
{
public class RigidbodyBasedMovement : StateBasedComponent<IEntityMovementState>,IEntityMovement
{
[SerializeField] private new Rigidbody rigidbody;
[SerializeField] private Animator animator;
public Vector3 Position { get; set; }
public Quaternion Rotation { get; set; }
public Vector3 Forward { get; }
public Vector3 ViewCenter { get; }
public Quaternion ViewRotation { get; }
public Vector3 LocomotionBasedVelocity { get; }
public Vector3 Velocity { get;private set; }
public Vector3 GroundVelocity { get; }
public Vector3 AngularVelocity { get; }
public bool IsGrounded { get; }
public void SyncMovement(Vector3 velocity, Vector3 position, Quaternion rotation, bool isGrounded)
{
}
public void Movement(Vector3 relativeVector)
{
}
public void Movement(InputAction.CallbackContext context)
{
}
public void ExecuteCommand<T>(T command = default)
{
}
public event Action<object> OnCommand;
public override void OnFixedUpdate(float deltaTime)
{
rigidbody.MovePosition(rigidbody.position + Velocity * deltaTime
);
}
private void OnAnimatorMove()
{
Velocity = animator.velocity;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 08c479c2ef329e94aaac1cc920eb8ce1
guid: 9db04e8e30068ef40b2afa725bdc239d
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,78 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BITKit;
using BITKit.Animations;
using BITKit.StateMachine;
using System.Linq;
using BITFALL.Player.Equip;
using Cinemachine;
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> : StateBasedMonoBehaviour<T>, 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() {Initialize();}
public virtual void OnStart() { }
public virtual void OnUpdate(float deltaTime) { }
public virtual void PlayAudio(string eventName) { }
public virtual void EquipEvent(string eventName){}
public virtual void AnimationEvent(string eventName){}
}
[CustomType(typeof(IEquipService))]
public class EntityEquipment : EntityComponent,IEquipService
{
public EntryGroup<IEquipBase> equips = new();
public IOptional<float> Zoom { get; } = new Optional<float>(){Value = 1};
public float InitialFov;
[SerializeField] private CinemachineVirtualCamera virtualCamera;
protected IEquipBase entryComplete;
private PlayerConfig playerConfig;
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 (equips.TryGetEntried(out entryComplete))
{
entryComplete.OnUpdate(deltaTime);
}
var current = virtualCamera.m_Lens.FieldOfView;
current= Mathf.Lerp(current,Zoom.Allow ? InitialFov / Zoom.Value : PlayerConfig.Singleton.Fov , deltaTime * 5);
current = Mathf.Clamp(current, 10, PlayerConfig.Singleton.Fov);
virtualCamera.m_Lens.FieldOfView = current;
}
}
}

View File

@@ -6,17 +6,19 @@ using UnityEngine;
namespace BITKit
{
public class AutoHealComponent : EntityComponent,IHealthCallback,IDamageCallback
public class AutoHealComponent : EntityComponent,IDamageCallback
{
[SerializeField] private IntervalUpdate healDelayInterval;
[SerializeField] private IntervalUpdate healInterval;
[SerializeField] private int healIncrement;
private readonly ValidHandle allowHeal = new();
[Inject]
private IHealth _health;
public override void Initialize(IEntity _entity)
{
base.Initialize(_entity);
_entity.RegisterCallback<IHealthCallback>(this);
_health.OnSetAlive += OnSetAlive;
_health.OnSetHealthPoint += OnSetHP;
_entity.RegisterCallback<IDamageCallback>(this);
}

View File

@@ -5,13 +5,15 @@ using UnityEngine;
namespace BITKit
{
public class AutoRespawnComponent : EntityComponent,IHealthCallback,IAction
public class AutoRespawnComponent : EntityComponent,IAction
{
[SerializeField] private IntervalUpdate respawnInterval;
private bool requestRespawn;
[Inject] private IHealth _health;
public override void OnAwake()
{
entity.RegisterCallback<IHealthCallback>(this);
_health.OnSetAlive += OnSetAlive;
_health.OnSetHealthPoint += OnSetHP;
}
public override void OnUpdate(float deltaTime)

View File

@@ -61,12 +61,13 @@ namespace BITKit.Entities
}
public record DamageMessage
{
public IEntity initiator;
public IEntity target;
public int damage;
public IDamagable hit;
public Location location;
public IDamageType damageType;
public IEntity Initiator;
public IEntity Target;
public bool RawDamage;
public int Damage;
public IDamagable Hit;
public Location Location;
public IDamageType DamageType;
}
public interface IDamageCallback
{
@@ -92,13 +93,13 @@ namespace BITKit.Entities
{
while (Messages.TryDequeue(out var damageMessage))
{
var unityEntity = (Entity)damageMessage.target;
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);
damageMessage.Initiator?.Invoke(damageMessage);
damageMessage.Target?.Invoke(damageMessage);
foreach (var x in damageMessage.target?.GetCallbacks<IDamageCallback>()!)
foreach (var x in damageMessage.Target?.GetCallbacks<IDamageCallback>()!)
{
x.OnGetDamage(damageMessage);
}

View File

@@ -1,40 +1,12 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using UnityEngine;
using UnityEngine.Events;
namespace BITKit.Entities
{
public interface IHealthCallback
{
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
{
/// <summary>
@@ -48,7 +20,7 @@ namespace BITKit.Entities
/// <summary>
/// 当受到伤害时的回调
/// </summary>
public event Func<DamageMessage,int,int> OnDamage;
public event Func<DamageMessage,int,int> OnDamageFactory;
int HealthPoint { get; set; }
int MaxHealthPoint { get; set; }
bool IsAlive { get; }
@@ -60,13 +32,9 @@ namespace BITKit.Entities
[SerializeField] private int healthPoint = 100;
[SerializeField] private int maxHealthPoint = 100;
[Header(Constant.Header.Providers)] [SerializeField, SerializeReference, SubclassSelector]
[Obsolete]
private IHealthCallback[] additiveCallback;
public event Action<int> OnSetHealthPoint;
public event Action<bool> OnSetAlive;
public event Func<DamageMessage,int, int> OnDamage;
public event Func<DamageMessage,int, int> OnDamageFactory;
public int HealthPoint
{
@@ -99,25 +67,12 @@ namespace BITKit.Entities
{
OnSetAliveInternal(IsAlive = _isAlive);
}
foreach (var x in entity.GetCallbacks<IHealthCallback>())
{
x.OnSetHP(newHP);
}
OnSetHealthPoint?.Invoke(newHP);
}
private void OnSetAliveInternal(bool alive)
{
IsAlive = alive;
foreach (var x in entity.GetCallbacks<IHealthCallback>())
{
x.OnSetAlive(alive);
}
// foreach (var x in additiveCallback)
// {
// x.OnSetAlive(alive);
// }
OnSetAlive?.Invoke(alive);
}
@@ -128,11 +83,13 @@ namespace BITKit.Entities
private void OnGetDamage(DamageMessage damageMessage)
{
if (damageMessage.target != entity) return;
var damage = damageMessage.damage;
foreach (var x in OnDamage.CastAsFunc())
if (damageMessage.Target != entity) return;
if (IsAlive is false) return;
var damage = damageMessage.Damage;
foreach (var x in OnDamageFactory.CastAsFunc().Reverse())
{
damage = x.Invoke(damageMessage,damage);
damage = x.Invoke(damageMessage,damage);
if (damage <= 0) break;
}
AddHP(-damage);
}

View File

@@ -21,7 +21,7 @@ namespace BITKit.Entities
}
private void OnGetDamage(DamageMessage obj)
{
if (obj.target != entity) return;
if (obj.Target != entity) return;
DamageMessages.Enqueue(obj);
onGetDamage?.Invoke(obj);
foreach (var x in callbacks)

View File

@@ -12,7 +12,7 @@ namespace BITKit.Entities
{
entity.Invoke(message);
}
public Rigidbody m_rigidbody;
[SerializeField]private Rigidbody m_rigidbody;
}
}

View File

@@ -9,7 +9,8 @@
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:508392158bd966c4d9c21e19661a441d"
"GUID:508392158bd966c4d9c21e19661a441d",
"GUID:7efac18f239530141802fb139776f333"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -1,10 +1,13 @@
using System;
using BITKit.Selection;
using BITKit.Sensors;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Interactions;
namespace BITKit.Entities.Player
{
public class EntityInteractive : EntityPlayerComponent
[CustomType(typeof(ISelector))]
public class EntityInteractive : EntityPlayerComponent,ISelector
{
[Header(Constant.Header.Settings)]
[SerializeReference, SubclassSelector] private ISensor sensor;
@@ -12,9 +15,25 @@ namespace BITKit.Entities.Player
[Header(Constant.Header.InternalVariables)]
private ISelectable selected;
private IntervalUpdate cd = new(0.08f);
[Inject]
private IHealth _health;
[Inject]
private InputActionGroup _inputActionReference;
public override void OnStart()
{
_health.OnSetAlive += OnSetAlive;
}
private void OnSetAlive(bool obj)
{
TryDeSelected();
}
public override void OnUpdate(float deltaTime)
{
if (sensor.Get().TryGetAny(x=>x.TryGetComponentAny<ISelectable>(out _),out var detected))
//if (sensor.Get().TryGetAny(x=>x.TryGetComponentAny<ISelectable>(out _),out var detected))
if (sensor.Get().TryGetAny(x=>x.GetComponentInParent<ISelectable>() is not null,out var detected))
{
if (detected.TryGetComponentAny<ISelectable>(out var _detected))
{
@@ -44,34 +63,44 @@ namespace BITKit.Entities.Player
{
if (selected is null) return;
selected.SetSelectionState(SelectionState.None);
foreach (var x in entity.GetCallbacks<ISelectableCallback>())
{
x.OnInactive(selected);
}
OnInactive?.Invoke(selected);
selected = null;
}
private void Detected(ISelectable detected)
{
selected = detected;
detected.SetSelectionState(SelectionState.Hover);
foreach (var x in entity.GetCallbacks<ISelectableCallback>())
{
x.OnHover(selected);
}
OnSelected?.Invoke(selected);
}
public void Interactive(InputAction.CallbackContext context)
{
if (context.interaction is not PressInteraction || !context.performed || cd.AllowUpdate is false) return;
if (context.interaction is not PressInteraction || !context.performed ) return;
if (cd.AllowUpdate is false) return;
var _selected = selected;
if (_selected is not MonoBehaviour monoBehaviour) return;
if (monoBehaviour.TryGetComponentAny<IAction>(out var action))
{
action.Execute();
}
foreach (var x in entity.GetCallbacks<ISelectableCallback>())
{
x.OnActive(_selected);
}
selected.SetSelectionState(SelectionState.Active);
OnActive?.Invoke(selected);
}
public bool TryGetCurrentSelectable(out ISelectable selectable)
{
selectable = selected;
return selectable != null;
}
public event Action<ISelectable> OnNone;
public event Action<ISelectable> OnHover;
public event Action<ISelectable> OnActive;
public event Action<ISelectable> OnInactive;
public event Action<ISelectable> OnFocus;
public event Action<ISelectable> OnSelected;
public event Action<ISelectable> OnEnabled;
public event Action<ISelectable> OnChecked;
public event Action<ISelectable> OnRoot;
}
}

View File

@@ -1,36 +0,0 @@
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)
{
}
}
}

View File

@@ -8,19 +8,23 @@ using UnityEngine;
namespace BITKit.Entities
{
[CustomType(typeof(IEntityPhysics))]
public class EntityPhysics : EntityComponent,IEntityPhysics, IHealthCallback
public class EntityPhysics : EntityComponent,IEntityPhysics
{
[SerializeField] private Animator animator;
[SerializeField] private Rigidbody[] rigidbodies;
[SerializeField] private Collider[] ragdollColliders;
[SerializeField] private Joint joint;
[SerializeField] private new Rigidbody rigidbody;
private CancellationToken _cancellationToken;
[Inject]
private IHealth _health;
public override void OnAwake()
{
entity.RegisterCallback<IHealthCallback>(this);
_health.OnSetAlive += OnSetAlive;
_health.OnSetHealthPoint += OnSetHP;
_cancellationToken = entity.Get<CancellationToken>();
}
async void IHealthCallback.OnSetAlive(bool alive)
private async void OnSetAlive(bool alive)
{
IsPhysics = !alive;
if (animator)
@@ -36,6 +40,11 @@ namespace BITKit.Entities
{
}
if (alive is false && joint is not null)
{
Destroy(joint);
}
}
public void OnSetHP(int hp)

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: de6a534eab93cbd4cacc9e47267c621b
guid: c570575d2e948724b980ea76eeca3259
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,20 @@
{
"name": "BITKit.Entities.Slot.Runtime",
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
"GUID:f32d23892f67f544299b53ae07475659",
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -1,7 +1,6 @@
fileFormatVersion: 2
guid: 3614fcbb2ebe14e418eadf82d1c67870
folderAsset: yes
DefaultImporter:
guid: e4e97feeabe888f4a8134328a497d6fa
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 632d0b190624f7f46971923e4fedffcb
guid: bd5ade15e3c249d4da89ea45637eaefb
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,16 @@
{
"name": "BITKit.Entities.Slot",
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": true
}

View File

@@ -1,7 +1,6 @@
fileFormatVersion: 2
guid: e8173f883ff93344db922487c65da5fa
folderAsset: yes
DefaultImporter:
guid: f32d23892f67f544299b53ae07475659
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:

View File

@@ -0,0 +1,10 @@
using System.Collections;
using System.Collections.Generic;
namespace BITKit.Entities.Slot
{
public interface IEntitySlot<T> where T : class
{
IDictionary<string,T> Slots { get; }
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 13003171a12d81c4eaee9c516471992a
guid: 6e62578e406f81744b5c6aad418e8783
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,15 @@
using System.Collections;
using System.Collections.Generic;
using AYellowpaper.SerializedCollections;
using UnityEngine;
namespace BITKit.Entities.Slot
{
[CustomType(typeof(IEntitySlot<Transform>))]
public sealed class UnityEntitySlot : EntityComponent, IEntitySlot<Transform>
{
[SerializeField] private SerializedDictionary<string,Transform> dictionary = new();
public IDictionary<string, Transform> Slots => dictionary;
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 1e8903c9eaac98b4788b121973994a29
guid: 41ac7c707a2add04dacff9f74980edaa
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -28,10 +28,48 @@ namespace BITKit.Entities
}
IServiceProvider Core.Entites.IEntity.ServiceProvider=> throw new InvalidOperationException("Unity Entity can't register component");
public void Inject(object obj)
{
foreach (var fieldInfo in obj
.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(fieldInfo=>fieldInfo.GetCustomAttribute<InjectAttribute>() is not null))
{
var type = fieldInfo.FieldType;
var attribute = fieldInfo.GetCustomAttribute<InjectAttribute>();
var currentValue = fieldInfo.GetValue(obj);
try
{
switch (currentValue)
{
case null:
break;
case Core.Entites.IEntityComponent entityComponent:
if(entityComponent.Entity.Id == Id)
continue;
break;
case MonoBehaviour { destroyCancellationToken: { IsCancellationRequested: false } }:
continue;
case not null:
continue;
}
}
catch (MissingReferenceException){}
if(genericEvent.TryGetObjectDirect(type.FullName,out var value))
{
fieldInfo.SetValue(obj,value);
}
else if(attribute?.CanBeNull is false)
{
BIT4Log.Warning<Entity>($"{name}未找到{type.FullName}");
BIT4Log.Warning<Entity>(genericEvent.GetDiagnostics());
}
}
}
private CancellationToken _cancellationToken;
private bool isInitialized;
private Core.Entites.IEntityComponent[] _components => entityComponents;
private Core.Entites.IEntityComponent[] _components => entityComponents.Cast<Core.Entites.IEntityComponent>().ToArray();
private void Awake()
{
@@ -44,39 +82,41 @@ namespace BITKit.Entities
}
private void Start()
{
foreach (var x in entityComponents)
try
{
foreach (var att in x.GetType().GetCustomAttributes<CustomTypeAttribute>())
var monoBehaviours = GetComponentsInChildren<MonoBehaviour>(true);
foreach (var x in monoBehaviours)
{
genericEvent.Set(att.Type,x);
genericEvent.Set(att.Type.FullName, x);
genericEvent.SetDirect(att.Type.FullName,x);
foreach (var att in x
//.GetCustomAttributes<CustomTypeAttribute>()
.GetType()
//.GetCustomAttributes<CustomTypeAttribute>()
.GetCustomAttributes()
.OfType<CustomTypeAttribute>()
)
{
genericEvent.Set(att.Type,x);
genericEvent.Set(att.Type.FullName, x);
genericEvent.SetDirect(att.Type.FullName,x);
}
genericEvent.Set(x.GetType(),x);
}
}
foreach (var x in GetComponentsInChildren<MonoBehaviour>(true))
{
foreach (var fieldInfo in x
.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(fieldInfo=>fieldInfo.GetCustomAttribute<InjectAttribute>() is not null))
foreach (var x in monoBehaviours)
{
var type = fieldInfo.FieldType;
if(genericEvent.TryGetObjectDirect(type.FullName,out var value))
{
fieldInfo.SetValue(x,value);
}
else
{
BIT4Log.Warning<Entity>($"{name}未找到{type.FullName}");
BIT4Log.Warning<Entity>(genericEvent.GetDiagnostics());
}
Inject(x);
}
}
entityComponents.ForEach(x => x.Initialize(this));
entityComponents.ForEach(x => x.Initialize(this));
entityComponents.ForEach(x => x.OnAwake());
entityComponents.ForEach(x => x.OnStart());
isInitialized = true;
entityComponents.ForEach(x => x.OnAwake());
entityComponents.ForEach(x => x.OnStart());
isInitialized = true;
}
catch (Exception e)
{
Debug.LogWarning(name);
Debug.LogException(e);
}
}
private void OnDestroy()
{

View File

@@ -18,8 +18,14 @@ namespace BITKit.Entities
public abstract class EntityComponent : MonoBehaviour, IEntityComponent
{
public IEntity entity { get; private set; }
protected Transform Transform { get; private set; }
private IEntity mEntity;
public virtual void Initialize(IEntity _entity) { entity = _entity; }
public virtual void Initialize(IEntity _entity)
{
Transform = transform;
entity = _entity;
Entity = _entity;
}
public virtual void OnAwake() { }
public virtual void OnStart() { }
public virtual void OnUpdate(float deltaTime) { }

View File

@@ -9,17 +9,22 @@ namespace BITKit.Entities
bool IsOvering { get; }
void AddOverride(object key);
void RemoveOverride(object key);
event Action<bool> OnOverride;
}
public interface IEntityOverrideCallback
{
void OnEntryOverride(bool @override);
}
[CustomType(typeof(IEntityOverride))]
public class EntityOverride : EntityComponent,IEntityOverride
{
[SerializeField,ReadOnly] private bool isOvering;
public bool IsOvering => _allowOverrideHandle;
private readonly ValidHandle _allowOverrideHandle = new();
public void AddOverride(object key) => _allowOverrideHandle.AddElement(key);
public void RemoveOverride(object key)=>_allowOverrideHandle.RemoveElement(key);
public event Action<bool> OnOverride;
public override void Initialize(IEntity _entity)
{
base.Initialize(_entity);
@@ -32,10 +37,8 @@ namespace BITKit.Entities
}
private void Override(bool @override)
{
foreach (var x in entity.GetCallbacks<IEntityOverrideCallback>())
{
x.OnEntryOverride(@override);
}
OnOverride?.Invoke(@override);
isOvering=@override;
}
}
}

View File

@@ -12,11 +12,12 @@ namespace BITKit.Entities.Player
public abstract class StateBasedPlayerComponent<T> : EntityPlayerComponent,IStateMachine<T> where T : IState
{
[SerializeField] private MonoStateMachine<T> stateMachine;
public override void Initialize(IEntity _entity)
public override void OnAwake()
{
base.Initialize(_entity);
stateMachine?.Initialize();
base.OnAwake();
}
public bool Enabled
{
get => stateMachine.Enabled;

View File

@@ -4,8 +4,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using UnityEditor.UIElements;
#if UNITY_EDITOR
using UnityEditor.UIElements;
using Cysharp.Threading.Tasks;
using UnityEditor;
#endif
@@ -30,14 +30,24 @@ namespace BITKit.Events
{
foreach (var x in Targets)
{
var method =x.Target.GetType().GetMethod(x.MethodName);
var methodName = x.MethodName;
var target = x.Target;
var split = methodName.Split('/');
if (x.Target is GameObject gameObject&& split.Length is 2 && BITSharp.TryGetTypeFromFullName(split[0],out var type) && gameObject.TryGetComponent(type,out var _target))
{
target = _target;
methodName = split[1];
}
var method =target.GetType().GetMethod(methodName);
try
{
method?.Invoke(x.Target, objects);
method?.Invoke(target, objects);
}
catch (TargetParameterCountException e)
{
Debug.LogWarning(string.Join(",",method?.GetParameters().Select(x=>x.Name)));
BIT4Log.Log<UnityEvent>(string.Join(",",method?.GetParameters().Select(x=>x.Name)));
throw;
}
}
@@ -114,14 +124,45 @@ namespace BITKit.Events
if (x.Target is not null)
{
field.choices = x.Target
.GetType()
.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(x=>x.IsSpecialName is false)
.Where(x=>x.GetCustomAttribute<ObsoleteAttribute>() is null)
.Select(x => x.Name)
//.Where(x=>_unityMethodNames.Contains(x) is false)
.ToList();
switch (x.Target)
{
case GameObject gameObject:
var methodNames = new List<string>();
foreach (var mono in gameObject.GetComponents<MonoBehaviour>())
{
foreach (var methodInfo in mono.GetComponents<MonoBehaviour>().Cast<object>().Append(gameObject)
.SelectMany(_mono => _mono
.GetType()
.GetMethods(BindingFlags.Instance | BindingFlags.Public |
BindingFlags.NonPublic))
.Where(info =>info.IsSpecialName is false && info.GetCustomAttribute<ObsoleteAttribute>() is null)
)
{
methodNames.Add($"{mono.GetType().FullName}/{methodInfo.Name}");
}
}
foreach (var VARIABLE in gameObject
.GetType()
.GetMethods()
.Where(info =>info.IsSpecialName is false && info.GetCustomAttribute<ObsoleteAttribute>() is null)
)
{
methodNames.Add(VARIABLE.Name);
}
field.choices = methodNames;
break;
default:
field.choices = x.Target
.GetType()
.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(x=>x.IsSpecialName is false)
.Where(x=>x.GetCustomAttribute<ObsoleteAttribute>() is null)
.Select(x => $"{x.Name}")
//.Where(x=>_unityMethodNames.Contains(x) is false)
.ToList();
break;
}
}

View File

@@ -57,17 +57,16 @@ namespace BITKit
private void Init()
{
if (allowGlobalActivation)
BITInputSystem.AllowInput.AddListener(Listen);
allowInput.AddListener(Allow);
BITInputSystem.AllowInput.AddListener(ListenGlobalInput);
allowInput.AddListener(AllowInput);
}
private void Listen(bool allowInput)
private void ListenGlobalInput(bool allowInput)
{
this.allowInput.SetElements(lockFile, allowInput);
this.allowInput.SetDisableElements(lockFile, !allowInput);
}
private void Allow(bool allow)
private void AllowInput(bool allow)
{
foreach (var action in actions)
{
@@ -80,7 +79,6 @@ namespace BITKit
action.Disable();
}
}
isEnabled = allow;
}

View File

@@ -1,28 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
public abstract class Mono : MonoBehaviour, IMonoProxy
{
protected virtual void Awake()
{
}
protected virtual void Start()
{
}
protected virtual void Update()
{
}
protected virtual void FixedUpdate()
{
}
protected virtual void LateUpdate()
{
}
protected virtual void OnDestroy()
{
}
}
}

View File

@@ -1,40 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace BITKit
{
public class MonoEvents : Mono
{
public UnityEvent OnAwake = new();
public UnityEvent OnStart = new();
public UnityEvent<float> OnUpdate = new();
public UnityEvent<float> OnFixexUpdate = new();
public UnityEvent<float> OnLateUpdate = new();
public UnityEvent OnDestroyComponent = new();
protected override void Awake()
{
OnAwake.Invoke();
}
protected override void Start()
{
OnStart.Invoke();
}
protected override void Update()
{
OnUpdate.Invoke(Time.deltaTime);
}
protected override void FixedUpdate()
{
OnFixexUpdate.Invoke(Time.deltaTime);
}
protected override void LateUpdate()
{
OnLateUpdate.Invoke(Time.deltaTime);
}
protected override void OnDestroy()
{
OnDestroyComponent.Invoke();
}
}
}

View File

@@ -9,7 +9,8 @@ namespace BITKit
public abstract class StateBasedMonoBehaviour<T> : MonoBehaviour, IStateMachine<T> where T : IState
{
[SerializeField] private MonoStateMachine<T> stateMachine;
protected Transform Transform => _transform ? _transform : _transform = transform;
private Transform _transform;
public bool Enabled
{
get => stateMachine.Enabled;

View File

@@ -27,7 +27,10 @@ namespace BITKit
break;
}
vector3 = collider.ClosestPoint(root.position + Vector3.up);
return vector3.y == collider.bounds.center.y + collider.bounds.extents.y;
var top = collider.bounds.center + collider.bounds.extents;
return Mathf.Abs(vector3.y - top.y) <0.16f;
//return vector3.y >= collider.bounds.center.y + collider.bounds.extents.y;
//return true;
}
return false;
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MyNamespace
{
public class JointBasedSync : MonoBehaviour
{
[SerializeField] private ConfigurableJoint joint;
[SerializeField] private Transform animate;
private Quaternion _initialRotation;
private void Start()
{
_initialRotation = joint.transform.localRotation;
}
private void FixedUpdate()
{
//joint.targetPosition = animate.localPosition;
joint.targetRotation = Quaternion.Inverse(animate.localRotation) * _initialRotation;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: d61f8d5d7b83b1941831e20da974aa54
guid: f6fe23fca67cb7346a3c423d97c9e101
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using BITKit.Core.Tuple;
using UnityEngine;
namespace BITKit.Physics
@@ -19,6 +20,10 @@ namespace BITKit.Physics
[SerializeField] private float positionSpring;
[SerializeField] private float positionDamper;
[SerializeField] private float maximumForce;
[SerializeField] private Optional<UnityTuple<Rigidbody, Transform>> rootSync;
[SerializeField] private Optional<ConfigurableJointMotion> overrideMotion;
[SerializeField] private Optional<ConfigurableJointMotion> overrideAngularMotion;
private void Start()
{
@@ -33,16 +38,46 @@ namespace BITKit.Physics
var drive = new JointDrive
{
positionDamper = positionDamper,
positionSpring = positionSpring,
positionSpring =Mathf.Lerp(0,positionSpring,Blend),
maximumForce = maximumForce,
};
foreach (var jointConfigure in jointConfigures)
{
jointConfigure.joint.angularXDrive = drive;
jointConfigure.joint.angularYZDrive = drive;
jointConfigure.joint.targetRotation = Quaternion.Inverse(jointConfigure.animate.localRotation) *
jointConfigure.InitialRotation;
// jointConfigure.joint.targetRotation =
// Quaternion.Lerp(
// Quaternion.identity,
// Quaternion.Inverse(jointConfigure.animate.localRotation) * jointConfigure.InitialRotation,
// Blend
// );
jointConfigure.joint.targetRotation = Quaternion.Inverse(jointConfigure.animate.localRotation) *
jointConfigure.InitialRotation;
jointConfigure.joint.targetPosition = jointConfigure.animate.localPosition;
if (overrideAngularMotion.Allow)
{
jointConfigure.joint.angularXMotion = overrideAngularMotion.Value;
jointConfigure.joint.angularYMotion = overrideAngularMotion.Value;
jointConfigure.joint.angularZMotion = overrideAngularMotion.Value;
}
if (overrideMotion.Allow)
{
jointConfigure.joint.xMotion = overrideMotion.Value;
jointConfigure.joint.yMotion = overrideMotion.Value;
jointConfigure.joint.zMotion = overrideMotion.Value;
}
}
if (rootSync.Allow)
{
var root = rootSync.Value;
root.Item1.transform.localPosition = root.Item2.localPosition;
root.Item1.MoveRotation(root.Item2.rotation);
}
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@@ -9,8 +10,22 @@ namespace BITKit
public static async UniTask AddForceAtPositionAsync(this Rigidbody rigidbody, Vector3 force, Vector3 position,ForceMode forceMode=ForceMode.Force)
{
await UniTask.DelayFrame(8);
if (rigidbody is not null)
rigidbody.AddForceAtPosition(force, position,forceMode);
try
{
rigidbody.AddForceAtPosition(force, position,forceMode);
}
catch(MissingReferenceException){}
}
public static async void Explosion(Vector3 position,float radius,LayerMask layerMask,float force)
{
await UniTask.DelayFrame(8);
foreach (var x in UnityEngine.Physics.OverlapSphere(position,radius,layerMask))
{
if(x.attachedRigidbody is null)continue;
x.attachedRigidbody.AddExplosionForce(force,position,radius);
//Debug.Log(x);
}
}
}
}

View File

@@ -1,17 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RotaryHeart.Lib.SerializableDictionary;
using UnityEngine.Events;
namespace BITKit
{
public class SubSelectable : MonoBehaviour, ISelectable
{
Selectable root;
public Transform GetTransform() => root.GetTransform();
public void SetSelectionState(SelectionState state)
{
root.SetSelectionState(state);
}
}
}

View File

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

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@@ -17,17 +18,16 @@ namespace BITKit
}
public interface ISelectable
{
Transform GetTransform();
void SetSelectionState(SelectionState state);
}
public interface ISelectableCallback
{
void OnHover(ISelectable selectable);
void OnActive(ISelectable selectable);
void OnInactive(ISelectable selectable);
}
public interface ISelectableComponent
{
Transform Transform { get; }
void SetSelectionState(SelectionState state);
event Action OnNone;
event Action OnHover;
event Action OnActive;
event Action OnInactive;
event Action OnFocus;
event Action OnSelected;
event Action OnEnabled;
event Action OnChecked;
event Action OnRoot;
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit.Selection
{
public interface ISelector
{
bool TryGetCurrentSelectable(out ISelectable selectable);
event Action<ISelectable> OnNone;
event Action<ISelectable> OnHover;
event Action<ISelectable> OnActive;
event Action<ISelectable> OnInactive;
event Action<ISelectable> OnFocus;
event Action<ISelectable> OnSelected;
event Action<ISelectable> OnEnabled;
event Action<ISelectable> OnChecked;
event Action<ISelectable> OnRoot;
}
}

View File

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

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@@ -6,21 +7,53 @@ namespace BITKit
public class Selectable : MonoBehaviour, ISelectable
{
public Transform GetTransform() => transform;
ISelectableComponent[] components;
void Start()
private void Start()
{
components = GetComponentsInChildren<ISelectableComponent>(true);
foreach (var x in components)
{
x.SetSelectionState(0);
}
OnNone?.Invoke();
}
public Transform Transform => transform;
public void SetSelectionState(SelectionState state)
{
foreach (var x in components)
switch (state)
{
x.SetSelectionState(state);
case SelectionState.None:
OnNone?.Invoke();
break;
case SelectionState.Hover:
OnHover?.Invoke();
break;
case SelectionState.Active:
OnActive?.Invoke();
break;
case SelectionState.Inactive:
OnInactive?.Invoke();
break;
case SelectionState.Focus:
OnFocus?.Invoke();
break;
case SelectionState.Selected:
OnSelected?.Invoke();
break;
case SelectionState.Enabled:
OnEnabled?.Invoke();
break;
case SelectionState.Checked:
OnChecked?.Invoke();
break;
case SelectionState.Root:
OnRoot?.Invoke();
break;
}
}
public event Action OnNone;
public event Action OnHover;
public event Action OnActive;
public event Action OnInactive;
public event Action OnFocus;
public event Action OnSelected;
public event Action OnEnabled;
public event Action OnChecked;
public event Action OnRoot;
}
}

View File

@@ -1,59 +1,46 @@
using System;
using UnityEngine;
using UnityEngine.Events;
namespace BITKit
{
public class SelectableEvent : MonoBehaviour, ISelectableComponent
public class SelectableEvent : MonoBehaviour
{
[Header(nameof(SelectionState.None))]
[SerializeField] UnityEvent OnNone;
[SerializeField] private UnityEvent OnNone;
[Header(nameof(SelectionState.Hover))]
[SerializeField] UnityEvent OnHover;
[SerializeField]private UnityEvent OnHover;
[Header(nameof(SelectionState.Active))]
[SerializeField] UnityEvent OnActive;
[SerializeField]private UnityEvent OnActive;
[Header(nameof(SelectionState.Inactive))]
[SerializeField] UnityEvent OnInactive;
[SerializeField]private UnityEvent OnInactive;
[Header(nameof(SelectionState.Focus))]
[SerializeField] UnityEvent OnFocus;
[SerializeField]private UnityEvent OnFocus;
[Header(nameof(SelectionState.Selected))]
[SerializeField] UnityEvent OnSelected;
[SerializeField]private UnityEvent OnSelected;
[Header(nameof(SelectionState.Enabled))]
[SerializeField] UnityEvent OnEnabled;
[SerializeField]private UnityEvent OnEnabled;
[Header(nameof(SelectionState.Checked))]
[SerializeField] UnityEvent OnChecked;
[SerializeField]private UnityEvent OnChecked;
[Header(nameof(SelectionState.Root))]
[SerializeField] UnityEvent OnRoot;
public void SetSelectionState(SelectionState state)
[SerializeField]private UnityEvent OnRoot;
private void Start()
{
switch (state)
var selectable = GetComponent<ISelectable>();
if (selectable == null)
{
case SelectionState.None:
OnNone.Invoke();
break;
case SelectionState.Hover:
OnHover.Invoke();
break;
case SelectionState.Active:
OnActive.Invoke();
break;
case SelectionState.Inactive:
OnInactive.Invoke();
break;
case SelectionState.Focus:
OnFocus.Invoke();
break;
case SelectionState.Selected:
OnSelected.Invoke();
break;
case SelectionState.Enabled:
OnEnabled.Invoke();
break;
case SelectionState.Checked:
OnChecked.Invoke();
break;
case SelectionState.Root:
OnRoot.Invoke();
break;
Debug.LogError($"No {nameof(ISelectable)} component found on {gameObject.name}");
return;
}
selectable.OnNone += OnNone.Invoke;
selectable.OnHover += OnHover.Invoke;
selectable.OnActive += OnActive.Invoke;
selectable.OnInactive += OnInactive.Invoke;
selectable.OnFocus += OnFocus.Invoke;
selectable.OnSelected += OnSelected.Invoke;
selectable.OnEnabled += OnEnabled.Invoke;
selectable.OnChecked += OnChecked.Invoke;
selectable.OnRoot += OnRoot.Invoke;
}
}
}

View File

@@ -38,6 +38,32 @@ namespace BITKit.Sensors
/// <returns></returns>
UniTask Execute();
}
[Serializable]
public class UnitySensor : ISensor
{
[SerializeField] private GameObject gameObject;
private ISensor _sensorImplementation => gameObject.GetComponent<ISensor>();
public IEnumerable<Transform> Get()
{
return _sensorImplementation.Get();
}
public bool IsValid(Collider _collider)
{
return _sensorImplementation.IsValid(_collider);
}
public float GetDistance()
{
return _sensorImplementation.GetDistance();
}
public UniTask Execute()
{
return _sensorImplementation.Execute();
}
}
[System.Serializable]
public class SensorMonoProxy:ISensor
{

View File

@@ -80,8 +80,15 @@ namespace BITKit.Sensors
#if UNITY_EDITOR
private void OnDrawGizmosSelected()
{
if (CurrentTarget is null) return;
Gizmos.DrawLine(sensorTransform.position,CurrentTarget.position);
try
{
if (CurrentTarget is null || sensorTransform is null) return;
Gizmos.DrawLine(sensorTransform.position,CurrentTarget.position);
}
catch (UnassignedReferenceException)
{
}
}
#endif
}

View File

@@ -4,6 +4,7 @@ using System.Linq;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Pool;
using UnityEngine.UIElements;
#if UNITY_EDITOR
using UnityEditor;
@@ -60,7 +61,26 @@ namespace BITKit.Sensors
}
}
public IEnumerable<Transform> Get() => detected.Select(x => x.transform).ToArray();
public IEnumerable<Transform> Get()
{
try
{
return detected.Select(x => x.transform).ToArray();
}
catch (MissingReferenceException)
{
List<Transform> list = new();
foreach (var x in detected)
{
try
{
list.Add(x.transform);
}
catch (MissingReferenceException){}
}
return list.ToArray();
}
}
//public bool IsValid(Collider _collider) => ignores.Contains(_collider.gameObject) is false;
public bool IsValid(Collider _collider)
@@ -100,19 +120,43 @@ namespace BITKit.Sensors
{
if (IsValid(_collider) is false) return;
if (detected.Contains(_collider))continue;
onDetected.Invoke(_collider);
detected.Add(_collider);
}
while (triggerExitQueue.TryDequeue(out var _collider))
{
if (IsValid(_collider) is false) return;
onLost.Invoke(_collider);
detected.Remove(_collider);
}
diagnosisNextFrame = detected.Any(x =>x is not null &&x.enabled is false);
try
{
diagnosisNextFrame = detected.Any(x =>x is not null &&x.enabled is false);
}
catch (MissingReferenceException)
{
diagnosisNextFrame = true;
}
if (diagnosisNextFrame)
{
detected = detected.Where(x => x.enabled).ToList();
var list = ListPool<Collider>.Get();
foreach (var VARIABLE in detected)
{
try
{
list.Add(VARIABLE);
}
catch (MissingReferenceException e)
{
}
}
detected.Clear();
detected.AddRange(list);
ListPool<Collider>.Release(list);
diagnosisNextFrame = false;
}
}

View File

@@ -1,40 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
public interface IMonoProxy
{
}
public class MonoProxy : Mono
{
[SerializeReference, SubclassSelector] public IMonoProxy proxy;
BehaviorUpdater updater = new();
protected override void Awake()
{
updater.Init(proxy);
updater.OnAwake();
}
protected override void Start()
{
updater.OnStart();
}
protected override void Update()
{
updater.OnUpdate(Time.deltaTime);
}
protected override void FixedUpdate()
{
updater.OnFixedUpdate(Time.fixedDeltaTime);
}
protected override void LateUpdate()
{
updater.OnLateUpdate(Time.deltaTime);
}
protected override void OnDestroy()
{
updater.OnDestroy();
}
}
}

View File

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

View File

@@ -10,7 +10,7 @@ using UnityEngine.UIElements;
namespace BITKit.StateMachine
{
[Serializable]
public class MonoStateMachine<TState> : IStateMachine<TState>, IMonoProxy where TState : IState
public class MonoStateMachine<TState> : IStateMachine<TState> where TState : IState
{
public bool Enabled
{
@@ -34,9 +34,12 @@ namespace BITKit.StateMachine
[SerializeReference, SubclassSelector] public List<TState> states = new();
[SerializeField,ReadOnly] private string _currentStateName;
[SerializeField] private bool debug;
[SerializeField] private bool transitionOnNextFrame;
public IDictionary<Type, TState> StateDictionary { get; } = new Dictionary<Type, TState>();
private bool _enabled;
private bool _enabled = true;
private readonly DoubleBuffer<TState> _nextState = new();
protected bool cancelUpdateStateThisFrame;
public void Initialize()
{
foreach (var state in states)
@@ -52,8 +55,17 @@ namespace BITKit.StateMachine
}
public void UpdateState(float deltaTime)
{
if(transitionOnNextFrame && _nextState.TryGetRelease(out var nextState))
TransitionStateInternal(nextState);
if (Enabled)
CurrentState?.OnStateUpdate(deltaTime);
{
if (cancelUpdateStateThisFrame is false)
{
CurrentState?.OnStateUpdate(deltaTime);
}
cancelUpdateStateThisFrame = false;
}
}
public void DisposeState()
@@ -65,14 +77,31 @@ namespace BITKit.StateMachine
TransitionState(nextState);
}
public void TransitionState(TState newState)
{
if(transitionOnNextFrame)
_nextState.Release(newState);
else
{
TransitionStateInternal(newState);
cancelUpdateStateThisFrame = true;
}
}
private void TransitionStateInternal(TState newState)
{
if (newState.Equals(CurrentState)) return;
var oldState = CurrentState;
if (oldState is not null)
{
oldState.OnStateExit(oldState, newState);
oldState.Enabled = false;
}
if (debug)
{
BIT4Log.Log<MonoStateMachine<TState>>($"TransitionState from {_currentStateName} to {newState.GetType().Name}");
}
newState.OnStateEntry(oldState);
CurrentState = newState;
OnStateChanged?.Invoke(oldState, newState);

View File

@@ -27,7 +27,7 @@ namespace BITKit.UX
}
public void Set(int value)
{
float w = Mathf.Clamp((float)value / 100 * 100, 0f, 100f);
var w =Mathf.Clamp(value * 0.01f, 0f, 100f);
Set(w);
}
public async void Set(float value)

View File

@@ -9,7 +9,7 @@ namespace BITKit.UX
[Serializable]
public class UIToolkitPanelMonoProxy : UXPanelImplement
{
[SerializeField] private MonoBehaviour monoBehaviour;
protected override IUXPanel _iuxPanelImplementation => (IUXPanel)monoBehaviour;
[SerializeField] private GameObject monoBehaviour;
protected override IUXPanel service => monoBehaviour.GetComponent<IUXPanel>();
}
}

View File

@@ -24,6 +24,10 @@ namespace BITKit.UX
[SerializeField] private bool allowCursor;
[SerializeField] private bool allowInput;
[SerializeField] private bool autoEntry;
protected readonly InputActionGroup inputActionGroup = new()
{
allowGlobalActivation = false
};
public bool IsAnimate => isAnimate;
public bool IsValid => cancellationToken.IsCancellationRequested is false;
public string Index { get; private set; }
@@ -50,12 +54,14 @@ namespace BITKit.UX
{
OnEntryOrExit(true);
document.rootVisualElement.SetActive(true);
inputActionGroup.allowInput.AddElement(this);
OnEntry?.Invoke();
}
void IUXPanel.Exit()
{
if (IsValid is false) return;
OnEntryOrExit(false);
inputActionGroup.allowInput.RemoveElement(this);
try
{
document.rootVisualElement.SetActive(false);

View File

@@ -9,8 +9,6 @@ using System;
using UnityEditor;
using Editor = UnityEditor.Editor;
using UnityEditor.UIElements;
#else
using Editor=BITKit.Constant.EmetyClass;
#endif
namespace BITKit
{
@@ -18,13 +16,13 @@ namespace BITKit
{
}
#if UNITY_EDITOR
[CustomEditor(typeof(MonoBehaviour),true)]
public class MonoBehaviorInspector : BITInspector<MonoBehaviour>
{
}
#endif
public class BITEditorUtils
{
public const string InspectorPath = "Assets/BITKit/Unity/UX/BITInspector.uss";
@@ -52,7 +50,7 @@ namespace BITKit
}
public class BITInspector<T> : Editor
{
const string ussName = "BITInspector";
private const string ussName = "BITInspector";
public class VisualElementCreator
{
public static implicit operator VisualElement(VisualElementCreator self)
@@ -78,7 +76,16 @@ namespace BITKit
}
else
{
FillDefaultInspector();
try
{
FillDefaultInspector();
}
catch (Exception e)
{
Debug.LogException(e);
return base.CreateInspectorGUI();
}
return root;
}
}
@@ -120,12 +127,14 @@ namespace BITKit
}
protected void FillDefaultInspector()
{
root.root.Clear();
FillDefaultInspector(root, serializedObject, true);
}
protected static void FillDefaultInspector(VisualElement container, SerializedObject serializedObject, bool hideScript)
{
var property = serializedObject.GetIterator();
container.Clear();
var property = serializedObject.GetIterator();
if (!property.NextVisible(true)) return; // Expand first child.
do
{
@@ -133,8 +142,9 @@ namespace BITKit
{
continue;
}
var type = serializedObject.targetObject.GetType().GetField(property.name);
if ( type is not null && Attribute.IsDefined(type.FieldType, typeof(ReadOnlyAttribute)))
if (type is not null && Attribute.IsDefined(type.FieldType, typeof(ReadOnlyAttribute)))
{
container.Create<Label>().bindingPath = property.propertyPath;
}
@@ -148,6 +158,7 @@ namespace BITKit
{
field.SetEnabled(false);
}
container.Add(field);
}
// try
@@ -164,11 +175,7 @@ namespace BITKit
// {
// Debug.LogException(e);
// }
}
while (property.NextVisible(false));
} while (property.NextVisible(false));
foreach (var method in serializedObject.targetObject.GetType().GetMethods())
{

View File

@@ -512,6 +512,12 @@ namespace BITKit
}
public static partial class UIToolkitExtensions
{
public static VisualElement Create(this VisualElement self, VisualTreeAsset asset)
{
var clone = asset.CloneTree();
self.Add(clone);
return clone;
}
public static T Create<T>(this VisualElement self, string name = Constant.EmetyString) where T : VisualElement, new()
{
var element = new T();
@@ -522,6 +528,16 @@ namespace BITKit
self.Add(element);
return element;
}
public static T Create<T>(this VisualElement self,Func<VisualElement> createFactory, string name = Constant.EmetyString) where T : VisualElement, new()
{
var element = createFactory.Invoke();
if (string.IsNullOrEmpty(name) is false)
{
element.name = name;
}
self.Add(element);
return element as T;
}
public static bool GetActive(this VisualElement self) => self.style.display.value == DisplayStyle.Flex;
public static void SetActive(this VisualElement self, bool active)
{

View File

@@ -35,9 +35,10 @@ namespace BITKit
if (TryMatch(out var prefab, keyWords))
{
var pool = pools.Get(prefab.name);
var instance = pool.Get(prefab,transform);
var instance = pool.Get(prefab, transform);
instance.SetPositionAndRotation(location, location);
instance.forward = location.forward;
if (location.forward.sqrMagnitude is not 0)
instance.forward = location.forward;
return instance;
}
else

View File

@@ -2,12 +2,9 @@
"name": "BITKit.Vehicles",
"rootNamespace": "",
"references": [
"GUID:a209c53514018594f9f482516f2a6781",
"GUID:99a47d73d3ad3374b9d12c982228df71",
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:30817c1a0e6d646d99c048fc403f5979",
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
"GUID:14fe60d984bf9f84eac55c6ea033a8f4"
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0"
],
"includePlatforms": [],
"excludePlatforms": [],
@@ -15,9 +12,7 @@
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [
"MIRROR"
],
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -1,10 +1,11 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
using BITKit.Entities;
using BITKit.BITInputSystem;
using BITKit.Events;
using UnityEngine.InputSystem;
namespace BITKit.Vehicles
{
public enum WheelType
@@ -13,121 +14,115 @@ namespace BITKit.Vehicles
Motor,
Steel,
}
[System.Serializable] //代表串行化,添加该标记的目的在于,使类成员可以在属性面板中显示
[System.Serializable]
public class AxisInfo
{
public WheelCollider[] wheels;
public Transform[] wheelModels;
public WheelType wheelType;
}
public class Vehicle : NetworkInteractivable, BITController.IVehicleActions, IAnchor
public sealed class Vehicle : MonoBehaviour
{
[Header(Constant.Header.Settings)]
public float maxMotorTorque = 64;
public float maxSteeringAngle = 45;
public float brakeTorque;
[Header(Constant.Header.Settings)] public float maxMotorTorque = 64;
[SerializeField] private float maxSteeringAngle = 45;
[SerializeField] private float brakeTorque;
[SerializeField] private Optional<float> optionalVertical;
[SerializeField] private Optional<float> optionalHorizontal;
[SerializeField] private Optional<float> optionalUpRight;
[Header(Constant.Header.Components)]
public new Rigidbody rigidbody;
public Transform driveAnchor;
[SerializeField]
private new Rigidbody rigidbody;
[SerializeField] private Transform driveAnchor;
[Header(Constant.Header.Gameobjects)]
public List<AxisInfo> axisInfos = new();
[SerializeField] private List<AxisInfo> axisInfos = new();
[SerializeField] private Transform steeringWheel;
[Header(Constant.Header.Events)]
[SerializeField] private UnityEvent onHighSpeed;
[SerializeField] private UnityEvent OnEntryHighSpeed;
[SerializeField] private UnityEvent OnExitHighSpeed;
[Header(Constant.Header.InternalVariables)]
float vertical;
float horizontal;
bool isbraking;
NetworkIdentity driver;
BITController controller;
public override void Excute(NetworkIdentity identity, string action)
private float vertical;
private float horizontal;
private bool isBraking;
private readonly ValidHandle highSpeedHandle = new();
private IEntity _entity;
private void Start()
{
if (driver is null)
highSpeedHandle.AddListener(x =>
{
driver = identity;
controller.Vehicle.Enable();
controller.Vehicle.SetCallbacks(this);
}
else
{
if (driver == identity)
if (x)
{
driver = null;
OnEntryHighSpeed.Invoke();
}
controller.Vehicle.Disable();
}
else
{
OnExitHighSpeed.Invoke();
}
onHighSpeed.Invoke(x);
});
highSpeedHandle.Invoke();
}
public virtual void OnVertical(InputAction.CallbackContext context)
private void Update()
{
var torque = maxMotorTorque *(optionalVertical.Allow ? optionalVertical.Value : vertical);
var steel =maxSteeringAngle * (optionalHorizontal.Allow ? optionalHorizontal.Value : horizontal);
axisInfos.ForEach(x =>
{
switch (x.wheelType)
{
case WheelType.Motor:
if (isBraking)
{
x.wheels.ForEach(wheelCollider => { wheelCollider.brakeTorque = brakeTorque; });
}
else
{
x.wheels.ForEach(wheelCollider => { wheelCollider.motorTorque = torque; });
x.wheels.ForEach(wheelCollider => { wheelCollider.brakeTorque = 0; });
}
break;
case WheelType.Steel:
var steelAngle = horizontal * 45;
x.wheelModels.ForEach(trans =>
{
trans.localEulerAngles = new Vector3(torque * Time.deltaTime, steelAngle, 0);
});
if (steeringWheel is not null)
steeringWheel.localEulerAngles = new Vector3(0, 0, steelAngle);
x.wheels.ForEach(wheelCollider => { wheelCollider.steerAngle = steel; });
break;
}
});
if (optionalUpRight.Allow)
{
rigidbody.AddRelativeTorque(rigidbody.transform.eulerAngles.z * optionalUpRight.Value * transform.forward, ForceMode.VelocityChange);
}
highSpeedHandle.SetElements(this, rigidbody.velocity.magnitude > 4);
}
public void OnVertical(InputAction.CallbackContext context)
{
vertical = context.ReadValue<float>();
}
public virtual void OnHorizontal(InputAction.CallbackContext context)
public void OnHorizontal(InputAction.CallbackContext context)
{
horizontal = context.ReadValue<float>();
}
public virtual void OnBrake(InputAction.CallbackContext context)
public void OnBrake(InputAction.CallbackContext context)
{
isbraking = context.performed;
}
public virtual Location GetLocation() => new(driveAnchor);
public virtual Rigidbody GetRigidbody() => rigidbody;
void Start()
{
controller = new();
controller.Vehicle.Enable();
}
void Update()
{
if (driver is not null && driver == NetworkClient.localPlayer)
{
var torque = maxMotorTorque * vertical;
var steel = horizontal * maxSteeringAngle;
axisInfos.ForEach(x =>
{
switch (x.wheelType)
{
case WheelType.Motor:
if (isbraking)
{
x.wheels.ForEach(x =>
{
x.brakeTorque = brakeTorque;
});
}
else
{
x.wheels.ForEach(x =>
{
x.motorTorque = torque;
});
x.wheels.ForEach(x =>
{
x.brakeTorque = 0;
});
}
break;
case WheelType.Steel:
var steelAngle = horizontal * 45;
x.wheelModels.ForEach(x =>
{
x.localEulerAngles = new(torque * Time.deltaTime, steelAngle, 0);
});
x.wheels.ForEach(x =>
{
x.steerAngle = steel;
});
break;
}
});
}
else
{
vertical = horizontal = default;
isbraking = default;
}
isBraking = context.performed;
}
}
}