This commit is contained in:
CortexCore
2023-10-02 23:24:56 +08:00
parent 8ef5c7ec0a
commit 947e52e748
183 changed files with 107857 additions and 9378 deletions

View File

@@ -50,6 +50,8 @@ namespace BITKit
remove => ApplicationService.OnDownloadComplete -= value;
}
public event Action OnDetectedLatestVersion;
public UniTask<string> DownloadLatestVersionAsync()
{
return _applicationServiceImplementation.DownloadLatestVersionAsync();
@@ -104,6 +106,12 @@ namespace BITKit
remove => OnDownloadComplete -= value;
}
public event Action OnDetectedLatestVersion
{
add => Singleton.OnDetectedLatestVersion += value;
remove => Singleton.OnDetectedLatestVersion -= value;
}
private UnityWebRequest downloadRequest;
private CancellationTokenSource _cancellationTokenSource;

View File

@@ -2,7 +2,6 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.Remoting.Contexts;
using UnityEngine;
using Cysharp.Threading.Tasks;
using System.Threading.Tasks;
@@ -79,10 +78,8 @@ namespace BITKit
BIT4Log.OnLog += Debug.Log;
BIT4Log.OnWarning += Debug.LogWarning;
BIT4Log.OnException += Debug.LogException;
var settings = Addressables.LoadAssetAsync<ScriptableObject>("Assets/BITKit/Unity/Configs/AppSettings.asset").WaitForCompletion() as BITSettingsSO;
//启动BITApp
BITApp.Start(Application.productName, settings!.appSettings);
BITApp.Start(Application.productName, new BITApp.AppSettings()).Forget();
AllowCursor = new();
AllowTouchSupport = new();

View File

@@ -1,10 +1,17 @@
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;
using UnityEngine;
namespace BITKit
{
public class BITSettingsSO : ScriptableObject
{
public BITApp.AppSettings appSettings;
[ContextMenu(nameof(Print))]
public void Print()
{
GUIUtility.systemCopyBuffer = JsonConvert.SerializeObject(appSettings.blackList, Formatting.Indented);
}
}
}

View File

@@ -196,8 +196,8 @@ namespace BITKit
private void Update()
{
//var debuger = DI.Get<IDebuger>();
var playerConfig = PlayerConfig.singleton;
var sensitivity = playerConfig.touchSensitivity;
var playerConfig = PlayerConfig.Singleton;
var sensitivity = playerConfig.TouchSensitivity;
//debuger.Log(nameof(Touch.activeTouches), Touch.activeTouches.Count.ToString());
touchesCount = Touch.activeTouches.Count;
@@ -229,8 +229,8 @@ 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 playerConfig = PlayerConfig.Singleton;
var sensitivity = playerConfig.Sensitivity * playerConfig.M_Yaw;
var delta = context.ReadValue<Vector2>();
switch (context.control.device)
{

View File

@@ -1,15 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
public class ExcuteCommand : MonoBehaviour
{
public string command;
public void Excute()
{
Data.Set("Cmd", command);
}
}
}

View File

@@ -0,0 +1,22 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
public class ExecuteCommand : MonoBehaviour
{
public string command;
[SerializeReference, SubclassSelector] private IReference format;
public void Execute()
{
Data.Set("Cmd", command);
}
public void Execute(string cmd)
{
if(format!=null)
cmd = format.Value.Replace("{x}",cmd);
BITCommands.Excute(cmd);
}
}
}

View File

@@ -5,11 +5,10 @@ namespace BITKit
{
public record PlayerConfig
{
[SaveData]
public static PlayerConfig singleton = new();
public float sensitivity = 1.81f;
public float touchSensitivity = 0.22f;
public float m_yaw = 0.022f;
public float fov = 75;
public static readonly PlayerConfig Singleton = new();
public float Sensitivity = 1.81f;
public float TouchSensitivity = 0.22f;
public float M_Yaw = 0.022f;
public float Fov = 75;
}
}

View File

