This commit is contained in:
CortexCore
2023-06-05 16:25:06 +08:00
parent 9027120bb8
commit 4565ff2e35
2947 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
public struct AnimatorParameter
{
public AnimatorControllerParameterType type;
public string name;
public object value;
public T Get<T>()
{
if (value is T t)
{
return t;
}
return default;
}
}
}

View File

@@ -0,0 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
}

View File

@@ -0,0 +1,39 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using Sirenix.OdinInspector;
using UnityEngine.UIElements;
namespace BITKit
{
public abstract class BITBehavior : SerializedMonoBehaviour, ICustomInspector
{
public VisualTreeAsset customTreeAsset;
public virtual void OnAwake() { }
public virtual void OnStart() { }
public virtual void OnStop() { }
public virtual void OnUpdate(float deltaTime) { }
public virtual void OnFixedUpdate(float deltaTime) { }
public virtual void OnLateUpdate(float deltaTime) { }
public virtual void OnDestroyComponent() { }
public virtual void SetActive(bool active) { }
public virtual Transform GetTransform() => transform;
public void Toggle()
{
enabled = !enabled;
}
public virtual string GetName()
{
return gameObject.name;
}
public virtual object GetDiagnostics()
{
throw new System.NotImplementedException();
}
public VisualElement GetVisualElement()
{
return customTreeAsset ? customTreeAsset.CloneTree() : null;
}
}
}

View File

@@ -0,0 +1,27 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
public class DeltaTimer
{
public static implicit operator int(DeltaTimer timer)
{
return ((int)(1f / timer.deltaTime));
}
public static implicit operator string(DeltaTimer timer)
{
return ((int)timer).ToString();
}
float deltaTime = 0.0f;
// Update is called once per frame
public void Update(float unscaleDeltaTime = -1)
{
if (unscaleDeltaTime is -1)
{
unscaleDeltaTime = Time.unscaledDeltaTime;
}
deltaTime += (unscaleDeltaTime - deltaTime) * 0.1f;
}
}
}

View File

@@ -0,0 +1,171 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using System.Reflection;
using UnityEngine.AddressableAssets;
#if UNITY_EDITOR
using UnityEditor;
using Editor = UnityEditor.Editor;
using UnityEditor.UIElements;
#else
using Editor=BITKit.Constant.EmetyClass;
#endif
namespace BITKit
{
public class BITAttribute : System.Attribute
{
}
public class ServerRpcAttribute : System.Attribute
{
}
public class ClientRpcAttribute : System.Attribute
{
}
#if UNITY_EDITOR
public class BITInspector<T> : Editor
{
const string ussName = "BITInspector";
public class VisualElementCreator
{
public static implicit operator VisualElement(VisualElementCreator self)
{
return self.root;
}
public VisualElement root;
public VE Create<VE>() where VE : VisualElement, new()
{
root = root ?? new();
var ve = new VE();
root.Add(ve);
return ve;
}
}
protected VisualElementCreator root = new();
protected T agent;
public override VisualElement CreateInspectorGUI()
{
if (serializedObject.targetObject is ICustomInspector inspector && inspector.GetVisualElement() is not null)
{
return inspector.GetVisualElement();
}
else
{
FillDefaultInspector();
return root;
}
}
protected Label CreateSubTitle(string value)
{
var label = root.Create<Label>();
label.text = value;
label.AddToClassList("subTitle");
return label;
}
void Awake()
{
root.root = new();
if (serializedObject.targetObject is T value)
{
agent = value;
}
}
void OnEnable()
{
StyleSheet css = Addressables.LoadAssetAsync<StyleSheet>(ussName).WaitForCompletion();
root.root.styleSheets.Add(css);
EditorApplication.update += OnUpdate;
}
void OnDisable()
{
EditorApplication.update -= OnUpdate;
}
protected virtual void OnUpdate()
{
}
protected void FillDefaultInspector()
{
FillDefaultInspector(root, serializedObject, true);
}
public static void FillDefaultInspector(VisualElement container, SerializedObject serializedObject, bool hideScript)
{
SerializedProperty property = serializedObject.GetIterator();
if (property.NextVisible(true)) // Expand first child.
{
do
{
if (property.propertyPath == "m_Script" && hideScript)
{
continue;
}
var type = serializedObject.targetObject.GetType().GetField(property.name);
var field = new PropertyField(property);
field.name = "PropertyField:" + property.propertyPath;
if (property.propertyPath == "m_Script" && serializedObject.targetObject != null)
{
field.SetEnabled(false);
}
try
{
if (type is not null)
{
var header = type.GetCustomAttribute<HeaderAttribute>();
if (header is not null)
{
Label label = new Label(header.header);
label.AddToClassList("subTitle");
container.Add(label);
}
}
}
catch (System.Exception e)
{
Debug.LogException(e);
}
container.Add(field);
}
while (property.NextVisible(false));
foreach (var method in serializedObject.targetObject.GetType().GetMethods())
{
if (method.GetCustomAttribute<BITAttribute>() is not null)
{
if (method.GetParameters().Length is 0)
{
var button = new Button(() => method.Invoke(serializedObject.targetObject, null));
button.text = method.Name;
container.Add(button);
}
}
}
}
}
}
public class BITProperty : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
PropertyField propertyField = new(property);
return propertyField;
}
}
#endif
}

View File

