This commit is contained in:
CortexCore
2025-03-09 13:38:23 +08:00
parent 8261a458e2
commit 18239a5ae4
67 changed files with 8573 additions and 831 deletions

View File

@@ -34,21 +34,47 @@ namespace BITKit.IO
var scriptableObject = objs[index];
var entity = new Entity();
var idComponent = new IdComponent();
var idComponent = new IdComponent()
{
Name = scriptableObject.name
};
entity.ServiceCollection.AddSingleton(idComponent);
var type = scriptableObject.GetType();
var typeName = type.Name;
entity.ServiceCollection.AddSingleton(type, scriptableObject);
foreach (var x in type.GetInterfaces())
{
entity.ServiceCollection.AddSingleton(x, scriptableObject);
}
while (type is not null)
{
if (type.BaseType is null) break;
entity.ServiceCollection.AddSingleton(type.BaseType, scriptableObject);
type = type.BaseType;
typeName += $":{type.Name}";
}
_entitiesService.Register(entity);
logger?.LogInformation($"已加载:{scriptableObject.name}:{type.Name},剩余:{index + 1}/{objs.Count}");
logger?.LogInformation($"已加载:{scriptableObject.name}:{typeName},剩余:{index + 1}/{objs.Count}");
_registeredEntities.Add(entity);
continue;
}
logger?.LogInformation("加载完成");
return;
}
public void Dispose()

View File