@@ -5,7 +5,6 @@ using UnityEngine.SceneManagement;
using System.Linq;
using Newtonsoft.Json;
using UnityEngine.Pool;
using BITModel;
namespace BITKit
{
public class UnityDiagnostics : MonoBehaviour, IDiagnostics

View File

@@ -14,7 +14,9 @@
"GUID:28c2d6a6727d47442a24a353f0d37846",
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:be17a8778dbfe454890ed8279279e153"
"GUID:be17a8778dbfe454890ed8279279e153",
"GUID:96f476e982d6fb945bfc9140ba094b7f",
"GUID:4307f53044263cf4b835bd812fc161a4"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -5,6 +5,9 @@ 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
@@ -31,10 +34,17 @@ namespace BITKit.Entities
public virtual void EquipEvent(string eventName){}
public virtual void AnimationEvent(string eventName){}
}
public class EntityEquipment : EntityComponent
[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();
@@ -56,6 +66,13 @@ namespace BITKit.Entities
{
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,7 +6,10 @@
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
"GUID:f822dbf6fdfd4a5469cccaa2e4eed3b6",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:75469ad4d38634e559750d17036d5f7c"
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:508392158bd966c4d9c21e19661a441d"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -1,3 +1,4 @@
using BITKit.Sensors;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Interactions;
@@ -6,24 +7,16 @@ namespace BITKit.Entities.Player
public class EntityInteractive : EntityPlayerComponent
{
[Header(Constant.Header.Settings)]
public float distance;
public LayerMask layerMask;
[Header(Constant.Header.Input)]
public InputActionReference interactiveAction;
private readonly InputActionGroup inputActionGroup = new();
[Header(Constant.Header.Gameobjects)]
[SerializeField] private Transform cameraTransform;
[SerializeReference, SubclassSelector] private ISensor sensor;
[Header(Constant.Header.InternalVariables)]
private ISelectable selected;
private IntervalUpdate cd = new(0.08f);
public override void OnUpdate(float deltaTime)
{
if (Physics.Raycast(cameraTransform.position,cameraTransform.forward, out var raycastHit, distance, layerMask,QueryTriggerInteraction.Collide))
if (sensor.Get().TryGetAny(x=>x.TryGetComponentAny<ISelectable>(out _),out var detected))
{
if (raycastHit.transform.TryGetComponentAny<ISelectable>(out var _detected))
if (detected.TryGetComponentAny<ISelectable>(out var _detected))
{
if (_detected == selected)
{
@@ -68,7 +61,7 @@ namespace BITKit.Entities.Player
}
public void Interactive(InputAction.CallbackContext context)
{
if (context.interaction is not PressInteraction || !context.performed) return;
if (context.interaction is not PressInteraction || !context.performed || cd.AllowUpdate is false) return;
var _selected = selected;
if (_selected is not MonoBehaviour monoBehaviour) return;
if (monoBehaviour.TryGetComponentAny<IAction>(out var action))

View File

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

View File

@@ -0,0 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit.Entities.Value
{
/// <summary>
/// 实体属性接口,通常用于角色的可被数值化的属性
/// </summary>
public interface IEntityValue
{
}
}

View File

@@ -17,8 +17,21 @@ namespace BITKit.Entities
private readonly Processor processor = new();
public IEntityComponent[] entityComponents { get; set; }
public ulong Id { get; private set; }
public CancellationToken CancellationToken => _cancellationToken;
Core.Entites.IEntityComponent[] Core.Entites.IEntity.Components => _components;
bool Core.Entites.IEntity.RegisterComponent<T>(T component)
{
throw new InvalidOperationException("Unity Entity can't register component");
}
IServiceProvider Core.Entites.IEntity.ServiceProvider=> throw new InvalidOperationException("Unity Entity can't register component");
private CancellationToken _cancellationToken;
private bool isInitialized;
private Core.Entites.IEntityComponent[] _components => entityComponents;
private void Awake()
{
Id = (ulong)Guid.NewGuid().GetHashCode();

View File

@@ -41,22 +41,22 @@ public class UnityEntitiesServiceSingleton:IEntitiesService
public IEntity Get(ulong id) => UnityEntitiesService.Get(id);
public IEntity[] Query<T>() where T : IEntityComponent
public IEntity[] Query<T>()
{
return UnityEntitiesService.Query<T>();
}
public T[] QueryComponents<T>() where T : IEntityComponent
public T[] QueryComponents<T>()
{
return UnityEntitiesService.QueryComponents<T>();
}
public (T, T1)[] QueryComponents<T, T1>() where T : IEntityComponent where T1 : IEntityComponent
public (T, T1)[] QueryComponents<T, T1>()
{
return UnityEntitiesService.QueryComponents<T, T1>();
}
public (T, T1, T2)[] QueryComponents<T, T1, T2>() where T : IEntityComponent where T1 : IEntityComponent where T2 : IEntityComponent
public (T, T1, T2)[] QueryComponents<T, T1, T2>()
{
return UnityEntitiesService.QueryComponents<T, T1, T2>();
}
@@ -64,13 +64,12 @@ public class UnityEntitiesServiceSingleton:IEntitiesService
public class UnityEntitiesService : MonoBehaviour,IEntitiesService
{
[RuntimeInitializeOnLoadMethod]
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void Initialize()
{
Dictionary.Clear();
RegisterQueue.Clear();
UnRegisterQueue.Clear();
}
public static bool Register(IEntity entity)
{
@@ -127,12 +126,12 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
public static IEntity Get(ulong id)=>Dictionary[id];
IEntity IEntitiesService.Get(ulong id)=>Get(id);
IEntity[] IEntitiesService.Query<T>()=>Query<T>();
public static IEntity[] Query<T>() where T : IEntityComponent
public static IEntity[] Query<T>()
{
return Entities.Where(x => ((Entity)x).TryGetComponentAny<T>(out _)).ToArray();
}
T[] IEntitiesService.QueryComponents<T>()=>QueryComponents<T>();
public static T[] QueryComponents<T>() where T : IEntityComponent
public static T[] QueryComponents<T>()
{
var list = ListPool<T>.Get();
foreach (var iEntity in Entities)
@@ -150,7 +149,7 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
return value;
}
(T, T1)[] IEntitiesService.QueryComponents<T,T1>()=>QueryComponents<T,T1>();
public static (T, T1)[] QueryComponents<T, T1>() where T : IEntityComponent where T1 : IEntityComponent
public static (T, T1)[] QueryComponents<T, T1>()
{
var list = ListPool<(T t, T1 t1)>.Get();
foreach (var iEntity in Entities)
@@ -168,7 +167,7 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
return value;
}
(T, T1, T2)[] IEntitiesService.QueryComponents<T,T1,T2>()=>QueryComponents<T,T1,T2>();
public static (T, T1, T2)[] QueryComponents<T, T1, T2>() where T : IEntityComponent where T1 : IEntityComponent where T2 : IEntityComponent
public static (T, T1, T2)[] QueryComponents<T, T1, T2>()
{
var list = ListPool<(T t, T1 t1, T2 t2)>.Get();
foreach (var iEntity in Entities)

View File

@@ -25,7 +25,6 @@ namespace BITKit.Entities.Editor
rootVisualElement.styleSheets.Add(BITEditorUtils.InspectorStyleSheet);
rootVisualElement.styleSheets.Add(BITEditorUtils.Style);
rootVisualElement.AddToClassList("pa-8");
}
private void Update()

View File

@@ -1,27 +0,0 @@
{
"name": "BITFALL.Entities.EquipSelector.Runtime",
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
"GUID:b355af20142c0c541ba9588ab1d0f64e",
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:30cdc242b1ac6a944a460f4ab0b77b88",
"GUID:677cd05ca06c46b4395470200b1acdad",
"GUID:7efac18f239530141802fb139776f333",
"GUID:84d565da37ad40546a118cfb3c3509f3",
"GUID:42a9827d94e00374aa52e51f0a1b035c",
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:9354affc93e0f3e4a904785e7d4c0f59"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -1,164 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BITKit;
using BITKit.Entities;
using UnityEngine.InputSystem;
using static UnityEditor.Progress;
using System.Diagnostics;
using System.Linq;
using BITKit.Entities.Player;
using UnityEngine.InputSystem.Interactions;
using Debug = UnityEngine.Debug;
namespace BITFALL
{
[CustomType(typeof(IPlayerEquipSelector))]
public class PlayerEquipSelector : EntityComponent,TaskSubscriber<IBasicItem>,IEntityInventoryCallback,IPlayerEquipSelector
{
[Header(Constant.Header.Components)]
public EntityEquipment equipment;
[Header(Constant.Header.InternalVariables)]
private readonly Dictionary<int, IBasicItem> equips=new();
private IBasicItemContainer inventory;
public event Action<IBasicItem> OnEquip;
public event Action<IBasicItem> OnDeEquip;
public event Action<IDictionary<int, IBasicItem>> OnUpdateEquip;
private IBasicItem currentEquip;
public override void OnAwake()
{
var health = entity.Get<IHealth>();
health.OnSetAlive += OnSetAlive;
OnDeEquip += DeEquip;
OnEquip += Equip;
}
public override void OnStart()
{
base.OnStart();
entity.RegisterCallback<TaskSubscriber<IBasicItem>>(this);
inventory = entity.Get<IBasicItemContainer>();
}
public void OnPrimary(InputAction.CallbackContext context)
{
if (context is not {interaction:PressInteraction ,performed:true}) return;
Equip(1);
}
public void OnSecondary(InputAction.CallbackContext context)
{
if (context is not {interaction:PressInteraction ,performed:true}) return;
Equip(2);
}
public void OnTertiary(InputAction.CallbackContext context)
{
if (context is not {interaction:PressInteraction ,performed:true}) return;
if (Equip(3) is false)
{
Equip(-1);
}
}
public void OnQuaternary(InputAction.CallbackContext context)
{
if (context is not {interaction:PressInteraction ,performed:true}) return;
Equip(4);
}
public void OnHolster(InputAction.CallbackContext context)
{
if (context is not {interaction:PressInteraction ,performed:true}) return;
Equip(-1);
}
private void OnSetAlive(bool alive)
{
if (alive) return;
foreach (var x in equips.ToArray())
{
inventory.Add(x.Value);
}
equips.Clear();
UpdateEquip();
Equip(-1);
}
int TaskSubscriber<IBasicItem>.Priority => 0;
bool TaskSubscriber<IBasicItem>.TryExecute(IBasicItem value)
{
var asset = value.GetAssetable();
if (IsSupportItem(value) is false) return false;
switch (asset)
{
case var _ when asset.TryGetProperty<EquipmentAsWeapon>(out _):
if (equips.TryAdd(1, value) || equips.TryAdd(2,value))
{
OnEquip?.Invoke(value);
UpdateEquip();
return true;
}
break;
}
return false;
}
public void OnAdd(IBasicItem item)
{
}
public void OnRemove(IBasicItem item)
{
if (IsSupportItem(item) is false)
{
UpdateEquip();
}
}
private bool IsSupportItem(IBasicItem item)
{
return equipment.equips.list.Any(x => x.AddressablePath == item.AddressablePath);
}
private void UpdateEquip()
{
OnUpdateEquip?.Invoke(new Dictionary<int, IBasicItem>(equips));
}
public bool TryDeEquip(IBasicItem item)
{
if (item is null) return false;
if (equips.Any(x => x.Value.AddressablePath == item.AddressablePath) is false) return false;
var index = equips.Single(x=>x.Value.AddressablePath==item.AddressablePath).Key;
if (equips.TryRemove(index) is false) return false;
if (!inventory.Add(item)) return false;
OnDeEquip?.Invoke(item);
UpdateEquip();
return true;
}
private void Equip(IBasicItem item)
{
if (item is null)
{
equipment.equips.Entry(-1);
}
else
{
equipment.equips.Entry(x=>x.AddressablePath == item.AddressablePath);
}
}
private bool Equip(int index)
{
if (!equips.TryGetValue(index, out var x) && index is not -1) return false;
if (index is -1)
{
OnEquip?.Invoke(x);
}
return true;
}
private void DeEquip(IBasicItem item)
{
equipment.equips.Entry(-1);
}
}
}

View File

@@ -0,0 +1,141 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.UIElements;
#if UNITY_EDITOR
using Cysharp.Threading.Tasks;
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.UIElements;
using Object = UnityEngine.Object;
namespace BITKit.Events
{
[Serializable]
public class UnityEventData
{
public Object Target;
public string MethodName;
}
[Serializable]
public class UnityEvent
{
public List<UnityEventData> Targets = new List<UnityEventData>();
public void Invoke(params object[] objects)
{
foreach (var x in Targets)
{
x.Target.GetType().GetMethod(x.MethodName)?.Invoke(x.Target,objects);
}
}
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(UnityEvent))]
public class UnityEventDataPropertyDrawer:PropertyDrawer
{
private VisualElement root;
private UnityEvent agent;
private SerializedProperty _property;
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
_property = property;
agent = property.Get<UnityEvent>();
root = new VisualElement
{
style =
{
paddingLeft = 10,
paddingTop = 10,
paddingRight = 10,
paddingBottom = 10,
}
};
root.styleSheets.Add(BITEditorUtils.InspectorStyleSheet);
Update();
return root;
}
private void Update()
{
root.Clear();
var targets = _property.FindPropertyRelative(nameof(UnityEvent.Targets));
_property.serializedObject.Update();
var label = root.Create<Label>();
label.text = _property.displayName;
var flex = root.Create<VisualElement>();
flex.style.flexDirection = FlexDirection.Row;
var containers = new[] { flex.Create<VisualElement>(), flex.Create<VisualElement>(),flex.Create<VisualElement>() };
containers[1].style.flexGrow = 1;
for (var i = 0; i < targets.arraySize; i++)
{
var x = agent.Targets[i];
var objectField = containers[0].Create<ObjectField>();
var field = containers[1].Create<DropdownField>();
var removeButton = containers[2].Create<Button>();
var data = targets.GetArrayElementAtIndex(i);
var target = data.FindPropertyRelative(nameof(UnityEventData.Target));
objectField.BindProperty(target);
if (x.Target is not null)
{
field.choices = x.Target.GetType().GetMethods().Select(x => x.Name).ToList();
}
field.value = x.MethodName;
field.RegisterValueChangedCallback(changeEvent =>
{
x.MethodName = changeEvent.newValue;
});
field.style.flexGrow = 1;
removeButton.text = "X";
removeButton.clicked+=()=>{
agent.Targets.Remove(x);
Update();
};
}
var addButton = root.Create<Button>();
addButton.text = "Add";
addButton.clicked += () =>
{
agent.Targets.Add(new());
Update();
};
var invokeButton = root.Create<Button>();
invokeButton.text = "Invoke";
invokeButton.clicked +=()=> agent.Invoke();
}
}
#endif
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Http;
using Cysharp.Threading.Tasks;
using UnityEngine;
// ReSharper disable UnassignedField.Local
namespace BITKit.Http
{
[Serializable]
public class HttpAction : IAction
{
private static readonly HttpClient _httpClient = new();
[SerializeReference, SubclassSelector] private IReference url;
public void Execute()
{
_httpClient.GetAsync(url.Value).AsUniTask().Forget();
}
}
}

View File

@@ -17,9 +17,11 @@ namespace BITKit.Http
[Header(Constant.Header.Settings)]
[SerializeReference,SubclassSelector] private IReference url;
[SerializeField] private double interval;
[SerializeField] private CollisionDetectionMode detectionMode;
[Header(Constant.Header.Output)]
[SerializeField] private UnityEvent<string> output;
[SerializeField] private UnityEvent<string> onException;
[Header(Constant.Header.Debug)]
[SerializeField, ReadOnly] private double time;
@@ -39,6 +41,14 @@ AutoReset = true
{
timer.Interval = interval*1000;
timer.Elapsed += (x, y) => OnUpdate();
timer.AutoReset = detectionMode switch
{
CollisionDetectionMode.ContinuousDynamic => true,
CollisionDetectionMode.ContinuousSpeculative => true,
CollisionDetectionMode.Continuous => true,
CollisionDetectionMode.Discrete => false,
_ => throw new ArgumentOutOfRangeException()
};
timer.Start();
}
private void OnDestroy()
@@ -50,14 +60,24 @@ AutoReset = true
{
Stopwatch stopwatch = new();
stopwatch.Start();
await _httpClient.GetStringAsync(url.Value);
//var result = await _httpClient.GetStringAsync(url.Value);
var response = await _httpClient.GetAsync(url.Value, _cancellationToken);
var result =await response.Content.ReadAsStringAsync();
_cancellationToken.ThrowIfCancellationRequested();
#if UNITY_EDITOR
if (UnityEditor.EditorApplication.isPlaying is false) return;
#endif
stopwatch.Stop();
time =System.TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalSeconds;
output.Invoke(url.Value);
await UniTask.SwitchToMainThread(_cancellationToken);
if (response.StatusCode is not System.Net.HttpStatusCode.OK)
{
onException.Invoke(result);
}
else
{
output.Invoke(result);
}
if(timer.AutoReset==false)
timer.Start();
}
}
}

View File

@@ -1,13 +1,22 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
// ReSharper disable InvertIf
namespace BITKit
{
public class LocationAdditive : MonoBehaviour
{
public Vector3 GlobalPosition { get; private set; }
public Vector3 GlobalEuler { get; private set; }
public Vector3 GlobalRotation { get; private set; }
private Vector3 currentPosition;
private Vector3 currentEuler;
private Vector3 globalPosition;
private Quaternion globalRotation;
public void AddPosition(Vector3 value)
{
currentPosition += value;
@@ -16,18 +25,44 @@ namespace BITKit
{
currentEuler += value;
}
public void SetGlobalPosition(Vector3 value)
{
globalPosition = value;
}
public void SetGlobalRotation(Quaternion value)
{
globalRotation = value;
}
public void LateUpdate()
{
if (currentEuler.IsDefault() is false)
switch (currentEuler,globalRotation)
{
transform.localEulerAngles = currentEuler;
currentEuler = default;
case var (euler,rotation) when euler.IsDefault() is false && rotation.IsDefault():
transform.localRotation = Quaternion.Euler(euler);
break;
case var (euler,rotation) when euler.IsDefault() && rotation.IsDefault() is false:
transform.rotation = globalRotation = rotation;
break;
case var (euler,rotation) when euler.IsDefault() is false && rotation.IsDefault() is false:
transform.rotation = globalRotation = rotation * Quaternion.Euler(euler);
break;
}
if (currentPosition.IsDefault() is false)
switch (currentPosition,globalPosition)
{
transform.localPosition = currentPosition;
currentPosition = default;
case var (position,global) when position.IsDefault() is false && global.IsDefault():
transform.localPosition = position;
break;
case var (position,global) when position.IsDefault() && global.IsDefault() is false:
transform.position =globalPosition= global;
break;
case var (position,global) when position.IsDefault() is false && global.IsDefault() is false:
transform.position = globalPosition = global + position;
break;
}
currentEuler = Vector3.zero;
currentPosition = Vector3.zero;
}
}
}

View File

@@ -0,0 +1,17 @@
{
"name": "BITKit.Net.Http",
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,55 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using BITKit.Entities;
using UnityEngine;
namespace BITKit.Net.Http
{
[CustomType(typeof(IHttpListenerService))]
public class UnityBasedHttpListenerService : EntityComponent,IHttpListenerService
{
[SerializeField] private int port = 8080;
[SerializeField] private bool autoStart = true;
private readonly IHttpListenerService _service = new HttpListenerService();
public bool IsListening => _service.IsListening;
public int Port
{
get => _service.Port;
set => _service.Port = port = value;
}
public event Func<HttpListenerRequest, HttpContent> OnRequest
{
add => _service.OnRequest += value;
remove => _service.OnRequest -= value;
}
public override void OnStart()
{
if (!autoStart) return;
_service.Port = port;
_service.Start();
}
public override void OnDestroyComponent()
{
_service.Stop();
}
void IHttpListenerService.Start()
{
_service.Port = port;
_service.Start();
}
void IHttpListenerService.Stop()
{
_service.Stop();
}
}
}

View File

@@ -0,0 +1,101 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
namespace BITKit.Net.LAN
{
public class UnityBasedLanBroadcaster : MonoBehaviour,ILANBroadcaster
{
[SerializeField] private int port;
[SerializeField] private bool broadcastOnStart = true;
[SerializeField] private bool listenOnStart = true;
[SerializeField] private bool log = true;
[SerializeField] private UnityEvent<EndPoint, string> onReceive;
[SerializeField] private UnityEvent<string> OnReceiveAsEndPoint;
private readonly ILANBroadcaster _service = new UdpBasedLanBroadcaster();
private CancellationToken _cancellationToken;
public int Port
{
get => port;
set => port = _service.Port = value;
}
public byte[] Buffer
{
get => _service.Buffer;
set => _service.Buffer = value;
}
public event Action<EndPoint, string> OnReceive
{
add => _service.OnReceive += value;
remove => _service.OnReceive -= value;
}
private void Start()
{
_cancellationToken = gameObject.GetCancellationTokenOnDestroy();
OnReceive += OnReceiveData;
_service.Port = port;
if(broadcastOnStart)
StartBroadcast();
if(listenOnStart)
StartListen();
}
private void OnDestroy()
{
StopBroadcast();
StopListen();
}
public void StartBroadcast()
{
_service.StartBroadcast();
}
public void StopBroadcast()
{
_service.StopBroadcast();
}
public void StartListen()
{
_service.StartListen();
}
public void StopListen()
{
_service.StopListen();
}
private async void OnReceiveData(EndPoint endPoint, string message)
{
try
{
await UniTask.SwitchToMainThread(_cancellationToken);
onReceive?.Invoke(endPoint,message);
OnReceiveAsEndPoint?.Invoke(endPoint.ToString());
if (log)
{
BIT4Log.Log<ILANBroadcaster>($"Receive from {endPoint}\nMessage:{message}");
}
}
catch(OperationCanceledException){}
catch (Exception e)
{
Debug.LogException(e);
}
}
}
}

View File

@@ -1,71 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using System;
using System.IO;
namespace BITKit
{
public class MessageReader : NetMessageReader<NetMessageProxy.MyMessage>
{
public override NetMessageProxy.MyMessage ReadBinary(BinaryReader reader)
{
return new()
{
_string = reader.ReadString(),
_int = reader.ReadInt16(),
_float = reader.ReadSingle(),
};
}
public override void WriteBinary(BinaryWriter writer, NetMessageProxy.MyMessage value)
{
writer.Write(value._string);
writer.Write(value._int);
writer.Write(value._float);
}
}
public class NetMessageProxy : MonoBehaviour
{
[System.Serializable]
public record MyMessage
{
public string _string;
public int _int;
public float _float;
}
[SerializeReference, SubclassSelector] public INetMessager provider;
public MyMessage testMessage;
void Awake()
{
provider.Init();
DI.Register<INetMessager>(provider);
provider.Register<MyMessage>(OnReceiveMessage);
}
[BIT]
public void SendTestMessage()
{
BITAppForUnity.ThrowIfNotPlaying();
provider.Send(testMessage);
}
[BIT]
public void SelfDiagnostics()
{
BITAppForUnity.ThrowIfNotPlaying();
BIT4Log.Log<NetMessageProxy>(provider.GetDiagnostics());
}
void OnReceiveMessage(MyMessage message)
{
BIT4Log.Log<NetMessageProxy>($"已成功收到NetMessage:\n{message}");
}
}
#if UNITY_EDITOR
[UnityEditor.CustomEditor(typeof(NetMessageProxy))]
public class NetMessageProxyInspector : BITInspector<NetMessageProxy>
{
}
#endif
}

View File

@@ -1,80 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Net;
using System.Threading;
using System.IO;
using System.Text;
using Cysharp.Threading.Tasks;
using BITKit.HttpNet.Model;
using System.Linq;
namespace BITKit.HttpNet
{
public class NetworkListener : MonoBehaviour
{
public int port = 7001;
public Provider output;
HttpListener listener = new();
bool isEnabled;
void OnEnable()
{
isEnabled = true;
}
void OnDisable()
{
isEnabled = false;
listener.Stop();
}
void Start()
{
Excute();
}
async void Excute()
{
if (!HttpListener.IsSupported)
{
Debug.Log("HttpListener is not supported this platform");
return;
}
listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
listener.Prefixes.Add($"http://+:{port}/");
var ticker = await DI.GetAsync<IThreadTicker>();
ticker.Add(Listen);
}
void Listen()
{
listener.Start();
while (isEnabled)
{
var result = listener.BeginGetContext(ListenerCallback, listener);
result.AsyncWaitHandle.WaitOne();
}
}
private void ListenerCallback(IAsyncResult result)
{
var context = listener.EndGetContext(result);
var request = context.Request;
var response = context.Response;
var output = response.OutputStream;
var responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
try
{
this.output?.Set(request);
responseString = BITModel.ContextModel.Get("success");
}
catch (System.Exception e)
{
responseString = BITModel.ContextModel.Error(e);
Debug.LogError(e);
}
var buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
output.Write(buffer);
output.Close();
response.Close();
}
}
}

View File

@@ -0,0 +1,24 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
namespace BITKit
{
public static partial class ObjectExtensions
{
public static T GetTargetAs<T>(this SerializedProperty self) where T : class
{
var objectType = self.serializedObject.targetObject.GetType();
var field = objectType.GetField(self.propertyPath);
return field.GetValue(self.serializedObject.targetObject) as T;
}
}
}
#endif

View File

@@ -3,9 +3,9 @@ using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
public class PhysicsImpacter : MonoBehaviour
public class PhysicsImpact : MonoBehaviour
{
void OnCollisionEnter(Collision collision)
private void OnCollisionEnter(Collision collision)
{
if (collision.transform.TryGetComponent<IPhysicsImpact>(out var impact))
{

View File

@@ -0,0 +1,17 @@
using System.Collections;
using System.Collections.Generic;
using BITKit.Events;
using UnityEditor;
using UnityEngine;
namespace BITKit.Physics
{
public class Prop_Physics : MonoBehaviour
{
[SerializeField] public UnityEvent OnImpact;
public void ()
{
Debug.Log("检测完成");
}
}
}

View File

@@ -20,25 +20,25 @@ namespace BITKit
public ReferenceSO so;
public override string Get() => so.value.IsNullOrEmpty() ? so.name : so.value;
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(ReferenceScriptableObject))]
public class ReferenceScriptableObjectDrawer : BITProperty
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
VisualElement root = new();
root.Add(base.CreatePropertyGUI(property));
Button button = new();
root.Add(button);
return root;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
base.OnGUI(position, property, label);
EditorGUI.PropertyField(position, property);
EditorGUI.LinkButton(position, "New Button");
}
}
#endif
// #if UNITY_EDITOR
// [CustomPropertyDrawer(typeof(ReferenceScriptableObject))]
// public class ReferenceScriptableObjectDrawer : BITProperty
// {
// public override VisualElement CreatePropertyGUI(SerializedProperty property)
// {
// VisualElement root = new();
// root.Add(base.CreatePropertyGUI(property));
//
// Button button = new();
// root.Add(button);
// return root;
// }
// public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
// {
// base.OnGUI(position, property, label);
// EditorGUI.PropertyField(position, property);
// EditorGUI.LinkButton(position, "New Button");
// }
// }
// #endif
}

View File

@@ -9,6 +9,7 @@ using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.SceneManagement;
using Debug = UnityEngine.Debug;
// ReSharper disable Unity.LoadSceneWrongIndex
namespace BITKit.SceneManagement
{
@@ -48,8 +49,10 @@ namespace BITKit.SceneManagement
[RuntimeInitializeOnLoadMethod]
private static void Initialize()
{
if (AllowInitialize)
if (AllowInitialize && SceneManager.sceneCount is not 0)
{
SceneManager.LoadSceneAsync(0);
}
}
#endif
public static event Action<string> OnLoadScene;

View File

@@ -0,0 +1,18 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using UnityEngine;
namespace BITKit.Sensors
{
public class MixSensor : Sensor
{
[SerializeReference, SubclassSelector] private ISensor[] sensors;
public override IEnumerable<Transform> Get()=>sensors.SelectMany(x => x.Get());
public override bool IsValid(Collider _collider) => sensors.Any(x => x.IsValid(_collider) is false) is false;
public override float GetDistance() => sensors.Min(x => x.GetDistance());
public override UniTask Execute() => UniTask.WhenAll(sensors.Select(x => x.Execute()));
}
}

View File

@@ -29,6 +29,7 @@ namespace BITKit.Sensors
private readonly Queue<Collider> triggerEnterQueue=new();
private readonly Queue<Collider> triggerExitQueue=new();
private bool diagnosisNextFrame;
private void OnTriggerEnter(Collider _collider)
{
@@ -87,7 +88,7 @@ namespace BITKit.Sensors
while (triggerEnterQueue.TryDequeue(out var _collider))
{
if (IsValid(_collider) is false) return;
if (triggerExitQueue.Contains(_collider) || detected.Contains(_collider))continue;
if (detected.Contains(_collider))continue;
detected.Add(_collider);
}
while (triggerExitQueue.TryDequeue(out var _collider))
@@ -95,6 +96,14 @@ namespace BITKit.Sensors
if (IsValid(_collider) is false) return;
detected.Remove(_collider);
}
diagnosisNextFrame = detected.Any(x => x.enabled is false);
if (diagnosisNextFrame)
{
detected = detected.Where(x => x.enabled).ToList();
diagnosisNextFrame = false;
}
}
}
#if UNITY_EDITOR

View File

@@ -22,5 +22,10 @@ namespace BITKit.UX
{
Alert.Print(message);
}
public void Execute(string message)
{
Alert.Print("提示", message);
}
}
}

View File

@@ -20,6 +20,15 @@ namespace BITKit.UX
{
UXAlert.Singleton.PrintAlertMessage(message);
}
public static void Print(string title, string content)
{
Print(new AlertMessage()
{
title = title,
message = content
});
}
}
public class UXAlert : MonoBehaviour
{

View File

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

View File

@@ -7,7 +7,7 @@ using UnityEngine.UIElements;
// ReSharper disable MemberCanBePrivate.Global
public class UXBuilder : MonoBehaviour
{
[SerializeField, SerializeReference, SubclassSelector]
[SerializeReference, SubclassSelector]
private IVisualElementProvider visualElementProvider;
[SerializeField] private VisualTreeAsset visualTreeAsset;
@@ -24,9 +24,9 @@ public class UXBuilder : MonoBehaviour
private IList _itemSource;
public T Build<T>() where T : VisualElement
public T Build<T>() where T : VisualElement,new()
{
var clone = visualTreeAsset.CloneTree()[0];
var clone =visualTreeAsset is not null ? visualTreeAsset.CloneTree()[0] : new T();
visualElementProvider.GetVisualElement().Add(clone);
instances.Add(clone);
return clone as T;

View File

@@ -21,15 +21,6 @@ namespace BITKit.UX
public const string Inspector = "inspector-container";
public const string ProcessBarFill = "fill-bar";
public const string Toggle = "context-toggle";
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

@@ -59,7 +59,7 @@ namespace BITKit.UX
[Header(Constant.Header.Settings)]
public string bindName;
[SerializeField, SerializeReference, SubclassSelector]
IReference bindNameProvider = new GetNameFromGameobject();
protected IReference bindNameProvider = new GetNameFromGameobject();
[Header(Constant.Header.InternalVariables)]
private UX m_visualElement;
protected IStyle style => visualElement.style;

View File

@@ -0,0 +1,11 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit.UX
{
public class UXJsonBasedTable : UXElement<JsonBasedTable>
{
}
}

View File

@@ -16,7 +16,15 @@ namespace BITKit.UX
public override void OnStart()
{
base.OnStart();
visualElement.RegisterValueChangedCallback(OnValueChanged);
switch (visualElement)
{
case CustomTextField customTextField:
customTextField.OnValueChanged += OnValueChanged;
break;
default:
visualElement.RegisterValueChangedCallback(OnValueChanged);
break;
}
}
public async void Set(string t)
{
@@ -32,9 +40,13 @@ namespace BITKit.UX
return visualElement.value;
}
void OnValueChanged(ChangeEvent<string> changeEvent)
private void OnValueChanged(string value)
{
onValueChanged.Invoke(changeEvent.newValue);
onValueChanged.Invoke(value);
}
private void OnValueChanged(ChangeEvent<string> changeEvent)
{
OnValueChanged(changeEvent.newValue);
}
}
}

View File

@@ -0,0 +1,45 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UIElements;
namespace BITKit.UX
{
public class CustomTextField : TextField
{
public const string errorUssName = "error";
public new class UxmlTraits : TextField.UxmlTraits
{
private readonly UxmlStringAttributeDescription m_RegexAttribute = new ()
{
name = "Regex"
};
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
{
base.Init(ve, bag, cc);
var textField = (CustomTextField)ve;
textField.Regex = m_RegexAttribute.GetValueFromBag(bag, cc);
}
}
public new class UxmlFactory : UxmlFactory<CustomTextField, UxmlTraits> { }
public CustomTextField():base()
{
this.RegisterValueChangedCallback(OnValueChangedInternal);
}
public string Regex { get; set; }
public event Action<string> OnValueChanged;
private void OnValueChangedInternal(ChangeEvent<string> evt)
{
var isMatch = string.IsNullOrEmpty(Regex) || System.Text.RegularExpressions.Regex.IsMatch(evt.newValue, Regex);
this.Q("unity-text-input").EnableInClassList(errorUssName, !isMatch);
if (isMatch)
{
OnValueChanged?.Invoke(evt.newValue);
}
}
}
}

View File

@@ -0,0 +1,96 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.UIElements;
namespace BITKit.UX
{
/// <summary>
/// 基于Json的Table生成元素
/// </summary>
public class JsonBasedTable : VisualElement
{
public new class UxmlTraits : VisualElement.UxmlTraits
{
private readonly UxmlStringAttributeDescription m_JsonAttribute = new ()
{
name = "Json"
};
private readonly UxmlBoolAttributeDescription m_allowWarningsAttribute = new ()
{
name = "allowWarnings",
defaultValue = false
};
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
{
base.Init(ve, bag, cc);
var table = (JsonBasedTable)ve;
table.Json = m_JsonAttribute.GetValueFromBag(bag, cc);
table.AllowWarning = m_allowWarningsAttribute.GetValueFromBag(bag, cc);
}
}
public new class UxmlFactory : UxmlFactory<JsonBasedTable, UxmlTraits> { }
private string _json;
public string Json
{
get => _json;
set
{
_json = value;
ApplyJson();
}
}
public bool AllowWarning { get; set; }
private readonly List<VisualElement> instanceColumns = new();
private void ApplyJson()
{
try
{
Clear();
style.flexDirection = FlexDirection.Row;
style.justifyContent = Justify.SpaceAround;
instanceColumns.Clear();
if (string.IsNullOrEmpty(Json)) return;
var jArray = JArray.Parse(Json);
var colLength = jArray.Max(x => x.Count());
var rowLength = jArray.Count;
for (var i = 0; i < colLength; i++)
{
instanceColumns.Add(this.Create<VisualElement>());
}
for (var y = 0; y < rowLength; y++)
{
var array = jArray[y] as JArray;
for (var x = 0; x < colLength; x++)
{
var instance = instanceColumns[x];
if (x >= array!.Count)
{
instance.Create<VisualElement>();
}
else
{
var label = instance.Create<Label>();
label.text = array[x].ToString();
}
}
}
}
catch (Exception)
{
if (AllowWarning)
throw;
}
}
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@@ -50,6 +51,7 @@ namespace BITKit.UX
_container.pickingMode = PickingMode.Ignore;
}
public override VisualElement contentContainer => _container;
public event Action<int> OnTabChanged;
private int currentTab=-1;
public int CurrentTab
@@ -116,6 +118,7 @@ namespace BITKit.UX
}
if(_container.Children().TryGet(index,out var element))
element.SetActive(true);
OnTabChanged?.Invoke(index);
}
}
}

View File

@@ -0,0 +1,13 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit.UX
{
[SerializeField]
public class UXServiceBasedAllowTouch : ICondition
{
public bool OnCheck() => true;
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
#endif
@@ -14,7 +15,10 @@ namespace BITKit.UX
/// </summary>
public class UXService : MonoBehaviour, IUXService
{
[RuntimeInitializeOnLoadMethod]
/// <summary>
/// 重新初始化,使用<see cref="RuntimeInitializeLoadType.SubsystemRegistration"/>确保在所有子系统注册后执行
/// </summary>
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void Initialized()
{
RegistryQueue.Clear();
@@ -76,8 +80,6 @@ namespace BITKit.UX
[SerializeReference, SubclassSelector] private IUXPanel initialPanel;
[SerializeField] private TextAsset validTexts;
private bool initialized;
private void Awake()
{
@@ -154,7 +156,7 @@ namespace BITKit.UX
{
if (panelsLabel is null || currentPanelLabel is null) return;
panelsLabel.text=string.Join("\n",UXService.Panels);
currentPanelLabel.text = string.Join("\n",UXService.EntryCompletedPanels);
currentPanelLabel.text = string.Join("\n",UXService.EntryCompletedPanels.Select(x=>x.Index));
}
}

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
namespace BITKit.UX
{
public class UXTabContainerEvent : UXElement<TabContainer>
{
[Tooltip("基于<see cref=\"TabBar\"/>的Tab切换事件")]
[SerializeField] private UnityEvent<bool>[] onEntryTab;
[SerializeField] private UnityEvent[] onEntry;
[SerializeField] private UnityEvent[] onExit;
private readonly DoubleBuffer<int> tabBuffer = new();
private CancellationToken _cancellationToken;
public override void OnAwake()
{
base.OnAwake();
_cancellationToken = gameObject.GetCancellationTokenOnDestroy();
}
public override async void OnStart()
{
base.OnStart();
visualElement.OnTabChanged += OnTabChanged;
foreach (var unityEvent in onEntryTab)
{
unityEvent.Invoke(false);
}
try
{
await UniTask.NextFrame(_cancellationToken);
OnTabChanged(visualElement.CurrentTab);
}
catch(OperationCanceledException){}
}
private void OnTabChanged(int obj)
{
if(onEntryTab.TryGetElementAt(tabBuffer.Current,out var unityEvent))
{
unityEvent.Invoke(false);
}
if(onEntryTab.TryGetElementAt(obj, out unityEvent))
{
unityEvent.Invoke(true);
}
if(onExit.TryGetElementAt(tabBuffer.Current,out var exitEvent))
{
exitEvent.Invoke();
}
if(onEntry.TryGetElementAt(obj, out var entryEvent))
{
entryEvent.Invoke();
}
tabBuffer.Release(obj);
}
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@@ -5,6 +6,7 @@ using BITKit;
using UnityEngine.Events;
namespace BITKit.UX
{
[Obsolete]
public class UXWindowEvent : MonoBehaviour, IWindowComponent
{
public UnityEvent<bool> onSetActive = new();

View File

@@ -4,8 +4,8 @@ using UnityEngine;
using UnityEngine.UIElements;
using System.Reflection;
using UnityEngine.AddressableAssets;
#if UNITY_EDITOR
using System;
#if UNITY_EDITOR
using UnityEditor;
using Editor = UnityEditor.Editor;
using UnityEditor.UIElements;
@@ -18,16 +18,13 @@ namespace BITKit
{
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true, Inherited = true)]
public class CustomTypeAttribute : System.Attribute
[CustomEditor(typeof(MonoBehaviour),true)]
public class MonoBehaviorInspector : BITInspector<MonoBehaviour>
{
public readonly Type Type;
public CustomTypeAttribute(Type type)
{
Type = type;
}
}
public class BITEditorUtils
{
public const string InspectorPath = "Assets/BITKit/Unity/UX/BITInspector.uss";