@@ -0,0 +1,541 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using System.Linq;
using System.Reflection;
using System.IO;
using System.Runtime.CompilerServices;
using UnityEngine.Networking;
using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Linq;
using System.Text;
using System.IO.Compression;
using System.Data;
using UnityEngine.UIElements;
namespace BITKit
{
public static partial class MathQ
{
public static bool IsNaN(this Quaternion self)
{
return float.IsNaN(self.x) || float.IsNaN(self.y) || float.IsNaN(self.z) || float.IsNaN(self.w);
}
}
public static partial class MathV
{
public static bool IsNaN(this Vector3 self)
{
return float.IsNaN(self.x) || float.IsNaN(self.y) || float.IsNaN(self.z);
}
public static Vector2 Fix(this Vector2 self, int length = 1024)
{
if (MathB.IsNormal(self.x, length) is false)
{
self.x = 0;
}
if (MathB.IsNormal(self.y, length) is false)
{
self.y = 0;
}
return self;
}
public static Vector3 Fix(this Vector3 self, int length = 1024)
{
if (MathB.IsNormal(self.x, length) is false)
{
self.x = 0;
}
if (MathB.IsNormal(self.y, length) is false)
{
self.y = 0;
}
if (MathB.IsNormal(self.z, length) is false)
{
self.z = 0;
}
return self;
}
public static bool Parallel(Vector2 vectorX, Vector2 vectorY)
{
return (vectorX, vectorY) switch
{
var (x, y) when (x.x > 0 && y.x > 0 && x.y > 0 && y.y > 0) => true,
var (x, y) when (x.x < 0 && y.x < 0 && x.y < 0 && y.y < 0) => true,
_ => false,
};
}
public static bool Approximately(Vector2 vectorX, Vector2 vectorY, float factor = 8)
{
/* var direction = vectorX - vectorY;
return direction.sqrMagnitude < factor; */
return Vector3.Angle(vectorX, vectorY) < 8;
}
public static Vector3 TransientRotationAxis(this Vector3 transientAxis)
{
transientAxis.x = TransientRotationAxis(transientAxis.x);
transientAxis.y = TransientRotationAxis(transientAxis.y);
transientAxis.z = TransientRotationAxis(transientAxis.z);
return transientAxis;
}
public static Vector3Int Align(this Vector3 self, int snapSize = 64)
{
Vector3Int result = new()
{
x = GetAlign(self.x),
y = GetAlign(self.y),
z = GetAlign(self.z),
};
return result * snapSize;
int GetAlign(float self)
{
var size = (int)self / snapSize;
var remainder = self % snapSize;
return remainder > snapSize / 2 ? size + 1 : size;
}
}
public static float GetLength(this Vector3 self)
{
return Mathf.Max(Mathf.Abs(self.x), Mathf.Abs(self.y), Mathf.Abs(self.z));
}
public static float GetValue(this Vector3 self)
{
var addValue = self.x + self.y + self.z;
var subtractValue = self.x - self.y - self.z;
if (MathF.Abs(addValue) == Mathf.Abs(subtractValue))
{
return addValue;
}
else
{
var sb = new StringBuilder();
sb.AppendLine("Not a valid vector");
sb.AppendLine($"{self.x}+{self.y}+{self.z} = {addValue}");
sb.AppendLine($"{self.x}-{self.y}-{self.z} = {subtractValue}");
sb.AppendLine($"{addValue}");
sb.AppendLine($"{subtractValue}");
throw new Exception(sb.ToString());
}
}
public static bool InRange(this Vector2Int self, Vector2Int other)
{
return self.x >= 0
&& self.y >= 0
&& other.x >= 0
&& other.y >= 0
&& other.x <= self.x
&& other.y <= self.y
&& (self + other).x >= 0
&& (self + other).y >= 0;
}
public static float TransientRotationAxis(this float transientAxis)
{
return (transientAxis %= 360) switch
{
var x when x > 180 => transientAxis - 360,
var x when x < -180 => transientAxis + 360,
_ => transientAxis,
};
}
public static float WrapAngle(float angle)
{
angle %= 360;
if (angle > 180)
return angle - 360;
return angle;
}
public static Vector3 WrapAngle(Vector3 vector)
{
return new Vector3
{
x = WrapAngle(vector.x),
y = WrapAngle(vector.y),
z = WrapAngle(vector.z),
};
}
private static float UnwrapAngle(float angle)
{
if (angle >= 0)
return angle;
angle = -angle % 360;
return 360 - angle;
}
public static Vector2Int ToVector2Int(this Vector2 self)
{
return new Vector2Int
{
x = (int)self.x,
y = (int)self.y,
};
}
}
public static partial class Utility
{
public static bool Includes(this LayerMask mask, int layer)
{
return (mask.value & 1 << layer) > 0;
}
public static byte[] ToByte(this string self)
{
return System.Text.Encoding.UTF8.GetBytes(self);
}
public static string Padding(this string self, int length = 16, char c = ' ')
{
Encoding coding = Encoding.GetEncoding("gb2312");
int dcount = 0;
foreach (char ch in self.ToCharArray())
{
if (coding.GetByteCount(ch.ToString()) == 2)
dcount++;
}
string w = self.PadRight(length - dcount, c);
return w;
}
public static bool IsDefault<T>(this T self) where T : IEquatable<T>
{
return self.Equals(default);
}
public static float Random(this float self) => UnityEngine.Random.Range(-self, self);
public static int Random(this int self) => UnityEngine.Random.Range(-self, self);
public static Location GetLocation(this Component self)
{
return new Location(self);
}
public static Location GetLocation(this GameObject self)
{
return new Location(self.transform);
}
public static T Random<T>(this IEnumerable<T> e)
{
return e.ElementAt(UnityEngine.Random.Range(0, e.Count()));
}
public static T Random<T>(this T[] self)
{
return self[UnityEngine.Random.Range(0, self.Length)];
}
public static bool IsNullOrEmpty(this string self)
{
return String.IsNullOrWhiteSpace(self);
}
public static bool IsValid(this string self)
{
return !self.IsNullOrEmpty();
}
public static UnityEvent AddListener(this UnityEvent unityEvent, UnityAction call)
{
unityEvent.AddListener(call);
return unityEvent;
}
public static string Combine(this string[] self)
{
if (self.IsNull())
{
return string.Empty;
}
StringBuilder stringBuilder = new();
self.ForEach(x =>
{
stringBuilder.Append(x);
});
return stringBuilder.ToString();
}
public static string Combine(this IEnumerable<string> self, bool split = false)
{
StringBuilder stringBuilder = new StringBuilder();
if (self.IsNull())
{
return string.Empty;
}
self.ForEach(x =>
{
stringBuilder.Append(x);
stringBuilder.Append(" ");
if (split)
{
stringBuilder.Append("\n");
}
});
return stringBuilder.ToString();
}
public static float ToFloat(this string self)
{
if (string.IsNullOrEmpty(self)) return default;
return float.Parse(self);
}
public static Vector3 MatchTarget(this ref Vector3 self, Vector3 pos, float normalizedTime, float start, float end)
{
if (normalizedTime >= start && normalizedTime <= end)
{
float process = normalizedTime / (end - start);
Vector3 direction = pos - self;
return Vector3.Lerp(default, direction, process);
}
return default;
}
public static Dictionary<string, string> ToDictionary(this string jsonSrting, params string[] removes)
{
removes.ForEach(x =>
{
jsonSrting = jsonSrting.Replace(x, string.Empty);
});
var jsonObject = JObject.Parse(jsonSrting);
var jTokens = jsonObject.Descendants().Where(p => !p.Any());
var tmpKeys = jTokens.Aggregate(new Dictionary<string, string>(),
(properties, jToken) =>
{
properties.Add(jToken.Path, jToken.ToString());
return properties;
});
return tmpKeys;
}
public static Dictionary<string, string> JsonToDictionary(this string jsonSrting, params string[] replace)
{
replace.ForEach(x =>
{
jsonSrting = jsonSrting.Replace(x, string.Empty);
});
Dictionary<string, string> dic = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonSrting);
return dic;
}
public static string DeleteLines(string text, int lineCount)
{
while (text.Split('\n').Length > lineCount)
text = text.Remove(0, text.Split('\n')[0].Length + 1);
return text;
}
public static TaskAwaiter GetAwaiter(this AsyncOperation asyncOp)
{
var tcs = new TaskCompletionSource<object>();
asyncOp.completed += obj => { tcs.SetResult(null); };
return ((Task)tcs.Task).GetAwaiter();
}
public static TaskAwaiter GetAwaiter(this System.Action action)
{
var tcs = new TaskCompletionSource<object>();
action += () => { tcs.SetResult(null); };
return ((Task)tcs.Task).GetAwaiter();
}
public static float GetDifference(this IEnumerable<float> self)
{
return self.Max() - self.Min();
}
public static void Toggle(this Behaviour self)
{
self.enabled = !self.enabled;
}
public static void SetEnabled(this UnityEngine.Behaviour self, bool value)
{
if (self)
{
self.enabled = value;
}
}
public static T Or<T>(params T[] ts)
{
for (int i = 0; i < ts.Length; i++)
{
var t = ts[i];
if (t != null && t.Equals(default))
{
}
else
{
return t;
}
}
return default;
}
public static bool TryGetComponentsInParent<T>(this GameObject self, out T[] components)
{
return TryGetComponentsInParent(self.transform, out components);
}
public static bool TryGetComponentsInParent<T>(this Component self, out T[] components)
{
components = self.GetComponentsInParent<T>();
return components.IsValid();
}
public static bool TryGetComponentAny<T>(this Component self, out T component)
{
component = self.GetComponentInChildren<T>();
if (component is not null)
{
return true;
}
component = self.GetComponentInParent<T>();
if (component is not null)
{
return true;
}
return false;
}
public static bool TryGetFirstOrDefault<T>(this IEnumerable<T> self, out T value)
{
value = default;
if (self.IsValid())
{
value = self.ElementAt(0);
return true;
}
return default;
}
public static TValue GetOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> self, TKey key)
{
TValue value = default;
self.TryGetValue(key, out value);
return value; ;
}
public static void DestoryChilds(this GameObject self)
{
if (self)
{
var list = self.GetComponentsInChildren<Transform>().ToList();
list.TryRemove(self.transform);
list.ForEach(x =>
{
GameObject.Destroy(x.gameObject);
});
}
}
public static bool Contains(this string self, IEnumerable<string> strs, out string key)
{
bool result = false;
string newKey = default;
strs.ForEach(x =>
{
if (self.Contains(x))
{
result = true;
newKey = x;
return;
}
});
key = newKey;
return result;
}
/// <summary>
/// 带毫秒的字符转换成时间DateTime格式
/// 可处理格式:[2014-10-10 10:10:10,666 或 2014-10-10 10:10:10 666 或 2014-10-10 10:10:10.666]
/// </summary>
public static DateTime GetDateTime(this string dateTime)
{
string[] strArr = dateTime.Split(new char[] { '-', ' ', ':', ',', '.' });
DateTime dt = new DateTime(int.Parse(strArr[0]),
int.Parse(strArr[1]),
int.Parse(strArr[2]),
int.Parse(strArr[3]),
int.Parse(strArr[4]),
int.Parse(strArr[5]),
int.Parse(strArr[6]));
return dt;
}
public static bool Equality<T>(this IEnumerable<T> self, IEnumerable<T> other)
{
bool result = true;
if (self.Count() != other.Count())
{
return false;
}
self.ForEach(x =>
{
if (other.Contains(x) == false)
{
result = false;
return;
}
});
return result;
}
public static string ReservedRows(this string self, int length, bool reverse = false)
{
StringBuilder stringBuilder = new(self);
var lines = self.Split("\n");
if (reverse)
{
lines.Reverse().ToList();
}
if (lines.Length > length)
{
stringBuilder.Clear();
for (int i = lines.Length - length; i < lines.Length; i++)
{
var words = lines[i];
if (words is not "\n")
{
stringBuilder.Append(words);
}
stringBuilder.Append("\n");
}
}
return stringBuilder.ToString();
}
}
public static partial class ReflectionExtensions
{
public static void ForEachProties<T>(this object self, UnityAction<T> action = null)
{
self.GetType().GetProperties().ForEach(x =>
{
Debug.Log(x.Name);
if (x.GetCustomAttribute<ObsoleteAttribute>() == null && x.GetValue(self) is T t)
{
if (action is not null) action.Invoke(t);
}
});
}
public static void ForEachFields<T>(this object self, UnityAction<T> action = null, UnityAction<FieldInfo> infoAction = null, UnityAction<FieldInfo, T> mixAction = null)
{
self.GetType().GetFields().ForEach(x =>
{
if (x.GetCustomAttribute<ObsoleteAttribute>() == null && x.GetValue(self) is T t)
{
if (infoAction is not null) infoAction.Invoke(x);
if (action is not null) action.Invoke(t);
if (mixAction is not null) mixAction.Invoke(x, t);
}
});
}
}
public static partial class UIToolkitExtensions
{
public static void SetActive(this VisualElement self, bool active)
{
self.style.display = new(active ? DisplayStyle.Flex : DisplayStyle.None);
}
public static float GetOpacity(this VisualElement self) => self.style.opacity.value;
public static void SetOpacity(this VisualElement self, float value) => self.style.opacity = new(value);
public static void ScrollToBottom(this ScrollView self)
{
self.verticalScroller.value =
self.verticalScroller.highValue > 0 ? self.verticalScroller.highValue : 0;
}
public static async void ScrollToBottomAutomatic(this ScrollView self, float delay = 0.02f)
{
if (self.verticalScroller.value == self.verticalScroller.highValue)
{
try
{
await Task.Delay(TimeSpan.FromSeconds(delay), BITApp.CancellationTokenSource.Token);
ScrollToBottom(self);
}
catch (OperationCanceledException) { }
catch (System.Exception)
{
throw;
}
}
}
}
}