@@ -135,7 +135,9 @@ namespace BITKit
[RuntimeInitializeOnLoadMethod]
private static void Reload()
{
BITApp.WalkUntilInitialize = new();
IsPlaying = true;
//启动BITApp
BITApp.SynchronizationContext = SynchronizationContext.Current;

View File

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

View File

@@ -0,0 +1,19 @@
{
"name": "Net.BITKit.Impact.Unity",
"rootNamespace": "",
"references": [
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:89bd0da52dc3cc94daadea6252c6ad1b",
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

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

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using AYellowpaper.SerializedCollections;
using BITKit;
using UnityEngine;
namespace Net.BITKit.Impact
{
public class ScriptableImpact : ScriptableObject,ITag
{
[SerializeReference, SubclassSelector] private IReference[] tags;
[SerializeField] private int priority;
[SerializeField] private Transform[] prefabs;
[SerializeField] private AudioClip[] audioClips;
public int Hash { get; set; }
public IReadOnlyCollection<string> Tags => tags.Select(x=>x.Get()).ToArray();
public Transform Prefab => prefabs.Random();
public AudioClip AudioClip => audioClips.Random();
public int Priority => priority;
}
}

View File

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

View File

@@ -4,6 +4,7 @@ using UnityEngine;
using UnityEngine.InputSystem;
using System;
using System.Linq;
using UnityEngine.InputSystem.Controls;
namespace BITKit
{
@@ -11,7 +12,7 @@ namespace BITKit
{
public static bool JustPressed(this InputAction.CallbackContext self)
{
return self.interaction is null && self.started;
return self is { started:true, control: ButtonControl { wasPressedThisFrame: true , isPressed:true} };
}
public static InputAction RegisterCallback(this InputAction self, Action<InputAction.CallbackContext> action)
{

View File

@@ -7,37 +7,6 @@ using ILogger = Microsoft.Extensions.Logging.ILogger;
namespace BITKit
{
public abstract class UnityLogger:ILogger
{
[HideInCallstack]
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
switch (logLevel)
{
case LogLevel.Critical:
case LogLevel.Error:
if (exception is not null)
{
Debug.LogException(exception);
}
else
{
Debug.LogError($"{CurrentScope}:{state.ToString()}");
}
break;
default:
Debug.Log($"{CurrentScope}:{state.ToString()}");
break;
}
}
public bool IsEnabled(LogLevel logLevel) => true;
private string CurrentScope { get; set; }
public IDisposable BeginScope<TState>(TState state) where TState : notnull
{
CurrentScope = typeof(TState).Name;
return null;
}
}
public sealed class UnityLogger<T>:ILogger<T>
{
[HideInCallstack]
@@ -53,11 +22,11 @@ namespace BITKit
}
else
{
Debug.LogError($"{typeof(T).Name}:{state.ToString()}");
Debug.LogError($"{typeof(T).CSharpName()}:{state.ToString()}");
}
break;
default:
Debug.Log($"<b>{typeof(T).Name}</b>:{state.ToString()}");
Debug.Log($"<b>{typeof(T).CSharpName()}</b>:{state.ToString()}");
break;
}
}

View File

@@ -27,22 +27,31 @@ namespace BITKit.Physics
var vertices = _mesh.vertices;
if (vertices.Length > 2048) return false;
if (vertices.Length > 256) return false;
var minPos = new Vector3(64, 64, 64);
var minDistance = 64f;
for (var index = 0; index < _mesh.triangles.Length; index+=3)
{
var x = vertices[_mesh.triangles[index]];
if (Vector3.Distance(x, _position) > minDistance)
{
continue;
}
var y = vertices[_mesh.triangles[index + 1]];
var z = vertices[_mesh.triangles[index + 2]];
var pos = GeometryUtils.GetPosInTriangle(x, y, z, _position);
if (Vector3.Distance(pos, _position) < Vector3.Distance(minPos, _position))
{
minPos = pos;
}
var distance = Vector3.Distance(pos, _position);
if (!(distance < minDistance)) continue;
minPos = pos;
minDistance = distance;
}
position = minPos;

View File

@@ -42,7 +42,9 @@ namespace BITKit.Pool
ReadyPool.Clear();
}
public async UniTask<T> Spawn<T>(string path) where T : class
public int DefaultCapacity { get; set; } = 8;
public async UniTask<T> Spawn<T>(string path,object prefab) where T : class
{
if (Pool.ContainsKey(path))
{
@@ -55,7 +57,7 @@ namespace BITKit.Pool
return obj as T;
}
if (usingList.Count>0)
if (usingList.Count>=DefaultCapacity)
{
obj = usingList[0];
usingList.RemoveAt(0);
@@ -81,13 +83,33 @@ namespace BITKit.Pool
#if UNITY_5_3_OR_NEWER
if (typeof(Object).IsAssignableFrom(typeof(T)))
{
var asset =await ModService.LoadAsset<T>(path);
var asset =prefab as T ?? await ModService.LoadAsset<T>(path);
if (asset is Object o)
{
var instance = Object.Instantiate(o);
list.Add(instance);
UsingPool.GetOrCreate(path).Add(instance);
ReadyPool.GetOrCreate(path);
if (instance is GameObject gameObject)
{
gameObject.GetCancellationTokenOnDestroy().Register(DisposeGo);
void DisposeGo()
{
Pool.GetOrCreate(path).TryRemove(gameObject);
UsingPool.GetOrCreate(path).TryRemove(gameObject);
var queue = ReadyPool.GetOrCreate(path);
var removeObjectList = new List<object>(queue);
removeObjectList.TryRemove(gameObject);
queue.Clear();
foreach (var x in removeObjectList)
{
queue.Enqueue(x);
}
}
}
return instance as T;
}
}

View File

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

View File

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

View File

@@ -8,19 +8,10 @@ namespace BITKit
{
public class Tag : MonoBehaviour,ITag
{
[Header(Constant.Header.Settings)]
[Tooltip("It's will be deprecated in the future, use reference instead.")]
[SerializeField] private string[] tags;
[Tooltip("Disable when tags is not empty")]
[SerializeReference,SubclassSelector] private IReference[] reference;
public int Hash => _id is 0 ? _id = MathE.GetHash(GetTags()) : _id;
public int Hash => _id is 0 ? _id = MathE.GetHash(Tags) : _id;
private int _id;
public string[] GetTags() => CacheTags ??= reference?.Length > 0 ? reference.Select(x => x.Value).ToArray() : tags;
private string[] CacheTags;
public void SetTags(IReference[] newReference)
{
reference = newReference;
CacheTags = null;
}
public IReadOnlyCollection<string> Tags=> _cacheTags ??= reference.Select(x => x.Value).ToArray();
private string[] _cacheTags;
}
}

View File

@@ -14,6 +14,7 @@ namespace BITKit
[Serializable]
public class IntervalTick:ITicker
{
[SerializeField]
private float interval;
public ulong TickCount=>IntervalTickService.GetTickCount(interval);

View File

@@ -32,11 +32,6 @@ namespace BITKit.UX
_container.Clear();
_template =await ModService.LoadAsset<VisualTreeAsset>("ui_radial_menu-template");
RootVisualElement.RegisterCallback<PointerDownEvent>(x =>
{
UXService.Return();
});
}
protected override void OnPanelEntry()
{

View File

@@ -74,7 +74,7 @@ namespace BITKit.UX
foreach (var fieldInfo in self.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
.Where(x => x.GetCustomAttribute<UXBindPathAttribute>() is not null)
)
{

View File

@@ -461,6 +461,11 @@ namespace BITKit
return true;
}
component = self.GetComponentInParent<T>(true);
if (component is not null)
{
return true;
}
component = self.GetComponent<T>();
return component is not null;
}
public static bool TryGetFirstOrDefault<T>(this IEnumerable<T> self, out T value)

View File

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

View File

@@ -0,0 +1,19 @@
{
"name": "Net.Project.B.VFX.Unity",
"rootNamespace": "",
"references": [
"GUID:d525ad6bd40672747bde77962f1c401e",
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
"GUID:24866f14213d2124aa20be037476b521"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

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

View File

@@ -0,0 +1,63 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BITKit;
using BITKit.Entities;
using Net.BITKit.Impact;
using UnityEngine;
namespace Net.BITKit.VFX
{
public class VFXService
{
private readonly IEntitiesService _entitiesService;
private readonly IReadOnlyCollection<ScriptableImpact> _scriptableImpacts;
public VFXService(IEntitiesService entitiesService)
{
_entitiesService = entitiesService;
_scriptableImpacts = _entitiesService.QueryComponents<ScriptableImpact>();
}
public AudioClip GetAudioClip(IReadOnlyCollection<string> tags)
{
var bestMatches = Search(tags);
return bestMatches.AudioClip;
}
public Transform GetPrefab(IReadOnlyCollection<string> tags)
{
var bestMatches = Search(tags);
return bestMatches.Prefab;
}
private ScriptableImpact Search(IReadOnlyCollection<string> tags)
{
var maxPoint = 0;
var max = new HashSet<ScriptableImpact>();
foreach (var impact in _scriptableImpacts)
{
var point = impact.Tags.Intersect(tags).Count();
if (point > maxPoint)
{
maxPoint = point;
max.Clear();
max.Add(impact);
}else if (point == maxPoint)
{
max.Add(impact);
}
}
if (max.Count is 1)
{
return max.First();
}
return max.OrderByDescending(x => x.Priority).First();
}
}
}

View File

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

View File

@@ -60,7 +60,7 @@ namespace BITKit.OpenWorld
#if UNITY_EDITOR
[BIT]
#endif
private void CalculateBounds()
public void CalculateBounds()
{
if (TryGetComponent<Collider>(out var _collider))
{

View File

@@ -25,7 +25,6 @@ namespace BITKit.OpenWorld
private readonly ConcurrentDictionary<int, IWorldChunkObject> dictionary=new();
[SerializeReference, SubclassSelector] private ITicker ticker;
[SerializeReference, SubclassSelector] private ISceneService sceneService;
[SerializeField, ReadOnly] private int count;
[SerializeField, ReadOnly] private int tickTaskCount;
[SerializeField] private bool drawBounds;
@@ -42,24 +41,13 @@ namespace BITKit.OpenWorld
protected virtual void Start()
{
sceneService?.RegisterLoadTaskAsync(LoadTask);
ticker.Add(OnTick);
destroyCancellationToken.Register(Dispose);
_quadtree = new QuadtreeRoot<IWorldChunkObject, Node<IWorldChunkObject>>(transform.position, size);
_camera = Camera.main;
}
private async UniTask LoadTask()
{
var frame=0;
while (count is 0 || frame++<32)
{
if (destroyCancellationToken.IsCancellationRequested) return;
await UniTask.NextFrame();
}
}
protected virtual void Dispose()
{
sceneService?.UnRegisterLoadTaskAsync(LoadTask);
ticker.Remove(OnTick);
_registerQueue.Clear();
_unregisterQueue.Clear();

View File

@@ -14,6 +14,7 @@ namespace BITKit.OpenWorld
{
public class WorldTerrainBehaviour : MonoBehaviour,IWorldChunkObject
{
public static UniTaskCompletionSource WaitUntilInitialized = new();
[SerializeReference, SubclassSelector] private IReference sceneName;
[SerializeField] private Vector3 size;
[SerializeField] private Vector3 position;
@@ -26,7 +27,15 @@ namespace BITKit.OpenWorld
var stopWatcher = new System.Diagnostics.Stopwatch();
stopWatcher.Start();
_sceneHandle = YooAssets.LoadSceneAsync(sceneName.Value,LoadSceneMode.Additive,priority:8);
await _sceneHandle;
try
{
await _sceneHandle.WithCancellation(destroyCancellationToken);
}
catch (OperationCanceledException)
{
}
stopWatcher.Stop();
Debug.Log($"加载场景 {sceneName.Value} 耗时 {stopWatcher.ElapsedMilliseconds}ms");
}