Compare commits

..

2 Commits

Author SHA1 Message Date
CortexCore f8bcf8a4d4 1 2025-04-28 15:11:01 +08:00
CortexCore 2d8978e694 1 2025-04-17 19:21:44 +08:00
24 changed files with 643 additions and 52 deletions

View File

@ -161,7 +161,17 @@ namespace BITKit.Entities
if (instances.TryGetValue(h0, out var v0) is false)
{
instances[h0] = v0 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T>();
try
{
instances[h0] = v0 = _entitiesInternal[id].ServiceProvider.GetRequiredService<T>();
}
catch (KeyNotFoundException)
{
_logger.LogWarning($"Missing Entity {id},Ignore for now");
hashset.Remove(id);
break;
}
}
array[i] = Unsafe.As<T>(v0);

View File

@ -39,7 +39,7 @@ namespace BITKit.Entities
public void Dispose()
{
_serviceProvider.Dispose();
_serviceProvider?.Dispose();
}
}
}

View File

@ -130,7 +130,7 @@ namespace BITKit
}
else
{
value = new TValue();
value = new TValue();
self.TryAdd(t, value);
}
return value;
@ -152,20 +152,11 @@ namespace BITKit
list.Remove(t);
return list.ToArray();
}
public static bool TryRemove<TKey, TValue>(this IDictionary<TKey, TValue> self, TKey t)
{
return self.ContainsKey(t) && self.Remove(t);
}
public static bool TryRemove<TKey, TValue>(this IDictionary<TKey, TValue> self, TKey t) => self.Remove(t);
public static void Set<TKey, TValue>(this IDictionary<TKey, TValue> self, TKey key, TValue value)
{
if (self.ContainsKey(key))
{
self[key] = value;
}
else
{
self.Add(key, value);
}
self[key] = value;
}
public static TValue Get<TKey,TValue>(this IDictionary<Type,TValue> self)
{

View File

@ -0,0 +1,16 @@
namespace Net.BITKit.UX.SnackBar
{
public enum Severity
{
Normal,
Info,
Success,
Warning,
Error
}
public interface ISnackBar
{
void Add(string message, Severity severity = Severity.Normal);
}
}

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

@ -0,0 +1,140 @@
fileFormatVersion: 2
guid: c528f3cd94a7aa0498af5e2f149e6908
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 KiB

View File

@ -0,0 +1,140 @@
fileFormatVersion: 2
guid: 37f923d9a5ec87146bfb5cef8c989fdb
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -836,6 +836,24 @@
"processors": "",
"interactions": "",
"initialStateCheck": true
},
{
"name": "Chat",
"type": "Button",
"id": "346fc321-a6f0-4d95-81d1-bc531ed3ed28",
"expectedControlType": "",
"processors": "",
"interactions": "",
"initialStateCheck": false
},
{
"name": "Confirm",
"type": "Button",
"id": "0c71f40f-c39e-4893-b4d7-2c1968a9730d",
"expectedControlType": "",
"processors": "",
"interactions": "",
"initialStateCheck": false
}
],
"bindings": [
@ -1146,6 +1164,39 @@
"action": "Delta",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "4f11c618-09f3-4ace-8f9f-efd7821ebe37",
"path": "<Keyboard>/enter",
"interactions": "",
"processors": "",
"groups": "",
"action": "Chat",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "265f9627-ae29-4f03-80b9-80a64c28a9bf",
"path": "<Keyboard>/enter",
"interactions": "",
"processors": "",
"groups": "",
"action": "Confirm",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "97306299-e0e4-4e18-805b-51a1674b037d",
"path": "<Keyboard>/space",
"interactions": "",
"processors": "",
"groups": "",
"action": "Confirm",
"isComposite": false,
"isPartOfComposite": false
}
]
},

View File

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

View File