View File

@@ -0,0 +1,66 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using System.Linq;
namespace BITKit
{
public static partial class Utility
{
public static class Path
{
[RuntimeInitializeOnLoadMethod]
static void Init()
{
dataPath = Application.dataPath;
persistentDataPath = Application.persistentDataPath;
currentDirectory = System.Environment.CurrentDirectory;
}
public static string dataPath { get; private set; }
public static string persistentDataPath { get; private set; }
public static string currentDirectory { get; private set; }
public static string Get(params string[] nextPaths)
{
currentDirectory = System.Environment.CurrentDirectory;
var path = currentDirectory;
var filePath = System.IO.Path.Combine(currentDirectory, "Assembly-CSharp.csproj");
if (File.Exists(filePath))
{
path = System.IO.Path.Combine(path, "Assets");
}
foreach (var nextPath in nextPaths)
{
path = System.IO.Path.Combine(path, nextPath);
}
return path;
}
public static string CombinePath(params string[] nextPaths)
{
string path = nextPaths[0];
for (int i = 1; i < nextPaths.Length - 1; i++)
{
path += "/" + nextPaths[i];
}
path += "/" + nextPaths.Last();
return path;
}
public static IEnumerable<string> ReadAllFile(string folderPath, string filter = null)
{
if (Directory.Exists(folderPath))
{
DirectoryInfo directoryInfo = new DirectoryInfo(folderPath);
var files = directoryInfo.GetFiles()
.OrderBy(x => x.LastWriteTime)
.Select(x => x);
if (filter.IsValid())
{
files = files.Where(x => x.Name.Contains(filter));
}
return files.Select(x => x.ToString());
}
return new List<string>();
}
}
}
}

