This commit is contained in:
CortexCore 2023-11-15 23:55:06 +08:00
parent 5446067f91
commit 70247f0242
82 changed files with 3271 additions and 579 deletions

View File

@ -10,10 +10,8 @@
"GUID:4307f53044263cf4b835bd812fc161a4",
"GUID:df380645f10b7bc4b97d4f5eb6303d95",
"GUID:d8b63aba1907145bea998dd612889d6b",
"GUID:be17a8778dbfe454890ed8279279e153",
"GUID:9e24947de15b9834991c9d8411ea37cf",
"GUID:84651a3751eca9349aac36a66bba901b",
"GUID:d525ad6bd40672747bde77962f1c401e"
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:e34a5702dd353724aa315fb8011f08c3"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@ -26,9 +26,9 @@ namespace BITKit
public static event Action OnNextLine;
private static Type currentType;
#if UNITY_64
[HideInCallstack]
//[HideInCallstack]
#endif
public static void Log(object x, int debugLevel = 0, ConsoleColor color = ConsoleColor.White)
public static void Log(object x, ConsoleColor color = ConsoleColor.White)
{
OnSetConsoleColor?.Invoke(color);
OnLog?.Invoke(x?.ToString());
@ -36,16 +36,16 @@ namespace BITKit
#if UNITY_64
[HideInCallstack]
#endif
public static void Log<T>(object x, int debugLevel = 0, ConsoleColor color = ConsoleColor.White)
public static void Log<T>(object x, ConsoleColor color = ConsoleColor.White)
{
if (currentType != typeof(T))
{
OnNextLine?.Invoke();
}
#if NET5_0_OR_GREATER
Log($"[{DateTime.Now}]{typeof(T).Name}:{x}", debugLevel);
Log($"[{DateTime.Now}]{typeof(T).Name}:{x}");
#else
Log($"{typeof(T).Name}:{x}", debugLevel);
Log($"{typeof(T).Name}:{x}");
#endif
currentType = typeof(T);
@ -60,16 +60,16 @@ namespace BITKit
#if UNITY_64
[HideInCallstack]
#endif
public static void Warning(object x, int debugLevel = 0)
public static void Warning(object x)
{
OnWarning?.Invoke(x.ToString());
}
#if UNITY_64
[HideInCallstack]
#endif
public static void Warning<T>(object x, int debugLevel = 0)
public static void Warning<T>(object x)
{
Warning($"{typeof(T).Name}:{x}", debugLevel);
Warning($"{typeof(T).Name}:{x}");
}
}
}

View File

