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

View File

@@ -0,0 +1,36 @@
using BITKit.Animations;
using Unity.Mathematics;
using UnityEngine;
namespace BITKit
{
public class MonoAnimatorProxy:MonoBehaviour,IAnimator
{
[SerializeField] private MonoBehaviour monoBehaviour;
private IAnimator _animatorImplementation => (IAnimator)monoBehaviour;
public void Play(string name, int index = 0, float normalizedTimeOffset = 0)
{
_animatorImplementation.Play(name, index, normalizedTimeOffset);
}
public void CrossFade(string name, float duration, int index = 0, float normalizedTimeOffset = 0)
{
_animatorImplementation.CrossFade(name, duration, index, normalizedTimeOffset);
}
public void OnStateEnter(int index, string name)
{
_animatorImplementation.OnStateEnter(index, name);
}
public void OnStateExit(int index, string name)
{
_animatorImplementation.OnStateExit(index, name);
}
public float3 GetRootVelocity()
{
return _animatorImplementation.GetRootVelocity();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3ec5e9dfed974baf9ce327cdc717ac6c
timeCreated: 1689957890

View File

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

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections;
using System.Collections.Generic;
using AYellowpaper.SerializedCollections;
using UnityEngine;
namespace BITKit
{
public class SetTargetFrameRate : MonoBehaviour
{
[SerializeField] private SerializedDictionary<string, int> frameRateDictionary;
[SerializeField] private int startFrameRate;
private int currentFrameRate;
private void Start()
{
currentFrameRate = Application.targetFrameRate;
}
public void SetFrameRate(string key)
{
if (frameRateDictionary.TryGetValue(key, out var frameRate))
{
SetFrameRate(frameRate);
}else if (int.TryParse(key, out frameRate))
{
SetFrameRate(frameRate);
}
}
public void SetFrameRate(int frameRate)
{
Application.targetFrameRate =currentFrameRate = frameRate;
}
}
}

View File

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

View File

@@ -41,10 +41,14 @@ namespace BITKit
public static void ThrowIfWindowNotFocus()
{
#if UNITY_EDITOR
if (UnityEditor.EditorWindow.mouseOverWindow.ToString() is not " (UnityEditor.GameView)")
var window = UnityEditor.EditorWindow.focusedWindow;
var windowName = window is not null ? window.ToString() : string.Empty;
switch (windowName)
{
//Debug.Log(UnityEditor.EditorWindow.mouseOverWindow);
throw new MouseNotOverGameViewException();
case " (UnityEditor.GameView)":
return;
default:
throw new MouseNotOverGameViewException();
}
#endif
}

View File

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

View File

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

View File

@@ -0,0 +1,22 @@
{
"name": "BITKit.Camera",
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:4307f53044263cf4b835bd812fc161a4",
"GUID:517785bb4600a5140b47eac5fa49b8fc"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6c5bd1d06c6446b4695026e1a418b39d
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Cysharp.Threading.Tasks;
using UnityEngine.UI;
namespace BITKit
{
public class CameraProvider : MonoBehaviour
{
[SerializeField] private string cameraName;
[SerializeField] private RenderTexture cameraTexture;
[SerializeField] private RawImage rawImage;
// Start is called before the first frame update
async void Start()
{
await Application.RequestUserAuthorization(UserAuthorization.WebCam);
if (Application.HasUserAuthorization(UserAuthorization.WebCam))
{
WebCamDevice[] devices = WebCamTexture.devices;//获取可用设备
if (WebCamTexture.devices.Length <= 0)
{
Debug.LogError("没有摄像头设备,请检查");
return;
}
BIT4Log.Log<CameraProvider>($"已获取到摄像头:{string.Join(" and ",devices.Select(x=>x.name))}");
string devicename =string.IsNullOrEmpty(cameraName) ? devices.First().name : cameraName;
var webCamTexture = new WebCamTexture(devicename, 256, 256, 30)
{
wrapMode = TextureWrapMode.Repeat
};
rawImage.texture = webCamTexture;
webCamTexture.Play();
}
else
{
BIT4Log.Warnning<CameraProvider>("未获取到WebCam授权");
}
}
}
}

View File

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

View File

@@ -1,16 +1,13 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using Cinemachine;
using Cinemachine.Utility;
using TouchPhase = UnityEngine.InputSystem.TouchPhase;
using UnityEngine.InputSystem.EnhancedTouch;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
using BITKit.IO;
using Newtonsoft.Json;
using System.IO;
using Cysharp.Threading.Tasks;
using UnityEngine.InputSystem.Controls;
namespace BITKit
{
public class SimpleCameraLook : MonoBehaviour
@@ -41,6 +38,8 @@ namespace BITKit
public AnimationCurve moveCurve = new();
public AnimationCurve touchMoveCurve = new();
public Vector2 cameraDistanceLimit = new(1, 64);
[Header(Constant.Header.Providers)]
[SerializeField,SerializeReference,SubclassSelector] private ICondition allowInput;
[Header(Constant.Header.Debug)]
public int touchesCount;
public bool isParallelVector;
@@ -55,6 +54,12 @@ namespace BITKit
private float savedDistance;
private float startDistance;
private CinemachineBrain _brain;
public Vector3 Position
{
get=>cameraRoot.position;
set=>cameraRoot.position = value;
}
public void Reset()
{
lookInput = MathV.TransientRotationAxis(startLocation.position);
@@ -73,6 +78,13 @@ namespace BITKit
{
touchMode = mode;
}
public void SetViewScale(float value)
{
tpv.CameraDistance = value;
}
public float GetViewScale() => tpv.CameraDistance;
public void Align(Transform target)
{
if (target.TryGetComponent<SimpleCameraLook>(out var x))
@@ -100,6 +112,7 @@ namespace BITKit
lookInput = MathV.TransientRotationAxis(target.eulerAngles);
}
}
public void Align(Vector3 position)=>cameraRoot.position= position;
public void SaveLocation()
{
savedLocation = new(cameraRoot);
@@ -155,7 +168,8 @@ namespace BITKit
freeLooking.RemoveDisableElements(this);
virtualCamera.enabled = true;
if (virtualCamera is not null)
virtualCamera.enabled = true;
}
private void OnDisable()
@@ -163,7 +177,8 @@ namespace BITKit
SetEnabled(false);
freeLooking.AddDisableElements(this);
virtualCamera.enabled = false;
if (virtualCamera is not null)
virtualCamera.enabled = false;
}
private void OnDestroy()
@@ -213,6 +228,7 @@ namespace BITKit
private void OnView(InputAction.CallbackContext context)
{
if (allowInput.OnCheck() is false) return;
var playerConfig = PlayerConfig.singleton;
var sensitivity = playerConfig.sensitivity * playerConfig.m_yaw;
var delta = context.ReadValue<Vector2>();
@@ -226,8 +242,6 @@ namespace BITKit
}
break;
case Touchscreen touchscreen:
/* lookInput.x -= delta.y * sensitivity;
lookInput.y += delta.x * sensitivity; */
switch (touchMode)
{
case TransformMode.Move:
@@ -279,12 +293,6 @@ namespace BITKit
{
}
catch (System.Exception)
{
throw;
}
}
private void OnAds(float delta)

View File

@@ -3,19 +3,20 @@ using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
public class ShowProfiler : BITBehavior, IDiagnostics
public class ShowProfiler : BITBehavior
{
[Header(Constant.Header.Settings)]
[SubclassSelector, SerializeReference] public References pingAddress;
[Header(Constant.Header.Output)]
public Provider fpsOutput;
public Provider pingOutput;
DeltaTimer timer = new();
Ping ping;
[SerializeField,SerializeReference,SubclassSelector] private IProvider fpsOutput;
[SerializeField,SerializeReference,SubclassSelector] private IProvider pingOutput;
[SerializeField,SerializeReference,SubclassSelector] private IProvider resolutionOutput;
[SerializeField,SerializeReference,SubclassSelector] private IProvider frameRateOutput;
private readonly DeltaTimer timer = new();
private Ping ping;
[Header(Constant.Header.InternalVariables)]
public int frameRate;
// Update is called once per frame
void Update()
private int frameRate;
private void Update()
{
timer.Update();
frameRate = timer;
@@ -26,20 +27,14 @@ namespace BITKit
{
pingOutput.Set(ping.time.ToString());
}
ping = new(pingAddress);
ping = new Ping(pingAddress);
}
resolutionOutput?.Set(Screen.currentResolution.ToString());
frameRateOutput?.Set(Application.targetFrameRate is -1 or 0 ? "Unlimited" : Application.targetFrameRate.ToString());
}
public override string GetName()
{
return nameof(ShowProfiler);
}
public override object GetDiagnostics()
{
Dictionary<string, string> dictioanry = new();
dictioanry.Add(nameof(fpsOutput), fpsOutput ? "有效" : "未定义");
dictioanry.Add(nameof(pingOutput), pingOutput ? "有效" : "未定义");
dictioanry.Add("FPS", timer);
return dictioanry;
}
}
}

View File

@@ -6,8 +6,8 @@ namespace BITKit
{
public class ShowVersion : MonoBehaviour
{
public Provider output;
void Start()
[SerializeField,SerializeReference,SubclassSelector] private IProvider output;
private void Start()
{
output?.Set(Application.version);
}

View File

@@ -9,20 +9,32 @@ namespace BITKit
public class WorldToScreenPoint : MonoBehaviour
{
[Header(Constant.Header.Settings)]
[SerializeField] Transform root;
[SerializeField] Vector3 offset;
[SerializeField] Optional<float> activeDistance;
[SerializeField] private Transform root;
[SerializeField] private Optional<Vector3> localOffset;
[SerializeField] private Optional<Vector3> worldOffset;
[SerializeField] private Optional<float> activeDistance;
[Header(Constant.Header.Events)]
[SerializeField] private UnityEvent<bool> setHeaderEnabled;
[SerializeField] private UnityEvent<Vector3> setHeaderPosition;
Transform cameraTrans;
void Start()
private Transform cameraTrans;
private void Start()
{
if (Camera.main != null) cameraTrans = Camera.main.transform;
}
void Update()
private void Update()
{
var position = root.position + root.rotation * offset;
var position = root.position;
if (localOffset.Allow)
{
position += root.rotation * localOffset;
}
if (worldOffset.Allow)
{
position+=worldOffset;
}
setHeaderPosition.Invoke(position);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -15,12 +15,88 @@ namespace BITKit.Mark
Vector3 GetPostion();
bool GetAcitve();
}
[SubSystemConfig(isMainThread = true)]
public class MarkSystem : SubBITSystem
public interface IMarkSystem
{
public Action<IMarkObject> OnAdd;
public Action<IMarkObject> Update;
public Action<IMarkObject> OnRemove;
event Action<IMarkObject> OnAdd;
event Action<IMarkObject> OnUpdate;
event Action<IMarkObject> OnRemove;
void Add(IMarkObject markObject);
void Remove(IMarkObject markObject);
}
[Serializable]
public class MarkSystemMonoProxy:IMarkSystem
{
[SerializeReference] private MonoBehaviour monoBehaviour;
private IMarkSystem _markSystemImplementation=>monoBehaviour as IMarkSystem;
public event Action<IMarkObject> OnAdd
{
add => _markSystemImplementation.OnAdd += value;
remove => _markSystemImplementation.OnAdd -= value;
}
public event Action<IMarkObject> OnUpdate
{
add => _markSystemImplementation.OnUpdate += value;
remove => _markSystemImplementation.OnUpdate -= value;
}
public event Action<IMarkObject> OnRemove
{
add => _markSystemImplementation.OnRemove += value;
remove => _markSystemImplementation.OnRemove -= value;
}
public void Add(IMarkObject markObject)
{
_markSystemImplementation.Add(markObject);
}
public void Remove(IMarkObject markObject)
{
_markSystemImplementation.Remove(markObject);
}
}
[Serializable]
public class MarkSystemSingleton:IMarkSystem
{
private IMarkSystem _markSystemImplementation=>MarkSystem.Singleton;
public event Action<IMarkObject> OnAdd
{
add => _markSystemImplementation.OnAdd += value;
remove => _markSystemImplementation.OnAdd -= value;
}
public event Action<IMarkObject> OnUpdate
{
add => _markSystemImplementation.OnUpdate += value;
remove => _markSystemImplementation.OnUpdate -= value;
}
public event Action<IMarkObject> OnRemove
{
add => _markSystemImplementation.OnRemove += value;
remove => _markSystemImplementation.OnRemove -= value;
}
public void Add(IMarkObject markObject)
{
_markSystemImplementation.Add(markObject);
}
public void Remove(IMarkObject markObject)
{
_markSystemImplementation.Remove(markObject);
}
}
public class MarkSystem : MonoBehaviour,IMarkSystem
{
internal static IMarkSystem Singleton { get; private set; }
public event Action<IMarkObject> OnAdd;
public event Action<IMarkObject> OnUpdate;
public event Action<IMarkObject> OnRemove;
List<IMarkObject> markObjects = new();
public void Add(IMarkObject markObject)
{
@@ -32,11 +108,17 @@ namespace BITKit.Mark
markObjects.TryRemove(markObject);
OnRemove?.Invoke(markObject);
}
public override void OnUpdate(float deltaTime)
private void Awake()
{
Singleton = this;
}
private void Update()
{
foreach (var markObject in markObjects.ToArray())
{
Update?.Invoke(markObject);
OnUpdate?.Invoke(markObject);
}
}
}

View File

@@ -13,9 +13,10 @@ namespace BITKit.Mark
public class MarkSystemUIToolkit : MonoBehaviour
{
public UXElement element;
[SerializeReference, SubclassSelector] public References className;
[SerializeField,SerializeReference, SubclassSelector] private References className;
[SerializeField, SerializeReference, SubclassSelector]
private IMarkSystem markSystem;
Dictionary<string, Label> dictionary = new();
MarkSystem markSystem;
IPanel panel;
CancellationToken cancellationToken;
void Awake()
@@ -25,11 +26,10 @@ namespace BITKit.Mark
void Start()
{
panel = element.GetVisualElement().panel;
markSystem = BITSystems.GetOrCreate<MarkSystem>();
if (markSystem is not null)
{
markSystem.OnAdd += OnAdd;
markSystem.Update += OnUpdate;
markSystem.OnUpdate += OnUpdate;
markSystem.OnRemove += OnRemove;
}
}
@@ -38,7 +38,7 @@ namespace BITKit.Mark
if (markSystem is not null)
{
markSystem.OnAdd -= OnAdd;
markSystem.Update -= OnUpdate;
markSystem.OnUpdate -= OnUpdate;
markSystem.OnRemove -= OnRemove;
}
}

View File

@@ -0,0 +1,18 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

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

View File

@@ -1,8 +1,19 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
[Serializable]
public class MonoConditionProxy : MonoBehaviour, ICondition
{
[SerializeField] private MonoBehaviour monoBehaviour;
private ICondition _conditionImplementation=>(ICondition)monoBehaviour;
public bool OnCheck()
{
return _conditionImplementation.OnCheck();
}
}
public class MonoCondition : MonoBehaviour, ICondition, IAction
{
public bool isSuccess;

View File

@@ -18,7 +18,7 @@ namespace BITKit.Sensors
IAudioObject currentAudioObject;
Collider currentCollider;
Collider[] colliders = new Collider[32];
public override IEnumerable<Transform> Get() => detecteds;
public override IEnumerable<Transform> Get() => detected;
public override UniTask Execute()
{
var cacheList = ListPool<Transform>.Get();
@@ -30,15 +30,15 @@ namespace BITKit.Sensors
cacheList.Add(currentCollider.transform);
}
}
detecteds = cacheList.ToArray();
detected = cacheList.ToArray();
ListPool<Transform>.Release(cacheList);
return UniTask.CompletedTask;
}
public override bool IsValid(Collider collider)
public override bool IsValid(Collider _collider)
{
if (ignoreColliders.Contains(collider) is false)
if (Vector3.Distance(transform.position, collider.transform.position) <= radius)
if (collider.TryGetComponent<IAudioObject>(out currentAudioObject))
if (ignoreColliders.Contains(_collider) is false)
if (Vector3.Distance(transform.position, _collider.transform.position) <= radius)
if (_collider.TryGetComponent<IAudioObject>(out currentAudioObject))
{
return currentAudioObject.GetVolume() >= 1;
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@@ -6,12 +7,35 @@ using BITKit;
using Cysharp.Threading.Tasks;
namespace BITKit.Sensors
{
/// <summary>
/// 传感器的接口定义
/// </summary>
public interface ISensor
{
/// <summary>
/// 是否监测到任何目标
/// </summary>
bool Any=>Get().Any();
/// <summary>
/// 获取检测到的目标
/// </summary>
/// <returns></returns>
IEnumerable<Transform> Get();
bool IsValid(Collider collider);
/// <summary>
/// 目标是否有效
/// </summary>
/// <param name="_collider">目标的碰撞体</param>
/// <returns></returns>
bool IsValid(Collider _collider);
/// <summary>
/// 获取传感器的范围
/// </summary>
/// <returns></returns>
float GetDistance();
/// <summary>
/// 传感器执行检测
/// </summary>
/// <returns></returns>
UniTask Execute();
}
[System.Serializable]
@@ -24,9 +48,9 @@ namespace BITKit.Sensors
return _sensorImplementation.Get();
}
public bool IsValid(Collider collider)
public bool IsValid(Collider _collider)
{
return _sensorImplementation.IsValid(collider);
return _sensorImplementation.IsValid(_collider);
}
public float GetDistance()
@@ -43,15 +67,14 @@ namespace BITKit.Sensors
{
[Header(Constant.Header.Settings)]
public LayerMask detectLayer;
public bool autoUpdate;
[Header(Constant.Header.Gameobjects)]
public Collider[] ignoreColliders;
[Header(Constant.Header.Components)]
public Sensor[] subSensors;
[Header(Constant.Header.InternalVariables)]
[System.NonSerialized]
public Transform[] detecteds = new Transform[0];
[NonSerialized]
public Transform[] detected = Array.Empty<Transform>();
public abstract IEnumerable<Transform> Get();
public abstract bool IsValid(Collider collider);
public abstract bool IsValid(Collider _collider);
public abstract UniTask Execute();
public abstract float GetDistance();
}

View File

@@ -5,7 +5,8 @@
"GUID:a209c53514018594f9f482516f2a6781",
"GUID:508392158bd966c4d9c21e19661a441d",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:14fe60d984bf9f84eac55c6ea033a8f4"
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:be17a8778dbfe454890ed8279279e153"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -14,19 +14,14 @@ namespace BITKit.Sensors
public float radius;
public int fov;
public bool requireSight;
public bool autoUpdate;
[Header(Constant.Header.Settings)]
public LayerMask blockLayer;
[Header(Constant.Header.InternalVariables)]
FrameUpdate frameUpdater;
Collider[] colliders = new Collider[32];
RaycastHit[] hits;
Collider currentCollider;
Location location;
int length;
Vector3 dir;
float maxDistance;
public override IEnumerable<Transform> Get() => detecteds;
private FrameUpdate frameUpdater;
private readonly Collider[] colliders = new Collider[32];
private RaycastHit[] hits;
public override IEnumerable<Transform> Get() => detected;
private void Update()
{
@@ -37,100 +32,64 @@ namespace BITKit.Sensors
}
public override UniTask Execute()
{
if (frameUpdater)
{
if (maxDistance is 0)
{
maxDistance = Mathf.Max(subSensors.Select(x => x.GetDistance()).Append(radius).ToArray());
}
location.position = transform.position;
location.rotation = transform.rotation;
var list = ListPool<Transform>.Get();
for (int i = 0; i < Physics.OverlapSphereNonAlloc(location, maxDistance, colliders, detectLayer); i++)
{
currentCollider = colliders[i];
if (IsValid(currentCollider))
list.Add(currentCollider.transform);
else
{
foreach (var sensor in subSensors)
{
if (sensor.IsValid(currentCollider))
{
list.Add(currentCollider.transform);
break;
}
}
}
}
detecteds = list.ToArray();
list.Clear();
ListPool<Transform>.Release(list);
}
if (frameUpdater.Allow is false) return UniTask.CompletedTask;
var location = new Location(transform);
var length = Physics.OverlapSphereNonAlloc(location, radius, colliders, detectLayer);
var list = new List<Transform>();
list.AddRange(from x in colliders.Take(length) where IsValid(x) select x.transform);
detected = list.ToArray();
list.Clear();
// detected = colliders
// .Take(length)
// .Select(x => x.transform)
// .ToArray();
return UniTask.CompletedTask;
}
public override bool IsValid(Collider collider)
public override bool IsValid(Collider _collider)
{
if (ignoreColliders.Contains(collider)
|| CheckFov(ref collider) is false
|| CheckSight(ref collider) is false
|| CheckDistance(ref collider) is false
)
switch (_collider)
{
return false;
case var _ when ignoreColliders.Contains(_collider):
return false;
case var _ when fov > 0 && CheckFov(ref _collider) is false:
case var _ when requireSight && CheckSight(ref _collider) is false:
return false;
default:
return true;
}
}
public override float GetDistance() => radius;
private bool CheckFov(ref Collider _collider)
{
var _dir = _collider.transform.position - transform.position;
if (_dir.sqrMagnitude <= 0) return false;
var dir = Quaternion.LookRotation(_dir);
return Vector3.Dot(transform.forward, _dir) > 0 && fov > Quaternion.Angle(transform.rotation, dir);
}
private bool CheckSight(ref Collider _collider)
{
if (!requireSight) return false;
var transform1 = _collider.transform;
var position = transform1.position;
var location = new Location(transform);
var length = Physics.RaycastNonAlloc(
location.position,
position - location,
hits,
Vector3.Distance(location, position),
blockLayer
);
if (length > 0)
{
if (hits[0].collider == _collider)
{
return true;
}
}
else return true;
}
public override float GetDistance() => radius;
bool CheckFov(ref Collider collider)
{
if (fov is not 0)
{
var _dir = collider.transform.position - transform.position;
if (_dir.sqrMagnitude > 0)
{
var dir = Quaternion.LookRotation(_dir);
if (Vector3.Dot(transform.forward, _dir) > 0 && fov > Quaternion.Angle(transform.rotation, dir))
{
return true;
}
else return false;
}
else return true;
}
else
{
return true;
}
}
bool CheckSight(ref Collider collider)
{
if (requireSight)
{
length = Physics.RaycastNonAlloc(
location.position,
collider.transform.position - location,
hits,
Vector3.Distance(location, collider.transform.position),
blockLayer
);
if (length > 0)
{
if (hits[0].collider == collider)
{
return true;
}
}
else return true;
}
return false;
}
bool CheckDistance(ref Collider collider)
{
return Vector3.Distance(collider.transform.position, transform.position) <= radius;
}
}
#if UNITY_EDITOR
#endif
}

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using UnityEngine;
namespace BITKit.Sensors
@@ -8,22 +10,29 @@ namespace BITKit.Sensors
{
[Header(Constant.Header.Settings)]
public float distance;
public override IEnumerable<Transform> Get() => detecteds;
public override IEnumerable<Transform> Get() => detected;
private readonly RaycastHit[] raycasts = new RaycastHit[16];
public override UniTask Execute()
{
if (Physics.Raycast(transform.position, transform.forward, out var rayhit, distance, detectLayer))
{
detecteds = new Transform[]{
rayhit.transform
};
}
else
{
detecteds = new Transform[0];
}
var _transform = transform;
var ray = new Ray(_transform.position,_transform.forward);
var size = Physics.RaycastNonAlloc(ray, raycasts, distance, detectLayer);
detected = raycasts
.Take(size)
.Select(x => x.collider)
.Where(IsValid)
.Select(x=>x.transform)
.ToArray();
return UniTask.CompletedTask;
}
public override bool IsValid(Collider collider) => true;
public override bool IsValid(Collider _collider) => ignoreColliders.Contains(_collider) is false;
public override float GetDistance() => distance;
private void Update()
{
if (autoUpdate)
{
Execute().Forget();
}
}
}
}

View File

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

View File

@@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.UIElements;
#endif
using UnityEngine;
using UnityEngine.UIElements;
namespace BITKit.Sensors
{
/// <summary>
/// 智能目标传感器,根据条件,智能选择目标
/// </summary>
public class SmartTargetSensor :MonoBehaviour,ISensor,IAction
{
/// <summary>
/// 自动更新
/// </summary>
[Header(Constant.Header.Settings)]
[SerializeField] private bool autoUpdate;
/// <summary>
/// 目标有效性验证
/// </summary>
[Header(Constant.Header.Providers)]
[SerializeField,SerializeReference,SubclassSelector] private IValidityProvider validityProvider;
/// <summary>
/// 主传感器
/// </summary>
[Header(nameof(Sensor))]
[SerializeField,SerializeReference,SubclassSelector] private ISensor sensor;
#if UNITY_EDITOR
[Header(Constant.Header.Debug)]
[SerializeField] private Transform sensorTransform;
#endif
public IEnumerable<Transform> Get() =>CurrentTarget is not null ? new[] { CurrentTarget }:Enumerable.Empty<Transform>();
public bool IsValid(Collider _collider) =>validityProvider?.IsValid(_collider) ?? true;
public float GetDistance() => sensor.GetDistance();
public Transform CurrentTarget { get; private set; }
private readonly List<Transform> detected = new();
public async UniTask Execute()
{
await sensor.Execute();
var _detected = sensor.Get().ToList();
if (_detected.Contains(CurrentTarget))
{
if (detected.Count is 1 && detected[0] == CurrentTarget)
{
}
else
{
detected.Clear();
detected.Add(CurrentTarget);
}
return;
}
CurrentTarget = _detected
.Where(_transform => IsValid(_transform.GetComponent<Collider>()))
.OrderBy(_transform => Vector3.Distance(transform.position, _transform.position))
.FirstOrDefault();
}
private void Update()
{
if(autoUpdate)Execute().Forget();
}
void IAction.Execute()
{
Execute().Forget();
}
#if UNITY_EDITOR
private void OnDrawGizmosSelected()
{
if (CurrentTarget is null) return;
Gizmos.DrawLine(sensorTransform.position,CurrentTarget.position);
}
#endif
}
#if UNITY_EDITOR
[CustomEditor(typeof(SmartTargetSensor))]
public class SmartTargetSensorInspector:BITInspector<SmartTargetSensor>
{
private ObjectField _objectField;
public override VisualElement CreateInspectorGUI()
{
FillDefaultInspector();
CreateSubTitle("Editor Debug Field");
_objectField = root.Create<ObjectField>();
_objectField.objectType = typeof(Transform);
_objectField.SetEnabled(false);
return root;
}
protected override void OnUpdate()
{
if (_objectField is not null)
{
_objectField.value = agent.CurrentTarget;
}
}
}
#endif
}

View File

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

View File

@@ -6,7 +6,6 @@ using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UIElements;
#if UNITY_EDITOR
using System.CodeDom;
using UnityEditor;
using UnityEditor.UIElements;
#endif
@@ -63,18 +62,24 @@ namespace BITKit.Sensors
public bool IsValid(Collider _collider)
{
if(allowStatic is false && _collider.gameObject.isStatic) return false;
if (ignores.Contains(_collider.gameObject)) return false;
var attachedRigidbody = _collider.attachedRigidbody;
var detectedObject = _collider switch
{
var x when attachedRigidbody is not null && useRigidbody => attachedRigidbody.gameObject,
_ => _collider.gameObject,
};
if (ignores.Contains(detectedObject)) return false;
return !detectedLayer.Allow || detectedLayer.Value.Includes(_collider.gameObject.layer);
}
public float GetDistance()
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
public UniTask Execute()
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
private void Update()

View File

@@ -20,7 +20,7 @@ namespace BITKit.StateMachine
}
[Header(Constant.Header.Components)]
[SerializeReference, SubclassSelector] public List<TState> states = new();
public IDictionary<System.Type, TState> StateDictonary { get; } = new Dictionary<Type, TState>();
public IDictionary<System.Type, TState> StateDictionary { get; } = new Dictionary<Type, TState>();
public IStateMachine<TState> StateMachine => this as IStateMachine<TState>;
TState tempState;
public virtual void OnStart()
@@ -29,7 +29,7 @@ namespace BITKit.StateMachine
{
//state.TransitionState = InternalTransitionState;
state.Initialize();
StateDictonary.Add(state.GetType(), state);
StateDictionary.Add(state.GetType(), state);
}
if (states.Count > 0)
{

View File

@@ -13,7 +13,8 @@
"GUID:84651a3751eca9349aac36a66bba901b",
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:9400d40641bab5b4a9702f65bf5c6eb5"
"GUID:9400d40641bab5b4a9702f65bf5c6eb5",
"GUID:7d3ace4c6aad3684abe11aa38b6cdf99"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

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

View File

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

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections;
using System.Collections.Generic;
using BITKit.UX;
using UnityEngine;
using UnityEngine.UIElements;
public interface IVisualElementProvider
{
VisualElement GetVisualElement();
T GetVisualElement<T>() where T : VisualElement;
}
[Serializable]
public class GetVisualElementFromUXElement:IVisualElementProvider
{
[SerializeField] private UXElement _uxElement;
public VisualElement GetVisualElement() => _uxElement.GetVisualElement();
public T GetVisualElement<T>() where T : VisualElement => GetVisualElement() as T;
}
[Serializable]
public class GetVisualElementFromUIDocument:IVisualElementProvider
{
[SerializeField] private UIDocument document;
[SerializeField] private string path;
public VisualElement GetVisualElement()
{
return document.rootVisualElement.Q(path);
}
public T GetVisualElement<T>() where T : VisualElement=> GetVisualElement() as T;
}

View File

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

View File

@@ -0,0 +1,35 @@
using System.Collections;
using System.Collections.Generic;
using BITKit.UX;
using UnityEngine;
using UnityEngine.UIElements;
public class UXBuilder : MonoBehaviour
{
[SerializeField, SerializeReference, SubclassSelector]
private IVisualElementProvider visualElementProvider;
[SerializeField] private VisualTreeAsset visualTreeAsset;
private readonly List<VisualElement> instances = new();
public T Build<T>() where T : VisualElement
{
var clone = visualTreeAsset.CloneTree()[0];
visualElementProvider.GetVisualElement().Add(clone);
instances.Add(clone);
return clone as T;
}
public UXContainer BuildAsContainer() => new(Build<VisualElement>());
public void Clear()
{
foreach (var x in instances)
{
visualElementProvider.GetVisualElement().Remove(x);
}
instances.Clear();
}
}

View File

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

View File

@@ -19,6 +19,16 @@ namespace BITKit.UX
public const string Icon = "icon-image";
public const string ContextListView = "context-listview";
public const string Inspector = "inspector-container";
public const string ProcessBarFill = "fill-bar";
public class Buttons
{
public const string Button_0 = "button--0";
public const string Button_1 = "button--0";
public const string Button_2 = "button--0";
public const string Button_3 = "button--0";
public const string Button_4 = "button--0";
public const string Button_5 = "button--0";
}
}

View File

@@ -7,24 +7,31 @@ namespace BITKit.UX
public class UXContainer
{
public static implicit operator VisualElement(UXContainer self) => self.visualElement;
public Label contextlabel;
public Label titleLabel;
public Label descriptionLabel;
public Label numberLabel;
public Button button;
public Button secButton;
public VisualElement visualElement;
public VisualElement icon;
public readonly Label contextLabel;
public readonly Label titleLabel;
public readonly Label descriptionLabel;
public readonly Label numberLabel;
public readonly Button button;
public readonly Button secButton;
public readonly VisualElement visualElement;
public readonly VisualElement container;
public readonly VisualElement icon;
public UXContainer(VisualElement visualElement)
{
this.visualElement = visualElement;
contextlabel = visualElement.Q<Label>(UXConstant.ContextLabel);
contextLabel = visualElement.Q<Label>(UXConstant.ContextLabel);
titleLabel = visualElement.Q<Label>(UXConstant.TitleLabel);
numberLabel = visualElement.Q<Label>(UXConstant.TitleLabel);
descriptionLabel = visualElement.Q<Label>(UXConstant.DescriptionLabel);
button = visualElement.Q<Button>(UXConstant.MainButton);
secButton = visualElement.Q<Button>(UXConstant.SecButton);
icon = visualElement.Q(UXConstant.Icon);
container = this.visualElement.Q(UXConstant.ContextContainer);
}
public T Get<T>(int index) where T : VisualElement => visualElement.Q<T>($"{typeof(T).Name}--{index}");
public void SetProcess(float process)
{
visualElement.Q(UXConstant.ProcessBarFill).style.width =Length.Percent(Mathf.Clamp(process * 100,0,100)) ;
}
}
}

View File

@@ -12,6 +12,7 @@ namespace BITKit.UX
protected bool isActive = true;
public virtual bool Get() => isActive;
public virtual void Set(bool active) { }
public virtual void OnAwake(){}
public virtual void OnStart() { }
public override void Set<T>(T obj)
{
@@ -30,25 +31,26 @@ namespace BITKit.UX
public virtual void SetPosition(Vector3 worldPosition)
{
if (Camera.main != null)
{
var cameraTrans = Camera.main.transform;
var visualElement = GetVisualElement();
var pos = RuntimePanelUtils
.CameraTransformWorldToPanel(visualElement.panel, worldPosition, Camera.main);
SetPosition(ref pos);
pos.x = (pos.x - visualElement.layout.width / 2);
visualElement.style.left = 0;
visualElement.style.top = 0;
visualElement.style.right = new StyleLength(StyleKeyword.Auto);
visualElement.style.bottom = new StyleLength(StyleKeyword.Auto);
visualElement.style.position = Position.Absolute;
visualElement.transform.position = pos;
visualElement.SetOpacity(Vector3.Dot(cameraTrans.forward, worldPosition - cameraTrans.position) > 0 ? 1 : 0);
}
GetVisualElement().SetPosition(worldPosition);
// if (Camera.main != null)
// {
// var cameraTrans = Camera.main.transform;
// var visualElement = GetVisualElement();
// var pos = RuntimePanelUtils
// .CameraTransformWorldToPanel(visualElement.panel, worldPosition, Camera.main);
//
// SetPosition(ref pos);
//
// pos.x = (pos.x - visualElement.layout.width / 2);
//
// visualElement.style.left = 0;
// visualElement.style.top = 0;
// visualElement.style.right = new StyleLength(StyleKeyword.Auto);
// visualElement.style.bottom = new StyleLength(StyleKeyword.Auto);
// visualElement.style.position = Position.Absolute;
// visualElement.transform.position = pos;
// visualElement.SetOpacity(Vector3.Dot(cameraTrans.forward, worldPosition - cameraTrans.position) > 0 ? 1 : 0);
// }
}
protected virtual void SetPosition(ref Vector2 position)
{
@@ -129,12 +131,13 @@ namespace BITKit.UX
visualElement.SetEnabled(active);
}
}
void Awake()
private void Awake()
{
cancellationToken = gameObject.GetCancellationTokenOnDestroy();
OnAwake();
OnStart();
}
void OnValidate()
private void OnValidate()
{
if (bindNameProvider is GetNameFromGameobject x)
{

View File

@@ -0,0 +1,13 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace BITKit.UX
{
public class UXListView : UXElement<ListView>
{
}
}

View File

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

View File

@@ -2,13 +2,13 @@
"name": "BITKit.UX.OnScreen",
"rootNamespace": "",
"references": [
"GUID:a209c53514018594f9f482516f2a6781",
"GUID:6ef4ed8ff60a7aa4bb60a8030e6f4008",
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:2bafac87e7f4b9b418d9448d219b01ab",
"GUID:be17a8778dbfe454890ed8279279e153",
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:9400d40641bab5b4a9702f65bf5c6eb5"
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:517785bb4600a5140b47eac5fa49b8fc"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -0,0 +1,124 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.EnhancedTouch;
using UnityEngine.UIElements;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace BITKit.UX
{
[Serializable]
public class AllowTouchWhenPointerNotOverUI : ICondition
{
public bool OnCheck() => UXAllowTouch.Singleton.AllowTouch;
}
/*
* 当指针进入区域时启用输入
* 当指针离开区域时禁用输入,直到所有设备都没有按下,才会再次启用输入
*/
/// <summary>
/// Allow touch when pointer not over UI
/// </summary>
public class UXAllowTouch : UXElement<VisualElement>, ICondition
{
internal static UXAllowTouch Singleton { get; private set; }
public bool AllowTouch;
internal bool IsHoveringUI { get; private set; }
public bool IsTouching { get; private set; }
private int updateRequest;
private CancellationTokenSource cancellationTokenSource;
public override void OnAwake()
{
Singleton = this;
EnhancedTouchSupport.Enable();
Touch.onFingerUp += OnFingerUp;
Touch.onFingerDown += OnFingerDown;
cancellationTokenSource = new CancellationTokenSource();
}
private void OnDestroy()
{
cancellationTokenSource.Cancel();
}
private async void OnFingerDown(Finger obj)
{
IsTouching = true;
try
{
await Task.Delay(TimeSpan.FromSeconds(Time.deltaTime*2));
AllowTouch = !IsHoveringUI;
}
catch (OperationCanceledException)
{
}
}
private void OnFingerUp(Finger obj)
{
IsTouching = false;
}
public override void OnStart()
{
base.OnStart();
visualElement.RegisterCallback<PointerEnterEvent>(OnPointerEnter);
visualElement.RegisterCallback<PointerLeaveEvent>(OnPointerLevel);
}
private void OnPointerLevel(PointerLeaveEvent evt)
{
IsHoveringUI = true;
if (isMouseInput) AllowTouch = false;
}
private void OnPointerEnter(PointerEnterEvent evt)
{
IsHoveringUI = false;
if (isMouseInput) AllowTouch = true;
}
public bool OnCheck() => AllowTouch;
private bool isMouseInput => Mouse.current.delta.ReadValue().sqrMagnitude > 0;
}
#if UNITY_EDITOR
[CustomEditor(typeof(UXAllowTouch))]
public class UXAllowTouchInspector:BITInspector<UXAllowTouch>
{
private Label allowTouchLabel;
private Label isHoveringUILabel;
private Label isTouching;
public override VisualElement CreateInspectorGUI()
{
FillDefaultInspector();
CreateSubTitle("Editor");
allowTouchLabel = root.Create<Label>();
isHoveringUILabel = root.Create<Label>();
isTouching = root.Create<Label>();
return root;
}
protected override void OnUpdate()
{
if (allowTouchLabel is null) return;
allowTouchLabel.text = agent.AllowTouch?"Allow Touch":"Block Touch";
isHoveringUILabel.text = agent.IsHoveringUI ? "Is Hovering UI" : "Not Hovering UI";
isTouching.text = agent.IsTouching ? "Is Touching" : "Not Touching";
allowTouchLabel.style.color = agent.AllowTouch?Color.green:Color.red;
isHoveringUILabel.style.color = agent.IsHoveringUI?Color.red:Color.green;
isTouching.style.color = agent.IsTouching?Color.green:Color.red;
}
}
#endif
}

View File

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

View File

@@ -107,67 +107,59 @@ namespace BITKit
{
FillDefaultInspector(root, serializedObject, true);
}
public static void FillDefaultInspector(VisualElement container, SerializedObject serializedObject, bool hideScript)
protected static void FillDefaultInspector(VisualElement container, SerializedObject serializedObject, bool hideScript)
{
SerializedProperty property = serializedObject.GetIterator();
if (property.NextVisible(true)) // Expand first child.
var property = serializedObject.GetIterator();
if (!property.NextVisible(true)) return; // Expand first child.
do
{
do
if (property.propertyPath == "m_Script" && hideScript)
{
if (property.propertyPath == "m_Script" && hideScript)
{
continue;
}
var type = serializedObject.targetObject.GetType().GetField(property.name);
var field = new PropertyField(property);
field.name = "PropertyField:" + property.propertyPath;
if (property.propertyPath == "m_Script" && serializedObject.targetObject != null)
{
field.SetEnabled(false);
}
try
{
if (type is not null)
{
var header = type.GetCustomAttribute<HeaderAttribute>();
if (header is not null)
{
Label label = new Label(header.header);
label.AddToClassList("subTitle");
container.Add(label);
}
}
}
catch (System.Exception e)
{
Debug.LogException(e);
}
container.Add(field);
continue;
}
while (property.NextVisible(false));
foreach (var method in serializedObject.targetObject.GetType().GetMethods())
var type = serializedObject.targetObject.GetType().GetField(property.name);
var field = new PropertyField(property)
{
if (method.GetCustomAttribute<BITAttribute>() is not null)
{
if (method.GetParameters().Length is 0)
{
var button = new Button(() => method.Invoke(serializedObject.targetObject, null));
button.text = method.Name;
name = "PropertyField:" + property.propertyPath
};
container.Add(button);
}
}
if (property.propertyPath == "m_Script" && serializedObject.targetObject != null)
{
field.SetEnabled(false);
}
// try
// {
// var header = type?.GetCustomAttribute<HeaderAttribute>();
// if (header != null)
// {
// var label = new Label(header.header);
// label.AddToClassList("subTitle");
// container.Add(label);
// }
// }
// catch (System.Exception e)
// {
// Debug.LogException(e);
// }
container.Add(field);
}
while (property.NextVisible(false));
foreach (var method in serializedObject.targetObject.GetType().GetMethods())
{
if (method.GetCustomAttribute<BITAttribute>() is null) continue;
if (method.GetParameters().Length is not 0) continue;
var button = new Button(() => method.Invoke(serializedObject.targetObject, null))
{
text = method.Name
};
container.Add(button);
}
}
}

View File

@@ -537,5 +537,34 @@ namespace BITKit
}
}
public static void SetPosition(this VisualElement self,Vector3 worldPosition)
{
try
{
var camera = Camera.main;
if (camera is null) return;
var cameraTrans = camera.transform;
var pos = RuntimePanelUtils
.CameraTransformWorldToPanel(self.panel, worldPosition, camera);
pos.x = (pos.x - self.layout.width / 2);
self.style.left = 0;
self.style.top = 0;
self.style.right = new StyleLength(StyleKeyword.Auto);
self.style.bottom = new StyleLength(StyleKeyword.Auto);
self.style.position = Position.Absolute;
// self.transform.position = pos;
self.style.left = pos.x;
self.style.top = pos.y;
self.SetOpacity(Vector3.Dot(cameraTrans.forward, worldPosition - cameraTrans.position) > 0 ? 1 : 0);
}
catch (Exception e)
{
BIT4Log.LogException(e);
}
}
}
}