View File

@@ -0,0 +1,50 @@
using System.Runtime.InteropServices;
using System.Threading;
using System;
namespace BITKit
{
class PerformanceTimer
{
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter(
out long lpPerformanceCount);
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(
out long lpFrequency);
private long startTime, stopTime;
private long freq;
public PerformanceTimer()
{
startTime = 0;
stopTime = 0;
if (QueryPerformanceFrequency(out freq) == false)
{
throw new Exception("Timer not supported.");
}
}
public void Start()
{
Thread.Sleep(0);
QueryPerformanceCounter(out startTime);
}
public void Stop()
{
QueryPerformanceCounter(out stopTime);
}
public double Duration
{
get
{
return (double)(stopTime - startTime) / (double)freq;
}
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;
namespace BITKit
{
[System.Serializable]
public class UnityPool<T> where T : Component
{
public UnityPool()
{
this.pool = new(Spawn, OnGet, OnReturn, OnDestroy, maxSize: 16);
}
[Header(Constant.Header.Prefabs)]
public T prefab;
[Header(Constant.Header.Gameobjects)]
public Transform root;
[Header(Constant.Header.InternalVariables)]
ObjectPool<T> pool;
public T Get(T element = null, Transform root = null)
{
if (element is not null)
prefab = element;
if (root is not null)
this.root = root;
return pool.Get();
}
public void Return(T element) => pool.Release(element);
T Spawn() => Transform.Instantiate(prefab, root);
void OnGet(T element) => element.gameObject.SetActive(true);
void OnReturn(T element) => element.gameObject.SetActive(false);
void OnDestroy(T element) => GameObject.Destroy(element.gameObject);
}
}

View File

@@ -0,0 +1,45 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
/// <summary>加工系统.处理系统,加工一个数据后返回,处理一个数据后返回</summary>
public interface IProcessor
{
T GetContext<T>(string key, T value);
void AddProcessor<T>(string key, Func<T, T> func);
void RemoveProcessor<T>(string key, Func<T, T> func);
T GetContext<T>(T value = default);
void AddProcessor<T>(Func<T, T> func);
void RemoveProcessor<T>(Func<T, T> func);
}
public class Processor : IProcessor
{
public Dictionary<string, List<object>> dictionary = new();
public T GetContext<T>(T value = default) => GetContext<T>(key, value);
public void AddProcessor<T>(Func<T, T> func) => AddProcessor<T>(key, func);
public void RemoveProcessor<T>(Func<T, T> func) => RemoveProcessor<T>(key, func);
string key => nameof(Processor);
public T GetContext<T>(string key, T value)
{
key = string.Empty.GetType<T>();
dictionary.Get(key).ForEach(x =>
{
var func = x as Func<T, T>;
value = func.Invoke(value);
});
return value;
}
public void AddProcessor<T>(string key, Func<T, T> func)
{
key = string.Empty.GetType<T>();
dictionary.Get(key).Add(func);
}
public void RemoveProcessor<T>(string key, Func<T, T> func)
{
key = string.Empty.GetType<T>();
dictionary.Get(key).Remove(func);
}
}
}

View File

@@ -0,0 +1,26 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace BITKit
{
public static class ScriptableObjectHelper
{
public static T Get<T>() where T : ScriptableObject
{
string name = typeof(T).Name;
T so = Resources.Load<T>(name);
#if UNITY_EDITOR
if (so is null)
{
so = ScriptableObject.CreateInstance<T>();
AssetDatabase.CreateAsset(so, $"Assets/Resources/{name}.asset");
AssetDatabase.SaveAssets();
}
#endif
return so;
}
}
}

View File

@@ -0,0 +1,57 @@
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using Newtonsoft.Json;
using System.Reflection;
using System.IO;
using BITKit.IO;
namespace BITKit
{
public class CacheTest
{
public struct MethodIndex
{
public Type type;
public string methodName;
public MethodInfo GetMethodInfo()
{
return type.GetMethod(methodName);
}
}
string path => PathHelper.GetFilePath("Cache", "CacheTest.cache");
[Test]
public void WriteCache()
{
var type = this.GetType();
MethodIndex value = new();
value.type = type;
value.methodName = nameof(ReadCache);
BITCache.Write(nameof(CacheTest), value);
Debug.Log($"已生成缓存:{path}");
}
[Test]
public void ReadCache()
{
if (BITCache.Read<MethodInfo>(path, out var info))
{
Debug.Log("已读取到缓存");
}
else
{
Debug.Log("未读取到缓存");
}
}
[Test]
public void ClearCache()
{
BITCache.Guid = Guid.NewGuid();
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
namespace BITKit
{
public class DateTimeTester
{
[Test]
public void GetTicks()
{
Debug.Log(DateTime.Now.Ticks);
var time = TimeUtils.GetNow();
Debug.Log($"long:\t{time}");
Debug.Log($"int:\t{(int)time}");
Debug.Log($"float:\t{(float)time}");
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using System.Text;
using UnityEngine.TestTools;
using System.Linq;
using Random = UnityEngine.Random;
namespace BITKit
{
public class FloatTest
{
[Test]
public void AddRandom()
{
float currentValue = 0;
for (int i = 0; i < Random.Range(1,4); i++)
{
float newValue = Random.Range(0, 8f);
Debug.Log($"{currentValue}+{newValue} = {currentValue+=newValue}");
}
}
}
}

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using Newtonsoft.Json;
using System.Reflection;
using System.IO;
using BITKit.IO;
using System.Text;
namespace BITKit
{
public class GenericEventTest
{
[Test]
public void TestInvokeByType()
{
GenericEvent genericEvent = new();
genericEvent.AddListener<string>(OnGetString);
genericEvent.Invoke<string>("Value 123");
genericEvent.Invoke(typeof(string).Name, "Value 321" as object);
void OnGetString(string value)
{
Debug.Log($"事件回调:{value}");
}
}
}
}

View File

@@ -0,0 +1,27 @@
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using Newtonsoft.Json;
namespace BITKit
{
public class IEnumerableTest
{
[Test]
public void AppendIEnumerable()
{
List<int> list = new();
list.CreateOrAddIfEmety(list,() => 1);
list.Add(2);
int[] array = new int[0];
array.CreateOrAddIfEmety(array,() => 1);
Debug.Log("Length Should Be 2");
Debug.Log($"List:{JsonConvert.SerializeObject(list, Formatting.Indented)}");
Debug.Log($"Array:{JsonConvert.SerializeObject(array, Formatting.Indented)}");
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using Newtonsoft.Json;
using System.Reflection;
using System.IO;
using BITKit.IO;
using System.Text;
namespace BITKit
{
public class MemoryStreamTest
{
[Test]
public void WriteStringToMemorySteam()
{
var _str = nameof(MemoryStreamTest);
var _int = 256;
var _float = 3.1415926;
byte[] bytes;
using (var ms = new MemoryStream())
{
using (BinaryWriter writer = new(ms))
{
writer.Write(_str);
writer.Write(_int);
writer.Write(_float);
}
bytes = ms.ToArray();
}
Debug.Log($"输入:\nstring:{_str}\nint{_int}\nfloat{_float}");
using (var ms = new MemoryStream(bytes))
{
using (var reader = new BinaryReader(ms))
{
_str = reader.ReadString();
_int = reader.ReadInt32();
_float = (float)reader.ReadDouble();
}
}
Debug.Log($":\nstring:{_str}\nint{_int}\nfloat{_float}");
}
}
}

View File

@@ -0,0 +1,57 @@
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using Newtonsoft.Json;
using System.Reflection;
using System.IO;
using BITKit.IO;
using System.Text;
namespace BITKit
{
public class ObjectMatcherTest
{
[Test]
public void TestObjectMatcher()
{
ObjectMatcher<string, string> matcher = new();
matcher.list = new ObjectElement<string, string>[]
{
new("xyz","x","y","z"),
new("XYZ","X","Y","Z"),
new("123","1","2","3"),
new("BulletHit","Hitbox","Blood"),
};
string[][] useCases = new string[][]{
new string[]{
"x","y","z"
},
new string[]{
"w","y","x","z"
},
new string[]{
"X","y","Z"
},
new string[]{
"3","1","2"
},
new string[]{
"1","5","7"
},
new string[]
{
"BulletHit","Hitbox","Blood"
}
};
StringBuilder stringBuilder = new();
foreach (var useCase in useCases)
{
stringBuilder.AppendLine($"当前用例:{JsonConvert.SerializeObject(useCase)}");
stringBuilder.AppendLine($"当前返回:{matcher.TryMatch(out string value, useCase)} @{value}");
}
Debug.Log(stringBuilder);
}
}
}

View File

@@ -0,0 +1,29 @@
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
namespace BITKit
{
public class ProcessorTester
{
[Test]
public void Test()
{
Processor processor = new();
processor.AddProcessor<int>("GetDamage", ReduceDamage);
var damage = processor.GetContext<int>("GetDamage", 64);
Debug.Log(damage);
processor.RemoveProcessor<int>("GetDamage", ReduceDamage);
damage = processor.GetContext<int>("GetDamage", 64);
Debug.Log(damage);
}
int ReduceDamage(int damage)
{
return damage / 2;
}
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using System.Text;
using UnityEngine.TestTools;
using System.Linq;
namespace BITKit
{
public class PropertyTest
{
[Test]
public void TestProperty()
{
TestValue(64);
TestValue(3.1415926);
TestValue(true);
TestValue(DateTime.Now);
}
void TestValue<T>(T value)
{
Property property = new Property();
property.SetProperty(value);
var output = property.GetProperty<T>();
Debug.Log($"<22><><EFBFBD><EFBFBD>ֵ:{value},<2C><><EFBFBD><EFBFBD>ֵ:{output},<2C><><EFBFBD><EFBFBD>:{value.Equals(output)}");
}
}
}

View File

@@ -0,0 +1,142 @@
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using System.Text;
using UnityEngine.TestTools;
using System.Linq;
namespace BITKit
{
public class StringTest
{
[Test]
public void JoinString()
{
List<string> stringList = new()
{
"UX",
"Test",
"Creator"
};
Debug.Log(string.Join("/",stringList));
}
[Test]
public void SpliteNamespace()
{
StringBuilder stringBuilder = new StringBuilder();
List<string> ignoreNamespaces = new()
{
"System",
"UnityEngine",
"Unity",
"Microsoft",
"UnityEditor",
"Google",
"Mono",
"ZXing",
"ImmersiveVRTools",
"MonKey",
"FLib",
"Kcp",
"Udx",
"Sirenix",
"TMPro",
"RotaryHeart",
"Cinemachine",
"ParadoxNotion",
"Net",
"VSCodeEditor",
"AOT",
"UnityEditorInternal",
"UnityEngineInternal",
"JetBrains",
"Bee",
"NotInvited",
"HighlightPlus",
"DG",
"Hierarchy2",
"Cysharp",
"JetBrains",
"Packages",
"Newtonsoft_X",
"Binding",
"NodeCanvas",
"SaveDuringPlay",
"LimWorks",
"MagicaCloth2",
"FastScriptReload",
"ParrelSync",
"KinematicCharacterController",
"LimWorksEditor",
"BuildComponent",
"dnlib",
"BigIntegerLibrary",
"Ionic",
"log4net",
"DG",
"ImmersiveVrToolsCommon",
"NUnit",
"HarmonyLib",
"MonoMod",
"WebDav",
"PlasticGui",
"Codice",
"GluonGui",
"PlasticPipe",
"XDiffGui",
"MacFsWatcher",
"MacUI",
"PlayerBuildProgramLibrary",
"ExCSS",
"ScriptCompilationBuildProgram",
"BeeBuildProgramCommon",
"Accessibility",
"CodiceApp",
"Newtonsoft",
"MergetoolGui",
"TreeEditor",
"MackySoft",
"FullscreenEditor",
};
var allTypes =new List<Type>();
var supportTypes=new List<Type>();
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
try
{
allTypes.AddRange(assembly.GetExportedTypes());
}
catch
{
continue;
}
}
stringBuilder.AppendLine($"以获取到类型:{allTypes.Count()}个");
foreach (var type in allTypes)
{
var typeName = type.Name;
var nameSpace = type.Namespace;
var rootNamespace =string.IsNullOrEmpty(nameSpace)?string.Empty : nameSpace.Split(@".").First();
var contrast = ignoreNamespaces.Contains(rootNamespace);
//stringBuilder.AppendLine($"类型名称:{typeName}\t命名空间{nameSpace}\t根命名空间:{rootNamespace}\t对比结果:{contrast}");
if(contrast)
{
}
else
{
supportTypes.Add(type);
}
}
stringBuilder.AppendLine($"所有类型{allTypes.Count()}个\t支持类型{supportTypes.Count}");
stringBuilder.AppendLine("已支持的命名空间:");
foreach (var x in supportTypes.Select(x=>x.Namespace).Distinct())
{
stringBuilder.AppendLine(x);
}
Debug.Log(stringBuilder);
}
}
}

View File

@@ -0,0 +1,26 @@
{
"name": "Tests",
"rootNamespace": "",
"references": [
"UnityEngine.TestRunner",
"UnityEditor.TestRunner",
"BITKits",
"BITKit"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": true,
"precompiledReferences": [
"nunit.framework.dll",
"Newtonsoft.Json.dll"
],
"autoReferenced": true,
"defineConstraints": [
"UNITY_INCLUDE_TESTS"
],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,22 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
public static partial class TextureHelper
{
public static Texture2D ToTexture2D(this RenderTexture rTex)
{
Texture2D tex = new Texture2D(rTex.width, rTex.height, TextureFormat.RGB24, false);
var old_rt = RenderTexture.active;
RenderTexture.active = rTex;
tex.ReadPixels(new Rect(0, 0, rTex.width, rTex.height), 0, 0);
tex.Apply();
RenderTexture.active = old_rt;
return tex;
}
}
}

View File

@@ -0,0 +1,68 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit
{
public static class TimeUtils
{
///<summary>
///2023-02-45 15:02:45:628
///</summary>
public const string dateTimeFormat = "yyyy-MM-dd HH:mm:ss:fff";
/// <summary>
/// 带毫秒的字符转换成时间DateTime格式
/// 可处理格式:[2014-10-10 10:10:10,666 或 2014-10-10 10:10:10 666 或 2014-10-10 10:10:10.666]
/// </summary>
/// 2022-12-30 15:39:48:795
/// 20080501T08:30:52Z"
/// yyyyMMddTHH:mm:ssZ
public static DateTime GetDateTime(string dateTime)
{
try
{
return DateTime.ParseExact(dateTime, dateTimeFormat, null);
}
catch (System.Exception)
{
try
{
return GetDateTime_SCADA(dateTime);
}
catch (System.Exception)
{
Debug.LogWarning($"{dateTime}\n{dateTimeFormat}");
throw;
}
}
}
public static float GetNow(DateTime now = default)
{
now = now == default ? DateTime.Now : now;
float time = 0;
time += now.Hour * 60 * 60;
time += now.Minute * 60;
time += now.Second;
time += now.Millisecond * 0.001f;
return time;
}
public static string GetNowString(DateTime now = default)
{
now = now == default ? DateTime.Now : now;
return now.ToString(dateTimeFormat);
}
static DateTime GetDateTime_SCADA(this string dateTime)
{
string[] strArr = dateTime.Split(new char[] { '-', ' ', ':', ',', '.' });
DateTime dt = new DateTime(int.Parse(strArr[0]),
int.Parse(strArr[1]),
int.Parse(strArr[2]),
int.Parse(strArr[3]),
int.Parse(strArr[4]),
int.Parse(strArr[5]),
int.Parse(strArr[6]));
return dt;
}
}
}

View File

@@ -0,0 +1,46 @@
using UnityEngine;
using UnityEngine.Networking;
using System;
using System.Runtime.CompilerServices;
public class UnityWebRequestAwaiter : INotifyCompletion
{
private UnityWebRequestAsyncOperation asyncOp;
private Action continuation;
public UnityWebRequestAwaiter(UnityWebRequestAsyncOperation asyncOp)
{
this.asyncOp = asyncOp;
asyncOp.completed += OnRequestCompleted;
}
public bool IsCompleted { get { return asyncOp.isDone; } }
public void GetResult() { }
public void OnCompleted(Action continuation)
{
this.continuation = continuation;
}
private void OnRequestCompleted(AsyncOperation obj)
{
if (continuation != null)
continuation();
}
}
public static class ExtensionMethods
{
public static UnityWebRequestAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOp)
{
return new UnityWebRequestAwaiter(asyncOp);
}
}
/*
// Usage example:
UnityWebRequest www = new UnityWebRequest();
// ...
await www.SendWebRequest();
Debug.Log(req.downloadHandler.text);
*/

View File

@@ -0,0 +1,268 @@
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UIElements;
using Sirenix.OdinInspector;
namespace BITKit
{
public abstract class Provider : MonoBehaviour, IProvider
{
public virtual T Get<T>()
{
throw new NotImplementedException();
}
public abstract void Set<T>(T obj);
}
public abstract class Provider<T> : Provider, IProvider<T>
{
public abstract T Get();
public abstract void Set(T t);
public override void Set<Unknow>(Unknow obj)
{
if (obj is T t)
{
Set(t);
}
}
}
public abstract class BITAction : MonoBehaviour, IAction
{
public abstract void Excute();
}
public interface ICustomInspector
{
VisualElement GetVisualElement();
}
[System.Serializable]
public struct FrameUpdate
{
float prevframe;
bool updatedThisFrame;
public static implicit operator bool(FrameUpdate self)
{
var updatedThisFrame = Utility.Time.time <= self.prevframe;
if (updatedThisFrame)
{
return false;
}
else
{
self.prevframe = Utility.Time.time;
return true;
}
}
}
[System.Serializable]
public class CompletionRate
{
public IntervalUpdate resetInterval = new(1);
int requestCount;
int successCount;
public float rate;
public int resetWhen = 64;
public static implicit operator float(CompletionRate cr)
{
return cr.rate;
}
public void Get()
{
requestCount++;
}
public void Release()
{
successCount++;
rate = (float)successCount / (float)requestCount;
if (requestCount > resetWhen)
{
requestCount = successCount = 0;
}
}
}
[System.Serializable]
public class Counter
{
public int count;
int currentCount;
public IntervalUpdate updater = new(1);
public static implicit operator int(Counter self) => self.Get();
public int Excute()
{
if (updater)
{
count = currentCount;
currentCount = 0;
}
currentCount++;
return count;
}
public int Get() => currentCount;
}
[System.Serializable]
public class IntervalUpdate
{
public IntervalUpdate(float updateInterval = 0)
{
this.updateInterval = updateInterval;
}
public bool enable = true;
public float updateInterval;
private double enableUpdateTime;
public bool canUpdate => (Utility.Time.timeAsDouble >= enableUpdateTime);
private bool canUpdateThisFrame;
public event Action<bool> onSetActive;
public static implicit operator bool(IntervalUpdate value)
{
return value is not null && value.CanUpdate();
}
public static implicit operator float(IntervalUpdate value)
{
return value is not null ? value.updateInterval : 0;
}
public bool CanUpdate()
{
canUpdateThisFrame = canUpdate;
if (canUpdate)
{
Reset();
}
return enable && canUpdateThisFrame;
}
public float GetDuration()
{
var duration = (float)(Utility.Time.timeAsDouble - enableUpdateTime);
//duration = duration.Round(2);
return duration;
}
public void Reset(bool immediately = false)
{
enableUpdateTime = Utility.Time.timeAsDouble + (immediately ? 0 : updateInterval);
}
public void AddDelay(float value)
{
Reset();
enableUpdateTime += value;
}
public void SetActive(bool active)
{
enable = active;
onSetActive?.Invoke(active);
}
}
public struct Location
{
public Location(Transform transform, bool local = false)
{
if (local)
{
position = transform.localPosition;
rotation = transform.localRotation;
}
else
{
position = transform.position;
rotation = transform.rotation;
}
forward = transform.forward;
}
public Location(Component component)
{
var transform = component.transform;
position = transform.position;
rotation = transform.rotation;
forward = transform.forward;
}
public Vector3 position;
public Vector3 forward;
public Quaternion rotation;
public Location Set(Vector3 value)
{
position = value;
return this;
}
public Location Set(Quaternion value)
{
rotation = value;
return this;
}
public Location Set(Transform value, bool isLocal)
{
if (isLocal)
{
position = value.localPosition; rotation = value.localRotation;
}
else
{
Set(value);
}
return this;
}
public Location Set(Transform value)
{
position = value.position; rotation = value.rotation;
return this;
}
public static Location Lerp(Location a, Location b, float t)
{
if (Quaternion.Dot(a, a) < Quaternion.kEpsilon)
a.rotation = Quaternion.identity;
if (Quaternion.Dot(b, b) < Quaternion.kEpsilon)
b.rotation = Quaternion.identity;
return new()
{
position = Vector3.Lerp(a.position, b.position, t),
rotation = Quaternion.Lerp(a.rotation, b.rotation, t)
};
}
public static implicit operator Vector3(Location self)
{
return self.position;
}
public static implicit operator Quaternion(Location self)
{
return self.rotation;
}
public static Location operator +(Location self, Location b)
{
return new()
{
position = self.position + b.position,
rotation = Quaternion.Euler(self.rotation.eulerAngles + b.rotation.eulerAngles),
};
}
public static Location operator -(Location self, Location b)
{
return new()
{
position = self.position - b.position,
rotation = Quaternion.Euler(self.rotation.eulerAngles - b.rotation.eulerAngles),
};
}
public static Location operator *(Location self, float weight)
{
return new()
{
position = self.position * weight,
rotation = Quaternion.Euler(self.rotation.eulerAngles * weight),
};
}
public static Location operator /(Location self, float weight)
{
return new()
{
position = self.position / weight,
rotation = Quaternion.Euler(self.rotation.eulerAngles / weight),
};
}
public bool isNull
{
get
{
return position == Vector3.zero && rotation == Quaternion.identity;
}
}
}
}

View File

@@ -0,0 +1,15 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace BITKit
{
public static class UtilityHelper
{
public static bool isPlaying => BehaviourHelper.Actived;
public static bool isValid => BehaviourHelper.Actived;
}
}