1
This commit is contained in:
@@ -20,6 +20,8 @@ namespace BITKit
|
|||||||
}
|
}
|
||||||
public class BITApp
|
public class BITApp
|
||||||
{
|
{
|
||||||
|
public static int Count => _count++;
|
||||||
|
private static int _count;
|
||||||
public static async UniTask SwitchToMainThread()
|
public static async UniTask SwitchToMainThread()
|
||||||
{
|
{
|
||||||
await UniTask.SwitchToSynchronizationContext(SynchronizationContext);
|
await UniTask.SwitchToSynchronizationContext(SynchronizationContext);
|
||||||
@@ -243,6 +245,7 @@ namespace BITKit
|
|||||||
private static DateTime InitialTime { get; set; }=DateTime.Now;
|
private static DateTime InitialTime { get; set; }=DateTime.Now;
|
||||||
public static async UniTask Start(string appName = nameof(BITApp),AppSettings settings=default)
|
public static async UniTask Start(string appName = nameof(BITApp),AppSettings settings=default)
|
||||||
{
|
{
|
||||||
|
_count = 0;
|
||||||
Time.TimeAsDouble = 0;
|
Time.TimeAsDouble = 0;
|
||||||
Time.DeltaTime = 1 / 60f;
|
Time.DeltaTime = 1 / 60f;
|
||||||
SynchronizationContext=SynchronizationContext.Current;
|
SynchronizationContext=SynchronizationContext.Current;
|
||||||
|
@@ -3,12 +3,15 @@
|
|||||||
namespace BITKit
|
namespace BITKit
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Method)]
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
public class BITCommandAttribute : Attribute { }
|
public class BITCommandAttribute : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自动注入依赖
|
/// 自动注入依赖
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[AttributeUsage(AttributeTargets.Field)]
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||||
public class InjectAttribute : System.Attribute
|
public class InjectAttribute : Attribute
|
||||||
{
|
{
|
||||||
public static void Clear(object obj)
|
public static void Clear(object obj)
|
||||||
{
|
{
|
||||||
|
@@ -8,7 +8,7 @@ namespace BITKit
|
|||||||
{
|
{
|
||||||
public static class BIT4Log
|
public static class BIT4Log
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR && !UNITY_WEBGL
|
||||||
[RuntimeInitializeOnLoadMethod]
|
[RuntimeInitializeOnLoadMethod]
|
||||||
private static void Reload()
|
private static void Reload()
|
||||||
{
|
{
|
||||||
|
@@ -125,6 +125,29 @@ namespace BITKit
|
|||||||
/// <param name="obj"></param>
|
/// <param name="obj"></param>
|
||||||
public static void Inject(object obj)
|
public static void Inject(object obj)
|
||||||
{
|
{
|
||||||
|
foreach (var propertyInfo in obj.GetType().GetProperties(ReflectionHelper.Flags))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (propertyInfo.GetCustomAttribute<ObsoleteAttribute>() is null &&
|
||||||
|
propertyInfo.GetCustomAttribute<InjectAttribute>() is not null)
|
||||||
|
{
|
||||||
|
lock (dictionary)
|
||||||
|
{
|
||||||
|
if(dictionary!.TryGetValue(propertyInfo.PropertyType,out var value))
|
||||||
|
{
|
||||||
|
BIT4Log.Log<DI>($"已为{obj.GetType().Name}.{propertyInfo.Name}注入{value.GetType().Name}");
|
||||||
|
propertyInfo.SetValue(obj,value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
BIT4Log.LogException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
foreach (var field in obj.GetType().GetFields(ReflectionHelper.Flags))
|
foreach (var field in obj.GetType().GetFields(ReflectionHelper.Flags))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@@ -15,7 +15,7 @@ namespace BITKit.Entities
|
|||||||
/// 等待初始化完成,通常用于其他系统需要等待实体初始化完成
|
/// 等待初始化完成,通常用于其他系统需要等待实体初始化完成
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void WaitForInitializationComplete();
|
void WaitForInitializationComplete();
|
||||||
ulong Id { get; }
|
int Id { get; }
|
||||||
CancellationToken CancellationToken { get; }
|
CancellationToken CancellationToken { get; }
|
||||||
bool TryGetComponent<T>(out T component);
|
bool TryGetComponent<T>(out T component);
|
||||||
IEntityComponent[] Components { get; }
|
IEntityComponent[] Components { get; }
|
||||||
@@ -81,18 +81,18 @@ namespace BITKit.Entities
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id"></param>
|
/// <param name="id"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IEntity Get(ulong id);
|
IEntity Get(int id);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 尝试通过Id获取Entity
|
/// 尝试通过Id获取Entity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id"></param>
|
/// <param name="id"></param>
|
||||||
/// <param name="entity"></param>
|
/// <param name="entity"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
bool TryGetEntity(ulong id, out IEntity entity);
|
bool TryGetEntity(int id, out IEntity entity);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 通过Id获取或添加Entity
|
/// 通过Id获取或添加Entity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IEntity GetOrAdd(ulong id,Func<ulong,IEntity> factory);
|
IEntity GetOrAdd(int id,Func<int,IEntity> factory);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询Entity,例如
|
/// 查询Entity,例如
|
||||||
|
@@ -31,12 +31,12 @@ namespace BITKit
|
|||||||
{
|
{
|
||||||
public int frameRate = 30;
|
public int frameRate = 30;
|
||||||
public PlayerState state;
|
public PlayerState state;
|
||||||
protected List<T> list = new();
|
public List<T> list { get; protected set; } =new();
|
||||||
public bool isPlaying;
|
public bool isPlaying;
|
||||||
public event Action onStart;
|
public event Action onStart;
|
||||||
public event Action onStop;
|
public event Action onStop;
|
||||||
protected T current;
|
protected T current;
|
||||||
Timer timer = new() { AutoReset = true };
|
private Timer timer = new() { AutoReset = true };
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
if (isPlaying is false)
|
if (isPlaying is false)
|
||||||
|
@@ -220,7 +220,6 @@ namespace BITKit.Mod
|
|||||||
private static Thread _Thread;
|
private static Thread _Thread;
|
||||||
private static bool _IsRunning;
|
private static bool _IsRunning;
|
||||||
private static bool _IsLocked;
|
private static bool _IsLocked;
|
||||||
private static AppDomain _ModDomain;
|
|
||||||
|
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
@@ -241,8 +240,6 @@ namespace BITKit.Mod
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_ModDomain = AppDomain.CreateDomain("ModDomain");
|
|
||||||
|
|
||||||
var modPath = Path.Combine(Environment.CurrentDirectory, "Mods\\");
|
var modPath = Path.Combine(Environment.CurrentDirectory, "Mods\\");
|
||||||
PathHelper.EnsureDirectoryCreated(modPath);
|
PathHelper.EnsureDirectoryCreated(modPath);
|
||||||
var directoryInfo = new DirectoryInfo(modPath);
|
var directoryInfo = new DirectoryInfo(modPath);
|
||||||
@@ -383,7 +380,6 @@ namespace BITKit.Mod
|
|||||||
_UnRegisterQueue.Clear();
|
_UnRegisterQueue.Clear();
|
||||||
Mods = Array.Empty<IMod>();
|
Mods = Array.Empty<IMod>();
|
||||||
_InstalledMods.Clear();
|
_InstalledMods.Clear();
|
||||||
AppDomain.Unload(_ModDomain);
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@@ -11,8 +11,8 @@ namespace BITKit
|
|||||||
public event Action<float> onProgess;
|
public event Action<float> onProgess;
|
||||||
public event Action<string> onSetTotalTime;
|
public event Action<string> onSetTotalTime;
|
||||||
public event Action<string> onTime;
|
public event Action<string> onTime;
|
||||||
float totalTime => (float)list.Count / frameRate;
|
public float totalTime => (float)list.Count / frameRate;
|
||||||
protected override void OnUpdate()
|
protected override async void OnUpdate()
|
||||||
{
|
{
|
||||||
if (list.Count > 0)
|
if (list.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -20,6 +20,7 @@ namespace BITKit
|
|||||||
if (state is PlayerState.Playing)
|
if (state is PlayerState.Playing)
|
||||||
index = Math.Clamp(++index, 0, list.Count + 32);
|
index = Math.Clamp(++index, 0, list.Count + 32);
|
||||||
|
|
||||||
|
await BITApp.SwitchToMainThread();
|
||||||
if (index > list.Count)
|
if (index > list.Count)
|
||||||
{
|
{
|
||||||
if (index - list.Count > frameRate / 2)
|
if (index - list.Count > frameRate / 2)
|
||||||
@@ -27,6 +28,8 @@ namespace BITKit
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (BITApp.CancellationToken.IsCancellationRequested) return;
|
||||||
output?.Invoke(list[index]);
|
output?.Invoke(list[index]);
|
||||||
onProgess?.Invoke(progess);
|
onProgess?.Invoke(progess);
|
||||||
onTime?.Invoke(GetTime(totalTime * progess));
|
onTime?.Invoke(GetTime(totalTime * progess));
|
||||||
@@ -63,5 +66,6 @@ namespace BITKit
|
|||||||
{
|
{
|
||||||
return new DateTime().AddSeconds(sec).ToString(timeFormat);
|
return new DateTime().AddSeconds(sec).ToString(timeFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -138,13 +138,16 @@ namespace BITKit
|
|||||||
{
|
{
|
||||||
StartInfo = StartInfo,
|
StartInfo = StartInfo,
|
||||||
};
|
};
|
||||||
|
var reportBuilder = new StringBuilder();
|
||||||
process.OutputDataReceived += (sender, args) =>
|
process.OutputDataReceived += (sender, args) =>
|
||||||
{
|
{
|
||||||
BIT4Log.Log<BITSharp>(args.Data);
|
//BIT4Log.Log<BITSharp>(args.Data);
|
||||||
|
reportBuilder.AppendLine(args.Data);
|
||||||
};
|
};
|
||||||
process.ErrorDataReceived += (sender, args) =>
|
process.ErrorDataReceived += (sender, args) =>
|
||||||
{
|
{
|
||||||
BIT4Log.Warning<BITSharp>(args.Data);
|
//BIT4Log.Warning<BITSharp>(args.Data);
|
||||||
|
reportBuilder.AppendLine($"<color=yellow>{args.Data}</color>");
|
||||||
};
|
};
|
||||||
|
|
||||||
process.Start();
|
process.Start();
|
||||||
@@ -173,6 +176,8 @@ namespace BITKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIT4Log.Log<BITSharp>(reportBuilder);
|
||||||
|
|
||||||
waiting?.Release(handle);
|
waiting?.Release(handle);
|
||||||
|
|
||||||
return Assembly.Load(bytes);
|
return Assembly.Load(bytes);
|
||||||
|
@@ -104,7 +104,7 @@ namespace BITKit
|
|||||||
System.IO.MemoryStream ms = new System.IO.MemoryStream(zippedData);
|
System.IO.MemoryStream ms = new System.IO.MemoryStream(zippedData);
|
||||||
System.IO.Compression.GZipStream compressedzipStream = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Decompress);
|
System.IO.Compression.GZipStream compressedzipStream = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Decompress);
|
||||||
System.IO.MemoryStream outBuffer = new System.IO.MemoryStream();
|
System.IO.MemoryStream outBuffer = new System.IO.MemoryStream();
|
||||||
byte[] block = new byte[1024];
|
byte[] block = new byte[1024*16];
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
int bytesRead = compressedzipStream.Read(block, 0, block.Length);
|
int bytesRead = compressedzipStream.Read(block, 0, block.Length);
|
||||||
|
@@ -6,7 +6,7 @@ TextureImporter:
|
|||||||
serializedVersion: 12
|
serializedVersion: 12
|
||||||
mipmaps:
|
mipmaps:
|
||||||
mipMapMode: 0
|
mipMapMode: 0
|
||||||
enableMipMap: 1
|
enableMipMap: 0
|
||||||
sRGBTexture: 1
|
sRGBTexture: 1
|
||||||
linearTexture: 0
|
linearTexture: 0
|
||||||
fadeOut: 0
|
fadeOut: 0
|
||||||
@@ -20,11 +20,12 @@ TextureImporter:
|
|||||||
externalNormalMap: 0
|
externalNormalMap: 0
|
||||||
heightScale: 0.25
|
heightScale: 0.25
|
||||||
normalMapFilter: 0
|
normalMapFilter: 0
|
||||||
|
flipGreenChannel: 0
|
||||||
isReadable: 0
|
isReadable: 0
|
||||||
streamingMipmaps: 0
|
streamingMipmaps: 0
|
||||||
streamingMipmapsPriority: 0
|
streamingMipmapsPriority: 0
|
||||||
vTOnly: 0
|
vTOnly: 0
|
||||||
ignoreMasterTextureLimit: 0
|
ignoreMipmapLimit: 0
|
||||||
grayScaleToAlpha: 0
|
grayScaleToAlpha: 0
|
||||||
generateCubemap: 6
|
generateCubemap: 6
|
||||||
cubemapConvolution: 0
|
cubemapConvolution: 0
|
||||||
@@ -36,24 +37,24 @@ TextureImporter:
|
|||||||
filterMode: 0
|
filterMode: 0
|
||||||
aniso: 1
|
aniso: 1
|
||||||
mipBias: 0
|
mipBias: 0
|
||||||
wrapU: 0
|
wrapU: 1
|
||||||
wrapV: 0
|
wrapV: 1
|
||||||
wrapW: 0
|
wrapW: 0
|
||||||
nPOTScale: 1
|
nPOTScale: 0
|
||||||
lightmap: 0
|
lightmap: 0
|
||||||
compressionQuality: 50
|
compressionQuality: 50
|
||||||
spriteMode: 0
|
spriteMode: 1
|
||||||
spriteExtrude: 1
|
spriteExtrude: 1
|
||||||
spriteMeshType: 1
|
spriteMeshType: 1
|
||||||
alignment: 0
|
alignment: 0
|
||||||
spritePivot: {x: 0.5, y: 0.5}
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
spritePixelsToUnits: 100
|
spritePixelsToUnits: 100
|
||||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
spriteBorder: {x: 14, y: 14, z: 14, w: 14}
|
||||||
spriteGenerateFallbackPhysicsShape: 1
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
alphaUsage: 1
|
alphaUsage: 1
|
||||||
alphaIsTransparency: 0
|
alphaIsTransparency: 1
|
||||||
spriteTessellationDetail: -1
|
spriteTessellationDetail: -1
|
||||||
textureType: 0
|
textureType: 8
|
||||||
textureShape: 1
|
textureShape: 1
|
||||||
singleChannelComponent: 0
|
singleChannelComponent: 0
|
||||||
flipbookRows: 1
|
flipbookRows: 1
|
||||||
@@ -63,6 +64,7 @@ TextureImporter:
|
|||||||
textureFormatSet: 0
|
textureFormatSet: 0
|
||||||
ignorePngGamma: 0
|
ignorePngGamma: 0
|
||||||
applyGammaDecoding: 0
|
applyGammaDecoding: 0
|
||||||
|
swizzle: 50462976
|
||||||
cookieLightType: 0
|
cookieLightType: 0
|
||||||
platformSettings:
|
platformSettings:
|
||||||
- serializedVersion: 3
|
- serializedVersion: 3
|
||||||
@@ -75,6 +77,7 @@ TextureImporter:
|
|||||||
crunchedCompression: 0
|
crunchedCompression: 0
|
||||||
allowsAlphaSplitting: 0
|
allowsAlphaSplitting: 0
|
||||||
overridden: 0
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
androidETC2FallbackOverride: 0
|
androidETC2FallbackOverride: 0
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
- serializedVersion: 3
|
- serializedVersion: 3
|
||||||
@@ -87,6 +90,7 @@ TextureImporter:
|
|||||||
crunchedCompression: 0
|
crunchedCompression: 0
|
||||||
allowsAlphaSplitting: 0
|
allowsAlphaSplitting: 0
|
||||||
overridden: 0
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
androidETC2FallbackOverride: 0
|
androidETC2FallbackOverride: 0
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
- serializedVersion: 3
|
- serializedVersion: 3
|
||||||
@@ -99,6 +103,7 @@ TextureImporter:
|
|||||||
crunchedCompression: 0
|
crunchedCompression: 0
|
||||||
allowsAlphaSplitting: 0
|
allowsAlphaSplitting: 0
|
||||||
overridden: 0
|
overridden: 0
|
||||||
|
ignorePlatformSupport: 0
|
||||||
androidETC2FallbackOverride: 0
|
androidETC2FallbackOverride: 0
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
spriteSheet:
|
spriteSheet:
|
||||||
@@ -107,17 +112,16 @@ TextureImporter:
|
|||||||
outline: []
|
outline: []
|
||||||
physicsShape: []
|
physicsShape: []
|
||||||
bones: []
|
bones: []
|
||||||
spriteID:
|
spriteID: 5e97eb03825dee720800000000000000
|
||||||
internalID: 0
|
internalID: 1537655665
|
||||||
vertices: []
|
vertices: []
|
||||||
indices:
|
indices:
|
||||||
edges: []
|
edges: []
|
||||||
weights: []
|
weights: []
|
||||||
secondaryTextures: []
|
secondaryTextures: []
|
||||||
nameFileIdTable: {}
|
nameFileIdTable: {}
|
||||||
spritePackingTag:
|
mipmapLimitGroupName:
|
||||||
pSDRemoveMatte: 0
|
pSDRemoveMatte: 0
|
||||||
pSDShowRemoveMatteOption: 0
|
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
assetBundleVariant:
|
assetBundleVariant:
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 80240497e71068c4f993ece76ba2d522
|
guid: c9f8c40b3a408b1439727f76e6d6fecc
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 744a684e46476f24d9dd31815a06f2d3
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Src/Unity/Art/Fonts/TTF/D DIN-PRO/D-DIN-PRO-400-Regular.otf
Normal file
BIN
Src/Unity/Art/Fonts/TTF/D DIN-PRO/D-DIN-PRO-400-Regular.otf
Normal file
Binary file not shown.
@@ -0,0 +1,21 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 18d84741efbe8b84b9ce12ff0c858b9e
|
||||||
|
TrueTypeFontImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
fontSize: 16
|
||||||
|
forceTextureCase: -2
|
||||||
|
characterSpacing: 0
|
||||||
|
characterPadding: 1
|
||||||
|
includeFontData: 1
|
||||||
|
fontNames:
|
||||||
|
- D-DIN-PRO
|
||||||
|
fallbackFontReferences: []
|
||||||
|
customCharacters:
|
||||||
|
fontRenderingMode: 0
|
||||||
|
ascentCalculationMode: 1
|
||||||
|
useLegacyBoundsCalculation: 0
|
||||||
|
shouldRoundAdvanceValue: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Src/Unity/Art/Fonts/TTF/D DIN-PRO/D-DIN-PRO-500-Medium.otf
Normal file
BIN
Src/Unity/Art/Fonts/TTF/D DIN-PRO/D-DIN-PRO-500-Medium.otf
Normal file
Binary file not shown.
@@ -0,0 +1,21 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 755f61ff7c01426468b49884d5ed26b7
|
||||||
|
TrueTypeFontImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
fontSize: 16
|
||||||
|
forceTextureCase: -2
|
||||||
|
characterSpacing: 0
|
||||||
|
characterPadding: 1
|
||||||
|
includeFontData: 1
|
||||||
|
fontNames:
|
||||||
|
- D-DIN-PRO
|
||||||
|
fallbackFontReferences: []
|
||||||
|
customCharacters:
|
||||||
|
fontRenderingMode: 0
|
||||||
|
ascentCalculationMode: 1
|
||||||
|
useLegacyBoundsCalculation: 0
|
||||||
|
shouldRoundAdvanceValue: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Src/Unity/Art/Fonts/TTF/D DIN-PRO/D-DIN-PRO-600-SemiBold.otf
Normal file
BIN
Src/Unity/Art/Fonts/TTF/D DIN-PRO/D-DIN-PRO-600-SemiBold.otf
Normal file
Binary file not shown.
@@ -0,0 +1,21 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ebac950db6b0bd143b1096e466c7a195
|
||||||
|
TrueTypeFontImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
fontSize: 16
|
||||||
|
forceTextureCase: -2
|
||||||
|
characterSpacing: 0
|
||||||
|
characterPadding: 1
|
||||||
|
includeFontData: 1
|
||||||
|
fontNames:
|
||||||
|
- D-DIN-PRO
|
||||||
|
fallbackFontReferences: []
|
||||||
|
customCharacters:
|
||||||
|
fontRenderingMode: 0
|
||||||
|
ascentCalculationMode: 1
|
||||||
|
useLegacyBoundsCalculation: 0
|
||||||
|
shouldRoundAdvanceValue: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Src/Unity/Art/Fonts/TTF/D DIN-PRO/D-DIN-PRO-700-Bold.otf
Normal file
BIN
Src/Unity/Art/Fonts/TTF/D DIN-PRO/D-DIN-PRO-700-Bold.otf
Normal file
Binary file not shown.
@@ -0,0 +1,21 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c8b8d7093b881444fb1d36d99d3192f6
|
||||||
|
TrueTypeFontImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
fontSize: 16
|
||||||
|
forceTextureCase: -2
|
||||||
|
characterSpacing: 0
|
||||||
|
characterPadding: 1
|
||||||
|
includeFontData: 1
|
||||||
|
fontNames:
|
||||||
|
- D-DIN-PRO
|
||||||
|
fallbackFontReferences: []
|
||||||
|
customCharacters:
|
||||||
|
fontRenderingMode: 0
|
||||||
|
ascentCalculationMode: 1
|
||||||
|
useLegacyBoundsCalculation: 0
|
||||||
|
shouldRoundAdvanceValue: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Src/Unity/Art/Fonts/TTF/D DIN-PRO/D-DIN-PRO-800-ExtraBold.otf
Normal file
BIN
Src/Unity/Art/Fonts/TTF/D DIN-PRO/D-DIN-PRO-800-ExtraBold.otf
Normal file
Binary file not shown.
@@ -0,0 +1,21 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 412a4509625be324cafbe72ab71b5dc5
|
||||||
|
TrueTypeFontImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
fontSize: 16
|
||||||
|
forceTextureCase: -2
|
||||||
|
characterSpacing: 0
|
||||||
|
characterPadding: 1
|
||||||
|
includeFontData: 1
|
||||||
|
fontNames:
|
||||||
|
- D-DIN-PRO
|
||||||
|
fallbackFontReferences: []
|
||||||
|
customCharacters:
|
||||||
|
fontRenderingMode: 0
|
||||||
|
ascentCalculationMode: 1
|
||||||
|
useLegacyBoundsCalculation: 0
|
||||||
|
shouldRoundAdvanceValue: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Src/Unity/Art/Fonts/TTF/D DIN-PRO/D-DIN-PRO-900-Heavy.otf
Normal file
BIN
Src/Unity/Art/Fonts/TTF/D DIN-PRO/D-DIN-PRO-900-Heavy.otf
Normal file
Binary file not shown.
@@ -0,0 +1,21 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 90caefb5f22ea9044bf798992714cfd7
|
||||||
|
TrueTypeFontImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
fontSize: 16
|
||||||
|
forceTextureCase: -2
|
||||||
|
characterSpacing: 0
|
||||||
|
characterPadding: 1
|
||||||
|
includeFontData: 1
|
||||||
|
fontNames:
|
||||||
|
- D-DIN-PRO
|
||||||
|
fallbackFontReferences: []
|
||||||
|
customCharacters:
|
||||||
|
fontRenderingMode: 0
|
||||||
|
ascentCalculationMode: 1
|
||||||
|
useLegacyBoundsCalculation: 0
|
||||||
|
shouldRoundAdvanceValue: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 614549820bd3c514eaf369e4895d1ef0
|
guid: 421721c07232d364a83d0ba06d07d95a
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
Binary file not shown.
@@ -0,0 +1,21 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 75478c64a6f70554f8c0e56337612324
|
||||||
|
TrueTypeFontImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
fontSize: 16
|
||||||
|
forceTextureCase: -2
|
||||||
|
characterSpacing: 0
|
||||||
|
characterPadding: 1
|
||||||
|
includeFontData: 1
|
||||||
|
fontNames:
|
||||||
|
- Digital Numbers
|
||||||
|
fallbackFontReferences: []
|
||||||
|
customCharacters:
|
||||||
|
fontRenderingMode: 0
|
||||||
|
ascentCalculationMode: 1
|
||||||
|
useLegacyBoundsCalculation: 0
|
||||||
|
shouldRoundAdvanceValue: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -41,6 +41,15 @@
|
|||||||
"interactions": "Press,Tap",
|
"interactions": "Press,Tap",
|
||||||
"initialStateCheck": false
|
"initialStateCheck": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Crawl",
|
||||||
|
"type": "Button",
|
||||||
|
"id": "350ae177-bf96-40b1-aff0-e10865947df9",
|
||||||
|
"expectedControlType": "Button",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "HoldCrouch",
|
"name": "HoldCrouch",
|
||||||
"type": "Button",
|
"type": "Button",
|
||||||
@@ -570,6 +579,17 @@
|
|||||||
"action": "Inspect",
|
"action": "Inspect",
|
||||||
"isComposite": false,
|
"isComposite": false,
|
||||||
"isPartOfComposite": false
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "a533436d-c3bf-4cb3-93b2-1ca02791e6d1",
|
||||||
|
"path": "<Keyboard>/leftCtrl",
|
||||||
|
"interactions": "Press,Hold",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "Crawl",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
37
Src/Unity/Pool/PoolObject.cs
Normal file
37
Src/Unity/Pool/PoolObject.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using ZXing.QrCode.Internal;
|
||||||
|
|
||||||
|
namespace BITKit
|
||||||
|
{
|
||||||
|
public interface IPoolObject
|
||||||
|
{
|
||||||
|
ValidHandle EnabledHandle { get; }
|
||||||
|
}
|
||||||
|
[CustomType(typeof(IPoolObject))]
|
||||||
|
public class PoolObject : MonoBehaviour, IPoolObject
|
||||||
|
{
|
||||||
|
[SerializeField, ReadOnly] private bool isEnabled;
|
||||||
|
[SerializeField, ReadOnly(HideLabel = true), TextArea] private string report;
|
||||||
|
public ValidHandle EnabledHandle { get; } = new();
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
EnabledHandle.AddListener(OnEnabled);
|
||||||
|
}
|
||||||
|
private void OnEnabled(bool obj)
|
||||||
|
{
|
||||||
|
isEnabled = obj;
|
||||||
|
report = EnabledHandle.ToString();
|
||||||
|
}
|
||||||
|
[BIT]
|
||||||
|
private void Check()
|
||||||
|
{
|
||||||
|
isEnabled = EnabledHandle.Allow;
|
||||||
|
report = EnabledHandle.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: a9619851d703d5b4fba4db3eefcdbf57
|
guid: 7efa56ee20709854aa759ada8501b977
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
@@ -37,9 +37,30 @@ namespace BITKit
|
|||||||
{
|
{
|
||||||
Prefab = _Prefabs[name],
|
Prefab = _Prefabs[name],
|
||||||
OnReturn = null,
|
OnReturn = null,
|
||||||
|
OnSpawn = OnSpawnInternal
|
||||||
};
|
};
|
||||||
return pool;
|
return pool;
|
||||||
|
|
||||||
|
void OnSpawnInternal(Transform newObject)
|
||||||
|
{
|
||||||
|
OnSpawn(name,newObject);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
private static void OnSpawn(string newName,Transform newObject)
|
||||||
|
{
|
||||||
|
if (newObject.TryGetComponent<IPoolObject>(out var obj) is false) return;
|
||||||
|
obj.EnabledHandle.AddListener(OnEnabled);
|
||||||
|
// BIT4Log.Log<PoolService>($"Adding {newObject.name} to pool");
|
||||||
|
return;
|
||||||
|
void OnEnabled(bool obj)
|
||||||
|
{
|
||||||
|
if(obj)return;
|
||||||
|
Release(newName,newObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[SerializeField] private SerializedDictionary<Transform,int> initialCapacity;
|
[SerializeField] private SerializedDictionary<Transform,int> initialCapacity;
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
@@ -52,6 +73,7 @@ namespace BITKit
|
|||||||
DefaultCapacity = value,
|
DefaultCapacity = value,
|
||||||
Root = transform,
|
Root = transform,
|
||||||
OnReturn = null,
|
OnReturn = null,
|
||||||
|
OnSpawn =OnSpawnInternal
|
||||||
};
|
};
|
||||||
_Prefabs.TryAdd(key.name, key);
|
_Prefabs.TryAdd(key.name, key);
|
||||||
_Pools.TryAdd(key.name, pool);
|
_Pools.TryAdd(key.name, pool);
|
||||||
@@ -65,6 +87,12 @@ namespace BITKit
|
|||||||
x.gameObject.SetActive(false);
|
x.gameObject.SetActive(false);
|
||||||
pool.Return(x);
|
pool.Return(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
void OnSpawnInternal(Transform newObject)
|
||||||
|
{
|
||||||
|
OnSpawn(key.name,newObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
206
Src/Unity/Prefabs/UX/UXModService.prefab
Normal file
206
Src/Unity/Prefabs/UX/UXModService.prefab
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &2407307322648522291
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4564055857529787139}
|
||||||
|
- component: {fileID: 1826877396954804926}
|
||||||
|
- component: {fileID: 4338477915639922851}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: open-manual-button
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &4564055857529787139
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2407307322648522291}
|
||||||
|
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: 2399068638639496861}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &1826877396954804926
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2407307322648522291}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 44e9dc9ae2389a74abe198bbd3f86c69, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
document: {fileID: 3996944250455040021}
|
||||||
|
bindName:
|
||||||
|
bindNameProvider:
|
||||||
|
rid: 1308798704739418114
|
||||||
|
allowRightClick: 0
|
||||||
|
onClick:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls:
|
||||||
|
- m_Target: {fileID: 4338477915639922851}
|
||||||
|
m_TargetAssemblyTypeName: BITKit.MonoAction, BITKit
|
||||||
|
m_MethodName: Execute
|
||||||
|
m_Mode: 1
|
||||||
|
m_Arguments:
|
||||||
|
m_ObjectArgument: {fileID: 0}
|
||||||
|
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||||
|
m_IntArgument: 0
|
||||||
|
m_FloatArgument: 0
|
||||||
|
m_StringArgument:
|
||||||
|
m_BoolArgument: 0
|
||||||
|
m_CallState: 2
|
||||||
|
onRightClick:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
clicked:
|
||||||
|
Targets: []
|
||||||
|
references:
|
||||||
|
version: 2
|
||||||
|
RefIds:
|
||||||
|
- rid: 1308798704739418114
|
||||||
|
type: {class: GetNameFromGameobject, ns: BITKit, asm: BITKit}
|
||||||
|
data:
|
||||||
|
gameobject: {fileID: 2407307322648522291}
|
||||||
|
--- !u!114 &4338477915639922851
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2407307322648522291}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: d7c307dd96b0ae44db43b135d73ae46a, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
mark:
|
||||||
|
actions:
|
||||||
|
- rid: 1308798704739418115
|
||||||
|
references:
|
||||||
|
version: 2
|
||||||
|
RefIds:
|
||||||
|
- rid: -2
|
||||||
|
type: {class: , ns: , asm: }
|
||||||
|
- rid: 1308798704739418115
|
||||||
|
type: {class: BITAppForUnity/OpenUrl, ns: BITKit, asm: BITKit}
|
||||||
|
data:
|
||||||
|
url: http://server.bitfall.icu:3000/root/iFactory.Cutting.Unity
|
||||||
|
urlReference:
|
||||||
|
rid: -2
|
||||||
|
--- !u!1 &2637929300846279534
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 2399068638639496861}
|
||||||
|
- component: {fileID: 3996944250455040021}
|
||||||
|
- component: {fileID: 287044842078939351}
|
||||||
|
- component: {fileID: 6825951330841255003}
|
||||||
|
- component: {fileID: 3858922243084897443}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: UXModService
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 2800000, guid: b34f30cbf6975d34fb6ca73deeb90202, type: 3}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &2399068638639496861
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2637929300846279534}
|
||||||
|
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:
|
||||||
|
- {fileID: 4564055857529787139}
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &3996944250455040021
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2637929300846279534}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_PanelSettings: {fileID: 11400000, guid: 64cd93f02c042ad43a96d66da32f0c6c, type: 2}
|
||||||
|
m_ParentUI: {fileID: 0}
|
||||||
|
sourceAsset: {fileID: 9197481963319205126, guid: 569bfcb917fa10f4d90045b7fb8c06aa, type: 3}
|
||||||
|
m_SortingOrder: 0
|
||||||
|
--- !u!114 &287044842078939351
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2637929300846279534}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: b3dfdbe1592c92b478ac90ee712f86ad, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
document: {fileID: 3996944250455040021}
|
||||||
|
modTemplate: {fileID: 9197481963319205126, guid: 5d8350eb5da74b34a81d90d7fdea10c7, type: 3}
|
||||||
|
--- !u!114 &6825951330841255003
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2637929300846279534}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: b9df4ccf721aaec45a7fadfead86ec48, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
document: {fileID: 3996944250455040021}
|
||||||
|
isAnimate: 0
|
||||||
|
allowCursor: 1
|
||||||
|
allowInput: 0
|
||||||
|
autoEntry: 0
|
||||||
|
entryDuration:
|
||||||
|
allow: 0
|
||||||
|
value: 0
|
||||||
|
exitDuration:
|
||||||
|
allow: 0
|
||||||
|
value: 0
|
||||||
|
--- !u!114 &3858922243084897443
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2637929300846279534}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 8c8c71e08d0a2544aae8e62cd2b86af2, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
7
Src/Unity/Prefabs/UX/UXModService.prefab.meta
Normal file
7
Src/Unity/Prefabs/UX/UXModService.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dda3edccc46d7114dbd766e0be5048f3
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
64
Src/Unity/Prefabs/UX/UXToolTips.prefab
Normal file
64
Src/Unity/Prefabs/UX/UXToolTips.prefab
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &4038659619979544204
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4157858068115888819}
|
||||||
|
- component: {fileID: 7044630544360675509}
|
||||||
|
- component: {fileID: 6198192946579484756}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: UXToolTips
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 2800000, guid: b34f30cbf6975d34fb6ca73deeb90202, type: 3}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &4157858068115888819
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4038659619979544204}
|
||||||
|
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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &7044630544360675509
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4038659619979544204}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_PanelSettings: {fileID: 11400000, guid: 64cd93f02c042ad43a96d66da32f0c6c, type: 2}
|
||||||
|
m_ParentUI: {fileID: 0}
|
||||||
|
sourceAsset: {fileID: 9197481963319205126, guid: f2cf6e666f7a52b46a238f0d116ec002,
|
||||||
|
type: 3}
|
||||||
|
m_SortingOrder: 1
|
||||||
|
--- !u!114 &6198192946579484756
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4038659619979544204}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 98955702b98a11c4e8563958148f5719, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
7
Src/Unity/Prefabs/UX/UXToolTips.prefab.meta
Normal file
7
Src/Unity/Prefabs/UX/UXToolTips.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a419287da88de9a4f8968dc024081425
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
65
Src/Unity/Prefabs/UX/UXWaiting.prefab
Normal file
65
Src/Unity/Prefabs/UX/UXWaiting.prefab
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &6649935359787004577
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 8519157962351608687}
|
||||||
|
- component: {fileID: 6174669802797320597}
|
||||||
|
- component: {fileID: 3316324608506949373}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: UXWaiting
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 2800000, guid: 2427f62ec555df341837da126e892853, type: 3}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &8519157962351608687
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6649935359787004577}
|
||||||
|
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_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &6174669802797320597
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6649935359787004577}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_PanelSettings: {fileID: 11400000, guid: 64cd93f02c042ad43a96d66da32f0c6c, type: 2}
|
||||||
|
m_ParentUI: {fileID: 0}
|
||||||
|
sourceAsset: {fileID: 9197481963319205126, guid: fd7776bbc384e3747a370568288ad98c, type: 3}
|
||||||
|
m_SortingOrder: 8
|
||||||
|
--- !u!114 &3316324608506949373
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6649935359787004577}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 241915c4814e5224f9d3ffd6dab7a98e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
handleTemplate: {fileID: 9197481963319205126, guid: 418bc306b2e063847b56f7b5f5a23f7d, type: 3}
|
||||||
|
asGlobal: 1
|
7
Src/Unity/Prefabs/UX/UXWaiting.prefab.meta
Normal file
7
Src/Unity/Prefabs/UX/UXWaiting.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5b88ec746b73c3b4d9d0ad26a07a4509
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -6,10 +6,10 @@ namespace BITKit
|
|||||||
public class AnimatorHelper : MonoBehaviour
|
public class AnimatorHelper : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private Transform root;
|
[SerializeField] private Transform root;
|
||||||
|
[SerializeField] private bool allowAnimatorMove;
|
||||||
private void OnAnimatorMove()
|
private void OnAnimatorMove()
|
||||||
{
|
{
|
||||||
if (root)
|
if (root && allowAnimatorMove)
|
||||||
root.SendMessageUpwards(nameof(OnAnimatorMove),SendMessageOptions.DontRequireReceiver);
|
root.SendMessageUpwards(nameof(OnAnimatorMove),SendMessageOptions.DontRequireReceiver);
|
||||||
}
|
}
|
||||||
private void AIAnimationEvent(string actionName)
|
private void AIAnimationEvent(string actionName)
|
||||||
|
@@ -46,6 +46,8 @@ namespace BITKit
|
|||||||
[SerializeReference, SubclassSelector] private IRemoteServices remoteServices;
|
[SerializeReference, SubclassSelector] private IRemoteServices remoteServices;
|
||||||
[SerializeReference, SubclassSelector] private IBuildinQueryServices buildinQueryServices;
|
[SerializeReference, SubclassSelector] private IBuildinQueryServices buildinQueryServices;
|
||||||
|
|
||||||
|
[SerializeField] private Optional<string> loadEntryScene;
|
||||||
|
|
||||||
[SerializeField] private UIDocument document;
|
[SerializeField] private UIDocument document;
|
||||||
|
|
||||||
[SerializeField] private bool isOffline;
|
[SerializeField] private bool isOffline;
|
||||||
@@ -178,12 +180,23 @@ namespace BITKit
|
|||||||
YooAssetUtils.RegisterPackage(packageName.Value);
|
YooAssetUtils.RegisterPackage(packageName.Value);
|
||||||
YooAssetUtils.RegisterResourcePackage(package);
|
YooAssetUtils.RegisterResourcePackage(package);
|
||||||
|
|
||||||
if (document)
|
if (loadEntryScene.Allow)
|
||||||
Destroy(document);
|
{
|
||||||
SceneManager.LoadScene(1);
|
_progressLabel.text="正在加载场景...";
|
||||||
|
await package.LoadSceneAsync(loadEntryScene.Value);
|
||||||
|
if (document)
|
||||||
|
Destroy(document);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (document)
|
||||||
|
Destroy(document);
|
||||||
|
SceneManager.LoadScene(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
await UniTask.SwitchToMainThread();
|
||||||
_progressBar.value =0;
|
_progressBar.value =0;
|
||||||
_progressLabel.text = e.Message;
|
_progressLabel.text = e.Message;
|
||||||
}
|
}
|
||||||
|
20
Src/Unity/Scripts/Assets/YooAssetVersionEvent.cs
Normal file
20
Src/Unity/Scripts/Assets/YooAssetVersionEvent.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Events;
|
||||||
|
using YooAsset;
|
||||||
|
|
||||||
|
namespace BITKit
|
||||||
|
{
|
||||||
|
public class YooAssetVersionEvent : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeReference, SubclassSelector] private IReference packageName;
|
||||||
|
[SerializeField] private UnityEvent<string> output;
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
var package = YooAssets.GetPackage(packageName.Value);
|
||||||
|
output?.Invoke(package.GetPackageVersion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 7869b4bffebc8f6439819f03f741da2b
|
guid: d8adb662636da83409ffabc85b2df24e
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
@@ -1,15 +1,16 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.Events;
|
||||||
|
|
||||||
namespace BITKit
|
namespace BITKit
|
||||||
{
|
{
|
||||||
public class ShowVersion : MonoBehaviour
|
public class ShowVersion : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField,SerializeReference,SubclassSelector] private IProvider output;
|
[SerializeField] private UnityEvent<string> output;
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
output?.Set(Application.version);
|
output?.Invoke(Application.version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -27,6 +27,12 @@ namespace BITKit.Console
|
|||||||
{
|
{
|
||||||
Application.logMessageReceivedThreaded += EnqueueLog;
|
Application.logMessageReceivedThreaded += EnqueueLog;
|
||||||
}
|
}
|
||||||
|
[BITCommand]
|
||||||
|
public static void Console_Exception_Print_StackTrace(int allow)
|
||||||
|
{
|
||||||
|
exceptionPrintStackTrace = allow is 1;
|
||||||
|
}
|
||||||
|
private static bool exceptionPrintStackTrace = false;
|
||||||
private class CommandSelector
|
private class CommandSelector
|
||||||
{
|
{
|
||||||
public VisualElement Container { get; set; }
|
public VisualElement Container { get; set; }
|
||||||
@@ -289,12 +295,14 @@ namespace BITKit.Console
|
|||||||
break;
|
break;
|
||||||
case LogType.Exception:
|
case LogType.Exception:
|
||||||
outputString.Add($"<color=red>{condition}</color>");
|
outputString.Add($"<color=red>{condition}</color>");
|
||||||
outputString.Add($"<color=red>{stackTrace}</color>");
|
if (exceptionPrintStackTrace)
|
||||||
|
outputString.Add($"<color=red>{stackTrace}</color>");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
outputString.Add(condition);
|
outputString.Add(condition);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var length = outputString.Count;
|
var length = outputString.Count;
|
||||||
if (length > logLineLimit)
|
if (length > logLineLimit)
|
||||||
{
|
{
|
||||||
|
@@ -1,100 +0,0 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using UnityEngine.Events;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using System.Threading;
|
|
||||||
using System;
|
|
||||||
namespace BITKit
|
|
||||||
{
|
|
||||||
public class DataPlayer : Provider
|
|
||||||
{
|
|
||||||
public DataPlayer<string> player = new();
|
|
||||||
public Provider output;
|
|
||||||
public Provider outputProgess;
|
|
||||||
public Provider outputTime;
|
|
||||||
public Provider outputTotalTime;
|
|
||||||
public UnityEvent onStart = new();
|
|
||||||
public UnityEvent<float> onChangeTime = new();
|
|
||||||
public UnityEvent onStop = new();
|
|
||||||
CancellationToken cancellationToken;
|
|
||||||
public override void Set<T>(T obj)
|
|
||||||
{
|
|
||||||
switch (obj)
|
|
||||||
{
|
|
||||||
case List<string> list:
|
|
||||||
player.Set(list);
|
|
||||||
break;
|
|
||||||
case string str:
|
|
||||||
player.Set(JsonConvert.DeserializeObject<List<string>>(str));
|
|
||||||
break;
|
|
||||||
case bool _boolean:
|
|
||||||
if (_boolean)
|
|
||||||
player.Start();
|
|
||||||
else
|
|
||||||
player.Stop();
|
|
||||||
break;
|
|
||||||
case float _float:
|
|
||||||
player.SetProgress(_float);
|
|
||||||
onChangeTime.Invoke(_float);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new System.Exception();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void Awake()
|
|
||||||
{
|
|
||||||
cancellationToken = gameObject.GetCancellationTokenOnDestroy();
|
|
||||||
if (output)
|
|
||||||
player.output += output.Set;
|
|
||||||
if (outputProgess)
|
|
||||||
player.onProgess += outputProgess.Set;
|
|
||||||
if (outputTime)
|
|
||||||
player.onTime += outputTime.Set;
|
|
||||||
if (outputTotalTime)
|
|
||||||
player.onSetTotalTime += outputTotalTime.Set;
|
|
||||||
player.onStart += async () =>
|
|
||||||
{
|
|
||||||
await UniTask.SwitchToMainThread(cancellationToken);
|
|
||||||
BIT4Log.Log<DataPlayer>("开始播放");
|
|
||||||
onStart.Invoke();
|
|
||||||
};
|
|
||||||
player.onStop += async () =>
|
|
||||||
{
|
|
||||||
await UniTask.SwitchToMainThread(cancellationToken);
|
|
||||||
BIT4Log.Log<DataPlayer>("停止播放");
|
|
||||||
onStop.Invoke();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
public void Play()
|
|
||||||
{
|
|
||||||
player.Start();
|
|
||||||
}
|
|
||||||
public void Stop()
|
|
||||||
{
|
|
||||||
player.Stop();
|
|
||||||
}
|
|
||||||
public void PlayOrPause()
|
|
||||||
{
|
|
||||||
player.PlayOrPause();
|
|
||||||
}
|
|
||||||
public void Offset(float time)
|
|
||||||
{
|
|
||||||
player.Offset(time);
|
|
||||||
|
|
||||||
}
|
|
||||||
public bool IsPlaying() => player.isPlaying;
|
|
||||||
public PlayerState GetState() => player.state;
|
|
||||||
public bool IsPaused() => GetState() is PlayerState.Paused;
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
onStop.Invoke();
|
|
||||||
}
|
|
||||||
void OnDestroy()
|
|
||||||
{
|
|
||||||
player.Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
106
Src/Unity/Scripts/DataPlayer/UnityDataPlayer.cs
Normal file
106
Src/Unity/Scripts/DataPlayer/UnityDataPlayer.cs
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using UnityEngine.Events;
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
|
using System.Threading;
|
||||||
|
using System;
|
||||||
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
|
namespace BITKit
|
||||||
|
{
|
||||||
|
public class UnityDataPlayer : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] private int rate;
|
||||||
|
[SerializeField] internal DataPlayer<string> player = new();
|
||||||
|
[SerializeField] private UnityEvent<string> output;
|
||||||
|
[SerializeField] private UnityEvent<float> outputProgess;
|
||||||
|
[SerializeField] private UnityEvent<string> outputTime;
|
||||||
|
[SerializeField] private UnityEvent<string> outputTotalTime;
|
||||||
|
[SerializeField] private UnityEvent onStart = new();
|
||||||
|
[SerializeField] private UnityEvent<float> onChangeTime = new();
|
||||||
|
[SerializeField] private UnityEvent onStop = new();
|
||||||
|
[BIT]
|
||||||
|
public void Play()
|
||||||
|
{
|
||||||
|
player.frameRate = rate;
|
||||||
|
player.Start();
|
||||||
|
}
|
||||||
|
[BIT]
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
player.Stop();
|
||||||
|
}
|
||||||
|
[BIT]
|
||||||
|
public void PlayOrPause()
|
||||||
|
{
|
||||||
|
player.PlayOrPause();
|
||||||
|
}
|
||||||
|
public void Offset(float time)
|
||||||
|
{
|
||||||
|
player.Offset(time);
|
||||||
|
}
|
||||||
|
public void SetData(List<string> data)
|
||||||
|
{
|
||||||
|
player.Set(data);
|
||||||
|
}
|
||||||
|
public bool IsPlaying() => player.isPlaying;
|
||||||
|
public PlayerState GetState() => player.state;
|
||||||
|
public bool IsPaused() => GetState() is PlayerState.Paused;
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
onStop.Invoke();
|
||||||
|
|
||||||
|
player.PlayOrPause();
|
||||||
|
player.output += output.Invoke;
|
||||||
|
player.onProgess += outputProgess.Invoke;
|
||||||
|
player.onTime += outputTime.Invoke;
|
||||||
|
player.onStart += async () =>
|
||||||
|
{
|
||||||
|
await UniTask.SwitchToMainThread();
|
||||||
|
if (destroyCancellationToken.IsCancellationRequested) return;
|
||||||
|
BIT4Log.Log<UnityDataPlayer>("开始播放");
|
||||||
|
onStart.Invoke();
|
||||||
|
};
|
||||||
|
player.onStop += async () =>
|
||||||
|
{
|
||||||
|
await UniTask.SwitchToMainThread();
|
||||||
|
if (destroyCancellationToken.IsCancellationRequested) return;
|
||||||
|
BIT4Log.Log<UnityDataPlayer>("停止播放");
|
||||||
|
onStop.Invoke();
|
||||||
|
};
|
||||||
|
player.onSetTotalTime += outputTotalTime.Invoke;
|
||||||
|
|
||||||
|
destroyCancellationToken.Register(player.Stop);
|
||||||
|
}
|
||||||
|
public void SetTime(float time)
|
||||||
|
{
|
||||||
|
player.SetProgress(time);
|
||||||
|
onChangeTime.Invoke(time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
[CustomType(typeof(UnityDataPlayer))]
|
||||||
|
public sealed class UnityDataPlayerInpsector:BITInspector<UnityDataPlayer>
|
||||||
|
{
|
||||||
|
private ProgressBar _progressBar;
|
||||||
|
public override VisualElement CreateInspectorGUI()
|
||||||
|
{
|
||||||
|
FillDefaultInspector();
|
||||||
|
|
||||||
|
_progressBar = root.Create<ProgressBar>();
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate()
|
||||||
|
{
|
||||||
|
_progressBar.value = agent.player.index;
|
||||||
|
_progressBar.highValue = agent.player.list.Count;
|
||||||
|
base.OnUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
@@ -62,6 +62,7 @@ namespace BITKit.Entities
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IEntityMovement:IStateMachine<IEntityMovementState>
|
public interface IEntityMovement:IStateMachine<IEntityMovementState>
|
||||||
{
|
{
|
||||||
|
Vector3 Size => Vector3.one;
|
||||||
float ReferenceSpeed => 2.5f;
|
float ReferenceSpeed => 2.5f;
|
||||||
Vector3 Position { get; set; }
|
Vector3 Position { get; set; }
|
||||||
Quaternion Rotation { get; set; }
|
Quaternion Rotation { get; set; }
|
||||||
@@ -138,5 +139,6 @@ namespace BITKit.Entities
|
|||||||
void BeforeUpdateMovement(float deltaTime);
|
void BeforeUpdateMovement(float deltaTime);
|
||||||
void AfterUpdateMovement(float deltaTime);
|
void AfterUpdateMovement(float deltaTime);
|
||||||
void ExecuteCommand<T>(T command);
|
void ExecuteCommand<T>(T command);
|
||||||
|
void DrawGizmos();
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -81,8 +81,8 @@ namespace BITKit.Entities
|
|||||||
{
|
{
|
||||||
public override DamageMessage ReadBinary(BinaryReader reader)
|
public override DamageMessage ReadBinary(BinaryReader reader)
|
||||||
{
|
{
|
||||||
UnityEntitiesService.TryGetEntity(reader.ReadUInt64(),out var initiator);
|
UnityEntitiesService.TryGetEntity(reader.ReadInt32(),out var initiator);
|
||||||
UnityEntitiesService.TryGetEntity(reader.ReadUInt64(),out var target);
|
UnityEntitiesService.TryGetEntity(reader.ReadInt32(),out var target);
|
||||||
return new DamageMessage()
|
return new DamageMessage()
|
||||||
{
|
{
|
||||||
Initiator = initiator as Entity,
|
Initiator = initiator as Entity,
|
||||||
@@ -114,6 +114,7 @@ namespace BITKit.Entities
|
|||||||
IHealth Health { get; }
|
IHealth Health { get; }
|
||||||
IUnityEntity UnityEntity { get; }
|
IUnityEntity UnityEntity { get; }
|
||||||
Rigidbody Rigidbody { get; }
|
Rigidbody Rigidbody { get; }
|
||||||
|
Collider Collider { get; }
|
||||||
void GiveDamage(DamageMessage message);
|
void GiveDamage(DamageMessage message);
|
||||||
}
|
}
|
||||||
public class DamageService:MonoBehaviour,IDamageService
|
public class DamageService:MonoBehaviour,IDamageService
|
||||||
|
@@ -90,11 +90,6 @@ namespace BITKit.Entities
|
|||||||
OnSetAlive?.Invoke(alive);
|
OnSetAlive?.Invoke(alive);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddHP(int hp)
|
|
||||||
{
|
|
||||||
OnHealthPointChangedInternal(healthPoint, healthPoint += hp);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnGetDamage(DamageMessage damageMessage)
|
private void OnGetDamage(DamageMessage damageMessage)
|
||||||
{
|
{
|
||||||
if (damageMessage.Target != UnityEntity) return;
|
if (damageMessage.Target != UnityEntity) return;
|
||||||
@@ -114,11 +109,23 @@ namespace BITKit.Entities
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Data.Get<bool>("god") is false)
|
|
||||||
AddHP(-damage);
|
|
||||||
|
|
||||||
damageMessage.Damage = damage;
|
damageMessage.Damage = damage;
|
||||||
|
if (Data.Get<bool>("god") is false)
|
||||||
|
{
|
||||||
|
healthPoint-=damage;
|
||||||
|
}
|
||||||
|
|
||||||
|
IsAlive = healthPoint >= 0;
|
||||||
|
|
||||||
|
OnSetHealthPoint?.Invoke(healthPoint);
|
||||||
|
|
||||||
OnDamageRelease?.Invoke(damageMessage);
|
OnDamageRelease?.Invoke(damageMessage);
|
||||||
|
|
||||||
|
if (!IsAlive)
|
||||||
|
{
|
||||||
|
OnSetAliveInternal(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
|
@@ -27,10 +27,24 @@ namespace BITKit.Entities
|
|||||||
}
|
}
|
||||||
public Rigidbody Rigidbody
|
public Rigidbody Rigidbody
|
||||||
{
|
{
|
||||||
get=>m_rigidbody;
|
get
|
||||||
|
{
|
||||||
|
EnsureConfigure();
|
||||||
|
return m_rigidbody;
|
||||||
|
}
|
||||||
set=>m_rigidbody=value;
|
set=>m_rigidbody=value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collider Collider
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
EnsureConfigure();
|
||||||
|
return _collider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private Collider _collider;
|
||||||
|
|
||||||
public void GiveDamage(DamageMessage message)
|
public void GiveDamage(DamageMessage message)
|
||||||
{
|
{
|
||||||
if (_unityEntity is not null)
|
if (_unityEntity is not null)
|
||||||
@@ -53,6 +67,7 @@ namespace BITKit.Entities
|
|||||||
_unityEntity = GetComponentInParent<IUnityEntity>(true);
|
_unityEntity = GetComponentInParent<IUnityEntity>(true);
|
||||||
_unityEntity?.Inject(this);
|
_unityEntity?.Inject(this);
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
|
_collider = GetComponent<Collider>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -3,7 +3,9 @@ using System.Collections.Generic;
|
|||||||
using BITFALL.Rig;
|
using BITFALL.Rig;
|
||||||
using BITKit.Entities;
|
using BITKit.Entities;
|
||||||
using Cysharp.Threading.Tasks.Triggers;
|
using Cysharp.Threading.Tasks.Triggers;
|
||||||
|
#if UNITY_EDITOR
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
#endif
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace BITKit
|
namespace BITKit
|
||||||
@@ -14,6 +16,7 @@ namespace BITKit
|
|||||||
[SerializeField] private EntityHitbox[] hitboxes;
|
[SerializeField] private EntityHitbox[] hitboxes;
|
||||||
|
|
||||||
[SerializeReference,SubclassSelector] private IReference[] tagReferences;
|
[SerializeReference,SubclassSelector] private IReference[] tagReferences;
|
||||||
|
#if UNITY_EDITOR
|
||||||
[BIT]
|
[BIT]
|
||||||
private void Build()
|
private void Build()
|
||||||
{
|
{
|
||||||
@@ -73,5 +76,6 @@ namespace BITKit
|
|||||||
}
|
}
|
||||||
EditorUtility.SetDirty(this);
|
EditorUtility.SetDirty(this);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "BITKit.Entities.Physics"
|
"name": "BITKit.Entities.Physics",
|
||||||
}
|
"rootNamespace": "",
|
||||||
|
"references": [
|
||||||
|
"GUID:14fe60d984bf9f84eac55c6ea033a8f4"
|
||||||
|
],
|
||||||
|
"includePlatforms": [],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": false,
|
||||||
|
"overrideReferences": false,
|
||||||
|
"precompiledReferences": [],
|
||||||
|
"autoReferenced": true,
|
||||||
|
"defineConstraints": [],
|
||||||
|
"versionDefines": [],
|
||||||
|
"noEngineReferences": false
|
||||||
|
}
|
@@ -10,6 +10,7 @@ namespace BITKit.Entities.Physics
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IEntityPhysics
|
public interface IEntityPhysics
|
||||||
{
|
{
|
||||||
|
ValidHandle DisablePhysics { get; }
|
||||||
Vector3 Center { get; }
|
Vector3 Center { get; }
|
||||||
bool IsPhysics { get; }
|
bool IsPhysics { get; }
|
||||||
Vector3 Velocity { get; set; }
|
Vector3 Velocity { get; set; }
|
||||||
|
@@ -20,7 +20,7 @@ namespace BITKit.Entities
|
|||||||
private readonly GenericEvent genericEvent = new();
|
private readonly GenericEvent genericEvent = new();
|
||||||
|
|
||||||
|
|
||||||
public ulong Id { get; set; }
|
public int Id { get; set; }
|
||||||
public CancellationToken CancellationToken { get; private set; }
|
public CancellationToken CancellationToken { get; private set; }
|
||||||
public IEntityBehavior[] Behaviors { get;private set; }
|
public IEntityBehavior[] Behaviors { get;private set; }
|
||||||
public IEntityComponent[] Components => Behaviors.Cast<IEntityComponent>().ToArray();
|
public IEntityComponent[] Components => Behaviors.Cast<IEntityComponent>().ToArray();
|
||||||
@@ -33,9 +33,43 @@ namespace BITKit.Entities
|
|||||||
IServiceProvider Entities.IEntity.ServiceProvider=> throw new InvalidOperationException("Unity Entity can't register component");
|
IServiceProvider Entities.IEntity.ServiceProvider=> throw new InvalidOperationException("Unity Entity can't register component");
|
||||||
public void Inject(object obj)
|
public void Inject(object obj)
|
||||||
{
|
{
|
||||||
|
foreach (var propertyInfo in obj
|
||||||
|
.GetType()
|
||||||
|
.GetProperties(ReflectionHelper.Flags)
|
||||||
|
.Where(x=>x.GetCustomAttribute<InjectAttribute>(true) is not null))
|
||||||
|
{
|
||||||
|
var type = propertyInfo.PropertyType;
|
||||||
|
var attribute = propertyInfo.GetCustomAttribute<InjectAttribute>();
|
||||||
|
var currentValue = propertyInfo.GetValue(obj);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (currentValue)
|
||||||
|
{
|
||||||
|
case null:
|
||||||
|
break;
|
||||||
|
case IEntityComponent entityComponent:
|
||||||
|
if(entityComponent.Entity.Id == Id)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
case MonoBehaviour { destroyCancellationToken: { IsCancellationRequested: false } }:
|
||||||
|
continue;
|
||||||
|
case not null:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (MissingReferenceException){}
|
||||||
|
if(genericEvent.TryGetObjectDirect(type.FullName,out var value))
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(obj,value,null);
|
||||||
|
}
|
||||||
|
else if(attribute?.CanBeNull is false)
|
||||||
|
{
|
||||||
|
BIT4Log.Warning<Entity>($"{name}未找到{obj.GetType().Name}需要的{type.FullName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
foreach (var fieldInfo in obj
|
foreach (var fieldInfo in obj
|
||||||
.GetType()
|
.GetType()
|
||||||
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
.GetFields(ReflectionHelper.Flags)
|
||||||
.Where(fieldInfo=>fieldInfo.GetCustomAttribute<InjectAttribute>(true) is not null))
|
.Where(fieldInfo=>fieldInfo.GetCustomAttribute<InjectAttribute>(true) is not null))
|
||||||
{
|
{
|
||||||
var type = fieldInfo.FieldType;
|
var type = fieldInfo.FieldType;
|
||||||
@@ -97,7 +131,7 @@ namespace BITKit.Entities
|
|||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
if (Id.IsDefault())
|
if (Id.IsDefault())
|
||||||
Id = (ulong)Guid.NewGuid().GetHashCode();
|
Id = GetInstanceID();
|
||||||
CancellationToken = gameObject.GetCancellationTokenOnDestroy();
|
CancellationToken = gameObject.GetCancellationTokenOnDestroy();
|
||||||
Set(CancellationToken);
|
Set(CancellationToken);
|
||||||
}
|
}
|
||||||
|
@@ -48,6 +48,13 @@ namespace BITKit.Entities
|
|||||||
stateMachine.Initialize();
|
stateMachine.Initialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnDestroyComponent()
|
||||||
|
{
|
||||||
|
base.OnDestroyComponent();
|
||||||
|
CurrentState?.OnStateExit(CurrentState,null);
|
||||||
|
}
|
||||||
|
|
||||||
void IStateMachine<T>.Initialize()
|
void IStateMachine<T>.Initialize()
|
||||||
{
|
{
|
||||||
stateMachine.Initialize();
|
stateMachine.Initialize();
|
||||||
|
@@ -38,10 +38,10 @@ public class UnityEntitiesServiceSingleton:IEntitiesService
|
|||||||
|
|
||||||
public CancellationToken CancellationToken => UnityEntitiesService.CancellationToken;
|
public CancellationToken CancellationToken => UnityEntitiesService.CancellationToken;
|
||||||
|
|
||||||
public IEntity Get(ulong id) => UnityEntitiesService.Get(id);
|
public IEntity Get(int id) => UnityEntitiesService.Get(id);
|
||||||
public bool TryGetEntity(ulong id, out IEntity entity) => UnityEntitiesService.TryGetEntity(id, out entity);
|
public bool TryGetEntity(int id, out IEntity entity) => UnityEntitiesService.TryGetEntity(id, out entity);
|
||||||
|
|
||||||
public IEntity GetOrAdd(ulong id, Func<ulong, IEntity> factory)=>UnityEntitiesService.GetOrAdd(id,factory);
|
public IEntity GetOrAdd(int id, Func<int, IEntity> factory)=>UnityEntitiesService.GetOrAdd(id,factory);
|
||||||
|
|
||||||
|
|
||||||
public IEntity[] Query<T>()
|
public IEntity[] Query<T>()
|
||||||
@@ -85,7 +85,7 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public static CancellationToken CancellationToken;
|
public static CancellationToken CancellationToken;
|
||||||
private static readonly ConcurrentDictionary<ulong,IEntity> Dictionary=new();
|
private static readonly ConcurrentDictionary<int,IEntity> Dictionary=new();
|
||||||
private static readonly Queue<IEntity> RegisterQueue = new();
|
private static readonly Queue<IEntity> RegisterQueue = new();
|
||||||
private static readonly Queue<IEntity> UnRegisterQueue = new();
|
private static readonly Queue<IEntity> UnRegisterQueue = new();
|
||||||
private void Awake()
|
private void Awake()
|
||||||
@@ -126,18 +126,18 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
|
|||||||
}
|
}
|
||||||
|
|
||||||
CancellationToken IEntitiesService.CancellationToken => CancellationToken;
|
CancellationToken IEntitiesService.CancellationToken => CancellationToken;
|
||||||
public static IEntity Get(ulong id)=>Dictionary[id];
|
public static IEntity Get(int id)=>Dictionary[id];
|
||||||
IEntity IEntitiesService.Get(ulong id)=>Get(id);
|
IEntity IEntitiesService.Get(int id)=>Get(id);
|
||||||
public static bool TryGetEntity(ulong id, out IEntity entity)
|
public static bool TryGetEntity(int id, out IEntity entity)
|
||||||
{
|
{
|
||||||
return Dictionary.TryGetValue(id, out entity);
|
return Dictionary.TryGetValue(id, out entity);
|
||||||
}
|
}
|
||||||
bool IEntitiesService.TryGetEntity(ulong id, out IEntity entity)=>TryGetEntity(id,out entity);
|
bool IEntitiesService.TryGetEntity(int id, out IEntity entity)=>TryGetEntity(id,out entity);
|
||||||
public static IEntity GetOrAdd(ulong id, Func<ulong, IEntity> factory)
|
public static IEntity GetOrAdd(int id, Func<int, IEntity> factory)
|
||||||
{
|
{
|
||||||
return Dictionary.GetOrAdd(id, factory);
|
return Dictionary.GetOrAdd(id, factory);
|
||||||
}
|
}
|
||||||
IEntity IEntitiesService.GetOrAdd(ulong id, Func<ulong, IEntity> factory)=>GetOrAdd(id,factory);
|
IEntity IEntitiesService.GetOrAdd(int id, Func<int, IEntity> factory)=>GetOrAdd(id,factory);
|
||||||
|
|
||||||
IEntity[] IEntitiesService.Query<T>()=>Query<T>();
|
IEntity[] IEntitiesService.Query<T>()=>Query<T>();
|
||||||
public static IEntity[] Query<T>()
|
public static IEntity[] Query<T>()
|
||||||
|
@@ -7,14 +7,14 @@ namespace BITKit.Entities
|
|||||||
{
|
{
|
||||||
public interface IdComponent
|
public interface IdComponent
|
||||||
{
|
{
|
||||||
ulong Id { get; }
|
int Id { get; }
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
}
|
}
|
||||||
public class UnityIdComponent : EntityBehavior,IdComponent
|
public class UnityIdComponent : EntityBehavior,IdComponent
|
||||||
{
|
{
|
||||||
[SerializeField] private ulong id;
|
[SerializeField] private int id;
|
||||||
[SerializeField] private string unityName;
|
[SerializeField] private string unityName;
|
||||||
public ulong Id => id;
|
public int Id => id;
|
||||||
public string Name => unityName;
|
public string Name => unityName;
|
||||||
public override void Initialize(IEntity _entity)
|
public override void Initialize(IEntity _entity)
|
||||||
{
|
{
|
||||||
|
@@ -19,7 +19,7 @@ namespace BITKit.Entities
|
|||||||
public struct EntitiesNetSyncBatchCommand
|
public struct EntitiesNetSyncBatchCommand
|
||||||
{
|
{
|
||||||
public int Length;
|
public int Length;
|
||||||
public ulong[] Ids;
|
public int[] Ids;
|
||||||
public ulong[] AddressablePaths;
|
public ulong[] AddressablePaths;
|
||||||
public EntitiesNetSyncCommand[] Commands;
|
public EntitiesNetSyncCommand[] Commands;
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ namespace BITKit.Entities
|
|||||||
{
|
{
|
||||||
using var ms = new MemoryStream(obj.Data);
|
using var ms = new MemoryStream(obj.Data);
|
||||||
using var reader = new BinaryReader(ms);
|
using var reader = new BinaryReader(ms);
|
||||||
var id = reader.ReadUInt64();
|
var id = reader.ReadInt32();
|
||||||
var path = reader.ReadUInt64();
|
var path = reader.ReadUInt64();
|
||||||
entitiesService.GetOrAdd(id, x => AddEntity(id, path)).TryGetComponent<IEntityBinaryHeader>(out var header);
|
entitiesService.GetOrAdd(id, x => AddEntity(id, path)).TryGetComponent<IEntityBinaryHeader>(out var header);
|
||||||
header.Deserialize(reader);
|
header.Deserialize(reader);
|
||||||
@@ -100,7 +100,7 @@ namespace BITKit.Entities
|
|||||||
header.Deserialize(reader);
|
header.Deserialize(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static IEntity AddEntity(ulong id,ulong addressableId)
|
private static IEntity AddEntity(int id,ulong addressableId)
|
||||||
{
|
{
|
||||||
var entity = AddressableHelper.Get<GameObject>(addressableId);
|
var entity = AddressableHelper.Get<GameObject>(addressableId);
|
||||||
var instance = Instantiate(entity).GetComponent<Entity>();
|
var instance = Instantiate(entity).GetComponent<Entity>();
|
||||||
@@ -146,7 +146,7 @@ namespace BITKit.Entities
|
|||||||
var batchCommand = new EntitiesNetSyncBatchCommand()
|
var batchCommand = new EntitiesNetSyncBatchCommand()
|
||||||
{
|
{
|
||||||
Length = headers.Length,
|
Length = headers.Length,
|
||||||
Ids = new ulong[headers.Length],
|
Ids = new int[headers.Length],
|
||||||
AddressablePaths = new ulong[headers.Length],
|
AddressablePaths = new ulong[headers.Length],
|
||||||
Commands = new EntitiesNetSyncCommand[headers.Length]
|
Commands = new EntitiesNetSyncCommand[headers.Length]
|
||||||
};
|
};
|
||||||
|
@@ -15,8 +15,8 @@ namespace BITKit.Entities.Player
|
|||||||
[SerializeField] private MonoStateMachine<T> stateMachine;
|
[SerializeField] private MonoStateMachine<T> stateMachine;
|
||||||
public override void OnAwake()
|
public override void OnAwake()
|
||||||
{
|
{
|
||||||
stateMachine?.Initialize();
|
|
||||||
base.OnAwake();
|
base.OnAwake();
|
||||||
|
stateMachine?.Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Enabled
|
public bool Enabled
|
||||||
|
@@ -2,12 +2,14 @@ using System;
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using UnityEditor.Rendering;
|
using UnityEditor.Rendering;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
|
using Debug = UnityEngine.Debug;
|
||||||
using Timer = System.Timers.Timer;
|
using Timer = System.Timers.Timer;
|
||||||
|
|
||||||
namespace BITKit.Http
|
namespace BITKit.Http
|
||||||
@@ -22,20 +24,33 @@ namespace BITKit.Http
|
|||||||
[Header(Constant.Header.Output)]
|
[Header(Constant.Header.Output)]
|
||||||
[SerializeField] private UnityEvent<string> output;
|
[SerializeField] private UnityEvent<string> output;
|
||||||
[SerializeField] private UnityEvent<string> onException;
|
[SerializeField] private UnityEvent<string> onException;
|
||||||
|
[SerializeField] private UnityEvent<int> onCalculateLength;
|
||||||
|
|
||||||
|
[Header(Constant.Header.Optional)]
|
||||||
|
[SerializeField] private Optional<string> overrideResponse;
|
||||||
|
|
||||||
|
|
||||||
[Header(Constant.Header.Debug)]
|
[Header(Constant.Header.Debug)]
|
||||||
[SerializeField, ReadOnly] private double time;
|
[SerializeField, ReadOnly] private double time;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[SerializeField, ReadOnly] private bool isConnected;
|
||||||
|
|
||||||
private readonly Timer timer = new()
|
private readonly Timer timer = new()
|
||||||
{
|
{
|
||||||
AutoReset = true
|
AutoReset = true
|
||||||
};
|
};
|
||||||
private readonly HttpClient _httpClient = new();
|
private readonly HttpClient _httpClient = new();
|
||||||
private CancellationToken _cancellationToken;
|
private bool _enabled;
|
||||||
|
|
||||||
private void Awake()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
_cancellationToken = gameObject.GetCancellationTokenOnDestroy();
|
_enabled = true;
|
||||||
|
}
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
_enabled = false;
|
||||||
}
|
}
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
@@ -50,6 +65,7 @@ AutoReset = true
|
|||||||
_ => throw new ArgumentOutOfRangeException()
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
};
|
};
|
||||||
timer.Start();
|
timer.Start();
|
||||||
|
destroyCancellationToken.ThrowIfCancellationRequested();
|
||||||
}
|
}
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
{
|
{
|
||||||
@@ -58,26 +74,83 @@ AutoReset = true
|
|||||||
}
|
}
|
||||||
private async void OnUpdate()
|
private async void OnUpdate()
|
||||||
{
|
{
|
||||||
Stopwatch stopwatch = new();
|
try
|
||||||
stopwatch.Start();
|
{
|
||||||
//var result = await _httpClient.GetStringAsync(url.Value);
|
if (_enabled)
|
||||||
var response = await _httpClient.GetAsync(url.Value, _cancellationToken);
|
{
|
||||||
var result =await response.Content.ReadAsStringAsync();
|
|
||||||
_cancellationToken.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
stopwatch.Stop();
|
if (overrideResponse.Allow)
|
||||||
time =System.TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalSeconds;
|
{
|
||||||
await UniTask.SwitchToMainThread(_cancellationToken);
|
await UniTask.SwitchToMainThread();
|
||||||
if (response.StatusCode is not System.Net.HttpStatusCode.OK)
|
try
|
||||||
{
|
{
|
||||||
onException.Invoke(result);
|
output.Invoke(overrideResponse.Value);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
isConnected = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Stopwatch stopwatch = new();
|
||||||
|
stopwatch.Start();
|
||||||
|
//var result = await _httpClient.GetStringAsync(url.Value);
|
||||||
|
var response = await _httpClient.GetAsync(url.Value,destroyCancellationToken);
|
||||||
|
if (destroyCancellationToken.IsCancellationRequested) return;
|
||||||
|
var result =await response.Content.ReadAsStringAsync();
|
||||||
|
if (destroyCancellationToken.IsCancellationRequested) return;
|
||||||
|
|
||||||
|
stopwatch.Stop();
|
||||||
|
time =System.TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalSeconds;
|
||||||
|
|
||||||
|
await UniTask.SwitchToMainThread();
|
||||||
|
if (destroyCancellationToken.IsCancellationRequested) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var length = int.Parse(response.Content.Headers.First(h => h.Key.Equals("Content-Length")).Value.First());
|
||||||
|
onCalculateLength.Invoke(length);
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.StatusCode is not System.Net.HttpStatusCode.OK)
|
||||||
|
{
|
||||||
|
onException.Invoke(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
output.Invoke(result);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isConnected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
catch(OperationCanceledException){}
|
||||||
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
output.Invoke(result);
|
BIT4Log.LogException(e);
|
||||||
|
isConnected = false;
|
||||||
}
|
}
|
||||||
if(timer.AutoReset==false)
|
|
||||||
|
if (timer.AutoReset == false)
|
||||||
|
{
|
||||||
|
if(destroyCancellationToken.IsCancellationRequested)return;
|
||||||
timer.Start();
|
timer.Start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "BITKit.MarkSystem.Runtime",
|
||||||
|
"rootNamespace": "",
|
||||||
|
"references": [
|
||||||
|
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||||
|
"GUID:6ef4ed8ff60a7aa4bb60a8030e6f4008",
|
||||||
|
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
|
||||||
|
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||||
|
"GUID:0b8afac07cb6a864385843f87eaa0e3f"
|
||||||
|
],
|
||||||
|
"includePlatforms": [],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": false,
|
||||||
|
"overrideReferences": false,
|
||||||
|
"precompiledReferences": [],
|
||||||
|
"autoReferenced": true,
|
||||||
|
"defineConstraints": [],
|
||||||
|
"versionDefines": [],
|
||||||
|
"noEngineReferences": false
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: a8172872d3daab147bc7fd15fd3a97a6
|
guid: 8915fe727b166284f9a8cbe958b03a05
|
||||||
AssemblyDefinitionImporter:
|
AssemblyDefinitionImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
userData:
|
userData:
|
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 0fe70d1be19be44f9929fd63250df79f
|
guid: 208a5380beb526044819d512687a0eaf
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
@@ -2,14 +2,11 @@
|
|||||||
"name": "BITKit.MarkSystem",
|
"name": "BITKit.MarkSystem",
|
||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [
|
"references": [
|
||||||
"GUID:a209c53514018594f9f482516f2a6781",
|
|
||||||
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
|
|
||||||
"GUID:66d2ae14764cc7d49aad4b16930747c0",
|
|
||||||
"GUID:6ef4ed8ff60a7aa4bb60a8030e6f4008",
|
|
||||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
|
||||||
"GUID:be17a8778dbfe454890ed8279279e153",
|
|
||||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||||
"GUID:9400d40641bab5b4a9702f65bf5c6eb5"
|
"GUID:6ef4ed8ff60a7aa4bb60a8030e6f4008",
|
||||||
|
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
|
||||||
|
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||||
|
"GUID:d8b63aba1907145bea998dd612889d6b"
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
@@ -17,9 +14,7 @@
|
|||||||
"overrideReferences": false,
|
"overrideReferences": false,
|
||||||
"precompiledReferences": [],
|
"precompiledReferences": [],
|
||||||
"autoReferenced": true,
|
"autoReferenced": true,
|
||||||
"defineConstraints": [
|
"defineConstraints": [],
|
||||||
"ODIN_INSPECTOR"
|
|
||||||
],
|
|
||||||
"versionDefines": [],
|
"versionDefines": [],
|
||||||
"noEngineReferences": false
|
"noEngineReferences": false
|
||||||
}
|
}
|
28
Src/Unity/Scripts/MarkSystem/Core/IMarkSystem.cs
Normal file
28
Src/Unity/Scripts/MarkSystem/Core/IMarkSystem.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace BITKit.MarkSystem
|
||||||
|
{
|
||||||
|
public interface IMarkObject
|
||||||
|
{
|
||||||
|
public int Id { get; }
|
||||||
|
public Vector3 Position { get; }
|
||||||
|
public object Object { get; }
|
||||||
|
}
|
||||||
|
public interface IMarkSystem
|
||||||
|
{
|
||||||
|
public void Register(IMarkObject markObject);
|
||||||
|
public void UnRegister(IMarkObject markObject);
|
||||||
|
}
|
||||||
|
public class MarkObject : IMarkObject
|
||||||
|
{
|
||||||
|
public override bool Equals(object obj) => obj is MarkObject x && x.Id == Id;
|
||||||
|
public override int GetHashCode() => Id.GetHashCode();
|
||||||
|
private static int count;
|
||||||
|
public int Id { get; } = count++;
|
||||||
|
public Vector3 Position { get; set; }
|
||||||
|
public object Object { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: d538ed72a7d2543d390cf79dbb36413c
|
guid: 26e45143692a3de45b4efef997c74811
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
@@ -1,125 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using BITKit.SubSystems;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace BITKit.Mark
|
|
||||||
{
|
|
||||||
|
|
||||||
public interface IMarkObject
|
|
||||||
{
|
|
||||||
string GetID();
|
|
||||||
string GetDisplay();
|
|
||||||
Vector3 GetPostion();
|
|
||||||
bool GetAcitve();
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IMarkSystem
|
|
||||||
{
|
|
||||||
event Action<IMarkObject> OnAdd;
|
|
||||||
event Action<IMarkObject> OnUpdate;
|
|
||||||
event Action<IMarkObject> OnRemove;
|
|
||||||
void Add(IMarkObject markObject);
|
|
||||||
void Remove(IMarkObject markObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class MarkSystemMonoProxy:IMarkSystem
|
|
||||||
{
|
|
||||||
[SerializeReference] private MonoBehaviour monoBehaviour;
|
|
||||||
private IMarkSystem _markSystemImplementation=>monoBehaviour as IMarkSystem;
|
|
||||||
public event Action<IMarkObject> OnAdd
|
|
||||||
{
|
|
||||||
add => _markSystemImplementation.OnAdd += value;
|
|
||||||
remove => _markSystemImplementation.OnAdd -= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public event Action<IMarkObject> OnUpdate
|
|
||||||
{
|
|
||||||
add => _markSystemImplementation.OnUpdate += value;
|
|
||||||
remove => _markSystemImplementation.OnUpdate -= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public event Action<IMarkObject> OnRemove
|
|
||||||
{
|
|
||||||
add => _markSystemImplementation.OnRemove += value;
|
|
||||||
remove => _markSystemImplementation.OnRemove -= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(IMarkObject markObject)
|
|
||||||
{
|
|
||||||
_markSystemImplementation.Add(markObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Remove(IMarkObject markObject)
|
|
||||||
{
|
|
||||||
_markSystemImplementation.Remove(markObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class MarkSystemSingleton:IMarkSystem
|
|
||||||
{
|
|
||||||
private IMarkSystem _markSystemImplementation=>MarkSystem.Singleton;
|
|
||||||
public event Action<IMarkObject> OnAdd
|
|
||||||
{
|
|
||||||
add => _markSystemImplementation.OnAdd += value;
|
|
||||||
remove => _markSystemImplementation.OnAdd -= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public event Action<IMarkObject> OnUpdate
|
|
||||||
{
|
|
||||||
add => _markSystemImplementation.OnUpdate += value;
|
|
||||||
remove => _markSystemImplementation.OnUpdate -= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public event Action<IMarkObject> OnRemove
|
|
||||||
{
|
|
||||||
add => _markSystemImplementation.OnRemove += value;
|
|
||||||
remove => _markSystemImplementation.OnRemove -= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(IMarkObject markObject)
|
|
||||||
{
|
|
||||||
_markSystemImplementation.Add(markObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Remove(IMarkObject markObject)
|
|
||||||
{
|
|
||||||
_markSystemImplementation.Remove(markObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public class MarkSystem : MonoBehaviour,IMarkSystem
|
|
||||||
{
|
|
||||||
internal static IMarkSystem Singleton { get; private set; }
|
|
||||||
public event Action<IMarkObject> OnAdd;
|
|
||||||
public event Action<IMarkObject> OnUpdate;
|
|
||||||
public event Action<IMarkObject> OnRemove;
|
|
||||||
List<IMarkObject> markObjects = new();
|
|
||||||
public void Add(IMarkObject markObject)
|
|
||||||
{
|
|
||||||
markObjects.Add(markObject);
|
|
||||||
OnAdd?.Invoke(markObject);
|
|
||||||
}
|
|
||||||
public void Remove(IMarkObject markObject)
|
|
||||||
{
|
|
||||||
markObjects.TryRemove(markObject);
|
|
||||||
OnRemove?.Invoke(markObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Awake()
|
|
||||||
{
|
|
||||||
Singleton = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Update()
|
|
||||||
{
|
|
||||||
foreach (var markObject in markObjects.ToArray())
|
|
||||||
{
|
|
||||||
OnUpdate?.Invoke(markObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,129 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
using BITKit.UX;
|
|
||||||
using BITKit.SubSystems;
|
|
||||||
using UnityEngine.UIElements;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Threading;
|
|
||||||
namespace BITKit.Mark
|
|
||||||
{
|
|
||||||
public class MarkSystemUIToolkit : MonoBehaviour
|
|
||||||
{
|
|
||||||
public UXElement element;
|
|
||||||
[SerializeField,SerializeReference, SubclassSelector] private References className;
|
|
||||||
[SerializeField, SerializeReference, SubclassSelector]
|
|
||||||
private IMarkSystem markSystem;
|
|
||||||
Dictionary<string, Label> dictionary = new();
|
|
||||||
IPanel panel;
|
|
||||||
CancellationToken cancellationToken;
|
|
||||||
void Awake()
|
|
||||||
{
|
|
||||||
cancellationToken = gameObject.GetCancellationTokenOnDestroy();
|
|
||||||
}
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
panel = element.GetVisualElement().panel;
|
|
||||||
if (markSystem is not null)
|
|
||||||
{
|
|
||||||
markSystem.OnAdd += OnAdd;
|
|
||||||
markSystem.OnUpdate += OnUpdate;
|
|
||||||
markSystem.OnRemove += OnRemove;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void OnDestroy()
|
|
||||||
{
|
|
||||||
if (markSystem is not null)
|
|
||||||
{
|
|
||||||
markSystem.OnAdd -= OnAdd;
|
|
||||||
markSystem.OnUpdate -= OnUpdate;
|
|
||||||
markSystem.OnRemove -= OnRemove;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void OnAdd(IMarkObject markObject)
|
|
||||||
{
|
|
||||||
GetOrCreate(markObject.GetID());
|
|
||||||
}
|
|
||||||
async void OnRemove(IMarkObject markObject)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await UniTask.SwitchToMainThread(cancellationToken);
|
|
||||||
if (dictionary.TryGetValue(markObject.GetID(), out var label))
|
|
||||||
{
|
|
||||||
element.GetVisualElement().Remove(label);
|
|
||||||
dictionary.Remove(markObject.GetID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (System.Exception e)
|
|
||||||
{
|
|
||||||
if (e is not OperationCanceledException)
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
async void OnUpdate(IMarkObject markObject)
|
|
||||||
{
|
|
||||||
var cameraTrans = Camera.main.transform;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await UniTask.SwitchToMainThread();
|
|
||||||
var active = markObject.GetAcitve();
|
|
||||||
var label = GetOrCreate(markObject.GetID());
|
|
||||||
if (active)
|
|
||||||
{
|
|
||||||
var pos = RuntimePanelUtils
|
|
||||||
.CameraTransformWorldToPanel(panel, markObject.GetPostion(), Camera.main);
|
|
||||||
pos.x = (pos.x - label.layout.width / 2);
|
|
||||||
|
|
||||||
Rect elementRect = new()
|
|
||||||
{
|
|
||||||
position = pos,
|
|
||||||
size = label.layout.size,
|
|
||||||
};
|
|
||||||
label.text = markObject.GetDisplay();
|
|
||||||
label.transform.position = pos;
|
|
||||||
if (Vector3.Dot(cameraTrans.forward, markObject.GetPostion() - cameraTrans.position) > 0)
|
|
||||||
{
|
|
||||||
label.SetActive(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
label.SetActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
label.SetActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (System.Exception)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Label GetOrCreate(string id)
|
|
||||||
{
|
|
||||||
if (dictionary.TryGetValue(id, out var label))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
label = new();
|
|
||||||
label.AddToClassList(className);
|
|
||||||
label.style.position = Position.Absolute;
|
|
||||||
dictionary.Add(id, label);
|
|
||||||
element.GetVisualElement().Add(label);
|
|
||||||
}
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
52
Src/Unity/Scripts/MarkSystem/UXMarkSystem.cs
Normal file
52
Src/Unity/Scripts/MarkSystem/UXMarkSystem.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using BITKit.MarkSystem;
|
||||||
|
using I18N.Other;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
|
namespace BITKit.UX
|
||||||
|
{
|
||||||
|
[CustomType(typeof(IMarkSystem))]
|
||||||
|
public class UXMarkSystem : MonoBehaviour,IMarkSystem
|
||||||
|
{
|
||||||
|
[SerializeField] private VisualTreeAsset template;
|
||||||
|
|
||||||
|
[UXBindPath("mark-container")]
|
||||||
|
private VisualElement _container;
|
||||||
|
|
||||||
|
private readonly CacheList<IMarkObject> _markObjects = new();
|
||||||
|
private readonly ConcurrentDictionary<int,VisualElement> _dictionary = new();
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
DI.Register<IMarkSystem>(this);
|
||||||
|
UXUtils.Inject(this);
|
||||||
|
_container.Clear();
|
||||||
|
}
|
||||||
|
public void Register(IMarkObject markObject)
|
||||||
|
{
|
||||||
|
_markObjects.Add(markObject);
|
||||||
|
_dictionary.GetOrAdd(markObject.Id,Create);
|
||||||
|
}
|
||||||
|
public void UnRegister(IMarkObject markObject)
|
||||||
|
{
|
||||||
|
_markObjects.Remove(markObject);
|
||||||
|
_dictionary.TryRemove(markObject.Id,out var x);
|
||||||
|
x.RemoveFromHierarchy();
|
||||||
|
}
|
||||||
|
private void LateUpdate()
|
||||||
|
{
|
||||||
|
foreach (var x in _markObjects.ValueArray)
|
||||||
|
{
|
||||||
|
_dictionary[x.Id].SetPosition(x.Position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private VisualElement Create(int id)
|
||||||
|
{
|
||||||
|
return _container.Create(template);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Src/Unity/Scripts/MarkSystem/UXMarkSystem.cs.meta
Normal file
11
Src/Unity/Scripts/MarkSystem/UXMarkSystem.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3cd5204b8318b3d408d1e2fc2818bf79
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -16,7 +16,6 @@ namespace BITKit.Mod
|
|||||||
public class UnityModService : MonoBehaviour
|
public class UnityModService : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeReference,SubclassSelector] private IReference[] referencedAssemblies;
|
[SerializeReference,SubclassSelector] private IReference[] referencedAssemblies;
|
||||||
[SerializeField] private bool loadLocalPackageOnStart;
|
|
||||||
private async void Start()
|
private async void Start()
|
||||||
{
|
{
|
||||||
DI.TryGet<IUXWaiting>(out var waiting);
|
DI.TryGet<IUXWaiting>(out var waiting);
|
||||||
@@ -57,8 +56,6 @@ namespace BITKit.Mod
|
|||||||
|
|
||||||
destroyCancellationToken.Register(ModService.Dispose);
|
destroyCancellationToken.Register(ModService.Dispose);
|
||||||
|
|
||||||
if (!loadLocalPackageOnStart) return;
|
|
||||||
|
|
||||||
ModService.OnPackageLoad+=OnPackageLoad;
|
ModService.OnPackageLoad+=OnPackageLoad;
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,59 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Unity.Mathematics;
|
|
||||||
|
|
||||||
namespace NativeQuadTree
|
|
||||||
{
|
|
||||||
[Serializable]
|
|
||||||
public struct AABB2D {
|
|
||||||
public float2 Center;
|
|
||||||
public float2 Extents;
|
|
||||||
|
|
||||||
public float2 Size => Extents * 2;
|
|
||||||
public float2 Min => Center - Extents;
|
|
||||||
public float2 Max => Center + Extents;
|
|
||||||
|
|
||||||
public AABB2D(float2 center, float2 extents)
|
|
||||||
{
|
|
||||||
Center = center;
|
|
||||||
Extents = extents;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Contains(float2 point) {
|
|
||||||
if (point[0] < Center[0] - Extents[0]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (point[0] > Center[0] + Extents[0]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (point[1] < Center[1] - Extents[1]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (point[1] > Center[1] + Extents[1]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Contains(AABB2D b) {
|
|
||||||
return Contains(b.Center + new float2(-b.Extents.x, -b.Extents.y)) &&
|
|
||||||
Contains(b.Center + new float2(-b.Extents.x, b.Extents.y)) &&
|
|
||||||
Contains(b.Center + new float2(b.Extents.x, -b.Extents.y)) &&
|
|
||||||
Contains(b.Center + new float2(b.Extents.x, b.Extents.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Intersects(AABB2D b)
|
|
||||||
{
|
|
||||||
//bool noOverlap = Min[0] > b.Max[0] ||
|
|
||||||
// b.Min[0] > Max[0]||
|
|
||||||
// Min[1] > b.Max[1] ||
|
|
||||||
// b.Min[1] > Max[1];
|
|
||||||
//
|
|
||||||
//return !noOverlap;
|
|
||||||
|
|
||||||
return (math.abs(Center[0] - b.Center[0]) < (Extents[0] + b.Extents[0])) &&
|
|
||||||
(math.abs(Center[1] - b.Center[1]) < (Extents[1] + b.Extents[1]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: aede0b75cc8640798d9a285521f5d6d1
|
|
||||||
timeCreated: 1578858902
|
|
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "BITKit.NativeQuadTree.Runtime",
|
|
||||||
"rootNamespace": "",
|
|
||||||
"references": [
|
|
||||||
"GUID:d8b63aba1907145bea998dd612889d6b",
|
|
||||||
"GUID:e0cd26848372d4e5c891c569017e11f1",
|
|
||||||
"GUID:2665a8d13d1b3f18800f46e256720795"
|
|
||||||
],
|
|
||||||
"includePlatforms": [],
|
|
||||||
"excludePlatforms": [],
|
|
||||||
"allowUnsafeCode": true,
|
|
||||||
"overrideReferences": false,
|
|
||||||
"precompiledReferences": [],
|
|
||||||
"autoReferenced": true,
|
|
||||||
"defineConstraints": [],
|
|
||||||
"versionDefines": [],
|
|
||||||
"noEngineReferences": false
|
|
||||||
}
|
|
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "BITKit.NativeQuadTree.Editor",
|
|
||||||
"rootNamespace": "",
|
|
||||||
"references": [
|
|
||||||
"GUID:d8b63aba1907145bea998dd612889d6b",
|
|
||||||
"GUID:e0cd26848372d4e5c891c569017e11f1",
|
|
||||||
"GUID:a9eec99827e569e45bfe3e5ea7494591",
|
|
||||||
"GUID:27619889b8ba8c24980f49ee34dbb44a",
|
|
||||||
"GUID:0acc523941302664db1f4e527237feb3"
|
|
||||||
],
|
|
||||||
"includePlatforms": [],
|
|
||||||
"excludePlatforms": [],
|
|
||||||
"allowUnsafeCode": false,
|
|
||||||
"overrideReferences": true,
|
|
||||||
"precompiledReferences": [
|
|
||||||
"nunit.framework.dll"
|
|
||||||
],
|
|
||||||
"autoReferenced": true,
|
|
||||||
"defineConstraints": [
|
|
||||||
"UNITY_EDITOR"
|
|
||||||
],
|
|
||||||
"versionDefines": [],
|
|
||||||
"noEngineReferences": false
|
|
||||||
}
|
|
@@ -1,61 +0,0 @@
|
|||||||
using NativeQuadTree;
|
|
||||||
using Unity.Collections;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class QuadTreeDrawer : EditorWindow
|
|
||||||
{
|
|
||||||
[MenuItem("Window/QuadTreeDrawer")]
|
|
||||||
static void Init()
|
|
||||||
{
|
|
||||||
GetWindow(typeof(QuadTreeDrawer)).Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Draw<T>(NativeQuadTree<T> quadTree) where T : unmanaged
|
|
||||||
{
|
|
||||||
QuadTreeDrawer window = (QuadTreeDrawer)GetWindow(typeof(QuadTreeDrawer));
|
|
||||||
window.DoDraw(quadTree, default, default);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DrawWithResults<T>(QuadTreeJobs.RangeQueryJob<T> queryJob) where T : unmanaged
|
|
||||||
{
|
|
||||||
QuadTreeDrawer window = (QuadTreeDrawer)GetWindow(typeof(QuadTreeDrawer));
|
|
||||||
window.DoDraw(queryJob);
|
|
||||||
}
|
|
||||||
|
|
||||||
[SerializeField]
|
|
||||||
Color[][] pixels;
|
|
||||||
|
|
||||||
void DoDraw<T>(NativeQuadTree<T> quadTree, NativeList<QuadElement<T>> results, AABB2D bounds) where T : unmanaged
|
|
||||||
{
|
|
||||||
pixels = new Color[256][];
|
|
||||||
for (var i = 0; i < pixels.Length; i++)
|
|
||||||
{
|
|
||||||
pixels[i] = new Color[256];
|
|
||||||
}
|
|
||||||
NativeQuadTree<T>.Draw(quadTree, results, bounds, pixels);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoDraw<T>(QuadTreeJobs.RangeQueryJob<T> queryJob) where T : unmanaged
|
|
||||||
{
|
|
||||||
DoDraw(queryJob.QuadTree, queryJob.Results, queryJob.Bounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnGUI()
|
|
||||||
{
|
|
||||||
if(pixels != null)
|
|
||||||
{
|
|
||||||
var texture = new Texture2D(256, 256);
|
|
||||||
for (var x = 0; x < pixels.Length; x++)
|
|
||||||
{
|
|
||||||
for (int y = 0; y < pixels[x].Length; y++)
|
|
||||||
{
|
|
||||||
texture.SetPixel(x, y, pixels[x][y]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
texture.Apply();
|
|
||||||
|
|
||||||
GUI.DrawTexture(new Rect(0, 0, position.width, position.height), texture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 832305bf6e10412ab212389d06708fea
|
|
||||||
timeCreated: 1578854647
|
|
@@ -1,134 +0,0 @@
|
|||||||
using System.Diagnostics;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NativeQuadTree;
|
|
||||||
using Unity.Burst;
|
|
||||||
using Unity.Collections;
|
|
||||||
using Unity.Jobs;
|
|
||||||
using Unity.Mathematics;
|
|
||||||
using UnityEngine;
|
|
||||||
using Debug = UnityEngine.Debug;
|
|
||||||
using Random = UnityEngine.Random;
|
|
||||||
|
|
||||||
public class QuadTreeTests
|
|
||||||
{
|
|
||||||
AABB2D Bounds => new AABB2D(0, 1000);
|
|
||||||
|
|
||||||
float2[] GetValues()
|
|
||||||
{
|
|
||||||
Random.InitState(0);
|
|
||||||
var values = new float2[20000];
|
|
||||||
|
|
||||||
for (int x = 0; x < values.Length; x++)
|
|
||||||
{
|
|
||||||
var val = new int2((int) Random.Range(-900, 900), (int) Random.Range(-900, 900));
|
|
||||||
values[x] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void InsertTriggerDivideBulk()
|
|
||||||
{
|
|
||||||
var values = GetValues();
|
|
||||||
|
|
||||||
var elements = new NativeArray<QuadElement<int>>(values.Length, Allocator.TempJob);
|
|
||||||
|
|
||||||
for (int i = 0; i < values.Length; i++)
|
|
||||||
{
|
|
||||||
elements[i] = new QuadElement<int>
|
|
||||||
{
|
|
||||||
pos = values[i],
|
|
||||||
element = i
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
using var quadtree = new NativeQuadTree<int>(Bounds, Allocator.TempJob);
|
|
||||||
var job = new QuadTreeJobs.AddBulkJob<int>
|
|
||||||
{
|
|
||||||
Elements = elements,
|
|
||||||
QuadTree = quadtree,
|
|
||||||
};
|
|
||||||
|
|
||||||
var s = Stopwatch.StartNew();
|
|
||||||
|
|
||||||
job.Run();
|
|
||||||
|
|
||||||
s.Stop();
|
|
||||||
Debug.Log(s.Elapsed.TotalMilliseconds);
|
|
||||||
|
|
||||||
QuadTreeDrawer.Draw(quadtree);
|
|
||||||
elements.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void RangeQueryAfterBulk()
|
|
||||||
{
|
|
||||||
var values = GetValues();
|
|
||||||
|
|
||||||
NativeArray<QuadElement<int>> elements = new NativeArray<QuadElement<int>>(values.Length, Allocator.TempJob);
|
|
||||||
|
|
||||||
for (int i = 0; i < values.Length; i++)
|
|
||||||
{
|
|
||||||
elements[i] = new QuadElement<int>
|
|
||||||
{
|
|
||||||
pos = values[i],
|
|
||||||
element = i
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var quadTree = new NativeQuadTree<int>(Bounds);
|
|
||||||
quadTree.ClearAndBulkInsert(elements);
|
|
||||||
|
|
||||||
var queryJob = new QuadTreeJobs.RangeQueryJob<int>
|
|
||||||
{
|
|
||||||
QuadTree = quadTree,
|
|
||||||
Bounds = new AABB2D(100, 140),
|
|
||||||
Results = new NativeList<QuadElement<int>>(1000, Allocator.TempJob)
|
|
||||||
};
|
|
||||||
|
|
||||||
var s = Stopwatch.StartNew();
|
|
||||||
queryJob.Run();
|
|
||||||
s.Stop();
|
|
||||||
Debug.Log(s.Elapsed.TotalMilliseconds + " result: " + queryJob.Results.Length);
|
|
||||||
|
|
||||||
QuadTreeDrawer.DrawWithResults(queryJob);
|
|
||||||
quadTree.Dispose();
|
|
||||||
elements.Dispose();
|
|
||||||
queryJob.Results.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void InsertTriggerDivideNonBurstBulk()
|
|
||||||
{
|
|
||||||
var values = GetValues();
|
|
||||||
|
|
||||||
var positions = new NativeArray<float2>(values.Length, Allocator.TempJob);
|
|
||||||
var quadTree = new NativeQuadTree<int>(Bounds);
|
|
||||||
|
|
||||||
positions.CopyFrom(values);
|
|
||||||
|
|
||||||
|
|
||||||
NativeArray<QuadElement<int>> elements = new NativeArray<QuadElement<int>>(positions.Length, Allocator.Temp);
|
|
||||||
|
|
||||||
for (int i = 0; i < positions.Length; i++)
|
|
||||||
{
|
|
||||||
elements[i] = new QuadElement<int>
|
|
||||||
{
|
|
||||||
pos = positions[i],
|
|
||||||
element = i
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var s = Stopwatch.StartNew();
|
|
||||||
|
|
||||||
quadTree.ClearAndBulkInsert(elements);
|
|
||||||
|
|
||||||
s.Stop();
|
|
||||||
Debug.Log(s.Elapsed.TotalMilliseconds);
|
|
||||||
|
|
||||||
QuadTreeDrawer.Draw(quadTree);
|
|
||||||
quadTree.Dispose();
|
|
||||||
positions.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,70 +0,0 @@
|
|||||||
namespace NativeQuadTree
|
|
||||||
{
|
|
||||||
public static class LookupTables
|
|
||||||
{
|
|
||||||
public static readonly ushort[] MortonLookup = {
|
|
||||||
// 0 1 100 101 10000 10001 10100 10101
|
|
||||||
0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015,
|
|
||||||
// 1000000 1000001 1000100 1000101 1010000 1010001 1010100 1010101
|
|
||||||
0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055,
|
|
||||||
// etc...
|
|
||||||
0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115,
|
|
||||||
0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155,
|
|
||||||
0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415,
|
|
||||||
0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455,
|
|
||||||
0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515,
|
|
||||||
0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555,
|
|
||||||
0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015,
|
|
||||||
0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055,
|
|
||||||
0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115,
|
|
||||||
0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155,
|
|
||||||
0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415,
|
|
||||||
0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455,
|
|
||||||
0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515,
|
|
||||||
0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555,
|
|
||||||
0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015,
|
|
||||||
0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055,
|
|
||||||
0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115,
|
|
||||||
0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155,
|
|
||||||
0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415,
|
|
||||||
0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455,
|
|
||||||
0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515,
|
|
||||||
0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555,
|
|
||||||
0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015,
|
|
||||||
0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055,
|
|
||||||
0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115,
|
|
||||||
0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155,
|
|
||||||
0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415,
|
|
||||||
0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455,
|
|
||||||
0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515,
|
|
||||||
0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555
|
|
||||||
};
|
|
||||||
|
|
||||||
public static readonly int[] DepthSizeLookup =
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1+2*2,
|
|
||||||
1+2*2+4*4,
|
|
||||||
1+2*2+4*4+8*8,
|
|
||||||
1+2*2+4*4+8*8+16*16,
|
|
||||||
1+2*2+4*4+8*8+16*16+32*32,
|
|
||||||
1+2*2+4*4+8*8+16*16+32*32+64*64,
|
|
||||||
1+2*2+4*4+8*8+16*16+32*32+64*64+128*128,
|
|
||||||
1+2*2+4*4+8*8+16*16+32*32+64*64+128*128+256*256,
|
|
||||||
};
|
|
||||||
|
|
||||||
public static readonly int[] DepthLookup =
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
2,
|
|
||||||
4,
|
|
||||||
8,
|
|
||||||
16,
|
|
||||||
32,
|
|
||||||
64,
|
|
||||||
128,
|
|
||||||
256,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 3bf2086533d64f3b93c5bf841ebc44b6
|
|
||||||
timeCreated: 1580073533
|
|
@@ -1,238 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Unity.Collections;
|
|
||||||
using Unity.Collections.LowLevel.Unsafe;
|
|
||||||
using Unity.Mathematics;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace NativeQuadTree
|
|
||||||
{
|
|
||||||
// Represents an element node in the quadtree.
|
|
||||||
public struct QuadElement<T> where T : unmanaged
|
|
||||||
{
|
|
||||||
public float2 pos;
|
|
||||||
public T element;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct QuadNode
|
|
||||||
{
|
|
||||||
// Points to this node's first child index in elements
|
|
||||||
public int firstChildIndex;
|
|
||||||
|
|
||||||
// Number of elements in the leaf
|
|
||||||
public short count;
|
|
||||||
public bool isLeaf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A QuadTree aimed to be used with Burst, supports fast bulk insertion and querying.
|
|
||||||
///
|
|
||||||
/// TODO:
|
|
||||||
/// - Better test coverage
|
|
||||||
/// - Automated depth / bounds / max leaf elements calculation
|
|
||||||
/// </summary>
|
|
||||||
public unsafe partial struct NativeQuadTree<T> : IDisposable where T : unmanaged
|
|
||||||
{
|
|
||||||
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
|
||||||
// Safety
|
|
||||||
AtomicSafetyHandle safetyHandle;
|
|
||||||
[NativeSetClassTypeToNullOnSchedule]
|
|
||||||
DisposeSentinel disposeSentinel;
|
|
||||||
#endif
|
|
||||||
// Data
|
|
||||||
[NativeDisableUnsafePtrRestriction]
|
|
||||||
UnsafeList<QuadElement<T>>* elements;
|
|
||||||
|
|
||||||
[NativeDisableUnsafePtrRestriction]
|
|
||||||
UnsafeList<int>* lookup;
|
|
||||||
|
|
||||||
[NativeDisableUnsafePtrRestriction]
|
|
||||||
UnsafeList<QuadNode>* nodes;
|
|
||||||
|
|
||||||
int elementsCount;
|
|
||||||
|
|
||||||
int maxDepth;
|
|
||||||
short maxLeafElements;
|
|
||||||
|
|
||||||
AABB2D bounds; // NOTE: Currently assuming uniform
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new QuadTree.
|
|
||||||
/// - Ensure the bounds are not way bigger than needed, otherwise the buckets are very off. Probably best to calculate bounds
|
|
||||||
/// - The higher the depth, the larger the overhead, it especially goes up at a depth of 7/8
|
|
||||||
/// </summary>
|
|
||||||
public NativeQuadTree(AABB2D bounds, Allocator allocator = Allocator.Temp, int maxDepth = 6, short maxLeafElements = 16,
|
|
||||||
int initialElementsCapacity = 256
|
|
||||||
) : this()
|
|
||||||
{
|
|
||||||
this.bounds = bounds;
|
|
||||||
this.maxDepth = maxDepth;
|
|
||||||
this.maxLeafElements = maxLeafElements;
|
|
||||||
elementsCount = 0;
|
|
||||||
|
|
||||||
if(maxDepth > 8)
|
|
||||||
{
|
|
||||||
// Currently no support for higher depths, the morton code lookup tables would have to support it
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
|
||||||
// TODO: Find out what the equivalent of this is in latest entities
|
|
||||||
// CollectionHelper.CheckIsUnmanaged<T>();
|
|
||||||
DisposeSentinel.Create(out safetyHandle, out disposeSentinel, 1, allocator);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Allocate memory for every depth, the nodes on all depths are stored in a single continuous array
|
|
||||||
var totalSize = LookupTables.DepthSizeLookup[maxDepth+1];
|
|
||||||
|
|
||||||
lookup = UnsafeList<int>.Create(
|
|
||||||
totalSize,
|
|
||||||
allocator,
|
|
||||||
NativeArrayOptions.ClearMemory);
|
|
||||||
|
|
||||||
nodes = UnsafeList<QuadNode>.Create(
|
|
||||||
totalSize,
|
|
||||||
allocator,
|
|
||||||
NativeArrayOptions.ClearMemory);
|
|
||||||
|
|
||||||
elements = UnsafeList<QuadElement<T>>.Create(
|
|
||||||
initialElementsCapacity,
|
|
||||||
allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearAndBulkInsert(NativeArray<QuadElement<T>> incomingElements)
|
|
||||||
{
|
|
||||||
// Always have to clear before bulk insert as otherwise the lookup and node allocations need to account
|
|
||||||
// for existing data.
|
|
||||||
Clear();
|
|
||||||
|
|
||||||
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
|
||||||
AtomicSafetyHandle.CheckWriteAndBumpSecondaryVersion(safetyHandle);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Resize if needed
|
|
||||||
if(elements->Capacity < elementsCount + incomingElements.Length)
|
|
||||||
{
|
|
||||||
elements->Resize(math.max(incomingElements.Length, elements->Capacity*2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare morton codes
|
|
||||||
var mortonCodes = new NativeArray<int>(incomingElements.Length, Allocator.Temp);
|
|
||||||
var depthExtentsScaling = LookupTables.DepthLookup[maxDepth] / bounds.Extents;
|
|
||||||
for (var i = 0; i < incomingElements.Length; i++)
|
|
||||||
{
|
|
||||||
var incPos = incomingElements[i].pos;
|
|
||||||
incPos -= bounds.Center; // Offset by center
|
|
||||||
incPos.y = -incPos.y; // World -> array
|
|
||||||
var pos = (incPos + bounds.Extents) * .5f; // Make positive
|
|
||||||
// Now scale into available space that belongs to the depth
|
|
||||||
pos *= depthExtentsScaling;
|
|
||||||
// And interleave the bits for the morton code
|
|
||||||
mortonCodes[i] = (LookupTables.MortonLookup[(int) pos.x] | (LookupTables.MortonLookup[(int) pos.y] << 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Index total child element count per node (total, so parent's counts include those of child nodes)
|
|
||||||
for (var i = 0; i < mortonCodes.Length; i++)
|
|
||||||
{
|
|
||||||
int atIndex = 0;
|
|
||||||
for (int depth = 0; depth <= maxDepth; depth++)
|
|
||||||
{
|
|
||||||
// Increment the node on this depth that this element is contained in
|
|
||||||
(*(int*) ((IntPtr) lookup->Ptr + atIndex * sizeof (int)))++;
|
|
||||||
atIndex = IncrementIndex(depth, mortonCodes, i, atIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare the tree leaf nodes
|
|
||||||
RecursivePrepareLeaves(1, 1);
|
|
||||||
|
|
||||||
// Add elements to leaf nodes
|
|
||||||
for (var i = 0; i < incomingElements.Length; i++)
|
|
||||||
{
|
|
||||||
int atIndex = 0;
|
|
||||||
|
|
||||||
for (int depth = 0; depth <= maxDepth; depth++)
|
|
||||||
{
|
|
||||||
var node = UnsafeUtility.ReadArrayElement<QuadNode>(nodes->Ptr, atIndex);
|
|
||||||
if(node.isLeaf)
|
|
||||||
{
|
|
||||||
// We found a leaf, add this element to it and move to the next element
|
|
||||||
UnsafeUtility.WriteArrayElement(elements->Ptr, node.firstChildIndex + node.count, incomingElements[i]);
|
|
||||||
node.count++;
|
|
||||||
UnsafeUtility.WriteArrayElement(nodes->Ptr, atIndex, node);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// No leaf found, we keep going deeper until we find one
|
|
||||||
atIndex = IncrementIndex(depth, mortonCodes, i, atIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mortonCodes.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
int IncrementIndex(int depth, NativeArray<int> mortonCodes, int i, int atIndex)
|
|
||||||
{
|
|
||||||
var atDepth = math.max(0, maxDepth - depth);
|
|
||||||
// Shift to the right and only get the first two bits
|
|
||||||
int shiftedMortonCode = (mortonCodes[i] >> ((atDepth - 1) * 2)) & 0b11;
|
|
||||||
// so the index becomes that... (0,1,2,3)
|
|
||||||
atIndex += LookupTables.DepthSizeLookup[atDepth] * shiftedMortonCode;
|
|
||||||
atIndex++; // offset for self
|
|
||||||
return atIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RecursivePrepareLeaves(int prevOffset, int depth)
|
|
||||||
{
|
|
||||||
for (int l = 0; l < 4; l++)
|
|
||||||
{
|
|
||||||
var at = prevOffset + l * LookupTables.DepthSizeLookup[maxDepth - depth+1];
|
|
||||||
|
|
||||||
var elementCount = UnsafeUtility.ReadArrayElement<int>(lookup->Ptr, at);
|
|
||||||
|
|
||||||
if(elementCount > maxLeafElements && depth < maxDepth)
|
|
||||||
{
|
|
||||||
// There's more elements than allowed on this node so keep going deeper
|
|
||||||
RecursivePrepareLeaves(at+1, depth+1);
|
|
||||||
}
|
|
||||||
else if(elementCount != 0)
|
|
||||||
{
|
|
||||||
// We either hit max depth or there's less than the max elements on this node, make it a leaf
|
|
||||||
var node = new QuadNode {firstChildIndex = elementsCount, count = 0, isLeaf = true };
|
|
||||||
UnsafeUtility.WriteArrayElement(nodes->Ptr, at, node);
|
|
||||||
elementsCount += elementCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RangeQuery(AABB2D bounds, NativeList<QuadElement<T>> results)
|
|
||||||
{
|
|
||||||
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
|
||||||
AtomicSafetyHandle.CheckReadAndThrow(safetyHandle);
|
|
||||||
#endif
|
|
||||||
new QuadTreeRangeQuery().Query(this, bounds, results);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
|
||||||
AtomicSafetyHandle.CheckWriteAndBumpSecondaryVersion(safetyHandle);
|
|
||||||
#endif
|
|
||||||
UnsafeUtility.MemClear(lookup->Ptr, lookup->Capacity * UnsafeUtility.SizeOf<int>());
|
|
||||||
UnsafeUtility.MemClear(nodes->Ptr, nodes->Capacity * UnsafeUtility.SizeOf<QuadNode>());
|
|
||||||
UnsafeUtility.MemClear(elements->Ptr, elements->Capacity * UnsafeUtility.SizeOf<QuadElement<T>>());
|
|
||||||
elementsCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
UnsafeList<QuadElement<T>>.Destroy(elements);
|
|
||||||
elements = null;
|
|
||||||
UnsafeList<int>.Destroy(lookup);
|
|
||||||
lookup = null;
|
|
||||||
UnsafeList<QuadNode>.Destroy(nodes);
|
|
||||||
nodes = null;
|
|
||||||
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
|
||||||
DisposeSentinel.Dispose(ref safetyHandle, ref disposeSentinel);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: b7b8c6b2d8b6d40ee814635e9e882a54
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@@ -1,77 +0,0 @@
|
|||||||
using Unity.Collections;
|
|
||||||
using Unity.Collections.LowLevel.Unsafe;
|
|
||||||
using Unity.Mathematics;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace NativeQuadTree
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Editor drawing of the NativeQuadTree
|
|
||||||
/// </summary>
|
|
||||||
public unsafe partial struct NativeQuadTree<T> where T : unmanaged
|
|
||||||
{
|
|
||||||
public static void Draw(NativeQuadTree<T> tree, NativeList<QuadElement<T>> results, AABB2D range,
|
|
||||||
Color[][] texture)
|
|
||||||
{
|
|
||||||
var widthMult = texture.Length / tree.bounds.Extents.x * 2 / 2 / 2;
|
|
||||||
var heightMult = texture[0].Length / tree.bounds.Extents.y * 2 / 2 / 2;
|
|
||||||
|
|
||||||
var widthAdd = tree.bounds.Center.x + tree.bounds.Extents.x;
|
|
||||||
var heightAdd = tree.bounds.Center.y + tree.bounds.Extents.y;
|
|
||||||
|
|
||||||
for (int i = 0; i < tree.nodes->Capacity; i++)
|
|
||||||
{
|
|
||||||
var node = UnsafeUtility.ReadArrayElement<QuadNode>(tree.nodes->Ptr, i);
|
|
||||||
|
|
||||||
if(node.count > 0)
|
|
||||||
{
|
|
||||||
for (int k = 0; k < node.count; k++)
|
|
||||||
{
|
|
||||||
var element =
|
|
||||||
UnsafeUtility.ReadArrayElement<QuadElement<T>>(tree.elements->Ptr, node.firstChildIndex + k);
|
|
||||||
|
|
||||||
texture[(int) ((element.pos.x + widthAdd) * widthMult)]
|
|
||||||
[(int) ((element.pos.y + heightAdd) * heightMult)] = Color.red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.IsCreated)
|
|
||||||
{
|
|
||||||
foreach (var element in results)
|
|
||||||
{
|
|
||||||
texture[(int)((element.pos.x + widthAdd) * widthMult)]
|
|
||||||
[(int)((element.pos.y + heightAdd) * heightMult)] = Color.green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawBounds(texture, range, tree);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DrawBounds(Color[][] texture, AABB2D bounds, NativeQuadTree<T> tree)
|
|
||||||
{
|
|
||||||
var widthMult = texture.Length / tree.bounds.Extents.x * 2 / 2 / 2;
|
|
||||||
var heightMult = texture[0].Length / tree.bounds.Extents.y * 2 / 2 / 2;
|
|
||||||
|
|
||||||
var widthAdd = tree.bounds.Center.x + tree.bounds.Extents.x;
|
|
||||||
var heightAdd = tree.bounds.Center.y + tree.bounds.Extents.y;
|
|
||||||
|
|
||||||
var top = new float2(bounds.Center.x, bounds.Center.y - bounds.Extents.y);
|
|
||||||
var left = new float2(bounds.Center.x - bounds.Extents.x, bounds.Center.y);
|
|
||||||
|
|
||||||
for (int leftToRight = 0; leftToRight < bounds.Extents.x * 2; leftToRight++)
|
|
||||||
{
|
|
||||||
var poxX = left.x + leftToRight;
|
|
||||||
texture[(int) ((poxX + widthAdd) * widthMult)][(int) ((bounds.Center.y + heightAdd + bounds.Extents.y) * heightMult)] = Color.blue;
|
|
||||||
texture[(int) ((poxX + widthAdd) * widthMult)][(int) ((bounds.Center.y + heightAdd - bounds.Extents.y) * heightMult)] = Color.blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int topToBottom = 0; topToBottom < bounds.Extents.y * 2; topToBottom++)
|
|
||||||
{
|
|
||||||
var posY = top.y + topToBottom;
|
|
||||||
texture[(int) ((bounds.Center.x + widthAdd + bounds.Extents.x) * widthMult)][(int) ((posY + heightAdd) * heightMult)] = Color.blue;
|
|
||||||
texture[(int) ((bounds.Center.x + widthAdd - bounds.Extents.x) * widthMult)][(int) ((posY + heightAdd) * heightMult)] = Color.blue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: e98d676f818a45d9851041ca067a6eab
|
|
||||||
timeCreated: 1580073676
|
|
@@ -1,110 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Unity.Collections;
|
|
||||||
using Unity.Collections.LowLevel.Unsafe;
|
|
||||||
using Unity.Mathematics;
|
|
||||||
|
|
||||||
namespace NativeQuadTree
|
|
||||||
{
|
|
||||||
public unsafe partial struct NativeQuadTree<T> where T : unmanaged
|
|
||||||
{
|
|
||||||
struct QuadTreeRangeQuery
|
|
||||||
{
|
|
||||||
NativeQuadTree<T> tree;
|
|
||||||
|
|
||||||
UnsafeList<T>* fastResults;
|
|
||||||
int count;
|
|
||||||
|
|
||||||
AABB2D bounds;
|
|
||||||
|
|
||||||
public void Query(NativeQuadTree<T> tree, AABB2D bounds, NativeList<QuadElement<T>> results)
|
|
||||||
{
|
|
||||||
this.tree = tree;
|
|
||||||
this.bounds = bounds;
|
|
||||||
count = 0;
|
|
||||||
|
|
||||||
// Get pointer to inner list data for faster writing
|
|
||||||
fastResults = (UnsafeList<T>*) NativeListUnsafeUtility.GetInternalListDataPtrUnchecked(ref results);
|
|
||||||
|
|
||||||
RecursiveRangeQuery(tree.bounds, false, 1, 1);
|
|
||||||
|
|
||||||
fastResults->Length = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RecursiveRangeQuery(AABB2D parentBounds, bool parentContained, int prevOffset, int depth)
|
|
||||||
{
|
|
||||||
if(count + 4 * tree.maxLeafElements > fastResults->Capacity)
|
|
||||||
{
|
|
||||||
fastResults->Resize(math.max(fastResults->Capacity * 2, count + 4 * tree.maxLeafElements));
|
|
||||||
}
|
|
||||||
|
|
||||||
var depthSize = LookupTables.DepthSizeLookup[tree.maxDepth - depth+1];
|
|
||||||
for (int l = 0; l < 4; l++)
|
|
||||||
{
|
|
||||||
var childBounds = GetChildBounds(parentBounds, l);
|
|
||||||
|
|
||||||
var contained = parentContained;
|
|
||||||
if(!contained)
|
|
||||||
{
|
|
||||||
if(bounds.Contains(childBounds))
|
|
||||||
{
|
|
||||||
contained = true;
|
|
||||||
}
|
|
||||||
else if(!bounds.Intersects(childBounds))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var at = prevOffset + l * depthSize;
|
|
||||||
|
|
||||||
var elementCount = UnsafeUtility.ReadArrayElement<int>(tree.lookup->Ptr, at);
|
|
||||||
|
|
||||||
if(elementCount > tree.maxLeafElements && depth < tree.maxDepth)
|
|
||||||
{
|
|
||||||
RecursiveRangeQuery(childBounds, contained, at+1, depth+1);
|
|
||||||
}
|
|
||||||
else if(elementCount != 0)
|
|
||||||
{
|
|
||||||
var node = UnsafeUtility.ReadArrayElement<QuadNode>(tree.nodes->Ptr, at);
|
|
||||||
|
|
||||||
if(contained)
|
|
||||||
{
|
|
||||||
var index = (void*) ((IntPtr) tree.elements->Ptr + node.firstChildIndex * UnsafeUtility.SizeOf<QuadElement<T>>());
|
|
||||||
|
|
||||||
UnsafeUtility.MemCpy((void*) ((IntPtr) fastResults->Ptr + count * UnsafeUtility.SizeOf<QuadElement<T>>()),
|
|
||||||
index, node.count * UnsafeUtility.SizeOf<QuadElement<T>>());
|
|
||||||
count += node.count;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int k = 0; k < node.count; k++)
|
|
||||||
{
|
|
||||||
var element = UnsafeUtility.ReadArrayElement<QuadElement<T>>(tree.elements->Ptr, node.firstChildIndex + k);
|
|
||||||
if(bounds.Contains(element.pos))
|
|
||||||
{
|
|
||||||
UnsafeUtility.WriteArrayElement(fastResults->Ptr, count++, element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static AABB2D GetChildBounds(AABB2D parentBounds, int childZIndex)
|
|
||||||
{
|
|
||||||
var half = parentBounds.Extents.x * .5f;
|
|
||||||
|
|
||||||
switch (childZIndex)
|
|
||||||
{
|
|
||||||
case 0: return new AABB2D(new float2(parentBounds.Center.x - half, parentBounds.Center.y + half), half);
|
|
||||||
case 1: return new AABB2D(new float2(parentBounds.Center.x + half, parentBounds.Center.y + half), half);
|
|
||||||
case 2: return new AABB2D(new float2(parentBounds.Center.x - half, parentBounds.Center.y - half), half);
|
|
||||||
case 3: return new AABB2D(new float2(parentBounds.Center.x + half, parentBounds.Center.y - half), half);
|
|
||||||
default: throw new Exception();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 98c569dc7c35745c5bf8a8cbca70fb3b
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@@ -1,54 +0,0 @@
|
|||||||
using Unity.Burst;
|
|
||||||
using Unity.Collections;
|
|
||||||
using Unity.Jobs;
|
|
||||||
|
|
||||||
namespace NativeQuadTree
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Examples on jobs for the NativeQuadTree
|
|
||||||
/// </summary>
|
|
||||||
public static class QuadTreeJobs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Bulk insert many items into the tree
|
|
||||||
/// </summary>
|
|
||||||
[BurstCompile]
|
|
||||||
public struct AddBulkJob<T> : IJob where T : unmanaged
|
|
||||||
{
|
|
||||||
[ReadOnly]
|
|
||||||
public NativeArray<QuadElement<T>> Elements;
|
|
||||||
|
|
||||||
public NativeQuadTree<T> QuadTree;
|
|
||||||
|
|
||||||
public void Execute()
|
|
||||||
{
|
|
||||||
QuadTree.ClearAndBulkInsert(Elements);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Example on how to do a range query, it's better to write your own and do many queries in a batch
|
|
||||||
/// </summary>
|
|
||||||
[BurstCompile]
|
|
||||||
public struct RangeQueryJob<T> : IJob where T : unmanaged
|
|
||||||
{
|
|
||||||
[ReadOnly]
|
|
||||||
public AABB2D Bounds;
|
|
||||||
|
|
||||||
[ReadOnly]
|
|
||||||
public NativeQuadTree<T> QuadTree;
|
|
||||||
|
|
||||||
public NativeList<QuadElement<T>> Results;
|
|
||||||
|
|
||||||
public void Execute()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 1000; i++)
|
|
||||||
{
|
|
||||||
QuadTree.RangeQuery(Bounds, Results);
|
|
||||||
Results.Clear();
|
|
||||||
}
|
|
||||||
QuadTree.RangeQuery(Bounds, Results);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 2815368828aa4ed8934169baddedefd2
|
|
||||||
timeCreated: 1580072573
|
|
@@ -1,2 +0,0 @@
|
|||||||
@import url("unity-theme://default");
|
|
||||||
VisualElement {}
|
|
@@ -3,59 +3,140 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
namespace BITKit
|
namespace BITKit
|
||||||
{
|
{
|
||||||
public interface IClosePoint
|
public interface IClosePoint
|
||||||
{
|
{
|
||||||
|
Vector3 CurrentPoint { get; }
|
||||||
Collider Collider { get; }
|
Collider Collider { get; }
|
||||||
bool TryGetClosePoint(out Vector3 vector3);
|
bool TryGetClosePoint(out Vector3 vector3);
|
||||||
}
|
}
|
||||||
[System.Serializable]
|
[Serializable]
|
||||||
public class GetClosePointFromCollider : IClosePoint
|
public class GetClosePointFromCollider : IClosePoint
|
||||||
{
|
{
|
||||||
public Transform root;
|
[SerializeField] private string name;
|
||||||
public LayerMask layerMask;
|
[SerializeField] private Transform transform;
|
||||||
public float distance;
|
[SerializeField] private Vector3 offset = Vector3.one;
|
||||||
|
[SerializeField] private LayerMask layerMask;
|
||||||
|
[SerializeField] private float distance;
|
||||||
|
[SerializeField] private float minHeight=0.32f;
|
||||||
|
[SerializeField] private float maxHeight = 1f;
|
||||||
|
public Vector3 CurrentPoint { get; set; }
|
||||||
public Collider Collider { get; set; }
|
public Collider Collider { get; set; }
|
||||||
|
private Collider[] _colliders=new Collider[8];
|
||||||
|
private Collider[] _mainCollider=new Collider[8];
|
||||||
public bool TryGetClosePoint(out Vector3 vector3)
|
public bool TryGetClosePoint(out Vector3 vector3)
|
||||||
{
|
{
|
||||||
vector3 = default;
|
vector3 = default;
|
||||||
if (UnityEngine.Physics.Raycast(root.position, root.forward, out var raycastHit, distance, layerMask))
|
StringBuilder reportBuilder = new();
|
||||||
|
reportBuilder.AppendLine($"检测任务:{name}");
|
||||||
|
var position = transform.position + transform.rotation * offset;
|
||||||
|
var detectedLength = Physics.OverlapSphereNonAlloc(position, distance, _mainCollider, layerMask);
|
||||||
|
reportBuilder.AppendLine($"检测到了{detectedLength}个碰撞体");
|
||||||
|
|
||||||
|
foreach (var collider in _mainCollider.Take(detectedLength).OrderBy(ByTop).Reverse())
|
||||||
|
//for (var i = 0; i <detectedLength ; i++)
|
||||||
{
|
{
|
||||||
var collider = raycastHit.collider;
|
//reportBuilder.AppendLine($"----------------------------检测到了碰撞体{_mainCollider[i].name}");
|
||||||
if (collider.isTrigger) return false;
|
//var collider = _mainCollider[i];
|
||||||
|
if (collider.isTrigger)
|
||||||
|
{
|
||||||
|
reportBuilder?.AppendLine("碰撞体是触发器");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (collider)
|
switch (collider)
|
||||||
{
|
{
|
||||||
case MeshCollider meshCollider:
|
case MeshCollider meshCollider:
|
||||||
if (meshCollider.convex is false)
|
if (meshCollider.convex is false)
|
||||||
return false;
|
{
|
||||||
|
reportBuilder?.AppendLine("MeshCollider未勾选Convex");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vector3 = collider.ClosestPoint(root.position + Vector3.up);
|
|
||||||
var top = collider.bounds.center + collider.bounds.extents;
|
|
||||||
|
|
||||||
if (Mathf.Abs(vector3.y - top.y) > 0.16f) return false;
|
var bounds = collider.bounds;
|
||||||
|
vector3 = collider.ClosestPoint(transform.position + Vector3.up * 64);
|
||||||
if (UnityEngine.Physics.Linecast(root.position, vector3, out var raycastHit2, layerMask))
|
var top = bounds.center.y + bounds.extents.y;
|
||||||
|
Debug.DrawLine(transform.position, transform.position + Vector3.up * top, Color.blue, 8f);
|
||||||
|
if (transform.position.y + minHeight > top)
|
||||||
{
|
{
|
||||||
if(raycastHit2.collider != collider)
|
reportBuilder?.AppendLine("高度不足");
|
||||||
return false;
|
continue;
|
||||||
};
|
|
||||||
foreach(var hit in UnityEngine.Physics.OverlapSphere(vector3, 0.1f, layerMask))
|
|
||||||
{
|
|
||||||
if(hit!= collider)
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nextPos = position;
|
||||||
|
nextPos.y = collider.bounds.center.y;
|
||||||
|
if (collider.Raycast(new Ray(nextPos, transform.forward), out _, distance) is false)
|
||||||
|
{
|
||||||
|
reportBuilder?.AppendLine("未检测到前方");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var height = Mathf.Abs(top - transform.position.y);
|
||||||
|
if (height > maxHeight)
|
||||||
|
{
|
||||||
|
reportBuilder?.AppendLine($"高度差距过大:{height}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Physics.Linecast(transform.position, vector3, out var raycastHit2, layerMask))
|
||||||
|
{
|
||||||
|
if (raycastHit2.collider != collider)
|
||||||
|
{
|
||||||
|
reportBuilder?.AppendLine($"检测到了其他碰撞体:{raycastHit2.transform.name}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
var length = Physics.OverlapSphereNonAlloc(vector3, 0.01f, _colliders, layerMask);
|
||||||
|
switch (length)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if (_colliders[0] != collider)
|
||||||
|
{
|
||||||
|
reportBuilder.AppendLine($"检测到了其他碰撞体{_colliders[0].name}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case > 1:
|
||||||
|
reportBuilder.AppendLine("检测到了更多碰撞体");
|
||||||
|
for (var ii = 0; ii < length; ii++)
|
||||||
|
{
|
||||||
|
//Debug.DrawLine(vector3, _colliders[ii].ClosestPoint(vector3), Color.red, 8);
|
||||||
|
reportBuilder.AppendLine($"\t{_colliders[ii].name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Collider = collider;
|
Collider = collider;
|
||||||
|
|
||||||
|
vector3.y = top;
|
||||||
|
CurrentPoint = vector3;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
reportBuilder.AppendLine("<color=green>成功</color>");
|
||||||
|
//BIT4Log.Log<GetClosePointFromCollider>(reportBuilder.ToString());
|
||||||
return true;
|
return true;
|
||||||
//return vector3.y >= collider.bounds.center.y + collider.bounds.extents.y;
|
|
||||||
//return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//BIT4Log.Log<GetClosePointFromCollider>(reportBuilder.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private float ByTop(Collider arg)
|
||||||
|
{
|
||||||
|
return arg.bounds.center.y + arg.bounds.extents.y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取碰撞点可以翻越后的点
|
/// 获取碰撞点可以翻越后的点
|
||||||
@@ -74,6 +155,7 @@ namespace BITKit
|
|||||||
public Vector3 StartPosition;
|
public Vector3 StartPosition;
|
||||||
public Vector3 EndPosition;
|
public Vector3 EndPosition;
|
||||||
|
|
||||||
|
public Vector3 CurrentPoint { get; set; }
|
||||||
public Collider Collider { get; set; }
|
public Collider Collider { get; set; }
|
||||||
private Rigidbody rigidbody;
|
private Rigidbody rigidbody;
|
||||||
|
|
||||||
@@ -92,7 +174,8 @@ namespace BITKit
|
|||||||
if (rigidbody.velocity.GetLength() < 0.1f) return false;
|
if (rigidbody.velocity.GetLength() < 0.1f) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var reportBuilder = new System.Text.StringBuilder();
|
//var reportBuilder = new System.Text.StringBuilder();
|
||||||
|
StringBuilder reportBuilder=null;
|
||||||
|
|
||||||
var forward = root.forward;
|
var forward = root.forward;
|
||||||
var sourceStartPosition = groundReference.position;
|
var sourceStartPosition = groundReference.position;
|
||||||
@@ -101,7 +184,7 @@ namespace BITKit
|
|||||||
|
|
||||||
var collider = UnityEngine.Physics.OverlapSphere(startPosition, radius, layerMask);
|
var collider = UnityEngine.Physics.OverlapSphere(startPosition, radius, layerMask);
|
||||||
|
|
||||||
reportBuilder.AppendLine($"检测到了{collider.Length}个碰撞体");
|
reportBuilder?.AppendLine($"检测到了{collider.Length}个碰撞体");
|
||||||
|
|
||||||
foreach (var hit in collider)
|
foreach (var hit in collider)
|
||||||
{
|
{
|
||||||
@@ -112,12 +195,12 @@ namespace BITKit
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
reportBuilder.AppendLine();
|
reportBuilder?.AppendLine();
|
||||||
reportBuilder.AppendLine($">{hit.name}");
|
reportBuilder?.AppendLine($">{hit.name}");
|
||||||
|
|
||||||
if(top.y>groundReference.transform.position.y+maxHeight)
|
if(top.y>groundReference.transform.position.y+maxHeight)
|
||||||
{
|
{
|
||||||
reportBuilder.AppendLine("高度超出可翻越高度");
|
reportBuilder?.AppendLine("高度超出可翻越高度");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,9 +211,9 @@ namespace BITKit
|
|||||||
|
|
||||||
if (hit.Raycast(ray, out var colliderHit, 8) is false)
|
if (hit.Raycast(ray, out var colliderHit, 8) is false)
|
||||||
{
|
{
|
||||||
reportBuilder.AppendLine("未检测到背面,算法错误");
|
reportBuilder?.AppendLine("未检测到背面,算法错误");
|
||||||
|
|
||||||
Debug.DrawRay(ray.origin, ray.direction * 8, Color.red, 8);
|
//Debug.DrawRay(ray.origin, ray.direction * 8, Color.red, 8);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,15 +234,15 @@ namespace BITKit
|
|||||||
}
|
}
|
||||||
catch (OperationCanceledException e)
|
catch (OperationCanceledException e)
|
||||||
{
|
{
|
||||||
reportBuilder.AppendLine(e.Message);
|
reportBuilder?.AppendLine(e.Message);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(UnityEngine.Physics.Raycast(EndPosition,Vector3.down,out _,1.6f,layerMask) is false)
|
if(UnityEngine.Physics.Raycast(EndPosition,Vector3.down,out _,1.6f,layerMask) is false)
|
||||||
{
|
{
|
||||||
Debug.DrawRay(EndPosition, Vector3.down*1.6f, Color.red, 8);
|
//Debug.DrawRay(EndPosition, Vector3.down*1.6f, Color.red, 8);
|
||||||
reportBuilder.AppendLine("未检测到地面,跳过");
|
reportBuilder?.AppendLine("未检测到地面,跳过");
|
||||||
continue;
|
continue;
|
||||||
//Debug.DrawRay(EndPosition, Vector3.down, Color.red, 8);
|
//Debug.DrawRay(EndPosition, Vector3.down, Color.red, 8);
|
||||||
}
|
}
|
||||||
@@ -174,7 +257,7 @@ namespace BITKit
|
|||||||
end2.y -= 0.1f;
|
end2.y -= 0.1f;
|
||||||
if(UnityEngine.Physics.Linecast(start2,end2,out var downHit,layerMask))
|
if(UnityEngine.Physics.Linecast(start2,end2,out var downHit,layerMask))
|
||||||
{
|
{
|
||||||
reportBuilder.AppendLine($"检测到了障碍物{downHit.collider.name}");
|
reportBuilder?.AppendLine($"检测到了障碍物{downHit.collider.name}");
|
||||||
|
|
||||||
//BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
//BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
||||||
continue;
|
continue;
|
||||||
@@ -186,8 +269,8 @@ namespace BITKit
|
|||||||
ray = new Ray(start, forward);
|
ray = new Ray(start, forward);
|
||||||
if(hit.Raycast(ray,out colliderHit,8) is false)
|
if(hit.Raycast(ray,out colliderHit,8) is false)
|
||||||
{
|
{
|
||||||
reportBuilder.AppendLine("未检测到正面,算法错误");
|
reportBuilder?.AppendLine("未检测到正面,算法错误");
|
||||||
Debug.DrawRay(ray.origin, ray.direction * 8, Color.red, 8);
|
//Debug.DrawRay(ray.origin, ray.direction * 8, Color.red, 8);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,14 +283,26 @@ namespace BITKit
|
|||||||
var lineDistance = Vector3.Distance(closeStart, closeEnd);
|
var lineDistance = Vector3.Distance(closeStart, closeEnd);
|
||||||
if(lineDistance > maxVaultDistance)
|
if(lineDistance > maxVaultDistance)
|
||||||
{
|
{
|
||||||
reportBuilder.AppendLine($"长度{lineDistance}超出可翻越距离{maxVaultDistance}");
|
reportBuilder?.AppendLine($"长度{lineDistance}超出可翻越距离{maxVaultDistance}");
|
||||||
|
|
||||||
Debug.DrawLine(closeStart,closeEnd, Color.yellow, 4);
|
//Debug.DrawLine(closeStart,closeEnd, Color.yellow, 4);
|
||||||
|
|
||||||
//BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
//BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Physics.Linecast(closeStart+Vector3.up*0.1f,closeEnd+Vector3.up*0.1f,out var _hit,layerMask))
|
||||||
|
{
|
||||||
|
|
||||||
|
//Debug.DrawLine(closeStart+Vector3.up*0.1f,_hit.point, Color.red, 4);
|
||||||
|
reportBuilder?.AppendLine("检测到了障碍物");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Debug.DrawLine(closeStart+Vector3.up*0.1f,closeEnd+Vector3.up*0.1f, Color.green, 4);
|
||||||
|
}
|
||||||
|
|
||||||
vector3 = colliderHit.point;
|
vector3 = colliderHit.point;
|
||||||
|
|
||||||
|
|
||||||
@@ -215,14 +310,19 @@ namespace BITKit
|
|||||||
|
|
||||||
vector3 += colliderHit.normal * 0.4f;
|
vector3 += colliderHit.normal * 0.4f;
|
||||||
|
|
||||||
reportBuilder.AppendLine();
|
reportBuilder?.AppendLine();
|
||||||
|
|
||||||
|
if(reportBuilder is not null)
|
||||||
BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
||||||
|
|
||||||
|
CurrentPoint = vector3;
|
||||||
|
Collider = hit;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
reportBuilder.AppendLine($"failed");
|
reportBuilder?.AppendLine($"failed");
|
||||||
|
|
||||||
|
if(reportBuilder is not null)
|
||||||
BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
BIT4Log.Log<GetVaultPointFromCollider>(reportBuilder.ToString());
|
||||||
|
|
||||||
vector3 = default;
|
vector3 = default;
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -5,12 +6,25 @@ namespace BITKit
|
|||||||
{
|
{
|
||||||
public class PhysicsImpact : MonoBehaviour
|
public class PhysicsImpact : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
private new Collider collider;
|
||||||
|
public event Action<Collision> OnPhysicsCollisionEnter;
|
||||||
|
[SerializeField] private Collider[] ignoreColliders;
|
||||||
|
private readonly HashSet<int> ignoreCollidersHash = new();
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
collider = GetComponent<Collider>();
|
||||||
|
ignoreCollidersHash.Clear();
|
||||||
|
if (ignoreColliders is null) return;
|
||||||
|
foreach (var x in ignoreColliders)
|
||||||
|
{
|
||||||
|
ignoreCollidersHash.Add(x.transform.GetInstanceID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void OnCollisionEnter(Collision collision)
|
private void OnCollisionEnter(Collision collision)
|
||||||
{
|
{
|
||||||
if (collision.transform.TryGetComponent<IPhysicsImpact>(out var impact))
|
if(ignoreCollidersHash.Contains(collision.transform.GetInstanceID())) return;
|
||||||
{
|
OnPhysicsCollisionEnter?.Invoke(collision);
|
||||||
impact.AddImpact(collision.relativeVelocity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -2,7 +2,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
#if UNITY_EDITOR
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Quadtree
|
namespace Quadtree
|
||||||
{
|
{
|
||||||
@@ -405,10 +407,12 @@ namespace Quadtree
|
|||||||
|
|
||||||
public void DrawBounds(bool displayNumberOfItems = false)
|
public void DrawBounds(bool displayNumberOfItems = false)
|
||||||
{
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
if (displayNumberOfItems)
|
if (displayNumberOfItems)
|
||||||
Handles.Label(Bounds.center, _items.Count.ToString());
|
Handles.Label(Bounds.center, _items.Count.ToString());
|
||||||
|
|
||||||
Gizmos.DrawWireCube(Bounds.center, Bounds.size);
|
Gizmos.DrawWireCube(Bounds.center, Bounds.size);
|
||||||
|
#endif
|
||||||
foreach (var subNode in SubNodes)
|
foreach (var subNode in SubNodes)
|
||||||
subNode.DrawBounds(displayNumberOfItems);
|
subNode.DrawBounds(displayNumberOfItems);
|
||||||
}
|
}
|
||||||
|
@@ -234,6 +234,7 @@ namespace BITKit.SceneManagement
|
|||||||
|
|
||||||
public async UniTask UnloadSceneAsync(string sceneName, CancellationToken cancellationToken)
|
public async UniTask UnloadSceneAsync(string sceneName, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
await UniTask.SwitchToMainThread();
|
||||||
OnUnloadScene?.Invoke(sceneName);
|
OnUnloadScene?.Invoke(sceneName);
|
||||||
|
|
||||||
await Task.Delay(100, destroyCancellationToken);
|
await Task.Delay(100, destroyCancellationToken);
|
||||||
@@ -246,7 +247,7 @@ namespace BITKit.SceneManagement
|
|||||||
SceneManager.LoadScene(1);
|
SceneManager.LoadScene(1);
|
||||||
|
|
||||||
destroyCancellationToken.ThrowIfCancellationRequested();
|
destroyCancellationToken.ThrowIfCancellationRequested();
|
||||||
|
await UniTask.SwitchToMainThread();
|
||||||
OnSceneUnloaded?.Invoke(sceneName);
|
OnSceneUnloaded?.Invoke(sceneName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,11 +6,12 @@ using BITKit.UX;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using BITKit.SceneManagement;
|
||||||
using Task = System.Threading.Tasks.Task;
|
using Task = System.Threading.Tasks.Task;
|
||||||
|
|
||||||
// ReSharper disable Unity.NoNullPropagation
|
// ReSharper disable Unity.NoNullPropagation
|
||||||
|
|
||||||
namespace BITKit.SceneManagement.UX
|
namespace BITKit.UX
|
||||||
{
|
{
|
||||||
public class UXSceneLoading : MonoBehaviour
|
public class UXSceneLoading : MonoBehaviour
|
||||||
{
|
{
|
||||||
@@ -30,14 +31,13 @@ namespace BITKit.SceneManagement.UX
|
|||||||
{
|
{
|
||||||
_cancellationToken = gameObject.GetCancellationTokenOnDestroy();
|
_cancellationToken = gameObject.GetCancellationTokenOnDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
DI.Inject(this);
|
||||||
sceneService.OnLoadScene += OnLoadScene;
|
sceneService.OnLoadScene += OnLoadScene;
|
||||||
sceneService.OnSceneLoadProgress+=OnSceneLoadProgress;
|
sceneService.OnSceneLoadProgress+=OnSceneLoadProgress;
|
||||||
sceneService.OnSceneLoaded += OnSceneLoaded;
|
sceneService.OnSceneLoaded += OnSceneLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
_currentProgress = Mathf.Lerp(_currentProgress, _progress, Time.deltaTime * 10);
|
_currentProgress = Mathf.Lerp(_currentProgress, _progress, Time.deltaTime * 10);
|
||||||
@@ -50,11 +50,11 @@ namespace BITKit.SceneManagement.UX
|
|||||||
sceneService.OnSceneLoaded -= OnSceneLoaded;
|
sceneService.OnSceneLoaded -= OnSceneLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void OnSceneLoadProgress(string arg1, float arg2)
|
private void OnSceneLoadProgress(string arg1, float arg2)
|
||||||
{
|
{
|
||||||
_progress = arg2;
|
_progress = arg2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLoadScene(string obj)
|
private void OnLoadScene(string obj)
|
||||||
{
|
{
|
||||||
sceneNameLabel?.Set(obj);
|
sceneNameLabel?.Set(obj);
|
||||||
@@ -62,6 +62,7 @@ namespace BITKit.SceneManagement.UX
|
|||||||
}
|
}
|
||||||
private async void OnSceneLoaded(string obj)
|
private async void OnSceneLoaded(string obj)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(autoDestroyAfterLoaded is false)return;
|
if(autoDestroyAfterLoaded is false)return;
|
||||||
backgroundImage.SetActive(false);
|
backgroundImage.SetActive(false);
|
||||||
try
|
try
|
||||||
|
@@ -5,7 +5,6 @@ using Cysharp.Threading.Tasks;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Pool;
|
using UnityEngine.Pool;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEditor.Search;
|
|
||||||
|
|
||||||
namespace BITKit.Sensors
|
namespace BITKit.Sensors
|
||||||
{
|
{
|
||||||
@@ -13,37 +12,83 @@ namespace BITKit.Sensors
|
|||||||
{
|
{
|
||||||
float GetVolume();
|
float GetVolume();
|
||||||
}
|
}
|
||||||
public class AudioSensor : MonoBehaviour,ISensor
|
|
||||||
|
public class AudioSensor : MonoBehaviour, ISensor
|
||||||
{
|
{
|
||||||
[Header(Constant.Header.Settings)]
|
|
||||||
[SerializeField] private bool autoUpdate;
|
[Header(Constant.Header.Settings)] [SerializeField]
|
||||||
[SerializeField]private float radius;
|
private bool autoUpdate;
|
||||||
|
|
||||||
|
[SerializeField] private float radius;
|
||||||
private readonly CacheList<Transform> cache = new();
|
private readonly CacheList<Transform> cache = new();
|
||||||
|
private readonly CacheList<AudioSensorService.AudioSensorData> data = new();
|
||||||
|
public AudioSensorService.AudioSensorData[] Noises => data.ValueArray;
|
||||||
|
private readonly HashSet<int> _addedSet = new();
|
||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
Id = GetInstanceID();
|
Id = GetInstanceID();
|
||||||
SensorQueue.Register(Id,this);
|
SensorQueue.Register(Id, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDisable()
|
private void OnDisable()
|
||||||
{
|
{
|
||||||
SensorQueue.UnRegister(Id);
|
SensorQueue.UnRegister(Id);
|
||||||
}
|
}
|
||||||
public UniTask Execute(float delta)
|
|
||||||
|
public async UniTask Execute(float delta)
|
||||||
{
|
{
|
||||||
var position = transform.position;
|
|
||||||
cache.Clear();
|
AudioSensorService.LockHash.Add(Id);
|
||||||
foreach (var x in AudioSensorService.QuadtreeRoot.Find(new Bounds(position, Vector3.one * radius)))
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var distance = Vector3.Distance(position, x.Position);
|
var position = transform.position;
|
||||||
if(distance>radius) continue;
|
cache.Clear();
|
||||||
cache.Add(x.Transform);
|
data.Clear();
|
||||||
|
_addedSet.Clear();
|
||||||
|
await UniTask.SwitchToTaskPool();
|
||||||
|
|
||||||
|
AudioSensorService.AudioSensorData[] value;
|
||||||
|
|
||||||
|
value = AudioSensorService.QuadtreeRoot.Find(new Bounds(position, Vector3.one * radius)).ToArray();
|
||||||
|
|
||||||
|
for (var index = 0; index < value.Length; index++)
|
||||||
|
{
|
||||||
|
var x = value[index];
|
||||||
|
var distance = Vector3.Distance(position, x.Position);
|
||||||
|
if (distance > radius) continue;
|
||||||
|
if (Ignores.Contains(x.Id)) continue;
|
||||||
|
_addedSet.Add(index);
|
||||||
|
// if (x.Transform)
|
||||||
|
// cache.Add(x.Transform);
|
||||||
|
// data.Add(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
await UniTask.SwitchToMainThread();
|
||||||
|
if (destroyCancellationToken.IsCancellationRequested) return;
|
||||||
|
foreach (var x in _addedSet)
|
||||||
|
{
|
||||||
|
if (value[x].Transform)
|
||||||
|
cache.Add(value[x].Transform);
|
||||||
|
data.Add(value[x]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return UniTask.CompletedTask;
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
BIT4Log.LogException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioSensorService.LockHash.Remove(Id);
|
||||||
|
//return UniTask.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HashSet<int> Ignores { get; } = new();
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public IEnumerable<Transform> Get() => cache.ValueArray;
|
public IEnumerable<Transform> Get() => cache.ValueArray;
|
||||||
public bool IsValid(Collider _collider) => false;
|
public bool IsValid(Collider _collider) => false;
|
||||||
public float GetDistance() => radius;
|
public float GetDistance() => radius;
|
||||||
public bool AutoUpdate=>autoUpdate;
|
public bool AutoUpdate => autoUpdate;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using kcp2k;
|
using kcp2k;
|
||||||
@@ -10,8 +11,10 @@ using UnityEngine.Pool;
|
|||||||
|
|
||||||
namespace BITKit.Sensors
|
namespace BITKit.Sensors
|
||||||
{
|
{
|
||||||
|
public struct ClassicNoise{}
|
||||||
public class AudioSensorService : MonoBehaviour
|
public class AudioSensorService : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
public static readonly HashSet<int> LockHash = new();
|
||||||
public class AudioSensorData:IItem<AudioSensorData,Node<AudioSensorData>>
|
public class AudioSensorData:IItem<AudioSensorData,Node<AudioSensorData>>
|
||||||
{
|
{
|
||||||
public int Id;
|
public int Id;
|
||||||
@@ -20,6 +23,8 @@ namespace BITKit.Sensors
|
|||||||
public Transform Transform;
|
public Transform Transform;
|
||||||
public Bounds Bounds;
|
public Bounds Bounds;
|
||||||
public ITag Tag;
|
public ITag Tag;
|
||||||
|
public object NoiseType;
|
||||||
|
public float ExpirationTime;
|
||||||
public Bounds GetBounds() => Bounds;
|
public Bounds GetBounds() => Bounds;
|
||||||
public Node<AudioSensorData> ParentNode { get; set; }
|
public Node<AudioSensorData> ParentNode { get; set; }
|
||||||
public void QuadTree_Root_Initialized(IQuadtreeRoot<AudioSensorData, Node<AudioSensorData>> root){}
|
public void QuadTree_Root_Initialized(IQuadtreeRoot<AudioSensorData, Node<AudioSensorData>> root){}
|
||||||
@@ -27,40 +32,72 @@ namespace BITKit.Sensors
|
|||||||
internal static readonly QuadtreeRoot<AudioSensorData, Node<AudioSensorData>> QuadtreeRoot =
|
internal static readonly QuadtreeRoot<AudioSensorData, Node<AudioSensorData>> QuadtreeRoot =
|
||||||
new(default, Vector3.one * 2048);
|
new(default, Vector3.one * 2048);
|
||||||
|
|
||||||
private static Pool<AudioSensorData> pool = new(()=>new(), x=>{}, 1000);
|
private static readonly Pool<AudioSensorData> pool = new(()=>new AudioSensorData(), x=>{}, 1000);
|
||||||
|
private static readonly ConcurrentQueue<AudioSensorData> registerQueue = new();
|
||||||
private static int count;
|
private static int count;
|
||||||
public static async void MakeNoise(Vector3 position,Transform transform)
|
private static readonly Queue<int> freeIds = new();
|
||||||
|
private static readonly ConcurrentDictionary<int, AudioSensorData> dictionary = new();
|
||||||
|
|
||||||
|
public static void MakeNoise(Vector3 position, Transform transform, float radius = 1,
|
||||||
|
object noiseType = null)
|
||||||
{
|
{
|
||||||
var data = pool.Take();
|
var data = pool.Take();
|
||||||
data.Id = count++;
|
data.Id = count++;
|
||||||
data.Position = position;
|
data.Position = position;
|
||||||
data.Transform = transform;
|
data.Transform = transform;
|
||||||
data.Bounds = new Bounds(position, Vector3.one *1);
|
data.Bounds = new Bounds(position, Vector3.one * 1);
|
||||||
data.Tag = transform.GetComponent<ITag>();
|
if (transform)
|
||||||
QuadtreeRoot.Insert(data);
|
data.Tag = transform.GetComponent<ITag>();
|
||||||
await UniTask.Delay(3000);
|
data.Radius = radius;
|
||||||
if (disposed) return;
|
data.ExpirationTime = Time.time + 0.5f;
|
||||||
QuadtreeRoot.Remove(data);
|
|
||||||
pool.Return(data);
|
registerQueue.Enqueue(data);
|
||||||
}
|
}
|
||||||
private static bool disposed;
|
|
||||||
[SerializeReference, SubclassSelector] private ITicker ticker;
|
[SerializeReference, SubclassSelector] private ITicker ticker;
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
disposed = false;
|
ticker.Add(OnTick);
|
||||||
ticker.Add(OnTick);
|
|
||||||
destroyCancellationToken.Register(Dispose);
|
destroyCancellationToken.Register(Dispose);
|
||||||
pool.Clear();
|
pool.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Dispose()
|
private void Dispose()
|
||||||
{
|
{
|
||||||
|
registerQueue.Clear();
|
||||||
ticker.Remove(OnTick);
|
ticker.Remove(OnTick);
|
||||||
disposed = true;
|
|
||||||
QuadtreeRoot.Clear();
|
QuadtreeRoot.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTick(float obj)
|
private void OnTick(float obj)
|
||||||
{
|
{
|
||||||
|
if (LockHash.Count > 0) return;
|
||||||
|
|
||||||
|
|
||||||
|
while (registerQueue.TryDequeue(out var data))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (data.ExpirationTime < Time.time)
|
||||||
|
{
|
||||||
|
pool.Return(data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QuadtreeRoot.Insert(data);
|
||||||
|
dictionary.TryAdd(data.Id, data);
|
||||||
|
}
|
||||||
|
var currentTime = Time.time;
|
||||||
|
foreach (var (id, data) in dictionary)
|
||||||
|
{
|
||||||
|
if (data.ExpirationTime > currentTime) continue;
|
||||||
|
freeIds.Enqueue(id);
|
||||||
|
QuadtreeRoot.Remove(data);
|
||||||
|
pool.Return(data);
|
||||||
|
}
|
||||||
|
while (freeIds.TryDequeue(out var id))
|
||||||
|
{
|
||||||
|
dictionary.TryRemove(id, out _);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -47,6 +47,7 @@ namespace BITKit.Sensors
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
UniTask Execute(float delta);
|
UniTask Execute(float delta);
|
||||||
|
HashSet<int> Ignores{ get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
@@ -74,6 +75,7 @@ namespace BITKit.Sensors
|
|||||||
{
|
{
|
||||||
return _sensorImplementation.Execute(delta);
|
return _sensorImplementation.Execute(delta);
|
||||||
}
|
}
|
||||||
|
public HashSet<int> Ignores => _sensorImplementation.Ignores;
|
||||||
}
|
}
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class SensorMonoProxy:ISensor
|
public class SensorMonoProxy:ISensor
|
||||||
@@ -101,6 +103,7 @@ namespace BITKit.Sensors
|
|||||||
{
|
{
|
||||||
return _sensorImplementation.Execute(delta);
|
return _sensorImplementation.Execute(delta);
|
||||||
}
|
}
|
||||||
|
public HashSet<int> Ignores => _sensorImplementation.Ignores;
|
||||||
}
|
}
|
||||||
public abstract class Sensor : MonoBehaviour, ISensor
|
public abstract class Sensor : MonoBehaviour, ISensor
|
||||||
{
|
{
|
||||||
@@ -109,13 +112,11 @@ namespace BITKit.Sensors
|
|||||||
public bool autoUpdate;
|
public bool autoUpdate;
|
||||||
[Header(Constant.Header.Gameobjects)]
|
[Header(Constant.Header.Gameobjects)]
|
||||||
public Collider[] ignoreColliders;
|
public Collider[] ignoreColliders;
|
||||||
[Header(Constant.Header.InternalVariables)]
|
|
||||||
[SerializeField,ReadOnly]
|
|
||||||
public Transform[] detected = Array.Empty<Transform>();
|
|
||||||
public abstract IEnumerable<Transform> Get();
|
public abstract IEnumerable<Transform> Get();
|
||||||
public abstract bool IsValid(Collider _collider);
|
public abstract bool IsValid(Collider _collider);
|
||||||
public abstract float GetDistance();
|
public abstract float GetDistance();
|
||||||
public virtual UniTask Execute(float delta)=>UniTask.CompletedTask;
|
public virtual UniTask Execute(float delta)=>UniTask.CompletedTask;
|
||||||
|
public HashSet<int> Ignores { get; } = new();
|
||||||
public int Id { get; private set; }
|
public int Id { get; private set; }
|
||||||
bool ISensor.AutoUpdate => autoUpdate;
|
bool ISensor.AutoUpdate => autoUpdate;
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user