@ -0,0 +1,64 @@
using System.IO;
using UnityEngine;
namespace Net.BITKit
{
public static class AudioClipUtils
{
public static byte[] AudioClipToWavBytes(AudioClip clip)
{
var samples = new float[clip.samples * clip.channels];
clip.GetData(samples, 0);
var wavData = ConvertToWav(samples, clip.channels, clip.frequency);
return wavData;
}
private static byte[] ConvertToWav(float[] samples, int channels, int sampleRate)
{
var stream = new MemoryStream();
var writer = new BinaryWriter(stream);
var byteRate = sampleRate * channels * 2;
// 写入 WAV 文件头
writer.Write(System.Text.Encoding.ASCII.GetBytes("RIFF"));
writer.Write(0); // placeholder for total file size
writer.Write(System.Text.Encoding.ASCII.GetBytes("WAVE"));
// fmt 块
writer.Write(System.Text.Encoding.ASCII.GetBytes("fmt "));
writer.Write(16); // PCM
writer.Write((short)1); // AudioFormat = PCM
writer.Write((short)channels);
writer.Write(sampleRate);
writer.Write(byteRate);
writer.Write((short)(channels * 2)); // Block align
writer.Write((short)16); // Bits per sample
// data 块
writer.Write(System.Text.Encoding.ASCII.GetBytes("data"));
writer.Write(0); // placeholder for data chunk size
// 写入样本
var sampleCount = samples.Length;
for (var i = 0; i < sampleCount; i++)
{
var intData = (short)(samples[i] * short.MaxValue);
writer.Write(intData);
}
// 回写文件长度
writer.Seek(4, SeekOrigin.Begin);
writer.Write((int)(stream.Length - 8)); // RIFF size
writer.Seek(40, SeekOrigin.Begin);
writer.Write((int)(stream.Length - 44)); // data chunk size
writer.Flush();
return stream.ToArray();
}
}
}

View File

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

View File