@ -15,8 +15,10 @@ namespace BITKit
bool IsEntered { get; set; }
void Entry();
UniTask EntryAsync();
void Entered();
void Exit();
UniTask ExitAsync();
void Exited();
}
[System.Serializable]
@ -92,6 +94,7 @@ namespace BITKit
try
{
await currentElement.ExitAsync();
currentElement.Exited();
}
catch (OperationCanceledException)
{
@ -107,6 +110,7 @@ namespace BITKit
try
{
await nextElement.EntryAsync();
nextElement.Entered();
}
catch (OperationCanceledException){}
OnEntry?.Invoke(nextElement);

View File

@ -1,4 +1,6 @@
namespace BITKit
using System;
namespace BITKit
{
public interface IOptional
{
@ -34,6 +36,10 @@
{
return Allow ? Value : other;
}
public T IfNotAllow(Func<T> other)
{
return Allow ? Value : other.Invoke();
}
public void SetValueThenAllow(T newValue)
{

View File

@ -1,4 +1,6 @@
using System;
using Cysharp.Threading.Tasks;
// ReSharper disable UnassignedGetOnlyAutoProperty
namespace BITKit.UX
@ -10,7 +12,7 @@ namespace BITKit.UX
/// <para>⭐异步打开与关闭</para>
/// <para>⭐当前可见状态</para>
/// <para>⭐基本UI导航回调</para>
public interface IUXPanel
public interface IUXPanel:IEntryElement,IUpdate
{
/// <summary>
/// 该面板是否具有动画
@ -32,8 +34,6 @@ namespace BITKit.UX
/// 该面板是否启用玩家输入
/// </summary>
bool AllowInput { get; }
void Entry();
void Exit();
/// <summary>
/// 事件回调,当面板被打开时触发
/// </summary>
@ -57,16 +57,42 @@ namespace BITKit.UX
public bool AllowInput => _iuxPanelImplementation.AllowInput;
public bool IsEntered
{
get => service.IsEntered;
set => service.IsEntered = value;
}
public void Entry()
{
_iuxPanelImplementation.Entry();
}
public UniTask EntryAsync()
{
return service.EntryAsync();
}
public void Entered()
{
service.Entered();
}
public void Exit()
{
_iuxPanelImplementation.Exit();
}
public UniTask ExitAsync()
{
return service.ExitAsync();
}
public void Exited()
{
service.Exited();
}
public event Action OnEntry
{
add => _iuxPanelImplementation.OnEntry += value;
@ -78,5 +104,10 @@ namespace BITKit.UX
add => _iuxPanelImplementation.OnExit += value;
remove => _iuxPanelImplementation.OnExit -= value;
}
public void OnUpdate(float deltaTime)
{
service.OnUpdate(deltaTime);
}
}
}

View File

@ -1,7 +1,39 @@
using System;
#if UNITY_64
using UnityEngine;
#endif
namespace BITKit
{
public class ConstantHash
{
public ConstantHash(object value)
{
#if UNITY_64
HashCode = Animator.StringToHash(value.ToString());
#else
HashCode = value.GetHashCode();
#endif
AsString = value.ToString();
}
public readonly int HashCode;
public readonly string AsString;
public static implicit operator string (ConstantHash self)
{
return self.AsString;
}
public static implicit operator int (ConstantHash self)
{
return self.HashCode;
}
public static implicit operator ConstantHash(string value)
{
return new ConstantHash(value);
}
public static implicit operator ConstantHash(int value)
{
return new ConstantHash(value);
}
}
public static partial class Constant
{
public partial struct Header

View File

@ -15,6 +15,10 @@ namespace BITKit
void AddListener<T>(TKey key, Action<T> action);
void Invoke<T>(TKey key, T value);
void RemoveListener<T>(TKey key, Action<T> action);
void SetDirect(int key, object value);
void GetDirect(int key, out object value);
void GetDirect<T>(int key,out T value);
}
/// <summary>泛型数据库主要使用方式为Get和Set</summary>
public interface IDatabase
@ -25,8 +29,10 @@ namespace BITKit
}
public class GenericEvent : IGenericEvent<string>, IDatabase, IDiagnostics
{
Dictionary<string, List<object>> events = new();
Dictionary<string, object> dictionary = new();
private readonly Dictionary<int,object> _directDirection = new();
private readonly Dictionary<string, List<object>> events = new();
private readonly Dictionary<string, object> dictionary = new();
public const string defaultEventName = nameof(GenericEvent);
public void AddListener<T>(Action<T> action) =>
AddListener<T>(defaultEventName, action);
@ -120,6 +126,28 @@ namespace BITKit
var list = events.Get(key);
list.TryRemove(action);
}
public void SetDirect(int key, object value)
{
_directDirection.Set(key, value);
}
public void GetDirect(int key,out object value)
{
value = _directDirection.Get(key);
}
public void GetDirect<T>(int key,out T value)
{
try
{
value = (T) _directDirection.Get(key);
}
catch (InvalidCastException)
{
value = default;
}
}
public void DebugAllValues()
{
StringBuilder stringBuilder = new();

View File

@ -28,6 +28,10 @@
{
current++;
}
public void Reset()
{
current = max;
}
public bool AllowOnly => current > 0;
public bool Allow => CanUpdate();
public bool CanUpdate()

View File

@ -3,7 +3,24 @@ using System.Collections.Generic;
namespace BITKit
{
public class ValidHandle
public interface IValidHandle
{
bool Allow { get; }
void AddElement(object obj);
void RemoveElement(object obj);
void AddDisableElements(object obj);
void RemoveDisableElements(object obj);
void SetElements(object obj, bool add = true);
void SetDisableElements(object obj, bool add = true);
void Invoke();
void Invoke(bool value);
void AddListener(Action<bool> action);
void RemoveListener(Action<bool> action);
void Clear();
}
[CustomType(typeof(IValidHandle))]
public sealed class ValidHandle: IValidHandle
{
public ValidHandle() {}
public ValidHandle(Action<bool> boolDelegate)
@ -24,7 +41,7 @@ namespace BITKit
private bool tempEnable;
private Action<bool> EventOnEnableChanged;
public virtual void AddElement(object obj)
public void AddElement(object obj)
{
if (objs.Contains(obj))
{
@ -36,7 +53,8 @@ namespace BITKit
}
CheckEnable();
}
protected void CheckEnable()
private void CheckEnable()
{
tempEnable = objs.Count > 0 && disableObjs.Count == 0;
if (tempEnable != enableHandle)
@ -46,7 +64,7 @@ namespace BITKit
EventOnEnableChanged.Invoke(enableHandle);
}
}
public virtual void RemoveElement(object obj)
public void RemoveElement(object obj)
{
if (objs.Contains(obj))
{
@ -58,8 +76,8 @@ namespace BITKit
}
CheckEnable();
}
public virtual int lenght => objs.Count;
public virtual string[] GetElements()
public int lenght => objs.Count;
public string[] GetElements()
{
List<string> elementNames = new List<string>();
for (int i = 0; i < objs.Count; i++)
@ -68,8 +86,8 @@ namespace BITKit
}
return elementNames.ToArray();
}
public virtual bool Contains(object obj) => objs.Contains(obj);
public virtual void AddDisableElements(object obj)
public bool Contains(object obj) => objs.Contains(obj);
public void AddDisableElements(object obj)
{
if (disableObjs.Contains(obj))
{
@ -103,7 +121,7 @@ namespace BITKit
RemoveElement(obj);
}
}
public virtual void SetDisableElements(object obj, bool add = true)
public void SetDisableElements(object obj, bool add = true)
{
if (add)
{

View File

@ -755,17 +755,6 @@
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "1441da96-a758-483a-9d4a-065dbbea93a3",
"path": "<Keyboard>/backspace",
"interactions": "",
"processors": "",
"groups": "",
"action": "Cancel",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "5f7a54af-6a1b-4e69-8a46-57a6772019cc",

View File

@ -1,5 +1,5 @@
{
"name": "Factory",
"name": "CameraView",
"maps": [
{
"name": "UI",
@ -11,7 +11,7 @@
"id": "1e929e23-fe63-4cb3-b0c3-65b90dd5c5ff",
"expectedControlType": "Button",
"processors": "",
"interactions": "",
"interactions": "Press",
"initialStateCheck": false
},
{
@ -20,7 +20,7 @@
"id": "925894f6-c732-4e18-b7f9-2a28b4635edc",
"expectedControlType": "Vector2",
"processors": "",
"interactions": "",
"interactions": "Press",
"initialStateCheck": true
}
],

View File

@ -26,7 +26,6 @@ RenderTexture:
m_UseDynamicScale: 0
m_BindMS: 0
m_EnableCompatibleFormat: 1
m_EnableRandomWrite: 0
m_TextureSettings:
serializedVersion: 2
m_FilterMode: 1

View File

@ -26,13 +26,13 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 627812465856688283}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: -1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &627812465856688277
MonoBehaviour:
@ -48,7 +48,8 @@ MonoBehaviour:
m_EditorClassIdentifier:
m_PanelSettings: {fileID: 11400000, guid: 64cd93f02c042ad43a96d66da32f0c6c, type: 2}
m_ParentUI: {fileID: 0}
sourceAsset: {fileID: 9197481963319205126, guid: b42b9a148466f1f41a27bfc482972943, type: 3}
sourceAsset: {fileID: 9197481963319205126, guid: b42b9a148466f1f41a27bfc482972943,
type: 3}
m_SortingOrder: 8
--- !u!114 &627812465856688278
MonoBehaviour:
@ -63,11 +64,10 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
document: {fileID: 627812465856688277}
cursor: 1
allowInput: 0
isAdditive: 1
inputAction: {fileID: 7903140770426422483, guid: 8cbfbf37476baaf4bb5c172bc099a585, type: 3}
nextOrPreviousAction: {fileID: 731292775259212495, guid: 8cbfbf37476baaf4bb5c172bc099a585, type: 3}
toggleAction: {fileID: 2853179072480755223, guid: 982f09e3c8458314bad75d3c12b901d4,
type: 3}
nextOrPreviousAction: {fileID: 731292775259212495, guid: 8cbfbf37476baaf4bb5c172bc099a585,
type: 3}
logLineLimit: 64
--- !u!114 &627812465856688279
MonoBehaviour:

View File

@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using Cysharp.Threading.Tasks;
using System.Threading;
@ -13,6 +14,7 @@ namespace BITKit.Animations
[Serializable]
public class AnimatorLayerInfo
{
public string LayerName;
public string stateName;
public string fullStateName;
internal string entryName;
@ -42,7 +44,11 @@ namespace BITKit.Animations
{
for (int i = layerInfos.Count - 1; i < index; i++)
{
layerInfos.Add(new());
var newLayer = new AnimatorLayerInfo
{
LayerName = animator.GetLayerName(i+1)
};
layerInfos.Add(newLayer);
}
}
@ -69,28 +75,18 @@ namespace BITKit.Animations
x.entryName = null;
}
}
public void CrossFade(string name, float duration, int index = 0, float normalizedTimeOffset = 0)
public void CrossFade(string animationName, float duration, int index = 0, float normalizedTimeOffset = 0)
{
name = name.Replace(".", "_");
animator.CrossFade(name, duration, index, normalizedTimeOffset);
animator.CrossFade(GetVariableName(animationName), duration, index, normalizedTimeOffset);
}
public void Play(string name, int index = -1, float normalizedTimeOffset = 0)
public void Play(string animationName, int index = -1, float normalizedTimeOffset = 0)
{
name = name.Replace(".", "_");
if (_registryStates.TryGetValue(name, out var stateInfo) && stateInfo.variables?.Length > 0)
if (debug)
{
name = stateInfo.variables.Random();
BIT4Log.Log<UnityAnimator>( $"{gameObject.name} Play:" + animationName);
}
animator.Play(name, index, normalizedTimeOffset);
}
public void Play(string name)
{
Play(name,-1,0);
animator.Play(GetVariableName(animationName), index, normalizedTimeOffset);
}
public void OnStateEnter(int index, string name)
@ -129,7 +125,20 @@ namespace BITKit.Animations
{
foreach (var x in animator.GetBehaviours<UnityAnimatorStateInfo>())
{
_registryStates.TryAdd(x.stateName, x);
try
{
_registryStates.TryAdd(x.StateName, x);
foreach (var v in x.VariableNames)
{
_registryStates.TryAdd(v, x);
}
}
catch (Exception e)
{
BIT4Log.Warning<UnityAnimator>(gameObject.name);
throw;
}
}
}
@ -140,5 +149,26 @@ namespace BITKit.Animations
this[i].currentState = animator.GetCurrentAnimatorStateInfo(i);
}
}
[ContextMenu(nameof(Diagnosis))]
private void Diagnosis()
{
}
private string GetVariableName(string animationName)
{
animationName = animationName.Replace(".", "_");
if (!_registryStates.TryGetValue(animationName, out var stateInfo)) return animationName;
animationName = stateInfo.StateName;
if (stateInfo.VariableAnimationNames.Length > 0)
{
animationName = stateInfo.VariableAnimationNames.Random();
}
return animationName;
}
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using BITKit;
using UnityEngine.Animations;
@ -13,13 +14,33 @@ namespace BITKit.Animations
{
public class UnityAnimatorStateInfo : StateMachineBehaviour
{
[SerializeReference, SubclassSelector] public References stateName;
[SerializeReference, SubclassSelector] private References stateName;
[SerializeReference,SubclassSelector] private IReference[] variableNames;
public IAnimator animator;
public int index;
private int _index;
public float duration;
[SerializeReference, SubclassSelector] public References[] variables;
[SerializeReference, SubclassSelector] private References[] variables;
public string StateName
{
get
{
try
{
return stateName;
}
catch (Exception e)
{
BIT4Log.Warning<UnityAnimatorStateInfo>(this);
throw;
}
}
}
public string[] VariableNames => variableNames.Select(x=>x.Get()).ToArray();
public string[] VariableAnimationNames => variables.Select(x=>x.Get()).ToArray();
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
_index = layerIndex;
EnsureCreation(animator);
try
{
@ -41,12 +62,12 @@ namespace BITKit.Animations
public override void OnStateMachineEnter(Animator animator, int stateMachinePathHash)
{
EnsureCreation(animator);
this.animator?.OnStateEnter(index, stateName);
this.animator?.OnStateEnter(_index, stateName);
}
public override void OnStateMachineExit(Animator animator, int stateMachinePathHash)
{
EnsureCreation(animator);
this.animator?.OnStateExit(index, stateName);
this.animator?.OnStateExit(_index, stateName);
}
public void Play()
@ -57,7 +78,7 @@ namespace BITKit.Animations
}
else
{
animator.CrossFade(stateName, duration, index);
animator.CrossFade(stateName, duration, _index);
}
}
void EnsureCreation(Animator animator)

View File

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

View File

@ -0,0 +1,182 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using BITKit.UX;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UIElements;
using YooAsset;
using Debug = UnityEngine.Debug;
namespace BITKit
{
public class BITFramework : MonoBehaviour
{
private static System.Diagnostics.Stopwatch Stopwatch;
[RuntimeInitializeOnLoadMethod]
private static void Reload()
{
Stopwatch = new Stopwatch();
#if UNITY_EDITOR
#else
SplashScreen.Stop(SplashScreen.StopBehavior.StopImmediate);
#endif
}
// [SerializeField] private AssetReference serviceReference;
// private async void Start()
// {
// if(InitializationState is not InitializationState.None)return;
// InitializationState = InitializationState.Initializing;
// var asyncOperationHandle = serviceReference.LoadAssetAsync<GameObject>();
// await UniTask.WaitUntil(() => asyncOperationHandle.IsDone);
// DontDestroyOnLoad(Instantiate(asyncOperationHandle.Result));
// Stopwatch.Stop();
// BIT4Log.Log<BITFramework>($"BITFramework加载完成,耗时:{Stopwatch.ElapsedMilliseconds}ms");
// }
[SerializeField] private string addressableName;
[SerializeField] private UXBar progressBar;
[SerializeField] private UIDocument document;
[SerializeField] private UXLabel progressLabel;
[SerializeField] private bool IsEditorSimulateMode;
private float CurrentOpacity
{
get => document.rootVisualElement.GetOpacity();
set => document.rootVisualElement.SetOpacity(value);
}
private async void Start()
{
#if UNITY_EDITOR
#else
IsEditorSimulateMode=false;
#endif
progressBar.Set(0f);
var stopwatch = new Stopwatch();
stopwatch.Start();
DontDestroyOnLoad(gameObject);
// 初始化资源系统
YooAssets.Initialize();
const string PackageName = "DefaultPackages";
// 创建默认的资源包
var package = YooAssets.TryGetPackage(PackageName) ?? YooAssets.CreatePackage(PackageName);
// 设置该资源包为默认的资源包可以使用YooAssets相关加载接口加载该资源包内容。
YooAssets.SetDefaultPackage(package);
const string defaultHostServer = "http://127.0.0.1/CDN/PC/v1.0";
const string fallbackHostServer = "http://127.0.0.1/CDN/PC/v1.0";
InitializeParameters initParameters = new HostPlayModeParameters
{
BuildinQueryServices = new GameQueryServices(),
RemoteServices = new RemoteServices(defaultHostServer, fallbackHostServer)
};
if (IsEditorSimulateMode)
{
var editorParameters = new EditorSimulateModeParameters
{
SimulateManifestFilePath = EditorSimulateModeHelper.SimulateBuild(EDefaultBuildPipeline.BuiltinBuildPipeline,PackageName)
};
initParameters = editorParameters;
}
var initOperation = package.InitializeAsync(initParameters);
progressLabel.Set("正在初始化资源系统...");
while (initOperation.IsDone is false)
{
await UniTask.NextFrame(destroyCancellationToken);
progressBar.Set(initOperation.Progress);
}
progressLabel.Set("正在更新资源包版本...");
var operation = package.UpdatePackageVersionAsync();
while (operation.IsDone is false)
{
await UniTask.NextFrame(destroyCancellationToken);
progressBar.Set(operation.Progress);
}
if (operation.Status == EOperationStatus.Succeed)
{
//更新成功
string packageVersion = operation.PackageVersion;
Debug.Log($"Updated package Version : {packageVersion}");
}
else
{
//更新失败
Debug.LogError(operation.Error);
}
progressLabel.Set("正在初始化Framework");
var frameworkHandle = YooAssets.LoadAssetAsync<GameObject>(addressableName);
while (frameworkHandle.IsDone is false)
{
await UniTask.NextFrame(destroyCancellationToken);
progressBar.Set(frameworkHandle.Progress);
}
var framework = Instantiate(frameworkHandle.AssetObject);
DontDestroyOnLoad(framework);
progressLabel.Set("已加载完成");
stopwatch.Stop();
Destroy(document);
BIT4Log.Log<BITFramework>("BITFramework加载完成,耗时:" + stopwatch.ElapsedMilliseconds + "ms");
SceneManager.LoadScene(1);
}
private void OnDestroy()
{
YooAssets.Destroy();
}
}
public class GameQueryServices : IBuildinQueryServices
{
public bool Query(string packageName, string fileName)
{
// 注意fileName包含文件格式
return StreamingAssetsHelper.FileExists(packageName, fileName);
}
}
/// <summary>
/// 远端资源地址查询服务类
/// </summary>
public class RemoteServices : IRemoteServices
{
private readonly string _defaultHostServer;
private readonly string _fallbackHostServer;
public RemoteServices(string defaultHostServer, string fallbackHostServer)
{
_defaultHostServer = defaultHostServer;
_fallbackHostServer = fallbackHostServer;
}
string IRemoteServices.GetRemoteMainURL(string fileName)
{
return $"{_defaultHostServer}/{fileName}";
}
string IRemoteServices.GetRemoteFallbackURL(string fileName)
{
return $"{_fallbackHostServer}/{fileName}";
}
}
}

View File

@ -0,0 +1,19 @@
{
"name": "BITKit.Assets",
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:e34a5702dd353724aa315fb8011f08c3",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:6ef4ed8ff60a7aa4bb60a8030e6f4008"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

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

View File

@ -0,0 +1,29 @@
using System.IO;
using System.Collections.Generic;
using UnityEngine;
using YooAsset;
/// <summary>
/// 资源文件查询服务类
/// </summary>
public class GameQueryServices : IBuildinQueryServices
{
public bool Query(string packageName, string fileName)
{
// 注意fileName包含文件格式
return StreamingAssetsHelper.FileExists(packageName, fileName);
}
}
/// <summary>
/// StreamingAssets目录下资源查询帮助类
/// </summary>
public sealed class StreamingAssetsHelper
{
public static void Init() { }
public static bool FileExists(string packageName, string fileName)
{
string filePath = Path.Combine(Application.streamingAssetsPath, packageName, fileName);
return File.Exists(filePath);
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: b1019fae5b305474fa9f3df5cea55a59
guid: a381463a70ed5a14bb32745229a52b64
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -6,7 +6,6 @@ using UnityEngine;
using Cysharp.Threading.Tasks;
using System.Threading.Tasks;
using UnityEngine.InputSystem;
using UnityEngine.AddressableAssets;
using Debug = UnityEngine.Debug;
namespace BITKit

View File

@ -1,33 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.AddressableAssets;
namespace BITKit
{
public class BITFramework : MonoBehaviour
{
private static Stopwatch Stopwatch;
private static InitializationState InitializationState;
[RuntimeInitializeOnLoadMethod]
private static void Reload()
{
InitializationState = InitializationState.None;
Stopwatch = Stopwatch.StartNew();
}
[SerializeField] private AssetReference serviceReference;
private async void Start()
{
if(InitializationState is not InitializationState.None)return;
InitializationState = InitializationState.Initializing;
var asyncOperationHandle = serviceReference.LoadAssetAsync<GameObject>();
await UniTask.WaitUntil(() => asyncOperationHandle.IsDone);
DontDestroyOnLoad(Instantiate(asyncOperationHandle.Result));
Stopwatch.Stop();
BIT4Log.Log<BITFramework>($"BITFramework加载完成,耗时:{Stopwatch.ElapsedMilliseconds}ms");
}
}
}

View File

@ -0,0 +1,51 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
public class ResetTransform : MonoBehaviour
{
[SerializeField] private bool resetPosition;
[SerializeField] private bool resetRotation;
[SerializeField] private bool resetScale;
[SerializeField] private bool resetOnDisable;
[SerializeField] private bool resetOnEnable;
private Vector3 _initialPosition;
private Vector3 _initialScale;
private Quaternion _initialRotation;
private Transform Transform;
private void Start()
{
Transform = transform;
_initialPosition = Transform.localPosition;
_initialRotation = Transform.localRotation;
_initialScale = Transform.localScale;
}
private void OnDisable()
{
if(resetOnDisable)
Execute();
}
private void OnEnable()
{
if(resetOnEnable)
Execute();
}
private void Execute()
{
if(resetPosition)
Transform.localPosition = _initialPosition;
if(resetRotation)
Transform.localRotation = _initialRotation;
if(resetScale)
Transform.localScale = _initialScale;
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 8d8750340a808e9468c8fcc9ca7e29a7
guid: 88e2cee55e14c524d960800ece5c00b0
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -9,13 +10,16 @@ using UnityEngine.InputSystem;
using Cysharp.Threading.Tasks;
using System.Text;
using System.IO;
using UnityEngine.InputSystem.Interactions;
namespace BITKit.Console
{
public class BITConsole : UXPanel
public class BITConsole : MonoBehaviour
{
[BITCommand]
public static void Clear()
public static async void Clear()
{
await BITApp.SwitchToMainThread();
singleton.outputString.Clear();
singleton.text.text = string.Empty;
}
@ -24,21 +28,27 @@ namespace BITKit.Console
const string commandListViewName = "commands-listview";
const string textName = "Text";
const string scrollViewName = "context-scrollview";
public InputActionReference inputAction;
public InputActionReference nextOrPreviousAction;
[SerializeField] private UIDocument document;
[SerializeReference] private InputActionReference toggleAction;
[SerializeReference] public InputActionReference nextOrPreviousAction;
private readonly InputActionGroup _inputActionGroup=new()
{
allowGlobalActivation = false
};
public int logLineLimit = 64;
private ListView commandListView;
private ListView commandListView;
private TextField textField;
private Label text;
private ScrollView scrollView;
private bool isActived;
private List<string> outputString = new();
private void Awake()
{
inputAction.action.Enable();
nextOrPreviousAction.action.Enable();
Application.logMessageReceivedThreaded += LogCallback;
}
private void Start()
{
singleton = this;
var visualElement = document.rootVisualElement;
textField = visualElement.Q<TextField>(textFieldName);
@ -51,13 +61,11 @@ namespace BITKit.Console
commandListView.selectionChanged += OnSelectionChange;
inputAction.action.performed += Toggle;
nextOrPreviousAction.action.performed += OnNextCommand;
text.text = string.Empty;
Application.logMessageReceived += LogCallback;
BIT4Log.OnNextLine += () =>
{
@ -66,18 +74,28 @@ namespace BITKit.Console
};
commandListView.SetActive(false);
_inputActionGroup.RegisterCallback(toggleAction,Toggle);
_inputActionGroup.RegisterCallback(nextOrPreviousAction, OnNextCommand);
_inputActionGroup.allowInput.AddElement(this);
Toggle(false);
}
private void OnDestroy()
{
inputAction.action.performed -= Toggle;
Application.logMessageReceived -= LogCallback;
_inputActionGroup.allowInput.RemoveElement(this);
Application.logMessageReceivedThreaded -= LogCallback;
}
public override async void Set(bool active)
public async void Toggle(bool active)
{
base.Set(active);
document.rootVisualElement.SetActive(active);
isActived = active;
BITAppForUnity.AllowCursor.SetElements(this,active);
BITInputSystem.AllowInput.SetDisableElements(this,active);
await UniTask.WaitForEndOfFrame(this);
if (active)
{
@ -92,7 +110,7 @@ namespace BITKit.Console
text.Blur();
}
}
void OnTextFieldValieChanged(ChangeEvent<string> callback)
private void OnTextFieldValieChanged(ChangeEvent<string> callback)
{
if (callback.newValue.IsValid())
{
@ -111,9 +129,7 @@ namespace BITKit.Console
{
commandListView.SetActive(false);
}
}
private void OnDropdownValueChanged(ChangeEvent<string> callback)
{
textField.SetValueWithoutNotify(callback.newValue);
@ -147,60 +163,56 @@ namespace BITKit.Console
}
}
void Toggle(InputAction.CallbackContext context)
private void Toggle(InputAction.CallbackContext context)
{
if (context.performed)
switch (context)
{
if (isActived is false)
{
UXFramework.Enter<BITConsole>();
}
else
{
UXFramework.Return();
}
case { interaction: PressInteraction, performed: true }:
Toggle(!isActived);
break;
}
}
async void LogCallback(string condition, string stackTrace, LogType type)
{
var debugLevel = Data.Get<int>("DebugLevel");
switch (type)
{
case LogType.Error:
outputString.Add($"<color=red>{condition}</color>");
if (debugLevel is 2)
outputString.Add(stackTrace);
break;
case LogType.Warning:
outputString.Add($"<color=yellow>{condition}</color>");
if (debugLevel is 2)
outputString.Add(stackTrace);
break;
case LogType.Exception:
outputString.Add($"<color=red>{condition}</color>");
outputString.Add($"<color=red>{stackTrace}</color>");
break;
default:
outputString.Add(condition);
break;
}
var length = outputString.Count;
if (length > logLineLimit)
{
outputString = outputString.GetRange(length - logLineLimit, logLineLimit);
}
StringBuilder stringBuilder = new();
outputString.ForEach(x => stringBuilder.AppendLine(x));
private async void LogCallback(string condition, string stackTrace, LogType type)
{
try
{
await UniTask.SwitchToMainThread(BITApp.CancellationToken);
scrollView.ScrollToBottomAutomatic();
text.text = stringBuilder.ToString();
switch (type)
{
case LogType.Error:
outputString.Add($"<color=red>{condition}</color>");
break;
case LogType.Warning:
outputString.Add($"<color=yellow>{condition}</color>");
break;
case LogType.Exception:
outputString.Add($"<color=red>{condition}</color>");
outputString.Add($"<color=red>{stackTrace}</color>");
break;
default:
outputString.Add(condition);
break;
}
var length = outputString.Count;
if (length > logLineLimit)
{
outputString = outputString.GetRange(length - logLineLimit, logLineLimit);
}
StringBuilder stringBuilder = new();
outputString.ForEach(x => stringBuilder.AppendLine(x));
try
{
await BITApp.SwitchToMainThread();
scrollView.ScrollToBottomAutomatic();
text.text = stringBuilder.ToString();
}
catch (OperationCanceledException)
{
}
}
catch (System.OperationCanceledException)
catch (Exception e)
{
Debug.LogException(e);
}
}
@ -218,7 +230,7 @@ namespace BITKit.Console
commandListView.style.width = size.x;
}
void OnSelectionChange(IEnumerable<object> selected)
private void OnSelectionChange(IEnumerable<object> selected)
{
var _selected = selected.First() as string;
textField.SetValueWithoutNotify(_selected);

View File

@ -1,6 +1,7 @@
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System.Net.Configuration;
using BITKit.Animations;
namespace BITKit.Entities
@ -14,9 +15,15 @@ namespace BITKit.Entities
[SerializeReference, SubclassSelector] private References[] boolParameters;
[SerializeReference, SubclassSelector] private References[] floatParameters;
private List<string> keyWords;
private ConstantHash[] _boolParameterHashes;
private ConstantHash[] _floatParameterHashes;
public override void OnAwake()
{
keyWords = animationKeyWords.Select(x => x.Get()).ToList();
_boolParameterHashes = boolParameters.Select(x =>new ConstantHash(x.Get())).ToArray();
_floatParameterHashes = floatParameters.Select(x =>new ConstantHash(x.Get())).ToArray();
}
public override void OnStart()
{
@ -35,26 +42,30 @@ namespace BITKit.Entities
});
}
}
public override void OnFixedUpdate(float deltaTime)
{
foreach (var boolPar in boolParameters)
bool cacheBool;
float cacheFloat;
foreach (var boolPar in _boolParameterHashes)
{
animators.ForEach(x =>
{
if (x.isActiveAndEnabled)
x.animator.SetBool(boolPar, UnityEntity.Get<bool>(boolPar));
});
foreach (var x in animators)
{
if (!x.isActiveAndEnabled) return;
UnityEntity.GetDirect<bool>(boolPar, out cacheBool);
x.animator.SetBool(boolPar.HashCode, cacheBool);
}
}
foreach (var floatPar in floatParameters)
foreach (var floatPar in _floatParameterHashes)
{
animators.ForEach(x =>
{
if (x.isActiveAndEnabled)
x.animator.SetFloat(floatPar, UnityEntity.Get<float>(floatPar));
});
foreach (var x in animators)
{
if (!x.isActiveAndEnabled) return;
UnityEntity.GetDirect<float>(floatPar, out cacheFloat);
x.animator.SetFloat(floatPar.HashCode, cacheFloat);
}
}
}
private void OnAnimatorMove()
{
if (enabled is false) return;

View File

@ -10,7 +10,7 @@ namespace BITKit.Entities.Player.Character
[SerializeField] private Renderer[] fpvRenderer = Array.Empty<Renderer>();
[SerializeField] private Renderer[] tpvRenderer = Array.Empty<Renderer>();
[Header(Constant.Header.Reference)]
[SerializeReference, SubclassSelector] public References _getDamage;
[SerializeReference, SubclassSelector] public IReference getDamage;
public override void OnStart()
{
var heal = UnityEntity.Get<IHealth>();
@ -33,7 +33,7 @@ namespace BITKit.Entities.Player.Character
}
private void OnSetHP(int hp)
{
UnityEntity.Invoke<string>(Constant.Animation.Play, _getDamage);
UnityEntity.Invoke<string>(Constant.Animation.Play, getDamage.Value);
}
private void SetFPV(bool isFpv)
{

View File

@ -1,132 +0,0 @@
using System;
using BITKit.Entities;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
namespace BITKit
{
public class NavAgentMovement: StateBasedBehavior<IEntityMovementState>,IEntityMovement
{
#region
[SerializeField] private NavMeshAgent agent;
[SerializeField] private new Rigidbody rigidbody;
[Inject] private IHealth _health;
[Inject(true)] private IEntityOverride _override;
#endregion
public override void OnStart()
{
if (_override is not null)
{
_override.OnOverride += (x) =>
{
agent.isStopped = x;
};
}
_health.OnSetAlive += OnSetAlive;
_health.OnSetHealthPoint += OnSetHP;
}
#region
public Vector3 Position
{
get=>transform.position;
set=>transform.position=value;
}
public Quaternion Rotation
{
get=>transform.rotation;
set=>transform.rotation=value;
}
public Vector3 Forward => transform.forward;
public Vector3 ViewCenter { get; set; }
public Quaternion ViewRotation { get; set; }
public Vector3 LocomotionBasedVelocity { get; private set; }
public Vector3 Velocity { get; private set; }
public Vector3 GroundVelocity { get; private set; }
public Vector3 AngularVelocity { get; private set; }
public bool IsGrounded { get; private set; }
private bool isDead;
private Vector3 recordPosition;
private Quaternion recordRotation;
private IEntityMovement _entityMovementImplementation;
#endregion
public override void OnUpdate(float deltaTime)
{
Velocity = agent.velocity;
var _groundVelocity = Velocity;
_groundVelocity.y = 0;
GroundVelocity = _groundVelocity;
IsGrounded = agent.isOnOffMeshLink is false;
UnityEntity.Set<bool>("IsMoving",Velocity.sqrMagnitude>=0.16f);
UnityEntity.Set<float>("SqrMagnitude",Velocity.sqrMagnitude);
if (!isDead) return;
recordPosition = rigidbody.position;
recordRotation = rigidbody.rotation * transform.rotation;
}
public void SyncMovement(Vector3 velocity, Vector3 position, Quaternion rotation, bool isGrounded)
{
}
public void Movement(Vector3 relativeVector)
{
}
public void Movement(InputAction.CallbackContext context)
{
throw new NotImplementedException();
}
public void ExecuteCommand<T>(T command)
{
throw new NotImplementedException();
}
public event Action<object> OnCommand;
public void OnSetAlive(bool alive)
{
switch (alive)
{
case false:
isDead = true;
break;
case true when isDead:
{
var _transform = transform;
_transform.position = new Vector3()
{
x=recordPosition.x,
y=0,
z=recordPosition.x,
};
rigidbody.position = recordPosition;
_transform.rotation *= recordRotation;
rigidbody.rotation = recordRotation;
isDead = false;
break;
}
}
}
public void OnSetHP(int hp)
{
}
}
}

View File

@ -16,6 +16,8 @@ namespace BITKit.Entities
public event Action<DamageMessage> OnEntityKilled;
void Execute(DamageMessage damageMessage);
}
public struct MeleeDamageMessage:IDamageType{}
public struct BulletDamageMessage:IDamageType{}
[Serializable]
public class DamageServiceSingleton:IDamageService
{
@ -69,6 +71,7 @@ namespace BITKit.Entities
public Location Location;
public IDamageType DamageType;
}
public interface IDamageCallback
{
void OnGetDamage(DamageMessage message);

View File

@ -1,7 +1,9 @@
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.UIElements;
#endif
using UnityEngine;
using UnityEngine.UIElements;
@ -18,9 +20,7 @@ namespace BITKit.Entities.InputSystem
[Inject(true)]
private IEntityOverride _override;
#if UNITY_EDITOR
[SerializeField,HideInInspector] internal bool Allow;
#endif
public override void Initialize(IEntity _entity)
{
base.Initialize(_entity);
@ -46,6 +46,18 @@ namespace BITKit.Entities.InputSystem
};
}
}
public override void OnStart()
{
base.OnStart();
inputActionGroup.allowInput.Invoke();
}
public override void OnDestroyComponent()
{
base.OnDestroyComponent();
inputActionGroup.Dispose();
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(EntityInputSystem))]

View File

@ -31,20 +31,27 @@ namespace BITKit.Entities.Player
public override void OnUpdate(float deltaTime)
{
//if (sensor.Get().TryGetAny(x=>x.TryGetComponentAny<ISelectable>(out _),out var detected))
if (sensor.Get().TryGetAny(x=>x.GetComponentInParent<ISelectable>() is not null,out var detected))
try
{
if (detected.TryGetComponentAny<ISelectable>(out var _detected))
if (sensor.Get().TryGetAny(x=>x.GetComponentInParent<ISelectable>() is not null,out var detected))
{
if (_detected == selected)
if (detected.TryGetComponentAny<ISelectable>(out var _detected))
{
if (_detected == selected)
{
}
else
{
TryDeSelected();
Detected(_detected);
}
}
else
{
TryDeSelected();
Detected(_detected);
}
}
else
@ -52,10 +59,14 @@ namespace BITKit.Entities.Player
TryDeSelected();
}
}
else
catch(MissingReferenceException e)
{}
catch (Exception e)
{
TryDeSelected();
Console.WriteLine(e);
throw;
}
}
private void TryDeSelected()
{

View File

@ -15,7 +15,6 @@ namespace BITKit.Entities
[SerializeField] private Collider[] ragdollColliders;
[SerializeField] private Joint[] joints;
[SerializeField] private new Rigidbody rigidbody;
private CancellationToken _cancellationToken;
[Inject]
private IHealth _health;
private readonly Dictionary<Joint,ConfigurableJointMotion> _jointXMotions=new();
@ -29,7 +28,6 @@ namespace BITKit.Entities
{
_health.OnSetAlive += OnSetAlive;
_health.OnSetHealthPoint += OnSetHP;
_cancellationToken = UnityEntity.Get<CancellationToken>();
foreach (var x in joints)
{
switch (x)
@ -53,7 +51,7 @@ namespace BITKit.Entities
animator.enabled = alive;
try
{
await Task.Delay(10, _cancellationToken);
await Task.Delay(10, destroyCancellationToken);
rigidbodies.ForEach(x => { x.isKinematic = alive; });
ragdollColliders.ForEach(x => { x.enabled = !alive; });
OnSetPhysics?.Invoke(!alive);

View File

@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@ -19,9 +20,18 @@ namespace BITKit.Entities.VFX
private void Play(string animationName)
{
if (isActiveAndEnabled is false) return;
if (keyWords.Contains(animationName) is false) return;
vfxPlayer.Execute();
try
{
if (isActiveAndEnabled is false) return;
if (keyWords.Contains(animationName) is false) return;
vfxPlayer.Execute();
}
catch (Exception e)
{
Debug.LogWarning(transform.name);
Debug.LogException(e);
}
}
}
}

View File

@ -156,6 +156,21 @@ namespace BITKit.Entities
public void Invoke<T>(string key, T value) => genericEvent.Invoke<T>(key, value);
public void Invoke<T>() where T : new() => genericEvent.Invoke<T>();
public void RemoveListener<T>(string key, Action<T> action) => genericEvent.RemoveListener<T>(key, action);
public void SetDirect(int key, object value)
{
genericEvent.SetDirect(key, value);
}
public void GetDirect(int key, out object value)
{
genericEvent.GetDirect(key, out value);
}
public void GetDirect<T>(int key, out T value)
{
genericEvent.GetDirect(key, out value);
}
public T Get<T>(string key = Constant.System.Internal)
{
var value = genericEvent.Get<T>(key);

View File

@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.IO;
using BITKit.Entities;
using UnityEngine;
using UnityEngine.AddressableAssets;
namespace BITKit.Entities
{
/// <summary>Entity接口用于复杂实体</summary>
@ -14,27 +13,27 @@ namespace BITKit.Entities
void AddService(object service);
void AddService(Type type, object service);
}
public class IEntityReader : NetMessageReader<IUnityEntity>
{
public override IUnityEntity ReadBinary(BinaryReader reader)
{
var id = reader.ReadInt32();
var path = reader.ReadString();
var entity = DI.Get<IEntitiesService>().Entities[id];
return (IUnityEntity)entity;
}
public override void WriteBinary(BinaryWriter writer, IUnityEntity value)
{
writer.Write(value.Id);
writer.Write(value.Id);
}
private IUnityEntity Create(int id, string path)
{
var entity = Addressables
.LoadAssetAsync<GameObject>(path)
.WaitForCompletion()
.GetComponent<IUnityEntity>();
return entity;
}
}
// public class IEntityReader : NetMessageReader<IUnityEntity>
// {
// public override IUnityEntity ReadBinary(BinaryReader reader)
// {
// var id = reader.ReadInt32();
// var path = reader.ReadString();
// var entity = DI.Get<IEntitiesService>().Entities[id];
// return (IUnityEntity)entity;
// }
// public override void WriteBinary(BinaryWriter writer, IUnityEntity value)
// {
// writer.Write(value.Id);
// writer.Write(value.Id);
// }
// private IUnityEntity Create(int id, string path)
// {
// var entity = Addressables
// .LoadAssetAsync<GameObject>(path)
// .WaitForCompletion()
// .GetComponent<IUnityEntity>();
// return entity;
// }
// }
}

View File

@ -0,0 +1,26 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit.Entities
{
public interface IdComponent
{
ulong Id { get; }
string Name { get; }
}
public class UnityIdComponent : EntityBehavior,IdComponent
{
[SerializeField] private ulong id;
[SerializeField] private string unityName;
public ulong Id => id;
public string Name => unityName;
public override void Initialize(IEntity _entity)
{
base.Initialize(_entity);
id = _entity.Id;
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: c9f4b115cecfadd40b191dc35f29ef08
guid: 7deed5246427534489a19e5325df9a8d
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -18,6 +18,8 @@ namespace BITKit.Entities.Editor
}
private Label _timeLabel;
private VisualElement _container;
private VisualElement _idContainer;
private VisualElement _nameContainer;
private void OnEnable()
{
_timeLabel = rootVisualElement.Create<Label>();
@ -25,15 +27,25 @@ namespace BITKit.Entities.Editor
rootVisualElement.styleSheets.Add(BITEditorUtils.InspectorStyleSheet);
rootVisualElement.styleSheets.Add(BITEditorUtils.Style);
rootVisualElement.AddToClassList("pa-8");
_idContainer = _container.Create<VisualElement>();
_nameContainer = _container.Create<VisualElement>();
_container.style.flexDirection = FlexDirection.Row;
_idContainer.style.flexDirection = FlexDirection.Column;
_nameContainer.style.flexDirection = FlexDirection.Column;
}
private void Update()
{
_timeLabel.text = DateTime.Now.ToString(CultureInfo.InvariantCulture);
_container.Clear();
_nameContainer.Clear();
_idContainer.Clear();
foreach (var x in UnityEntitiesService.Entities)
{
_container.Create<Label>().text = $"{x.Id}\t{x}";
//_container.Create<Label>().text = $"{x.Id}\t{x}";
_idContainer.Create<Label>().text = $"{x.Id}";
_nameContainer.Create<Label>().text = $"{x}";
}
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
@ -15,7 +16,7 @@ namespace BITKit
[SerializeField, ReadOnly] private bool isEnabled;
private InitializationState state = InitializationState.None;
public ValidHandle allowInput = new();
private readonly List<InputAction> actions = new();
private readonly ConcurrentDictionary<string,InputAction> actions = new();
public InputActionGroup RegisterCallback(InputActionReference reference,
Action<InputAction.CallbackContext> callback)
@ -27,22 +28,38 @@ namespace BITKit
}
EnsureConfiguration();
var action = reference.action.Clone();
var action = actions.GetOrAdd(reference.name, _ =>
{
var newAction = reference.action.Clone();
newAction.Rename(reference.name);
return newAction;
});
action.RegisterCallback(callback);
allowInput.Invoke();
actions
.Where(x => x.name == action.name)
.CreateOrAddIfEmety(actions, action)
.ForEach(x => { x.RegisterCallback(callback); });
return this;
}
public void Inherit(InputActionGroup other)
{
throw new NotImplementedException();
}
public InputAction GetAction(string name)
{
if(actions.TryGetValue(name,out var action))
return action;
throw new ArgumentException($"未知的引用{name}");
}
public InputAction GetAction(InputActionReference reference)
{
if(actions.TryGetValue(reference.name,out var action))
return action;
throw new ArgumentException($"未知的引用{reference.name}");
}
public void UnRegisterCallback(InputActionReference reference, Action<InputAction.CallbackContext> callback)
{
foreach (var action in actions.Where(x => x.name == reference.action.name))
{
if(actions.TryGetValue(reference.name,out var action))
action.UnRegisterCallback(callback);
}
}
private void EnsureConfiguration()
@ -68,7 +85,7 @@ namespace BITKit
private void AllowInput(bool allow)
{
foreach (var action in actions)
foreach (var action in actions.Values)
{
if (allow)
{
@ -81,14 +98,13 @@ namespace BITKit
}
isEnabled = allow;
}
public void Dispose()
{
foreach (var action in actions)
foreach (var action in actions.Values)
{
action.Disable();
action.Dispose();
}
actions.Clear();
}
}

View File

@ -1,50 +0,0 @@
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.UIElements;
namespace BITKit
{
[System.Serializable]
public record UnityReference : IReference
{
[SerializeField] internal int index;
private AssetableReference asset;
public string Get()
{
asset ??= Addressables.LoadAssetAsync<AssetableReference>(nameof(AssetableReference)).WaitForCompletion();
return asset.Get(index);
}
internal void Set(int _index) => index = _index;
}
public class AssetableReference:ScriptableObject
{
[SerializeField]
private List<string> values;
internal string Get(int index) => values[index];
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(UnityReference))]
public class UnityReferenceInspector :PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var index = property.FindPropertyRelative(nameof(UnityReference.index)).intValue;
return new Label(index.ToString());
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var index = property.FindPropertyRelative(nameof(UnityReference.index)).intValue;
//var unityReference = property.serializedObject.targetObject.GetType().GetField(property.name).GetValue(property.serializedObject) as UnityReference;
EditorGUI.DrawRect(position,Color.gray);
//EditorGUI.LabelField(position,new GUIContent(unityReference.index.T
}
}
#endif
}

View File

@ -1,12 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
public class TestAssetableReference : MonoBehaviour
{
[SerializeReference, SubclassSelector] public IReference reference;
public UnityReference UnityReference;
}
}

View File

@ -6,8 +6,7 @@
"GUID:045a42f233e479d41adc32d02b99631e",
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:6ef4ed8ff60a7aa4bb60a8030e6f4008",
"GUID:9e24947de15b9834991c9d8411ea37cf",
"GUID:84651a3751eca9349aac36a66bba901b"
"GUID:e34a5702dd353724aa315fb8011f08c3"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@ -17,6 +17,8 @@ namespace BITKit.SceneManagement
/// 在场景加载完成后,是否初始化主场景
/// </summary>
bool InitializeMainSceneOnLoad { get; }
string[] GetScenes(params string[] tags);
/// <summary>
/// 加载场景
/// </summary>
@ -56,6 +58,7 @@ namespace BITKit.SceneManagement
private ISceneService _sceneServiceImplementation1 => _sceneServiceImplementation;
protected abstract ISceneService _sceneServiceImplementation { get; }
public bool InitializeMainSceneOnLoad => _sceneServiceImplementation.InitializeMainSceneOnLoad;
public string[] GetScenes(params string[] tags)=> _sceneServiceImplementation.GetScenes(tags);
public UniTask LoadSceneAsync(string sceneName,CancellationToken cancellationToken, LoadSceneMode loadSceneMode = LoadSceneMode.Additive,
bool activateOnLoad = true)

View File

@ -2,13 +2,14 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;
using YooAsset;
using Debug = UnityEngine.Debug;
using Object = UnityEngine.Object;
@ -26,6 +27,11 @@ namespace BITKit.SceneManagement
{
private ISceneService _sceneServiceImplementation => SceneService.Singleton;
public bool InitializeMainSceneOnLoad=>SceneService.Singleton.InitializeMainSceneOnLoad;
public string[] GetScenes(params string[] tags)
{
return SceneService.Singleton.GetScenes(tags);
}
public UniTask LoadSceneAsync(string sceneName, CancellationToken cancellationToken,
LoadSceneMode loadSceneMode = LoadSceneMode.Additive, bool activateOnLoad = true)=>SceneService.Singleton.LoadSceneAsync(sceneName,cancellationToken,loadSceneMode,activateOnLoad);
@ -88,9 +94,11 @@ namespace BITKit.SceneManagement
[SerializeField] private Optional<float> allowLoadDelay;
#endif
[SerializeField] private Optional<string> allowLoadMainScene;
[SerializeField] private Optional<string> allowMenuScene;
private readonly Dictionary<string, Scene> LoadedObjects = new();
private CancellationToken _cancellationToken;
private readonly List<SceneInstance> _loadedObjects = new();
private void Awake()
{
Singleton = this;
@ -98,11 +106,26 @@ namespace BITKit.SceneManagement
}
private void Start()
{
if (allowMenuScene.Allow)
{
YooAssets
.LoadSceneAsync(allowMenuScene.Value).ToUniTask(cancellationToken: _cancellationToken)
.Forget();
}
if (allowLoadMainScene.Allow is false) return;
LoadSceneAsync(allowLoadMainScene.Value,_cancellationToken,LoadSceneMode.Single,false).Forget();
}
public bool InitializeMainSceneOnLoad => true;
public async UniTask LoadSceneAsync(string sceneName,CancellationToken cancellationToken, LoadSceneMode loadSceneMode = LoadSceneMode.Additive,
public string[] GetScenes(params string[] tags)
{
var infos = YooAssets.GetAssetInfos(tags);
return infos.Where(x=>x.Address.Split("_")[0] is "Maps").Select(x=>x.Address).ToArray();
}
public async UniTask LoadSceneAsync(string sceneName, CancellationToken cancellationToken,
LoadSceneMode loadSceneMode = LoadSceneMode.Additive,
bool activateOnLoad = true)
{
try
@ -111,51 +134,66 @@ namespace BITKit.SceneManagement
stopwatchWatcher.Start();
BIT4Log.Log<SceneService>($"正在加载场景:{sceneName}");
OnLoadScene?.Invoke(sceneName);
#if UNITY_EDITOR
if (allowLoadDelay.Allow)
{
var progress = 0f;
while (progress < allowLoadDelay.Value)
{
OnSceneLoadProgress?.Invoke(sceneName, progress +=1/allowLoadDelay.Value * Time.deltaTime);
OnSceneLoadProgress?.Invoke(sceneName, progress += 1 / allowLoadDelay.Value * Time.deltaTime);
cancellationToken.ThrowIfCancellationRequested();
await UniTask.NextFrame(cancellationToken);
}
}
#endif
var asyncOperation = Addressables.LoadSceneAsync(sceneName, loadSceneMode, activateOnLoad);
while (asyncOperation.IsDone is false)
// var asyncOperation = Addressables.LoadSceneAsync(sceneName, loadSceneMode, activateOnLoad);
// while (asyncOperation.IsDone is false)
// {
// await UniTask.NextFrame(cancellationToken);
// var progress = asyncOperation.PercentComplete;
// OnSceneLoadProgress?.Invoke(sceneName,progress);
// }
var sceneMode = UnityEngine.SceneManagement.LoadSceneMode.Single;
var handle = YooAssets.LoadSceneAsync(sceneName, sceneMode);
while (handle.IsDone is false)
{
var progress = handle.Progress;
await UniTask.NextFrame(cancellationToken);
var progress = asyncOperation.PercentComplete;
OnSceneLoadProgress?.Invoke(sceneName,progress);
OnSceneLoadProgress?.Invoke(sceneName, progress);
}
LoadedObjects.Add(sceneName, handle.SceneObject);
OnSceneLoadProgress?.Invoke(sceneName, 1);
await Task.Delay(100, cancellationToken);
OnSceneLoaded?.Invoke(sceneName);
stopwatchWatcher.Stop();
if (activateOnLoad is false)
{
asyncOperation.Result.ActivateAsync().ToUniTask(cancellationToken: cancellationToken).Forget();
_loadedObjects.Add(asyncOperation.Result);
}
// if (activateOnLoad is false)
// {
// asyncOperation.Result.ActivateAsync().ToUniTask(cancellationToken: cancellationToken).Forget();
// _loadedObjects.Add(asyncOperation.Result);
// }
BIT4Log.Log<SceneService>($"场景:{sceneName}加载完成,耗时:{stopwatchWatcher.ElapsedMilliseconds}ms");
}
catch (OperationCanceledException)
{
}
}
public async UniTask UnloadSceneAsync(string sceneName, CancellationToken cancellationToken)
{
await UniTask.SwitchToMainThread();
if (LoadedObjects.TryRemove(sceneName) is false) return;
//await SceneManager.UnloadSceneAsync(scene);
SceneManager.LoadScene(1);
destroyCancellationToken.ThrowIfCancellationRequested();
OnUnloadScene?.Invoke(sceneName);
foreach (var x in _loadedObjects)
{
await Addressables.UnloadSceneAsync(x);
}
OnSceneUnloaded?.Invoke(sceneName);
}

View File

@ -7,6 +7,11 @@ using BITKit;
using Cysharp.Threading.Tasks;
namespace BITKit.Sensors
{
public static class SensorGlobalSettings
{
public static bool Enabled = true;
}
/// <summary>
/// 传感器的接口定义
/// </summary>

View File

@ -0,0 +1,29 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace BITKit.Sensors
{
public class SensorEditorWindow : EditorWindow
{
private Toggle _toggle;
[MenuItem("Tools/Sensor/EditorWindow")]
public static void ShowWindow()
{
GetWindow<SensorEditorWindow>("SensorEditorWindow");
}
private void CreateGUI()
{
_toggle = rootVisualElement.Create<Toggle>("Enable Sensor");
_toggle.label = "Enable Sensor";
_toggle.value = SensorGlobalSettings.Enabled;
}
private void Update()
{
SensorGlobalSettings.Enabled = _toggle.value;
}
}
}

View File

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

View File

@ -6,6 +6,8 @@ using System.Linq;
using Cysharp.Threading.Tasks;
using UnityEngine.Jobs;
using UnityEngine.Pool;
using UnityEngine.Profiling;
namespace BITKit.Sensors
{
public class RangeSensor : Sensor
@ -21,11 +23,20 @@ namespace BITKit.Sensors
private FrameUpdate frameUpdater;
private readonly Collider[] colliders = new Collider[32];
private RaycastHit[] hits;
public override IEnumerable<Transform> Get() => detected;
public override IEnumerable<Transform> Get()
{
if (!_detectedDoubleBuffer.TryGetRelease(out var newRelease)) return _detectedBuffer;
Profiler.BeginSample("Release Detected Buffer");
_detectedBuffer = newRelease;
Profiler.EndSample();
return _detectedBuffer;
}
private readonly DoubleBuffer<IEnumerable<Transform>> _detectedDoubleBuffer=new();
private IEnumerable<Transform> _detectedBuffer;
private void Update()
{
if (autoUpdate)
if (autoUpdate && SensorGlobalSettings.Enabled)
{
Execute().Forget();
}
@ -35,14 +46,11 @@ namespace BITKit.Sensors
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();
Profiler.BeginSample("Filter Detected Colliders");
var _newDetected = from x in colliders.Take(length) where IsValid(x) select x.transform;
Profiler.EndSample();
//detected = _newDetected.ToArray();
_detectedDoubleBuffer.Release(_newDetected);
return UniTask.CompletedTask;
}
@ -81,15 +89,24 @@ namespace BITKit.Sensors
Vector3.Distance(location, position),
blockLayer
);
if (length > 0)
switch (length)
{
if (hits[0].collider == _collider)
{
case 0:
return true;
}
case 1:
if (hits[0].collider == _collider)
{
return true;
}
break;
default:
if (hits.Take(length).Any(x => ignoreColliders.Contains(x.collider) is false))
{
return false;
}
break;
}
else return true;
return false;
return true;
}
}
}

View File

@ -7,6 +7,7 @@ using UnityEditor;
using UnityEditor.UIElements;
#endif
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.UIElements;
namespace BITKit.Sensors
@ -21,13 +22,8 @@ namespace BITKit.Sensors
/// </summary>
[Header(Constant.Header.Settings)]
[SerializeField] private bool autoUpdate;
/// <summary>
/// 目标有效性验证
/// </summary>
[Header(Constant.Header.Providers)]
[SerializeField,SerializeReference,SubclassSelector] private IValidityProvider validityProvider;
[SerializeField] private Optional<string[]> ignoreTags;
[SerializeField] private Optional<IntervalUpdate> optionalRetargetInterval;
/// <summary>
/// 主传感器
/// </summary>
@ -40,37 +36,59 @@ namespace BITKit.Sensors
#endif
public IEnumerable<Transform> Get() =>CurrentTarget is not null ? new[] { CurrentTarget }:Enumerable.Empty<Transform>();
public bool IsValid(Collider _collider) =>validityProvider?.IsValid(_collider) ?? true;
public bool IsValid(Collider _collider)
{
if (ignoreTags.Allow)
{
if (_collider.TryGetComponent<ITag>(out var iTags))
{
var tags = iTags.GetTags();
foreach (var x in ignoreTags.Value)
{
if (tags.Contains(x))
{
return false;
}
}
}
}
return true;
}
public float GetDistance() => sensor.GetDistance();
public Transform CurrentTarget { get; private set; }
private readonly List<Transform> detected = new();
private IEnumerable<Transform> detected = ArraySegment<Transform>.Empty;
public async UniTask Execute()
{
await sensor.Execute();
var _detected = sensor.Get().ToList();
if (_detected.Contains(CurrentTarget))
Profiler.BeginSample("Release Detected Buffer");
var newDetected = sensor.Get();
Profiler.EndSample();
// ReSharper disable once PossibleMultipleEnumeration
if (newDetected.Contains(CurrentTarget))
{
if (detected.Count is 1 && detected[0] == CurrentTarget)
if (optionalRetargetInterval.Allow && optionalRetargetInterval.Value.AllowUpdate)
{
}
else
{
detected.Clear();
detected.Add(CurrentTarget);
return;
}
return;
}
CurrentTarget = _detected
Profiler.BeginSample("Filter Detected");
// ReSharper disable once PossibleMultipleEnumeration
CurrentTarget = newDetected
.Where(_transform => IsValid(_transform.GetComponent<Collider>()))
.OrderBy(_transform => Vector3.Distance(transform.position, _transform.position))
.FirstOrDefault();
Profiler.EndSample();
}
private void Update()
{
if(autoUpdate)Execute().Forget();
if(autoUpdate && SensorGlobalSettings.Enabled)Execute().Forget();
}
void IAction.Execute()

View File

@ -2,7 +2,6 @@ using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.UIElements;
namespace BITKit.UX

View File

@ -6,7 +6,6 @@ using UnityEngine;
using UnityEngine.UIElements;
using UnityEngine.InputSystem;
using BITKit;
using UnityEngine.AddressableAssets;
using Cysharp.Threading.Tasks;
namespace BITKit.UX.Internal
{

View File

@ -2,7 +2,6 @@ using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEngine.AddressableAssets;
namespace BITKit.UX
{
public class UXConstant

View File

@ -13,8 +13,9 @@ namespace BITKit.UX
[Obsolete("Use UXService instead")]
public class UXFramework : MonoBehaviour
{
public static Dictionary<string, UXPanel> panels = new();
public static Stack<UXPanel> stacks = new();
public static readonly Dictionary<string, UXPanel> panels = new();
public static readonly Stack<UXPanel> stacks = new();
private static UXFramework singleton;
private static UXPanel current;
@ -95,7 +96,7 @@ namespace BITKit.UX
}
}
void OnDestroy()
private void OnDestroy()
{
if (singleton == this)
{
@ -107,7 +108,7 @@ namespace BITKit.UX
}
}
void Start()
private void Start()
{
GetComponentsInChildren<UXPanel>(true).ForEach(x =>
{
@ -127,5 +128,7 @@ namespace BITKit.UX
Enter(startPanel);
}
}
}
}

View File

@ -24,6 +24,11 @@ namespace BITKit.UX
[SerializeField] private bool allowCursor;
[SerializeField] private bool allowInput;
[SerializeField] private bool autoEntry;
[Header(Constant.Header.Settings)]
[SerializeField] private Optional<float> entryDuration;
[SerializeField] private Optional<float> exitDuration;
protected readonly InputActionGroup inputActionGroup = new()
{
allowGlobalActivation = false
@ -34,51 +39,109 @@ namespace BITKit.UX
public bool AllowCursor => allowCursor;
public bool AllowInput => allowInput;
protected CancellationToken cancellationToken { get; private set; }
protected float TargetOpacity { get; private set; }
protected virtual VisualElement background => document.rootVisualElement;
protected float CurrentOpacity
{
get => background?.GetOpacity() ?? _currentOpacity;
set
{
_currentOpacity = value;
background?.SetOpacity(value);
}
}
private float _currentOpacity;
protected virtual void Awake()
{
cancellationToken = gameObject.GetCancellationTokenOnDestroy();
Index= typeof(UIToolKitPanel) == GetType() ? gameObject.name : GetType().Name;
document.rootVisualElement.SetActive(false);
background?.SetOpacity(0);
}
protected virtual void Start()
{
if(IsValid && autoEntry)
UXService.Entry(this);
}
public bool IsEntered { get; set; }
public void Entry()
{
UXService.Entry(this);
}
protected virtual void OnEnable()=>UXService.Register(this);
protected virtual void OnDisable()=>UXService.UnRegister(this);
void IUXPanel.Entry()
{
void IEntryElement.Entry()
{
TargetOpacity = 1;
OnEntryOrExit(true);
document.rootVisualElement.SetActive(true);
inputActionGroup.allowInput.AddElement(this);
OnEntry?.Invoke();
}
void IUXPanel.Exit()
async UniTask IEntryElement.EntryAsync()
{
if (entryDuration.Allow is false) return;
while (CurrentOpacity < 1 && TargetOpacity is 1)
{
await UniTask.NextFrame(cancellationToken);
}
}
void IEntryElement.Entered()
{
inputActionGroup.allowInput.AddElement(this);
}
void IEntryElement.Exit()
{
if (IsValid is false) return;
TargetOpacity = 0;
OnEntryOrExit(false);
inputActionGroup.allowInput.RemoveElement(this);
try
}
async UniTask IEntryElement.ExitAsync()
{
if (exitDuration.Allow is false) return;
while (CurrentOpacity > 0 && TargetOpacity is 0)
{
document.rootVisualElement.SetActive(false);
}
catch (Exception e)
{
BIT4Log.Warning<UIToolKitPanel>(name);
BIT4Log.LogException(e);
await UniTask.NextFrame(cancellationToken);
}
OnExit?.Invoke();
}
void IEntryElement.Exited()
{
document.rootVisualElement.SetActive(false);
}
public event Action OnEntry;
public event Action OnExit;
protected virtual void OnEntryOrExit(bool isEntry)
{
}
public virtual void OnUpdate(float deltaTime)
{
var duration = 1f;
if (TargetOpacity is 1)
{
if (entryDuration.Allow is false)
{
CurrentOpacity = TargetOpacity;
return;
}
duration = entryDuration.Value;
}
else
{
if (exitDuration.Allow is false)
{
CurrentOpacity = TargetOpacity;
return;
}
duration = exitDuration.Value;
}
CurrentOpacity = Mathf.MoveTowards(CurrentOpacity,TargetOpacity,1f/duration * Time.deltaTime);
}
}
}

View File

@ -2,6 +2,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
#if UNITY_EDITOR
using UnityEditor;
#endif
@ -15,6 +16,7 @@ namespace BITKit.UX
/// </summary>
public class UXService : MonoBehaviour, IUXService
{
/// <summary>
/// 重新初始化,使用<see cref="RuntimeInitializeLoadType.SubsystemRegistration"/>确保在所有子系统注册后执行
/// </summary>
@ -25,10 +27,13 @@ namespace BITKit.UX
UnRegistryQueue.Clear();
Panels.Clear();
EntryQueue.Clear();
EntryCompletedPanels.Clear();
CurrentPanel = null;
History.Clear();
EntryGroup = new EntryGroup<IUXPanel>();
}
private static EntryGroup<IUXPanel> EntryGroup = new();
/// <summary>
/// 内部注册面板队列
/// </summary>
@ -52,12 +57,12 @@ namespace BITKit.UX
/// <summary>
/// 已启用面板
/// </summary>
internal static readonly Stack<IUXPanel> EntryCompletedPanels = new();
internal static IUXPanel CurrentPanel;
/// <summary>
/// 历史面板
/// </summary>
private static readonly Stack<IUXPanel> History = new();
internal static readonly Stack<IUXPanel> History = new();
public static void Register(IUXPanel panel) => RegistryQueue.Enqueue(panel);
@ -67,7 +72,6 @@ namespace BITKit.UX
public static void Return()
{
if (!History.TryPop(out _)) return;
if (History.TryPop(out var returnPanel))
{
Entry(returnPanel);
@ -80,57 +84,92 @@ namespace BITKit.UX
[SerializeReference, SubclassSelector] private IUXPanel initialPanel;
private bool initialized;
private void Awake()
{
DI.Register<IUXService>(this);
}
}
private void Start()
{
EntryGroup.OnEntry += OnEntry;
EntryGroup.OnExit += OnExit;
if (initialPanel is not null)
{
Entry(initialPanel);
}
}
private static void OnExit(IUXPanel obj)
{
History.Push(obj);
}
private static void OnEntry(IUXPanel obj)
{
CurrentPanel = obj;
}
private void Update()
{
while (UnRegistryQueue.TryDequeue(out var result))
{
if (result is null) continue;
EntryGroup.list.Remove(result);
Panels.Remove(result.Index);
}
while (RegistryQueue.TryDequeue(out var result))
{
if (result is null) continue;
EntryGroup.list.Add(result);
Panels.Set(result.Index, result);
result.Exit();
}
if (initialized is false && initialPanel is not null)
if (EntryQueue.TryPop(out var nextPanel))
{
initialized = true;
Entry(initialPanel);
EntryGroup.Entry(x=>x.Index==nextPanel.Index);
BITAppForUnity.AllowCursor.SetElements(this, nextPanel.AllowCursor);
BITInputSystem.AllowInput.SetElements(this, nextPanel.AllowInput);
}
if (!EntryQueue.TryPop(out var next) || next is null) return;
if (EntryGroup.TryGetEntried(out var currentPanel))
{
currentPanel.OnUpdate(Time.deltaTime);
};
if (Panels.ContainsKey(next.Index) is false) return;
while (EntryCompletedPanels.TryPop(out var entryCompletedPanel))
{
entryCompletedPanel?.Exit();
}
try
{
next.Entry();
}
catch (Exception e)
{
Debug.LogWarning(next.Index);
Debug.LogException(e);
}
BITAppForUnity.AllowCursor.SetElements(this, next.AllowCursor);
BITInputSystem.AllowInput.SetElements(this, next.AllowInput);
EntryCompletedPanels.Push(next);
History.Push(next);
// if (initialized is false && initialPanel is not null)
// {
// initialized = true;
// Entry(initialPanel);
// }
//
// if (!EntryQueue.TryPop(out var next) || next is null) return;
//
// if (Panels.ContainsKey(next.Index) is false) return;
//
// while (EntryCompletedPanels.TryPop(out var entryCompletedPanel))
// {
// entryCompletedPanel?.Exit();
// }
//
// try
// {
// next.Entry();
// }
// catch (Exception e)
// {
// Debug.LogWarning(next.Index);
// Debug.LogException(e);
// }
//
// BITAppForUnity.AllowCursor.SetElements(this, next.AllowCursor);
// BITInputSystem.AllowInput.SetElements(this, next.AllowInput);
//
// EntryCompletedPanels.Push(next);
// History.Push(next);
}
void IUXService.Register(IUXPanel panel) => Register(panel);
@ -151,6 +190,7 @@ namespace BITKit.UX
{
private Label currentPanelLabel;
private Label panelsLabel;
private Label historyLabel;
public override VisualElement CreateInspectorGUI()
{
FillDefaultInspector();
@ -158,16 +198,18 @@ namespace BITKit.UX
currentPanelLabel = root.Create<Label>();
CreateSubTitle("Panels");
panelsLabel = root.Create<Label>();
CreateSubTitle("History");
historyLabel = root.Create<Label>();
return root;
}
protected override void OnUpdate()
{
if (panelsLabel is null || currentPanelLabel is null) return;
if (panelsLabel is null || currentPanelLabel is null || historyLabel is null) return;
panelsLabel.text=string.Join("\n",UXService.Panels);
currentPanelLabel.text = string.Join("\n",UXService.EntryCompletedPanels.Select(x=>x.Index));
currentPanelLabel.text = string.Join("\n",UXService.CurrentPanel?.Index);
historyLabel.text = string.Join("\n",UXService.History.Select(x=>x.Index));
}
}
#endif

View File

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

View File

@ -0,0 +1,66 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace BITKit.UX
{
/// <summary>
/// Created by Vitens on 2020/12/11 20:48:35
///
/// Description :
/// 全屏背景图片等比例拉伸自适应
/// </summary>
[ExecuteInEditMode]
public class UGUIBackgroundImageScaler : MonoBehaviour
{
//图片原大小(压缩前的)
[SerializeField] private Vector2 textureOriginSize = new Vector2(2048, 1024);
// Start is called before the first frame update
private void Start()
{
Scaler();
}
//适配
private void Scaler()
{
//当前画布尺寸
Vector2 canvasSize = gameObject.GetComponentInParent<Canvas>().GetComponent<RectTransform>().sizeDelta;
//当前画布尺寸长宽比
float screenxyRate = canvasSize.x / canvasSize.y;
//图片尺寸 这个得到的结果是 (0,0) ?
//Vector2 bgSize = bg.mainTexture.texelSize;
Vector2 bgSize = textureOriginSize;
//视频尺寸长宽比
float texturexyRate = bgSize.x / bgSize.y;
RectTransform rt = (RectTransform)transform;
//视频x偏长,需要适配y下面的判断 '>' 改为 '<' 就是视频播放器的视频方式)
if (texturexyRate > screenxyRate)
{
int newSizeY = Mathf.CeilToInt(canvasSize.y);
int newSizeX = Mathf.CeilToInt((float)newSizeY / bgSize.y * bgSize.x);
rt.sizeDelta = new Vector2(newSizeX, newSizeY);
}
else
{
int newVideoSizeX = Mathf.CeilToInt(canvasSize.x);
int newVideoSizeY = Mathf.CeilToInt((float)newVideoSizeX / bgSize.x * bgSize.y);
rt.sizeDelta = new Vector2(newVideoSizeX, newVideoSizeY);
}
}
private void Update()
{
#if UNITY_EDITOR
//editor模式下测试用
Scaler();
#endif
}
}
}

View File

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

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using System.Reflection;
using UnityEngine.AddressableAssets;
using System;
#if UNITY_EDITOR
using UnityEditor;

View File

@ -39,6 +39,24 @@ namespace BITKit
}
public static partial class MathV
{
public static bool InFovRange(Vector3 selfPosition,Vector3 selfForward, Vector3 target, float fov)
{
var direction = target - selfPosition;
var angle = Vector3.Angle(direction, selfForward);
return angle < fov;
}
public static bool IsForward(Vector3 selfPosition, Vector3 selfForward,Vector3 targetPos)
{
// Get the direction from referencePos to targetPos
Vector3 directionToTarget = (targetPos - selfPosition).normalized;
// Calculate the dot product
float dotProduct = Vector3.Dot(directionToTarget, selfForward);
// If dot product is greater than 0, targetPos is in front of referencePos
return dotProduct > 0;
}
// 对于 Vector3
public static Vector3 AlignRotation(Vector3 eulerAngles, float angleIncrement)
{

View File

@ -28,6 +28,12 @@ namespace BITKit
private readonly List<T> _list=new();
public int DefaultCapacity
{
get => defaultCapacity;
set => defaultCapacity = value;
}
public T Get(T element = null, Transform _root = null)
{
if (_list.Count == defaultCapacity)

View File

@ -5,6 +5,7 @@ using UnityEngine;
using BITKit;
using UnityEngine.Events;
using UnityEngine.Pool;
using UnityEngine.UIElements;
namespace BITKit
{
@ -18,6 +19,8 @@ namespace BITKit
private static VFXService sinleton;
public VFX[] vfxs;
private readonly Dictionary<string, UnityPool<Transform>> pools = new();
[SerializeField] private Optional<int> defaultCapacity;
private void Awake()
{
sinleton = this;
@ -37,6 +40,8 @@ namespace BITKit
if (TryMatch(out var prefab, keyWords))
{
var pool = pools.Get(prefab.name);
if (defaultCapacity.Allow)
pool.DefaultCapacity = defaultCapacity.Value;
var instance = pool.Get(prefab, transform);
instance.SetPositionAndRotation(location, location);
if (location.forward.sqrMagnitude is not 0)

View File

@ -58,13 +58,14 @@ namespace BITKit.Vehicles
private readonly ValidHandle highSpeedHandle = new();
private IUnityEntity _unityEntity;
[Inject]
[Inject(true)]
private IHealth _health;
public override void OnAwake()
{
base.OnAwake();
_health.OnSetAlive += OnSetAlive;
if (_health is not null)
_health.OnSetAlive += OnSetAlive;
}
private void OnSetAlive(bool obj)
@ -122,7 +123,7 @@ namespace BITKit.Vehicles
{
trans.localEulerAngles = new Vector3(torque * Time.deltaTime, steelAngle, 0);
});
if (steeringWheel is not null)
if (steeringWheel)
steeringWheel.localEulerAngles = new Vector3(0, 0, steelAngle);
x.wheels.ForEach(wheelCollider => { wheelCollider.steerAngle = steel; });
break;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 08c4abb8e020e3342aa81690c0ea78ef
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3}

View File

@ -2,13 +2,6 @@
background-color: rgb(113, 113, 113);
}
.Console-Text {
font-size: 18px;
color: rgba(233, 233, 233, 0.63);
-unity-font-definition: url('project://database/Assets/BITKit/Art/Fonts/NotoSansSC-Regular%20SDF.asset?fileID=11400000&guid=4897d78d91e2fa34bbc06b9e213ac6d4&type=2#NotoSansSC-Regular SDF');
-unity-font-style: bold;
}
.Console-ScrollView {
background-color: rgb(87, 87, 87);
}
@ -60,5 +53,5 @@ ListView Label {
}
ListView Label:hover {
color: rgba(32, 32, 32, 255);
color: rgb(32, 32, 32);
}

View File

@ -1,5 +1,6 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<Style src="project://database/Assets/BITKit/UX/BITConsole.uss?fileID=7433441132597879392&amp;guid=9175bfb75cd47b9488b9f12bd34e50fd&amp;type=3#BITConsole" />
<Style src="project://database/Assets/BITKit/Unity/UX/BITConsole.uss?fileID=7433441132597879392&amp;guid=9175bfb75cd47b9488b9f12bd34e50fd&amp;type=3#BITConsole" />
<Style src="project://database/Assets/BITKit/Unity/UX/Common/Common.uss?fileID=7433441132597879392&amp;guid=a3a69d3518fd02b489e721f3c5b0b539&amp;type=3#Common" />
<ui:VisualElement name="Root" style="position: absolute; left: 0; top: 0; right: 0; bottom: 0;">
<ui:VisualElement name="Console" class="Console" style="width: 1024px; height: 768px; border-top-left-radius: 16px; border-bottom-left-radius: 16px; border-top-right-radius: 16px; border-bottom-right-radius: 16px; padding-left: 16px; padding-right: 16px; padding-top: 8px; padding-bottom: 8px; margin-left: auto; margin-right: auto; margin-top: auto; margin-bottom: auto;">
<ui:Label text="Console" display-tooltip-when-elided="true" class="Console-Text" />

View File

@ -122,6 +122,11 @@ TabBar Button:disabled {
-unity-font: url('project://database/Assets/BITKit/Unity/Art/Fonts/TTF/SourceHanMono/SourceHanMono-Medium.ttc?fileID=12800000&guid=c8058440fb1ea26488e022a5ee5b3b35&type=3#SourceHanMono-Medium');
}
.theme-dark .unity-text-element {
color: rgb(231, 231, 231);
-unity-font: url('project://database/Assets/BITKit/Unity/Art/Fonts/TTF/SourceHanMono/SourceHanMono-Medium.ttc?fileID=12800000&guid=c8058440fb1ea26488e022a5ee5b3b35&type=3#SourceHanMono-Medium');
}
.theme-dark DropdownField > VisualElement > VisualElement {
-unity-background-image-tint-color: rgb(128, 128, 128);
}
@ -205,3 +210,7 @@ Button {
#unity-progress-bar > VisualElement > VisualElement {
}
PopupTextElement.unity-text-element {
color: rgb(24, 24, 24);
}

View File

@ -0,0 +1,39 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 19101, guid: 0000000000000000e000000000000000, type: 0}
m_Name: Common_PC_Overlay
m_EditorClassIdentifier:
themeUss: {fileID: -4733365628477956816, guid: ac803f0924e239645ac6b2fc9baebc65,
type: 3}
m_TargetTexture: {fileID: 0}
m_ScaleMode: 2
m_ReferenceSpritePixelsPerUnit: 100
m_Scale: 1
m_ReferenceDpi: 96
m_FallbackDpi: 96
m_ReferenceResolution: {x: 1920, y: 1080}
m_ScreenMatchMode: 0
m_Match: 0.421
m_SortingOrder: 1
m_TargetDisplay: 0
m_ClearDepthStencil: 1
m_ClearColor: 0
m_ColorClearValue: {r: 0, g: 0, b: 0, a: 0}
m_DynamicAtlasSettings:
m_MinAtlasSize: 8
m_MaxAtlasSize: 4096
m_MaxSubTextureSize: 64
m_ActiveFilters: -1
m_AtlasBlitShader: {fileID: 9101, guid: 0000000000000000f000000000000000, type: 0}
m_RuntimeShader: {fileID: 9100, guid: 0000000000000000f000000000000000, type: 0}
m_RuntimeWorldShader: {fileID: 9102, guid: 0000000000000000f000000000000000, type: 0}
textSettings: {fileID: 0}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 918ab67128d80634cbca61ac58b651f0
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,7 +1,9 @@
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.UIElements;
#endif
using UnityEngine;
using UnityEngine.UIElements;

View File

@ -4,7 +4,9 @@
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:4307f53044263cf4b835bd812fc161a4",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50"
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
"GUID:7efac18f239530141802fb139776f333"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@ -0,0 +1,46 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BITKit.Entities;
using Cinemachine;
using UnityEngine;
namespace BITKit.Scene
{
public class CinemachineEntitiesGroup : MonoBehaviour
{
[SerializeField] private IEntitiesService _entitiesService;
[SerializeField] private CinemachineTargetGroup targetGroup;
[SerializeField] private Optional<Entity[]> initialEntities;
private void Update()
{
// foreach (var x in initialEntities.IfNotAllow(()=>_entitiesService.Query<IHealth>().Cast<Entity>().ToArray()))
// {
//
// }
targetGroup.m_Targets =
initialEntities.IfNotAllow(() => _entitiesService.Query<IHealth>().Cast<Entity>().ToArray())
.Select(x => new CinemachineTargetGroup.Target()
{
target = x.transform,
radius = 1,
weight = x.TryGetComponent<IHealth>(out var heal) ? heal.IsAlive ? 1 : 0 : 0
})
.ToArray();
if (targetGroup.m_Targets.Length is 0)
{
targetGroup.m_Targets = initialEntities.IfNotAllow(() => _entitiesService.Query<IHealth>().Cast<Entity>().ToArray()).Select(
x=>
new CinemachineTargetGroup.Target()
{
target = x.transform,
radius = 1,
weight = 1
}
).ToArray();
}
}
}
}

View File

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

View File

@ -3,7 +3,6 @@ using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Experimental.Audio;
using UnityEngine.UIElements;

View File

@ -5,7 +5,6 @@ using UnityEditor;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using System.Linq;
using UnityEngine.AddressableAssets;
using BITKit;
using BITKit.UX;
namespace BITKit.Editors
@ -24,18 +23,18 @@ namespace BITKit.Editors
}
public void CreateGUI()
{
root = Addressables.LoadAssetAsync<VisualTreeAsset>(nameof(ReferenceEditor)).WaitForCompletion().CloneTree();
rootVisualElement.Add(root);
listView = root.Q<ListView>(UXConstant.ContextListView);
var allList = AssetDatabase
.FindAssets($"t:{nameof(ReferenceSO)}")
.Select(x => AssetDatabase.GUIDToAssetPath(x))
.Select(x => AssetDatabase.LoadAssetAtPath<ReferenceSO>(x))
.ToList();
listView.itemsSource = allList;
// root = Addressables.LoadAssetAsync<VisualTreeAsset>(nameof(ReferenceEditor)).WaitForCompletion().CloneTree();
// rootVisualElement.Add(root);
//
// listView = root.Q<ListView>(UXConstant.ContextListView);
//
// var allList = AssetDatabase
// .FindAssets($"t:{nameof(ReferenceSO)}")
// .Select(x => AssetDatabase.GUIDToAssetPath(x))
// .Select(x => AssetDatabase.LoadAssetAtPath<ReferenceSO>(x))
// .ToList();
//
// listView.itemsSource = allList;
}
}
}

View File

@ -15,6 +15,10 @@ namespace BITKit
public BBParameter<int> intParameter;
public BBParameter<int> floatParameter;
public BBParameter<string> stringParameter;
public override string ToString()
{
return $"{command}";
}
protected override void OnExecute()
{

View File

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

View File

@ -0,0 +1,25 @@
using System;
using System.Collections;
using System.Collections.Generic;
using NodeCanvas.Framework;
using ParadoxNotion.Design;
using UnityEngine;
using UnityEngine.AI;
namespace BITKit.NodeCanvas.Pathfinding
{
[Category("Pathfinding")]
public class SetNavMeshAgentOptions : ActionTask<NavMeshAgent>
{
public BBParameter<bool> overrideUpdateRotation = false;
public BBParameter<bool> overrideUpdatePosition = false;
protected override void OnExecute()
{
agent.updateRotation = overrideUpdateRotation.value;
agent.updatePosition = overrideUpdatePosition.value;
EndAction();
}
}
}

View File

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