View File

@@ -1,8 +1,12 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Xml.Linq;
using UnityEngine;
using UnityEngine.Pool;
using Object = UnityEngine.Object;
namespace BITKit
{
[System.Serializable]
@@ -10,26 +14,43 @@ namespace BITKit
{
public UnityPool()
{
this.pool = new(Spawn, OnGet, OnReturn, OnDestroy, maxSize: 16);
pool = new ObjectPool<T>(Spawn, OnGet, OnReturn, OnDestroy, maxSize: 16);
}
[Header(Constant.Header.Prefabs)]
public T prefab;
[Header(Constant.Header.Gameobjects)]
public Transform root;
[Header(Constant.Header.InternalVariables)]
ObjectPool<T> pool;
public T Get(T element = null, Transform root = null)
private ObjectPool<T> pool;
public T Get(T element = null, Transform _root = null)
{
if (element is not null)
prefab = element;
if (root is not null)
this.root = root;
if (_root is not null)
root = _root;
return pool.Get();
}
public void Return(T element) => pool.Release(element);
T Spawn() => Transform.Instantiate(prefab, root);
void OnGet(T element) => element.gameObject.SetActive(true);
void OnReturn(T element) => element.gameObject.SetActive(false);
void OnDestroy(T element) => GameObject.Destroy(element.gameObject);
private T Spawn() => Object.Instantiate(prefab, root);
private void OnGet(T element) => element.gameObject.SetActive(true);
private void OnReturn(T element) => element.gameObject.SetActive(false);
private void OnDestroy(T element) => Object.Destroy(element.gameObject);
#region
private readonly ConcurrentDictionary<string, T> _dictionary=new();
public T GetByKey(string key)
{
var instance = _dictionary.GetOrAdd(key, s => Get());
return instance;
}
public void RemoveByKey(string key)
{
_dictionary.TryRemove(key);
}
#endregion
}
}