@ -8,20 +8,31 @@ using System.Linq;
namespace BITKit
{
[System.Serializable]
[Serializable]
public class InputActionGroup : IDisposable
{
public override string ToString()
private class InputActionProxy
{
return $"Source:{Source}\nEnabled:{isEnabled}\nInitialized:{state}\nKeys:{string.Join("\n",actions.Keys)}";
public event Action<InputAction.CallbackContext> Callback;
public void Invoke(InputAction.CallbackContext context)
{
try
{
Callback?.Invoke(context);
}
catch (OperationCanceledException)
{
}
}
}
public string Source;
private int lockFile = Guid.NewGuid().GetHashCode();
private int _lockFile = Guid.NewGuid().GetHashCode();
public bool allowGlobalActivation = true;
[SerializeField, ReadOnly] private bool isEnabled;
private InitializationState state = InitializationState.None;
private InitializationState _state = InitializationState.None;
public readonly ValidHandle allowInput = new();
private readonly ConcurrentDictionary<string,InputAction> actions = new();
private readonly ConcurrentDictionary<string,InputAction> _actions = new();
private readonly ConcurrentDictionary<int, InputActionProxy> _callbacks = new();
/// <summary>
/// 注册所有(started,performed,canceled)回调
@ -33,20 +44,14 @@ namespace BITKit
Action<InputAction.CallbackContext> callback)
{
var action = EnsureCreated(reference);
action.RegisterCallback(callback);
_callbacks[action.GetHashCode()].Callback += callback;
return this;
}
public InputActionGroup RegisterCallback(InputAction inputAction,Action<InputAction.CallbackContext> callback)
{
EnsureConfiguration();
var action = actions.GetOrAdd(inputAction.name, _=>inputAction.Clone());
allowInput.Invoke();
action.RegisterCallback(callback);
var action = EnsureCreated(inputAction);
_callbacks[action.GetHashCode()].Callback += callback;
return this;
}
@ -59,10 +64,16 @@ namespace BITKit
}
EnsureConfiguration();
var action = actions.GetOrAdd(reference.name, _ =>
var action = _actions.GetOrAdd(reference.name, _ =>
{
var newAction = reference.action.Clone();
newAction.Rename(reference.name);
var callback = _callbacks[newAction.GetHashCode()] = new();
newAction.performed += callback.Invoke;
newAction.canceled+=callback.Invoke;
newAction.started+=callback.Invoke;
return newAction;
});
@ -73,10 +84,16 @@ namespace BITKit
public InputAction EnsureCreated(InputAction inputAction)
{
EnsureConfiguration();
var action = actions.GetOrAdd(inputAction.name, _ =>
var action = _actions.GetOrAdd(inputAction.name, _ =>
{
var newAction = inputAction.Clone();
newAction.Rename(inputAction.name);
var callback = _callbacks[newAction.GetHashCode()] = new();
newAction.performed += callback.Invoke;
newAction.canceled+=callback.Invoke;
newAction.started+=callback.Invoke;
return newAction;
});
@ -91,34 +108,38 @@ namespace BITKit
}
public InputAction GetAction(string name)
{
if(actions.TryGetValue(name,out var action))
if(_actions.TryGetValue(name,out var action))
return action;
throw new ArgumentException($"未知的引用{name}");
}
public InputAction GetAction(InputActionReference reference)
{
if(actions.TryGetValue(reference.name,out var action))
if(_actions.TryGetValue(reference.name,out var action))
return action;
throw new ArgumentException($"未知的引用{reference.name}");
}
public void UnRegisterCallback(InputActionReference reference, Action<InputAction.CallbackContext> callback)
{
if(actions.TryGetValue(reference.name,out var action))
action.UnRegisterCallback(callback);
if (_actions.TryGetValue(reference.name, out var action))
{
_callbacks[action.GetHashCode()].Callback -= callback;
}
}
public void UnRegisterCallback(InputAction inputAction, Action<InputAction.CallbackContext> callback)
{
if(actions.TryGetValue(inputAction.name,out var action))
action.UnRegisterCallback(callback);
if (_actions.TryGetValue(inputAction.name, out var action))
{
_callbacks[action.GetHashCode()].Callback -= callback;
}
}
private void EnsureConfiguration()
{
if (state is not InitializationState.Initialized)
if (_state is not InitializationState.Initialized)
{
Init();
state = InitializationState.Initialized;
_state = InitializationState.Initialized;
}
}
@ -131,12 +152,12 @@ namespace BITKit
private void ListenGlobalInput(bool allowInput)
{
this.allowInput.SetDisableElements(lockFile, !allowInput);
this.allowInput.SetDisableElements(_lockFile, !allowInput);
}
private void AllowInput(bool allow)
{
foreach (var action in actions.Values)
foreach (var action in _actions.Values)
{
if (allow)
{
@ -151,12 +172,12 @@ namespace BITKit
}
public void Dispose()
{
foreach (var action in actions.Values)
foreach (var action in _actions.Values)
{
action.Disable();
action.Dispose();
}
actions.Clear();
_actions.Clear();
}
}
}

View File

@ -134,6 +134,8 @@ namespace BITKit.UX
_confirmButton.clicked += Close;
_cancelButton.clicked += Close;
BITInputSystem.AllowInput.AddDisableElements(this);
if (message.OnConfirm is not null)
{
@ -156,6 +158,7 @@ namespace BITKit.UX
}
private void Close()
{
BITInputSystem.AllowInput.RemoveDisableElements(this);
Dispose();
BITAppForUnity.AllowCursor.RemoveElement(this);
}

View File

@ -41,6 +41,12 @@ namespace Net.BITKit.UX
x.text = _localizationService.GetLocalizedString('#'+x.viewDataKey);
}
foreach (var x in visualElement.Query<ProgressBar>(className:USS).ToList())
{
if(string.IsNullOrEmpty(x.viewDataKey))continue;
x.title = _localizationService.GetLocalizedString('#'+x.viewDataKey);
}
foreach (var x in visualElement.Query(className:USS).ToList())
{
if(string.IsNullOrEmpty(x.viewDataKey))continue;

View File

@ -124,11 +124,9 @@ namespace BITKit.UX
{
//WaitUtilTransitionCompleted = new();
}
protected readonly InputActionGroup InputActionGroup = new()
public readonly InputActionGroup InputActionGroup = new()
{
allowGlobalActivation = false,
Source = nameof(UIToolKitPanel)
};
public virtual bool CloseWhenClickOutside { get;}
public virtual bool IsWindow { get; }
@ -241,7 +239,7 @@ namespace BITKit.UX
await UniTask.NextFrame();
await OnExitAsync.UniTaskFunc();
try
{
var cts = new CancellationTokenSource();
@ -251,6 +249,10 @@ namespace BITKit.UX
catch (OperationCanceledException)
{
}
finally
{
await UniTask.NextFrame();
}
RootVisualElement?.RemoveFromClassList(USSExit);
RootVisualElement?.RemoveFromClassList(USSExitAsync);

View File

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

View File

@ -0,0 +1,70 @@
using System;
using System.Collections;
using System.Collections.Generic;
using BITKit;
using BITKit.Tween;
using BITKit.UX;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
namespace Net.BITKit.UX.SnackBar
{
public class UXSnackBar<TPanel> : UIToolkitSubPanel<TPanel>,ISnackBar where TPanel :IUXPanel
{
[UXBindPath("snack_bar-container")] private VisualElement _snackBarContainer;
private VisualTreeAsset _template;
private readonly ValidHandle _waitHandle = new ValidHandle();
public UXSnackBar(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
protected override void OnInitiated()
{
base.OnInitiated();
_template = _snackBarContainer.Q<TemplateContainer>().templateSource;
_snackBarContainer.Clear();
BITAppForUnity.AllowCursor.AddListener(OnAllowCursor);
}
private void OnAllowCursor(bool obj)
{
if (obj)
{
_waitHandle.AddElement(this);
}
else
{
_waitHandle.RemoveElement(this);
}
}
public async void Add(string message, Severity severity = Severity.Normal)
{
var ve = _snackBarContainer.Create(_template);
ve.AddToClassList($"severity-{severity.ToString().ToLower()}");
ve.Get<Label>().text = message;
if (ve.Q("VisualElement--1") is { } bar)
{
await BITween.Lerp(x => bar.style.width = new StyleLength(Length.Percent(x)), 0f, 100, 5, Mathf.Lerp);
}
else
{
await UniTask.Delay(5000);
}
await _waitHandle;
ve.RemoveFromHierarchy();
}
}
}

View File

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

View File

@ -679,7 +679,7 @@ namespace BITKit
self.schedule.Execute(() =>
{
self.scrollOffset = new Vector2(0, float.MaxValue);
});
}).ExecuteLater(1);;
}
public static void ScrollToBottomAutomatic(this ScrollView self, float delay = 0.02f)
{
@ -707,7 +707,8 @@ namespace BITKit
public static Vector2 GetScreenPosition(this VisualElement self, Vector3 worldPosition)
{
var panel = (self.panel ?? self.parent.panel) ?? self.parent.parent.panel;
var panel = self.panel;
if (panel is null) return default;
var pos = RuntimePanelUtils
.CameraTransformWorldToPanel(panel, worldPosition, Camera);

View File

@ -7,7 +7,7 @@ ScrollView {
--unity-metrics-single_line-height: 500px;
}
ScrollView Scroller.unity-scroller{
ScrollView Scroller.unity-scroller {
width: 8;
}
@ -653,3 +653,8 @@ OnScreenButton.selected {
transform-origin: left top;
scale: 0.8 0.8;
}
.text-overflow-warp-normal .unity-text-element {
overflow: hidden;
white-space: normal;
}

View File

@ -53,6 +53,10 @@ Slider.material {
min-width: 128px;
}
.material .selected Button {
background-color: rgba(26, 115, 232, 0.25);
}
.material Button:hover {
background-color: rgba(26, 115, 232, 0.25);
transition-duration: 0.32s;

View File

@ -26,6 +26,24 @@ namespace BITKit.Scene
var rotation = transform.rotation;
Gizmos.DrawCube(position, rotation*bounds.Value);
}
RenderRay(transform.up);
RenderRay(transform.forward);
RenderRay(transform.right);
RenderRay(-transform.right);
RenderRay(-transform.up);
RenderRay(-transform.forward);
return;
void RenderRay(Vector3 direction)
{
if (Physics.Raycast(position, direction, out var hit))
{
Debug.DrawLine(position, hit.point, color);
}
}
}
}
}