View File

@@ -3,10 +3,19 @@ using System.Collections.Generic;
using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UIElements;
namespace BITKit
{
[Serializable]
public class IProviderMonoProxy : IProvider
{
[SerializeField] private MonoBehaviour monoBehaviour;
private IProvider _provider=>monoBehaviour as IProvider;
public T Get<T>() => _provider.Get<T>();
public void Set<T>(T t) => _provider.Set<T>(t);
}
public abstract class Provider : MonoBehaviour, IProvider
{
public virtual T Get<T>()
@@ -35,11 +44,12 @@ namespace BITKit
{
VisualElement GetVisualElement();
}
[System.Serializable]
[Serializable]
public struct FrameUpdate
{
float prevframe;
bool updatedThisFrame;
public bool Allow => this;
private float prevframe;
private bool updatedThisFrame;
public static implicit operator bool(FrameUpdate self)
{
var updatedThisFrame = BITApp.Time.DeltaTime <= self.prevframe;
@@ -54,14 +64,14 @@ namespace BITKit
}
}
}
[System.Serializable]
[Serializable]
public class CompletionRate
{
public IntervalUpdate resetInterval = new(1);
int requestCount;
int successCount;
public float rate;
public int resetWhen = 64;
private int requestCount;
private int successCount;
public static implicit operator float(CompletionRate cr)
{
return cr.rate;