1
This commit is contained in:
@@ -1,19 +1,116 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AYellowpaper.SerializedCollections;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
using Object = UnityEngine.Object;
|
||||
using Random = UnityEngine.Random;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace BITKit
|
||||
{
|
||||
public class AddressableHelper
|
||||
public class AddressableHelper:MonoBehaviour
|
||||
{
|
||||
public static string GetAddressablePath(Object obj)
|
||||
private static IDictionary<ulong,string> PathsById { get; } = new Dictionary<ulong, string>();
|
||||
public static T Get<T>(ulong id) where T : Object
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
return string.Empty;
|
||||
#else
|
||||
throw new NotImplementedException();
|
||||
#endif
|
||||
var task = YooAssets.LoadAssetAsync<T>(PathsById[id]);
|
||||
task.WaitForAsyncComplete();
|
||||
return task.AssetObject.As<T>();
|
||||
}
|
||||
[SerializeField] private SerializedDictionary<ulong,string> pathsById;
|
||||
private void Start()
|
||||
{
|
||||
PathsById.Clear();
|
||||
foreach (var x in pathsById)
|
||||
{
|
||||
PathsById.Add(x.Key,x.Value);
|
||||
}
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
[BIT]
|
||||
private void BuildCache()
|
||||
{
|
||||
var guids = AssetDatabase.FindAssets($"t:Object",new[] {"Assets"});
|
||||
var paths = guids.Select(AssetDatabase.GUIDToAssetPath);
|
||||
|
||||
var objects = new List<IAddressable>();
|
||||
var stringBuilder = new System.Text.StringBuilder();
|
||||
|
||||
|
||||
foreach (var path in paths)
|
||||
{
|
||||
var asset = AssetDatabase.LoadAssetAtPath<Object>(path);
|
||||
switch (asset)
|
||||
{
|
||||
case GameObject go when go.TryGetComponent(out IAddressable addressable):
|
||||
objects.Add(addressable);
|
||||
break;
|
||||
case IAddressable addressable:
|
||||
objects.Add(addressable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stringBuilder.AppendLine($"所有资源数量:{guids.Length},其中包含{objects.Count}个Addressable资源");
|
||||
|
||||
pathsById.Clear();
|
||||
foreach (var x in objects)
|
||||
{
|
||||
if (x is not Object unityObject) continue;
|
||||
|
||||
//if (x.AddressableId is ulong.MinValue or ulong.MaxValue)
|
||||
{
|
||||
x.AddressableId = RandomUlong.NextUlong;
|
||||
EditorUtility.SetDirty(unityObject);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (x.AddressableId is not ulong.MinValue && !string.IsNullOrEmpty(x.AddressablePath))
|
||||
{
|
||||
if (pathsById.TryAdd(x.AddressableId, x.AddressablePath))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
stringBuilder.AppendLine($"资源{unityObject.name}的AddressableId:{x.AddressableId}已经存在");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
stringBuilder.AppendLine($"{unityObject.name}的AddressableId或AddressablePath为空");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
stringBuilder.AppendLine($"{unityObject.name}遇到了错误:{e.Message}");
|
||||
}
|
||||
}
|
||||
EditorUtility.SetDirty(this);
|
||||
Debug.Log(stringBuilder);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public static class RandomUlong
|
||||
{
|
||||
private static readonly System.Random _random = new();
|
||||
|
||||
public static ulong NextUlong
|
||||
{
|
||||
get
|
||||
{
|
||||
var buf = new byte[8];
|
||||
_random.NextBytes(buf);
|
||||
return BitConverter.ToUInt64(buf, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,8 +9,18 @@ namespace BITKit
|
||||
|
||||
private void OnAnimatorMove()
|
||||
{
|
||||
if (root is not null)
|
||||
root.SendMessage(nameof(OnAnimatorMove));
|
||||
if (root)
|
||||
root.SendMessageUpwards(nameof(OnAnimatorMove),SendMessageOptions.DontRequireReceiver);
|
||||
}
|
||||
private void AIAnimationEvent(string actionName)
|
||||
{
|
||||
if (root)
|
||||
root.SendMessage(nameof(AIAnimationEvent), actionName,SendMessageOptions.DontRequireReceiver);
|
||||
}
|
||||
public void AnimationEvent(string eventName)
|
||||
{
|
||||
if(root)
|
||||
root.SendMessage(nameof(AnimationEvent), eventName,SendMessageOptions.DontRequireReceiver);
|
||||
}
|
||||
}
|
||||
}
|
@@ -7,15 +7,23 @@ namespace BITKit.Animations
|
||||
{
|
||||
public class OverrideAnimatorFallbackController : MonoBehaviour
|
||||
{
|
||||
[SerializeField,ReadOnly] private bool _isOverride;
|
||||
[SerializeField, ReadOnly] private bool _isOverride;
|
||||
[SerializeField, ReadOnly] private string _buildReport="None";
|
||||
[SerializeField] private AnimatorOverrideController overrideController;
|
||||
[SerializeField] private AnimatorOverrideController[] additionalOverrideControllers;
|
||||
private void Start()
|
||||
{
|
||||
if (!overrideController) return;
|
||||
if (!TryGetComponent<Animator>(out var animator) ||
|
||||
animator.runtimeAnimatorController is not AnimatorOverrideController sourceController) return;
|
||||
animator.runtimeAnimatorController = sourceController.CopyAndFillMissingContent(overrideController);
|
||||
|
||||
var controller = sourceController.CopyAndFillMissingContent(overrideController);
|
||||
|
||||
foreach (var additional in additionalOverrideControllers)
|
||||
{
|
||||
controller = controller.CopyAndFillMissingContent(additional);
|
||||
}
|
||||
animator.runtimeAnimatorController = controller;
|
||||
_isOverride = true;
|
||||
}
|
||||
}
|
||||
|
@@ -195,6 +195,7 @@ namespace BITKit.Animations
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!animator.runtimeAnimatorController) return;
|
||||
for (var i = 0; i < animator.layerCount; i++)
|
||||
{
|
||||
this[i].currentState = animator.GetCurrentAnimatorStateInfo(i);
|
||||
|
@@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using BITKit.IO;
|
||||
using BITKit.UX;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
@@ -39,105 +40,153 @@ namespace BITKit
|
||||
// BIT4Log.Log<BITFramework>($"BITFramework加载完成,耗时:{Stopwatch.ElapsedMilliseconds}ms");
|
||||
// }
|
||||
|
||||
[SerializeField] private string addressableName;
|
||||
[SerializeField] private UXBar progressBar;
|
||||
[SerializeField] private UIDocument document;
|
||||
[SerializeField] private UXLabel progressLabel;
|
||||
[SerializeReference, SubclassSelector] private IReference addressableName;
|
||||
[SerializeReference, SubclassSelector] private IReference packageName = new Reference("DefaultPackages");
|
||||
|
||||
[SerializeReference, SubclassSelector] private IRemoteServices remoteServices;
|
||||
[SerializeReference, SubclassSelector] private IBuildinQueryServices buildinQueryServices;
|
||||
|
||||
[SerializeField] private UIDocument document;
|
||||
|
||||
[SerializeField] private bool isOffline;
|
||||
[SerializeField] private bool IsEditorSimulateMode;
|
||||
|
||||
private float CurrentOpacity
|
||||
{
|
||||
get => document.rootVisualElement.GetOpacity();
|
||||
set => document.rootVisualElement.SetOpacity(value);
|
||||
}
|
||||
|
||||
[UXBindPath("progress-bar")]
|
||||
private ProgressBar _progressBar;
|
||||
[UXBindPath("progress-label")]
|
||||
private Label _progressLabel;
|
||||
private async void Start()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
#else
|
||||
IsEditorSimulateMode=false;
|
||||
#endif
|
||||
|
||||
progressBar.Set(0f);
|
||||
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
DontDestroyOnLoad(gameObject);
|
||||
// 初始化资源系统
|
||||
YooAssets.Initialize();
|
||||
|
||||
const string PackageName = "DefaultPackages";
|
||||
// 创建默认的资源包
|
||||
var package = YooAssets.TryGetPackage(PackageName) ?? YooAssets.CreatePackage(PackageName);
|
||||
|
||||
// 设置该资源包为默认的资源包,可以使用YooAssets相关加载接口加载该资源包内容。
|
||||
YooAssets.SetDefaultPackage(package);
|
||||
|
||||
const string defaultHostServer = "http://127.0.0.1/CDN/PC/v1.0";
|
||||
const string fallbackHostServer = "http://127.0.0.1/CDN/PC/v1.0";
|
||||
|
||||
InitializeParameters initParameters = new HostPlayModeParameters
|
||||
try
|
||||
{
|
||||
BuildinQueryServices = new GameQueryServices(),
|
||||
RemoteServices = new RemoteServices(defaultHostServer, fallbackHostServer)
|
||||
};
|
||||
if (IsEditorSimulateMode)
|
||||
{
|
||||
var editorParameters = new EditorSimulateModeParameters
|
||||
#if UNITY_EDITOR
|
||||
#else
|
||||
IsEditorSimulateMode = false;
|
||||
#endif
|
||||
UXUtils.Inject(this);
|
||||
|
||||
_progressBar.value=0f;
|
||||
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
DontDestroyOnLoad(gameObject);
|
||||
// 初始化资源系统
|
||||
YooAssets.Initialize();
|
||||
|
||||
// 创建默认的资源包
|
||||
var package = YooAssets.TryGetPackage(packageName.Value) ?? YooAssets.CreatePackage(packageName.Value);
|
||||
|
||||
// 设置该资源包为默认的资源包,可以使用YooAssets相关加载接口加载该资源包内容。
|
||||
YooAssets.SetDefaultPackage(package);
|
||||
|
||||
|
||||
InitializeParameters initParameters = new HostPlayModeParameters
|
||||
{
|
||||
SimulateManifestFilePath = EditorSimulateModeHelper.SimulateBuild("BuiltinBuildPipeline",PackageName)
|
||||
BuildinQueryServices = buildinQueryServices,
|
||||
RemoteServices = remoteServices
|
||||
};
|
||||
initParameters = editorParameters;
|
||||
}
|
||||
|
||||
var initOperation = package.InitializeAsync(initParameters);
|
||||
progressLabel.Set("正在初始化资源系统...");
|
||||
while (initOperation.IsDone is false)
|
||||
{
|
||||
await UniTask.NextFrame(destroyCancellationToken);
|
||||
progressBar.Set(initOperation.Progress);
|
||||
}
|
||||
if (IsEditorSimulateMode)
|
||||
{
|
||||
|
||||
var editorParameters = new EditorSimulateModeParameters
|
||||
{
|
||||
|
||||
SimulateManifestFilePath =
|
||||
EditorSimulateModeHelper.SimulateBuild("ScriptableBuildPipeline", packageName.Value)
|
||||
};
|
||||
initParameters = editorParameters;
|
||||
}else if (isOffline)
|
||||
{
|
||||
initParameters = new OfflinePlayModeParameters();
|
||||
}
|
||||
|
||||
progressLabel.Set("正在更新资源包版本...");
|
||||
var operation = package.UpdatePackageVersionAsync();
|
||||
while (operation.IsDone is false)
|
||||
{
|
||||
await UniTask.NextFrame(destroyCancellationToken);
|
||||
progressBar.Set(operation.Progress);
|
||||
}
|
||||
InitializationOperation initOperation = null;
|
||||
try
|
||||
{
|
||||
initOperation = package.InitializeAsync(initParameters);
|
||||
_progressLabel.text ="正在初始化资源系统...";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_progressLabel.text =e.Message;
|
||||
|
||||
if (operation.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
//更新成功
|
||||
string packageVersion = operation.PackageVersion;
|
||||
Debug.Log($"Updated package Version : {packageVersion}");
|
||||
}
|
||||
else
|
||||
{
|
||||
//更新失败
|
||||
Debug.LogError(operation.Error);
|
||||
}
|
||||
initParameters = new HostPlayModeParameters
|
||||
{
|
||||
BuildinQueryServices = buildinQueryServices,
|
||||
RemoteServices = remoteServices
|
||||
};
|
||||
|
||||
progressLabel.Set("正在初始化Framework");
|
||||
var frameworkHandle = YooAssets.LoadAssetAsync<GameObject>(addressableName);
|
||||
while (frameworkHandle.IsDone is false)
|
||||
{
|
||||
await UniTask.NextFrame(destroyCancellationToken);
|
||||
progressBar.Set(frameworkHandle.Progress);
|
||||
}
|
||||
initOperation = package.InitializeAsync(initParameters);
|
||||
}
|
||||
|
||||
var framework = Instantiate(frameworkHandle.AssetObject);
|
||||
DontDestroyOnLoad(framework);
|
||||
progressLabel.Set("已加载完成");
|
||||
while (initOperation.IsDone is false)
|
||||
{
|
||||
await UniTask.NextFrame(destroyCancellationToken);
|
||||
_progressBar.value =initOperation.Progress;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_progressLabel.text="正在更新资源包版本...";
|
||||
var operation = package.UpdatePackageVersionAsync();
|
||||
while (operation.IsDone is false)
|
||||
{
|
||||
await UniTask.NextFrame(destroyCancellationToken);
|
||||
_progressBar.value = operation.Progress;
|
||||
}
|
||||
|
||||
|
||||
if (operation.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
//更新成功
|
||||
string packageVersion = operation.PackageVersion;
|
||||
Debug.Log($"Updated package Version : {packageVersion}");
|
||||
}
|
||||
else
|
||||
{
|
||||
//更新失败
|
||||
Debug.LogError(operation.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BIT4Log.LogException(e);
|
||||
_progressLabel.text =e.Message;
|
||||
}
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
Destroy(document);
|
||||
|
||||
BIT4Log.Log<BITFramework>("BITFramework加载完成,耗时:" + stopwatch.ElapsedMilliseconds + "ms");
|
||||
|
||||
SceneManager.LoadScene(1);
|
||||
|
||||
if (addressableName is not null)
|
||||
{
|
||||
_progressLabel.text ="正在初始化Framework";
|
||||
var frameworkHandle = YooAssets.LoadAssetAsync<GameObject>(addressableName.Value);
|
||||
while (frameworkHandle.IsDone is false)
|
||||
{
|
||||
await UniTask.NextFrame(destroyCancellationToken);
|
||||
_progressBar.value=frameworkHandle.Progress;
|
||||
}
|
||||
|
||||
var framework = Instantiate(frameworkHandle.AssetObject);
|
||||
DontDestroyOnLoad(framework);
|
||||
_progressLabel.text="已加载完成";
|
||||
|
||||
|
||||
BIT4Log.Log<BITFramework>("BITFramework加载完成,耗时:" + stopwatch.ElapsedMilliseconds + "ms");
|
||||
}
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
YooAssetUtils.RegisterPackage(packageName.Value);
|
||||
YooAssetUtils.RegisterResourcePackage(package);
|
||||
|
||||
if (document)
|
||||
Destroy(document);
|
||||
SceneManager.LoadScene(1);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_progressBar.value =0;
|
||||
_progressLabel.text = e.Message;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
@@ -146,23 +195,43 @@ namespace BITKit
|
||||
}
|
||||
}
|
||||
|
||||
public class GameQueryServices : IBuildinQueryServices
|
||||
[Serializable]
|
||||
public sealed class GameQueryServices : IBuildinQueryServices
|
||||
{
|
||||
public bool Query(string packageName, string fileName)
|
||||
{
|
||||
// 注意:fileName包含文件格式
|
||||
return StreamingAssetsHelper.FileExists(packageName, fileName);
|
||||
}
|
||||
|
||||
public bool Query(string packageName, string fileName, string fileCRC)=>Query(packageName,fileName);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class LocalQueryServices : IBuildinQueryServices
|
||||
{
|
||||
public readonly string Path;
|
||||
|
||||
public LocalQueryServices(string path)
|
||||
{
|
||||
Path = path;
|
||||
}
|
||||
|
||||
public bool Query(string packageName, string fileName, string fileCRC)
|
||||
{
|
||||
return File.Exists(System.IO.Path.Combine(Path, fileName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 远端资源地址查询服务类
|
||||
/// </summary>
|
||||
public class RemoteServices : IRemoteServices
|
||||
[Serializable]
|
||||
public sealed class RemoteServices : IRemoteServices
|
||||
{
|
||||
private readonly string _defaultHostServer;
|
||||
private readonly string _fallbackHostServer;
|
||||
|
||||
[SerializeField] private string _defaultHostServer;
|
||||
[SerializeField] private string _fallbackHostServer;
|
||||
public RemoteServices(){}
|
||||
public RemoteServices(string defaultHostServer, string fallbackHostServer)
|
||||
{
|
||||
_defaultHostServer = defaultHostServer;
|
||||
|
@@ -5,7 +5,9 @@
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:6ef4ed8ff60a7aa4bb60a8030e6f4008"
|
||||
"GUID:6ef4ed8ff60a7aa4bb60a8030e6f4008",
|
||||
"GUID:d525ad6bd40672747bde77962f1c401e",
|
||||
"GUID:49b49c76ee64f6b41bf28ef951cb0e50"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
@@ -13,6 +13,8 @@ public class GameQueryServices : IBuildinQueryServices
|
||||
// 注意:fileName包含文件格式
|
||||
return StreamingAssetsHelper.FileExists(packageName, fileName);
|
||||
}
|
||||
|
||||
public bool Query(string packageName, string fileName, string fileCRC)=>Query(packageName,fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
48
Src/Unity/Scripts/Assets/YooAssetUtils.cs
Normal file
48
Src/Unity/Scripts/Assets/YooAssetUtils.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
namespace BITKit.IO
|
||||
{
|
||||
public class YooAssetUtils
|
||||
{
|
||||
[RuntimeInitializeOnLoadMethod]
|
||||
private static void Reload()
|
||||
{
|
||||
OnPackageRegistered = null;
|
||||
OnPackageUnregistered = null;
|
||||
_registeredPackages.Clear();
|
||||
_registeredResourcePackages.Clear();
|
||||
}
|
||||
public static event Action<string> OnPackageRegistered;
|
||||
public static event Action<string> OnPackageUnregistered;
|
||||
public static IEnumerable<string> RegisteredPackages => _registeredPackages.ToArray();
|
||||
public static IEnumerable<ResourcePackage> RegisteredResourcePackages => _registeredResourcePackages.ToArray();
|
||||
private static readonly List<ResourcePackage> _registeredResourcePackages = new();
|
||||
private static readonly List<string> _registeredPackages = new();
|
||||
|
||||
public static void RegisterPackage(string packageName)
|
||||
{
|
||||
if (_registeredPackages.Contains(packageName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_registeredPackages.Add(packageName);
|
||||
OnPackageRegistered?.Invoke(packageName);
|
||||
}
|
||||
public static void UnregisterPackage(string packageName)
|
||||
{
|
||||
if (!_registeredPackages.Contains(packageName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_registeredPackages.Remove(packageName);
|
||||
OnPackageUnregistered?.Invoke(packageName);
|
||||
}
|
||||
public static void RegisterResourcePackage(ResourcePackage package)=>_registeredResourcePackages.Add(package);
|
||||
public static void UnregisterResourcePackage(ResourcePackage package)=>_registeredResourcePackages.Remove(package);
|
||||
}
|
||||
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6b88c0718e45444c886e28026f920cc
|
||||
guid: ec8acf90d1797fe46b793e0d1c2f24f4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@@ -5,11 +5,46 @@ using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
using BITKit.UX;
|
||||
using Cinemachine.Utility;
|
||||
using UnityEngine.InputSystem;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
#if !UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
public class SkipSplash
|
||||
{
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]
|
||||
private static void BeforeSplashScreen()
|
||||
{
|
||||
#if UNITY_WEBGL
|
||||
Application.focusChanged += Application_focusChanged;
|
||||
#else
|
||||
System.Threading.Tasks.Task.Run(AsyncSkip);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_WEBGL
|
||||
private static void Application_focusChanged(bool obj)
|
||||
{
|
||||
Application.focusChanged -= Application_focusChanged;
|
||||
SplashScreen.Stop(SplashScreen.StopBehavior.StopImmediate);
|
||||
}
|
||||
|
||||
#else
|
||||
private static void AsyncSkip()
|
||||
{
|
||||
SplashScreen.Stop(SplashScreen.StopBehavior.StopImmediate);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
namespace BITKit
|
||||
{
|
||||
|
||||
public class MouseNotOverGameViewException : System.Exception
|
||||
{
|
||||
public MouseNotOverGameViewException()
|
||||
@@ -22,10 +57,11 @@ namespace BITKit
|
||||
[Serializable]
|
||||
public class OpenUrl:IAction
|
||||
{
|
||||
[SerializeField] private string url;
|
||||
public void Execute()
|
||||
[SerializeField] public string url;
|
||||
[SerializeReference,SubclassSelector] public IReference urlReference;
|
||||
public virtual void Execute()
|
||||
{
|
||||
Application.OpenURL(url);
|
||||
Application.OpenURL(urlReference is not null?urlReference.Value:url);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +79,17 @@ namespace BITKit
|
||||
}
|
||||
public static bool IsPlaying { get;private set; }
|
||||
public static bool IsPointerOverUI { get; set; }
|
||||
|
||||
public static bool IsEditor
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static ValidHandle AllowCursor = new();
|
||||
public static ValidHandle AllowTouchSupport = new();
|
||||
public static GameObject GameObject;
|
||||
@@ -59,6 +106,16 @@ namespace BITKit
|
||||
public static void ThrowIfWindowNotFocus()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
switch (Camera.main)
|
||||
{
|
||||
case {} camera:
|
||||
if (camera.pixelRect.Contains(Input.mousePosition) is false)
|
||||
{
|
||||
throw new MouseNotOverGameViewException();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var window = UnityEditor.EditorWindow.focusedWindow;
|
||||
var windowName = window is not null ? window.ToString() : string.Empty;
|
||||
switch (windowName)
|
||||
@@ -106,8 +163,9 @@ namespace BITKit
|
||||
}
|
||||
}
|
||||
[BITCommand]
|
||||
public static void Exit()
|
||||
public static async void Exit()
|
||||
{
|
||||
await BITApp.SwitchToMainThread();
|
||||
BITApp.Stop();
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorApplication.isPlaying = false;
|
||||
|
@@ -228,7 +228,8 @@ namespace BITKit
|
||||
|
||||
private void OnView(InputAction.CallbackContext context)
|
||||
{
|
||||
if (allowInput.OnCheck() is false) return;
|
||||
|
||||
if (allowInput is { Allow: false }) return;
|
||||
var playerConfig = PlayerConfig.Singleton;
|
||||
var sensitivity = playerConfig.Sensitivity * playerConfig.M_Yaw;
|
||||
var delta = context.ReadValue<Vector2>();
|
||||
@@ -266,6 +267,7 @@ namespace BITKit
|
||||
{
|
||||
try
|
||||
{
|
||||
if (allowInput is { Allow: false }) return;
|
||||
BITAppForUnity.ThrowIfWindowNotFocus();
|
||||
switch (context.control.device)
|
||||
{
|
||||
@@ -309,6 +311,8 @@ namespace BITKit
|
||||
|
||||
private void OnEntry(InputAction.CallbackContext context)
|
||||
{
|
||||
if (allowInput is { Allow: false }) return;
|
||||
|
||||
if (context.started)
|
||||
{
|
||||
var delta = viewAction.action.ReadValue<Vector2>();
|
||||
@@ -323,6 +327,8 @@ namespace BITKit
|
||||
|
||||
private void OnMovement(InputAction.CallbackContext context)
|
||||
{
|
||||
if (allowInput is { Allow: false }) return;
|
||||
|
||||
switch (context.control.device)
|
||||
{
|
||||
case Mouse mouse:
|
||||
|
@@ -9,9 +9,12 @@ namespace BITKit
|
||||
{
|
||||
private void Start()
|
||||
{
|
||||
foreach (var x in GetComponentsInChildren<SkinnedMeshRenderer>())
|
||||
foreach (var x in GetComponentsInChildren<Renderer>(true))
|
||||
{
|
||||
x.updateWhenOffscreen = true;
|
||||
if (x is SkinnedMeshRenderer skinnedMeshRenderer)
|
||||
{
|
||||
skinnedMeshRenderer.updateWhenOffscreen = true;
|
||||
}
|
||||
x.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||||
}
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ namespace BITKit
|
||||
public class AutoSetLayer : MonoBehaviour
|
||||
{
|
||||
public int layer;
|
||||
void Start()
|
||||
private void Start()
|
||||
{
|
||||
GetComponentsInChildren<Transform>(true).ForEach(x=>
|
||||
{
|
||||
|
@@ -1,40 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Cysharp.Threading.Tasks;
|
||||
namespace BITKit
|
||||
{
|
||||
public class EffectPlayer : MonoBehaviour
|
||||
{
|
||||
[Header(Constant.Header.Settings)]
|
||||
[SerializeField] float duration;
|
||||
[Header(Constant.Header.Components)]
|
||||
[SerializeField] ParticleSystem[] particleSystems;
|
||||
[SerializeField] Behaviour[] behaviours;
|
||||
void Start()
|
||||
{
|
||||
particleSystems.ForEach(x => x.Stop());
|
||||
behaviours.ForEach(x => x.enabled = false);
|
||||
}
|
||||
public async void Excute()
|
||||
{
|
||||
particleSystems.ForEach(x =>
|
||||
{
|
||||
x.time = 0;
|
||||
x.Play(true);
|
||||
});
|
||||
behaviours.ForEach(x =>
|
||||
{
|
||||
x.enabled = true;
|
||||
});
|
||||
await UniTask.Delay(System.TimeSpan.FromSeconds(duration));
|
||||
if (BehaviourHelper.Actived)
|
||||
{
|
||||
behaviours.ForEach(x =>
|
||||
{
|
||||
x.enabled = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -31,7 +31,7 @@ namespace BITKit
|
||||
public override VisualElement CreateInspectorGUI()
|
||||
{
|
||||
CreateSubTitle("TextAsset Reader");
|
||||
FillDefaultInspector(root, serializedObject, true);
|
||||
FillDefaultInspector();
|
||||
var excute = root.Create<Button>();
|
||||
|
||||
//excute.bindingPath = nameof(ReadFromTextAsset.Excute);
|
||||
|
@@ -24,7 +24,7 @@ namespace BITKit
|
||||
{
|
||||
public override VisualElement CreateInspectorGUI()
|
||||
{
|
||||
FillDefaultInspector(root, serializedObject, true);
|
||||
FillDefaultInspector();
|
||||
|
||||
var slider = root.Create<Slider>();
|
||||
slider.SetValueWithoutNotify(agent.asset.renderScale);
|
||||
|
@@ -14,6 +14,7 @@ namespace BITKit
|
||||
[SerializeReference,SubclassSelector] private IProvider pingOutput;
|
||||
[SerializeReference,SubclassSelector] private IProvider resolutionOutput;
|
||||
[SerializeReference,SubclassSelector] private IProvider frameRateOutput;
|
||||
[SerializeReference, SubclassSelector] private INetClient clientPing;
|
||||
private readonly DeltaTimer timer = new();
|
||||
private Ping ping;
|
||||
[Header(Constant.Header.InternalVariables)]
|
||||
@@ -28,7 +29,12 @@ namespace BITKit
|
||||
|
||||
if (fpsInterval.AllowUpdate)
|
||||
fpsOutput.Set((string)timer);
|
||||
if (pingOutput is not null)
|
||||
|
||||
if (clientPing is not null)
|
||||
{
|
||||
pingOutput.Set(clientPing.Ping.ToString());
|
||||
}
|
||||
else if (pingOutput is not null)
|
||||
{
|
||||
switch (ping)
|
||||
{
|
||||
|
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit
|
||||
@@ -9,4 +11,22 @@ namespace BITKit
|
||||
string GetConfig(params object[] args);
|
||||
void Configure(params object[] args);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class ConfigProviders:IConfigProvider
|
||||
{
|
||||
[SerializeReference,SubclassSelector] private IConfigProvider[] providers;
|
||||
public string GetConfig(params object[] args)
|
||||
{
|
||||
return string.Join("\n",providers.Select(x=>x.GetConfig(args)));
|
||||
}
|
||||
|
||||
public void Configure(params object[] args)
|
||||
{
|
||||
foreach (var provider in providers)
|
||||
{
|
||||
provider.Configure(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,6 @@ namespace BITKit
|
||||
public float Sensitivity = 1.81f;
|
||||
public float TouchSensitivity = 0.22f;
|
||||
public float M_Yaw = 0.022f;
|
||||
public float Fov = 75;
|
||||
public float Fov = 90;
|
||||
}
|
||||
}
|
@@ -3,12 +3,29 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using BITKit;
|
||||
using BITKit.Core.Tuple;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace BITKit
|
||||
{
|
||||
|
||||
[Serializable]
|
||||
public sealed class CommandConfigProvider:IConfigProvider
|
||||
{
|
||||
[SerializeField] private UnityTuple<string, string>[] pairs;
|
||||
public string GetConfig(params object[] args)
|
||||
{
|
||||
return string.Join("\n",pairs);
|
||||
}
|
||||
|
||||
public void Configure(params object[] args)
|
||||
{
|
||||
foreach (var pair in pairs)
|
||||
{
|
||||
BITCommands.Excute($"set {pair.Item1} {pair.Item2}");
|
||||
}
|
||||
}
|
||||
}
|
||||
public class ScriptableExec : MonoBehaviour
|
||||
{
|
||||
[SerializeReference,SubclassSelector] private IConfigProvider configProvider;
|
||||
|
@@ -1,12 +1,20 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
#if RH_SerializedDictionary
|
||||
using RotaryHeart.Lib.SerializableDictionary;
|
||||
#endif
|
||||
using AYellowpaper.SerializedCollections;
|
||||
namespace BITKit
|
||||
{
|
||||
public sealed class TranslateSO : ScriptableObject
|
||||
{
|
||||
#if RH_SerializedDictionary
|
||||
public SerializableDictionaryBase<string, string> dictionary = new();
|
||||
#else
|
||||
public SerializedDictionary<string, string> dictionary = new();
|
||||
#endif
|
||||
public string Get(string text, bool isLocalization = true)
|
||||
{
|
||||
foreach (var word in dictionary)
|
||||
@@ -14,7 +22,11 @@ namespace BITKit
|
||||
var value = word.Value;
|
||||
if (isLocalization)
|
||||
{
|
||||
value = DI.Get<ITranslator>().Translate(value);
|
||||
try
|
||||
{
|
||||
value = DI.Get<ITranslator>().Translate(value);
|
||||
}
|
||||
catch (NullReferenceException){}
|
||||
}
|
||||
text = text.Replace(word.Key, value);
|
||||
}
|
||||
@@ -22,11 +34,18 @@ namespace BITKit
|
||||
}
|
||||
public string GetAt(string key, bool isLocalization = true)
|
||||
{
|
||||
var translater = DI.Get<ITranslator>();
|
||||
|
||||
if (dictionary.TryGetValue(key, out var value))
|
||||
{
|
||||
if (isLocalization)
|
||||
value = translater.Translate(value);
|
||||
try
|
||||
{
|
||||
if (isLocalization)
|
||||
{
|
||||
var translater = DI.Get<ITranslator>();
|
||||
value = translater.Translate(value);
|
||||
}
|
||||
}
|
||||
catch (NullReferenceException){}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
@@ -10,12 +11,86 @@ using UnityEngine.InputSystem;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using Google.Apis.Http;
|
||||
using UnityEngine.InputSystem.Interactions;
|
||||
using Label = UnityEngine.UIElements.Label;
|
||||
// ReSharper disable PossibleMultipleEnumeration
|
||||
|
||||
namespace BITKit.Console
|
||||
{
|
||||
public class BITConsole : MonoBehaviour
|
||||
{
|
||||
[RuntimeInitializeOnLoadMethod]
|
||||
private static void Reload()
|
||||
{
|
||||
Application.logMessageReceivedThreaded += EnqueueLog;
|
||||
}
|
||||
private class CommandSelector
|
||||
{
|
||||
public VisualElement Container { get; set; }
|
||||
public int Index
|
||||
{
|
||||
get => _index;
|
||||
set
|
||||
{
|
||||
if (_methods.Length is 0)
|
||||
{
|
||||
_index = -1;
|
||||
return;
|
||||
}
|
||||
_index = (value+_methods.Length)%_methods.Length;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
public event Action<MethodInfo> OnSelected;
|
||||
|
||||
private int _index;
|
||||
private MethodInfo[] _methods=Array.Empty<MethodInfo>();
|
||||
public void Rebuild()
|
||||
{
|
||||
Container.Clear();
|
||||
for (var i = 0; i < _methods.Length; i++)
|
||||
{
|
||||
var method = _methods[i];
|
||||
|
||||
var button = Container.Create<Button>();
|
||||
|
||||
StringBuilder stringBuilder = new(method.Name);
|
||||
|
||||
foreach (var parameterInfo in method.GetParameters())
|
||||
{
|
||||
stringBuilder.Append($" {parameterInfo.ParameterType.Name}:{parameterInfo.Name}");
|
||||
}
|
||||
|
||||
button.clicked+= () =>
|
||||
{
|
||||
OnSelected?.Invoke(method);
|
||||
Rebuild();
|
||||
};
|
||||
|
||||
button.text = stringBuilder.ToString();
|
||||
|
||||
Container.Add(button);
|
||||
}
|
||||
|
||||
}
|
||||
public void SetMethods(IEnumerable<MethodInfo> methods)
|
||||
{
|
||||
if (methods.IsValid())
|
||||
{
|
||||
if (_methods.SequenceEqual(methods)) return;
|
||||
}
|
||||
|
||||
_methods=methods.IsValid()?methods.ToArray():Array.Empty<MethodInfo>();
|
||||
if (_methods!.Length is 0)
|
||||
{
|
||||
_index = -1;
|
||||
}
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
[BITCommand]
|
||||
public static async void Clear()
|
||||
{
|
||||
@@ -23,75 +98,92 @@ namespace BITKit.Console
|
||||
singleton.outputString.Clear();
|
||||
singleton.text.text = string.Empty;
|
||||
}
|
||||
static BITConsole singleton;
|
||||
const string textFieldName = "TextField";
|
||||
const string commandListViewName = "commands-listview";
|
||||
const string textName = "Text";
|
||||
const string scrollViewName = "context-scrollview";
|
||||
private static BITConsole singleton;
|
||||
[SerializeField] private UIDocument document;
|
||||
[SerializeReference] private InputActionReference toggleAction;
|
||||
[SerializeReference] public InputActionReference nextOrPreviousAction;
|
||||
|
||||
private static ConcurrentQueue<(string condition, string stackTrace, LogType type)> logQueue = new();
|
||||
private static void EnqueueLog(string condition, string stackTrace, LogType type)
|
||||
{
|
||||
logQueue.Enqueue((condition, stackTrace, type));
|
||||
}
|
||||
|
||||
private readonly InputActionGroup _inputActionGroup=new()
|
||||
{
|
||||
allowGlobalActivation = false
|
||||
};
|
||||
public int logLineLimit = 64;
|
||||
private ListView commandListView;
|
||||
[UXBindPath("commands-container")]
|
||||
private VisualElement commandContainer;
|
||||
[UXBindPath("TextField")]
|
||||
private TextField textField;
|
||||
[UXBindPath("Text")]
|
||||
private Label text;
|
||||
[UXBindPath( "context-scrollview")]
|
||||
private ScrollView scrollView;
|
||||
private bool isActived;
|
||||
private bool _isRunning;
|
||||
private List<string> outputString = new();
|
||||
private void Awake()
|
||||
{
|
||||
Application.logMessageReceivedThreaded += LogCallback;
|
||||
}
|
||||
|
||||
private CommandSelector _commandSelector;
|
||||
private void Start()
|
||||
{
|
||||
UXUtils.Inject(this);
|
||||
|
||||
_commandSelector = new()
|
||||
{
|
||||
Container = commandContainer,
|
||||
};
|
||||
_commandSelector.OnSelected += x =>
|
||||
{
|
||||
textField.SetValueWithoutNotify(x.Name);
|
||||
textField.Blur();
|
||||
textField.Focus();
|
||||
};
|
||||
|
||||
|
||||
singleton = this;
|
||||
var visualElement = document.rootVisualElement;
|
||||
textField = visualElement.Q<TextField>(textFieldName);
|
||||
commandListView = visualElement.Q<ListView>(commandListViewName);
|
||||
text = visualElement.Q<Label>(textName);
|
||||
scrollView = visualElement.Q<ScrollView>(scrollViewName);
|
||||
|
||||
|
||||
|
||||
textField.RegisterValueChangedCallback(OnTextFieldValieChanged);
|
||||
textField.RegisterValueChangedCallback(OnTextFieldValueChanged);
|
||||
textField.RegisterCallback<KeyDownEvent>(OnKeyDown);
|
||||
|
||||
commandListView.selectionChanged += OnSelectionChange;
|
||||
|
||||
nextOrPreviousAction.action.performed += OnNextCommand;
|
||||
|
||||
text.text = string.Empty;
|
||||
|
||||
|
||||
|
||||
BIT4Log.OnNextLine += () =>
|
||||
{
|
||||
if (outputString.Count is not 0 && outputString.Last() != string.Empty)
|
||||
outputString.Add(string.Empty);
|
||||
};
|
||||
|
||||
commandListView.SetActive(false);
|
||||
|
||||
_inputActionGroup.RegisterCallback(toggleAction,Toggle);
|
||||
_inputActionGroup.RegisterCallback(nextOrPreviousAction, OnNextCommand);
|
||||
//_inputActionGroup.RegisterCallback(nextOrPreviousAction, OnNextCommand);
|
||||
|
||||
_inputActionGroup.allowInput.AddElement(this);
|
||||
|
||||
Toggle(false);
|
||||
|
||||
BIT4Log.OnNextLine += OnNextLine;
|
||||
|
||||
destroyCancellationToken.Register(() =>
|
||||
{
|
||||
BIT4Log.OnNextLine -= OnNextLine;
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
private void OnNextLine()
|
||||
{
|
||||
if (outputString.Count is not 0 && outputString.Last() != string.Empty)
|
||||
outputString.Add(string.Empty);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
_inputActionGroup.allowInput.RemoveElement(this);
|
||||
Application.logMessageReceivedThreaded -= LogCallback;
|
||||
}
|
||||
public async void Toggle(bool active)
|
||||
{
|
||||
_commandSelector.SetMethods(null);
|
||||
|
||||
document.rootVisualElement.SetActive(active);
|
||||
isActived = active;
|
||||
_isRunning = active;
|
||||
|
||||
BITAppForUnity.AllowCursor.SetElements(this,active);
|
||||
BITInputSystem.AllowInput.SetDisableElements(this,active);
|
||||
@@ -110,41 +202,26 @@ namespace BITKit.Console
|
||||
text.Blur();
|
||||
}
|
||||
}
|
||||
private void OnTextFieldValieChanged(ChangeEvent<string> callback)
|
||||
private void OnTextFieldValueChanged(ChangeEvent<string> callback)
|
||||
{
|
||||
if (callback.newValue.IsValid())
|
||||
if (string.IsNullOrEmpty(callback.newValue) is false)
|
||||
{
|
||||
var commands = BITCommands.GetMethodInfos(callback.newValue).Select(x => x.Name).ToList();
|
||||
if (commands.Count is 0)
|
||||
{
|
||||
commandListView.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
commandListView.itemsSource = commands;
|
||||
commandListView.SetActive(true);
|
||||
}
|
||||
var commands = BITCommands.GetMethodInfos(callback.newValue).ToArray();
|
||||
|
||||
_commandSelector.SetMethods(commands);
|
||||
|
||||
commandContainer.SetActive(commands.Length is not 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
commandListView.SetActive(false);
|
||||
commandContainer.SetActive(false);
|
||||
|
||||
_commandSelector.SetMethods(null);
|
||||
}
|
||||
}
|
||||
private void OnDropdownValueChanged(ChangeEvent<string> callback)
|
||||
{
|
||||
textField.SetValueWithoutNotify(callback.newValue);
|
||||
OnTextFieldValieChanged(callback);
|
||||
textField.Focus();
|
||||
}
|
||||
private void OnNextCommand(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context.started)
|
||||
{
|
||||
var index = context.ReadValue<Vector2>().y;
|
||||
}
|
||||
}
|
||||
private void OnKeyDown(KeyDownEvent keyDownEvent)
|
||||
private async void OnKeyDown(KeyDownEvent keyDownEvent)
|
||||
{
|
||||
var nextStop=true;
|
||||
switch (keyDownEvent.keyCode)
|
||||
{
|
||||
case KeyCode.Return:
|
||||
@@ -153,13 +230,38 @@ namespace BITKit.Console
|
||||
LogCallback($">{cmd}", string.Empty, LogType.Log);
|
||||
|
||||
textField.SetValueWithoutNotify(string.Empty);
|
||||
|
||||
await UniTask.NextFrame();
|
||||
|
||||
if (destroyCancellationToken.IsCancellationRequested) return;
|
||||
|
||||
|
||||
textField.Blur();
|
||||
|
||||
textField.Focus();
|
||||
|
||||
BITCommands.Excute(cmd);
|
||||
|
||||
_commandSelector.SetMethods(null);
|
||||
|
||||
break;
|
||||
case KeyCode.Tab:
|
||||
break;
|
||||
case KeyCode.DownArrow when string.IsNullOrEmpty(textField.text) is false:
|
||||
_commandSelector.Index-=1;
|
||||
break;
|
||||
case KeyCode.UpArrow when string.IsNullOrEmpty(textField.text) is false:
|
||||
_commandSelector.Index+=1;
|
||||
break;
|
||||
default:
|
||||
nextStop = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (nextStop)
|
||||
{
|
||||
keyDownEvent.StopPropagation();
|
||||
keyDownEvent.PreventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +270,7 @@ namespace BITKit.Console
|
||||
switch (context)
|
||||
{
|
||||
case { interaction: PressInteraction, performed: true }:
|
||||
Toggle(!isActived);
|
||||
Toggle(!_isRunning);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -205,6 +307,7 @@ namespace BITKit.Console
|
||||
await BITApp.SwitchToMainThread();
|
||||
scrollView.ScrollToBottomAutomatic();
|
||||
text.text = stringBuilder.ToString();
|
||||
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
@@ -218,24 +321,23 @@ namespace BITKit.Console
|
||||
|
||||
private void Update()
|
||||
{
|
||||
while (logQueue.TryDequeue(out var log))
|
||||
{
|
||||
LogCallback(log.condition, log.stackTrace, log.type);
|
||||
}
|
||||
|
||||
if (_isRunning is false) return;
|
||||
|
||||
var pos = textField.worldTransform.GetPosition();
|
||||
var size = textField.layout.size;
|
||||
|
||||
commandListView.style.left = 0;
|
||||
commandListView.style.top = 0;
|
||||
commandContainer.style.left = 0;
|
||||
commandContainer.style.top = 0;
|
||||
|
||||
pos.y += size.y;
|
||||
commandListView.transform.position = pos;
|
||||
commandContainer.transform.position = pos;
|
||||
|
||||
commandListView.style.width = size.x;
|
||||
}
|
||||
|
||||
private void OnSelectionChange(IEnumerable<object> selected)
|
||||
{
|
||||
var _selected = selected.First() as string;
|
||||
textField.SetValueWithoutNotify(_selected);
|
||||
commandListView.itemsSource?.Clear();
|
||||
commandListView.SetActive(false);
|
||||
commandContainer.style.width = size.x;
|
||||
}
|
||||
}
|
||||
}
|
@@ -69,7 +69,7 @@ namespace BITKit
|
||||
TextField textField;
|
||||
public override VisualElement CreateInspectorGUI()
|
||||
{
|
||||
FillDefaultInspector(root, serializedObject, true);
|
||||
FillDefaultInspector();
|
||||
|
||||
textField = root.Create<TextField>();
|
||||
var button = root.Create<Button>();
|
||||
|
@@ -1,74 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
namespace BITKit
|
||||
{
|
||||
public class PhysicsDoor : MonoBehaviour, IAction,IDescription
|
||||
{
|
||||
public enum State
|
||||
{
|
||||
Close,
|
||||
Open,
|
||||
HalfOpen,
|
||||
Locked,
|
||||
}
|
||||
[SerializeField] private string description;
|
||||
[SerializeField] private bool allowPhysics = true;
|
||||
[SerializeField] private Rigidbody root;
|
||||
[SerializeField] private Vector3 openEuler;
|
||||
[SerializeField] private Vector3 closeEuler;
|
||||
[SerializeField] private State state;
|
||||
[SerializeField] private Collider[] ignoreColliders;
|
||||
private void Start()
|
||||
{
|
||||
var selfColliders = GetComponentsInChildren<Collider>(true);
|
||||
var parentCollider = GetComponentInParent<Collider>(true);
|
||||
foreach (var self in selfColliders)
|
||||
{
|
||||
foreach (var ignore in ignoreColliders)
|
||||
{
|
||||
Physics.IgnoreCollision(self, ignore, true);
|
||||
}
|
||||
|
||||
if (parentCollider is not null)
|
||||
Physics.IgnoreCollision(self, parentCollider, true);
|
||||
}
|
||||
Set();
|
||||
}
|
||||
public void Execute()
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case State.Open:
|
||||
state = State.Close;
|
||||
Set();
|
||||
break;
|
||||
case State.Close:
|
||||
state = State.Open;
|
||||
Set();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Set(bool isClosed)
|
||||
{
|
||||
state = isClosed ? State.Close : State.Open;
|
||||
root.transform.localEulerAngles = isClosed ? closeEuler : openEuler;
|
||||
if (allowPhysics)
|
||||
root.isKinematic = isClosed;
|
||||
}
|
||||
|
||||
private void Set()
|
||||
{
|
||||
var isClosed = state switch
|
||||
{
|
||||
State.Locked => true,
|
||||
State.Close => true,
|
||||
State.Open => false,
|
||||
_ => true
|
||||
};
|
||||
Set(isClosed);
|
||||
}
|
||||
public string Name => description;
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit
|
||||
{
|
||||
public class PhysicsDoorManager : MonoBehaviour
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b5481cf34bf4a145898ac81e58abf8f
|
||||
guid: bf1c155248e26c446b9f5bd892f84eef
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
@@ -0,0 +1,137 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Unity.SharpZipLib.Utils;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.Audio;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace BITKit.Mod
|
||||
{
|
||||
public class DotNetSdkRoslynService
|
||||
{
|
||||
private const string _InstalledFilesKey = "DotNetSdkRoslyn_InstalledFiles";
|
||||
public static string DownloadUrl =>
|
||||
"http://server.bitfall.icu:3000/root/BITKit.DotNetSdkRoslyn.Unity/archive/main.zip";
|
||||
public static bool Installed=>File.Exists(CSCPath);
|
||||
public static string CSCPath =>
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(BITKit),"DotnetSdkRoslyn","csc.dll");
|
||||
public static string FolderPath =>
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(BITKit),"DotnetSdkRoslyn");
|
||||
public static event Action OnInstall;
|
||||
public static event Action OnInstalled;
|
||||
public static event Action OnUnInstalled;
|
||||
public static event Action<Exception> OnInstallFailed;
|
||||
public static event Action<float> OnDownloadProgress;
|
||||
|
||||
private static string[] _InstalledFiles
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!PlayerPrefs.HasKey(_InstalledFilesKey)) return Array.Empty<string>();
|
||||
var json = PlayerPrefs.GetString(_InstalledFilesKey);
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<string[]>(json);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BIT4Log.LogException(e);
|
||||
}
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
set
|
||||
{
|
||||
PlayerPrefs.SetString(_InstalledFilesKey, JsonConvert.SerializeObject(value));
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
}
|
||||
|
||||
public static async UniTask Install()
|
||||
{
|
||||
await UniTask.SwitchToMainThread();
|
||||
OnInstall?.Invoke();
|
||||
var request = UnityWebRequest.Get(DownloadUrl);
|
||||
try
|
||||
{
|
||||
request.SendWebRequest();
|
||||
while (request.isDone is false)
|
||||
{
|
||||
await UniTask.SwitchToMainThread();
|
||||
OnDownloadProgress?.Invoke(request.downloadProgress);
|
||||
await UniTask.NextFrame();
|
||||
}
|
||||
OnDownloadProgress?.Invoke(1);
|
||||
|
||||
using var ms = new MemoryStream(request.downloadHandler.data);
|
||||
|
||||
request.Dispose();
|
||||
|
||||
await UniTask.SwitchToTaskPool();
|
||||
var zipArchive = new ZipArchive(ms);
|
||||
|
||||
PathHelper.EnsureDirectoryCreated(FolderPath);
|
||||
|
||||
List<string> installedFiles = new();
|
||||
|
||||
var reportBuilder =new StringBuilder();
|
||||
reportBuilder.AppendLine($"正在安装文件到:{FolderPath}");
|
||||
|
||||
var entryFolder = zipArchive.Entries[0].FullName;
|
||||
foreach (var zipArchiveEntry in zipArchive.Entries)
|
||||
{
|
||||
var entryPath = Path.Combine(FolderPath, zipArchiveEntry.FullName.Replace(entryFolder,string.Empty));
|
||||
if (zipArchiveEntry.Name is "")
|
||||
{
|
||||
reportBuilder.AppendLine($"正在创建目录:{entryPath}");
|
||||
PathHelper.EnsureDirectoryCreated(entryPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportBuilder.AppendLine($"正在解压文件:{entryPath}");
|
||||
await using var entryStream = zipArchiveEntry.Open();
|
||||
await using var fs = System.IO.File.Create(entryPath);
|
||||
await entryStream.CopyToAsync(fs);
|
||||
installedFiles.Add(entryPath);
|
||||
}
|
||||
}
|
||||
await UniTask.SwitchToMainThread();
|
||||
_InstalledFiles = installedFiles.ToArray();
|
||||
installedFiles.Clear();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await UniTask.SwitchToMainThread();
|
||||
request.Dispose();
|
||||
OnInstallFailed?.Invoke(e);
|
||||
return;
|
||||
}
|
||||
OnInstalled?.Invoke();
|
||||
}
|
||||
public static async UniTask UnInstall()
|
||||
{
|
||||
if (Installed is false)
|
||||
{
|
||||
BIT4Log.Warning<DotNetSdkRoslynService>("未安装,无法卸载");
|
||||
return;
|
||||
}
|
||||
await UniTask.SwitchToMainThread();
|
||||
var files = _InstalledFiles;
|
||||
await UniTask.SwitchToTaskPool();
|
||||
foreach (var path in files)
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
await UniTask.SwitchToMainThread();
|
||||
PlayerPrefs.DeleteKey(_InstalledFilesKey);
|
||||
PlayerPrefs.Save();
|
||||
OnUnInstalled?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97e364d5d74ebe94da6abf95c6d42c5b
|
||||
guid: 56389bdbeb2065541a8e62a4ae5bd746
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@@ -16,7 +16,8 @@
|
||||
"GUID:d525ad6bd40672747bde77962f1c401e",
|
||||
"GUID:be17a8778dbfe454890ed8279279e153",
|
||||
"GUID:96f476e982d6fb945bfc9140ba094b7f",
|
||||
"GUID:4307f53044263cf4b835bd812fc161a4"
|
||||
"GUID:4307f53044263cf4b835bd812fc161a4",
|
||||
"GUID:d8b63aba1907145bea998dd612889d6b"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
@@ -1,105 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BITKit.PlayerCamera;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
namespace BITKit.Entities.Player.Character
|
||||
{
|
||||
public class EntityCharacter : EntityPlayerBehavior
|
||||
{
|
||||
[Header(Constant.Header.Components)]
|
||||
[SerializeField] private Renderer[] fpvRenderer = Array.Empty<Renderer>();
|
||||
[SerializeField] private Renderer[] tpvRenderer = Array.Empty<Renderer>();
|
||||
[SerializeField] private Renderer[] fpvOverrideRenderers = Array.Empty<Renderer>();
|
||||
[SerializeField] private Transform[] tpvRendererGroup = Array.Empty<Transform>();
|
||||
[Header(Constant.Header.Reference)]
|
||||
[SerializeReference, SubclassSelector] public IReference getDamage;
|
||||
|
||||
[Inject(true)] private IHealth _health;
|
||||
|
||||
[Inject(true)] private IPlayerCameraService _cameraService;
|
||||
|
||||
[Inject(true)] private IEntityOverride _entityOverride;
|
||||
|
||||
private Renderer[] _tpvRendererGroup;
|
||||
|
||||
public override void OnStart()
|
||||
{
|
||||
if (_health is not null)
|
||||
{
|
||||
_health.OnSetAlive += _ => UpdateMeshState();
|
||||
_health.OnSetHealthPoint += OnSetHP;
|
||||
}
|
||||
|
||||
if (_cameraService is not null)
|
||||
_cameraService.OnCameraActivated += _ => UpdateMeshState();
|
||||
|
||||
if(_entityOverride is not null)
|
||||
_entityOverride.OnOverride += _ => UpdateMeshState();
|
||||
|
||||
_tpvRendererGroup = tpvRendererGroup.SelectMany(x => x.GetComponentsInChildren<Renderer>(true)).ToArray();
|
||||
}
|
||||
public override void OnPlayerInitialized()
|
||||
{
|
||||
UpdateMeshState();
|
||||
}
|
||||
public override void OnPlayerDispose()
|
||||
{
|
||||
SetFPV(false);
|
||||
}
|
||||
private void OnSetHP(int hp)
|
||||
{
|
||||
UnityEntity.Invoke<string>(Constant.Animation.Play, getDamage.Value);
|
||||
}
|
||||
|
||||
private void UpdateMeshState()
|
||||
{
|
||||
switch (_health, _cameraService)
|
||||
{
|
||||
case (null, null):
|
||||
SetFPV(true);
|
||||
break;
|
||||
case (null, not null):
|
||||
SetFPV(_cameraService.IsCameraActivated);
|
||||
break;
|
||||
case (not null, null):
|
||||
SetFPV(_health.IsAlive);
|
||||
break;
|
||||
case (not null, not null):
|
||||
SetFPV(_health.IsAlive && _cameraService.IsCameraActivated);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetFPV(bool isFpv)
|
||||
{
|
||||
var shadowMode = isFpv ?
|
||||
ShadowCastingMode.ShadowsOnly :
|
||||
ShadowCastingMode.On;
|
||||
foreach (var x in fpvRenderer)
|
||||
{
|
||||
x.enabled = isFpv;
|
||||
}
|
||||
foreach (var x in tpvRenderer)
|
||||
{
|
||||
x.shadowCastingMode = shadowMode;
|
||||
}
|
||||
foreach (var x in _tpvRendererGroup)
|
||||
{
|
||||
x.shadowCastingMode =
|
||||
_entityOverride is not null
|
||||
? _entityOverride.IsOvering ? ShadowCastingMode.On : shadowMode
|
||||
: shadowMode;
|
||||
}
|
||||
|
||||
if (_entityOverride is not null)
|
||||
{
|
||||
foreach (var x in fpvOverrideRenderers)
|
||||
{
|
||||
x.enabled = isFpv && _entityOverride.IsOvering;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -62,6 +62,7 @@ namespace BITKit.Entities
|
||||
/// </summary>
|
||||
public interface IEntityMovement:IStateMachine<IEntityMovementState>
|
||||
{
|
||||
float ReferenceSpeed => 2.5f;
|
||||
Vector3 Position { get; set; }
|
||||
Quaternion Rotation { get; set; }
|
||||
Vector3 Forward { get; }
|
||||
@@ -113,12 +114,12 @@ namespace BITKit.Entities
|
||||
/// 基于相对坐标的移动
|
||||
/// </summary>
|
||||
/// <param name="relativeVector"></param>
|
||||
void Movement(Vector3 relativeVector);
|
||||
void OnMovement(Vector3 relativeVector);
|
||||
/// <summary>
|
||||
/// 基于InputAction的移动
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
void Movement(InputAction.CallbackContext context);
|
||||
void OnMovement(InputAction.CallbackContext context);
|
||||
/// <summary>
|
||||
/// 执行命令
|
||||
/// </summary>
|
||||
|
@@ -12,8 +12,8 @@ namespace BITKit.Entities.Movement
|
||||
[SerializeField] private new Rigidbody rigidbody;
|
||||
[SerializeField] private Animator animator;
|
||||
[SerializeField] private bool allowRootMotion;
|
||||
|
||||
|
||||
|
||||
|
||||
public Vector3 Position { get; set; }
|
||||
public Quaternion Rotation { get; set; }
|
||||
public Vector3 Forward { get; }
|
||||
@@ -35,11 +35,11 @@ namespace BITKit.Entities.Movement
|
||||
{
|
||||
}
|
||||
|
||||
public void Movement(Vector3 relativeVector)
|
||||
public void OnMovement(Vector3 relativeVector)
|
||||
{
|
||||
}
|
||||
|
||||
public void Movement(InputAction.CallbackContext context)
|
||||
public void OnMovement(InputAction.CallbackContext context)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using BITKit;
|
||||
using BITKit.SubSystems;
|
||||
@@ -9,14 +10,16 @@ namespace BITKit.Entities
|
||||
{
|
||||
|
||||
public interface IDamageType { }
|
||||
|
||||
public interface IDamageService
|
||||
{
|
||||
public event Action<DamageMessage> OnEntityDamaged;
|
||||
public event Action<DamageMessage> OnEntityKilled;
|
||||
void Execute(DamageMessage damageMessage);
|
||||
}
|
||||
public struct MeleeDamageMessage:IDamageType{}
|
||||
public struct MeleeDamageMessage : IDamageType
|
||||
{
|
||||
public bool Bleeding;
|
||||
}
|
||||
public struct BulletDamageMessage:IDamageType{}
|
||||
[Serializable]
|
||||
public class DamageServiceSingleton:IDamageService
|
||||
@@ -71,6 +74,34 @@ namespace BITKit.Entities
|
||||
public Vector3 Position;
|
||||
public Quaternion Rotation;
|
||||
public IDamageType DamageType;
|
||||
public RaycastHit? RaycastHit;
|
||||
}
|
||||
|
||||
public sealed class DamageMessageNetMessageWriter : NetMessageReader<DamageMessage>
|
||||
{
|
||||
public override DamageMessage ReadBinary(BinaryReader reader)
|
||||
{
|
||||
UnityEntitiesService.TryGetEntity(reader.ReadUInt64(),out var initiator);
|
||||
UnityEntitiesService.TryGetEntity(reader.ReadUInt64(),out var target);
|
||||
return new DamageMessage()
|
||||
{
|
||||
Initiator = initiator as Entity,
|
||||
Target = target as Entity,
|
||||
RawDamage = reader.ReadBoolean(),
|
||||
Damage = reader.ReadInt32(),
|
||||
Position = reader.ReadFloat3(),
|
||||
Rotation = reader.ReadQuaternion(),
|
||||
};
|
||||
}
|
||||
public override void WriteBinary(BinaryWriter writer, DamageMessage value)
|
||||
{
|
||||
writer.Write(value.Initiator?.Id ?? 0);
|
||||
writer.Write(value.Target?.Id ?? 0);
|
||||
writer.Write(value.RawDamage);
|
||||
writer.Write(value.Damage);
|
||||
writer.WriteFloat3(value.Position);
|
||||
writer.WriteQuaternion(value.Rotation);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IDamageCallback
|
||||
@@ -79,35 +110,65 @@ namespace BITKit.Entities
|
||||
}
|
||||
public interface IDamagable
|
||||
{
|
||||
IHealth Health { get; }
|
||||
IUnityEntity UnityEntity { get; }
|
||||
Rigidbody Rigidbody { get; }
|
||||
void GiveDamage(DamageMessage message);
|
||||
}
|
||||
public class DamageService:MonoBehaviour,IDamageService
|
||||
{
|
||||
internal static IDamageService Singleton { get; set; }
|
||||
public static IDamageService Singleton { get;private set; }
|
||||
private readonly Queue<DamageMessage> Messages = new();
|
||||
|
||||
[SerializeReference,SubclassSelector] private INetClient netClient;
|
||||
[SerializeReference,SubclassSelector] private INetServer netServer;
|
||||
|
||||
private INetProvider netClientProvider => netClient.Source as INetProvider;
|
||||
private INetProvider netServerProvider => netServer.Source as INetProvider;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Singleton = this;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
netClientProvider.AddCommandListener<DamageMessage>(ExecuteInternal);
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (!netServer.IsRunningServer && netClient.IsConnected) return;
|
||||
while (Messages.TryDequeue(out var damageMessage))
|
||||
{
|
||||
var unityEntity = (Entity)damageMessage.Target;
|
||||
if (!unityEntity || !unityEntity.TryGetComponent<IHealth>(out var heal) || !heal.IsAlive) continue;
|
||||
|
||||
damageMessage.Initiator?.Invoke(damageMessage);
|
||||
damageMessage.Target?.Invoke(damageMessage);
|
||||
|
||||
ExecuteInternal(damageMessage);
|
||||
|
||||
netServerProvider?.AllClientCommand(damageMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteInternal(DamageMessage damageMessage)
|
||||
{
|
||||
IHealth heal = null;
|
||||
if (damageMessage.Target?.TryGetComponent<IHealth>(out heal) is false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
damageMessage.Initiator?.Invoke(damageMessage);
|
||||
damageMessage.Target?.Invoke(damageMessage);
|
||||
|
||||
if (heal!.IsAlive)
|
||||
{
|
||||
OnEntityDamaged?.Invoke(damageMessage);
|
||||
if (heal.IsAlive is false)
|
||||
{
|
||||
OnEntityKilled?.Invoke(damageMessage);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
OnEntityKilled?.Invoke(damageMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Remoting.Contexts;
|
||||
using UnityEngine;
|
||||
@@ -20,21 +21,34 @@ namespace BITKit.Entities
|
||||
/// <summary>
|
||||
/// 当受到伤害时的回调
|
||||
/// </summary>
|
||||
public event Func<DamageMessage,int,int> OnDamageFactory;
|
||||
public event Func<DamageMessage,int,int> OnDamageFactory;
|
||||
/// <summary>
|
||||
/// 收到伤害时的回调
|
||||
/// </summary>
|
||||
public event Action<DamageMessage> OnDamageRelease;
|
||||
/// <summary>
|
||||
/// 当伤害被阻止时的回调
|
||||
/// </summary>
|
||||
public event Action<DamageMessage> OnDamageVoid;
|
||||
|
||||
int HealthPoint { get; set; }
|
||||
int MaxHealthPoint { get; set; }
|
||||
bool IsAlive { get; }
|
||||
}
|
||||
[CustomType(typeof(IHealth))]
|
||||
public class EntityHealth : EntityBehavior, IHealth
|
||||
public class EntityHealth : EntityBehavior, IHealth,IEntityBinaryComponent
|
||||
{
|
||||
[Header(Constant.Header.Settings)]
|
||||
[SerializeField] private int healthPoint = 100;
|
||||
[SerializeField] private int maxHealthPoint = 100;
|
||||
|
||||
public int Id { get; } = 84946486;
|
||||
|
||||
public event Action<int> OnSetHealthPoint;
|
||||
public event Action<bool> OnSetAlive;
|
||||
public event Func<DamageMessage,int, int> OnDamageFactory;
|
||||
public event Action<DamageMessage> OnDamageRelease;
|
||||
public event Action<DamageMessage> OnDamageVoid;
|
||||
|
||||
public int HealthPoint
|
||||
{
|
||||
@@ -61,7 +75,7 @@ namespace BITKit.Entities
|
||||
|
||||
private void OnHealthPointChangedInternal(int old, int newHP)
|
||||
{
|
||||
healthPoint = newHP;
|
||||
healthPoint =Mathf.Clamp(newHP,-1,maxHealthPoint) ;
|
||||
var _isAlive = newHP >= 0;
|
||||
if (_isAlive != IsAlive)
|
||||
{
|
||||
@@ -84,15 +98,28 @@ namespace BITKit.Entities
|
||||
private void OnGetDamage(DamageMessage damageMessage)
|
||||
{
|
||||
if (damageMessage.Target != UnityEntity) return;
|
||||
if (IsAlive is false) return;
|
||||
var damage = damageMessage.Damage;
|
||||
foreach (var x in OnDamageFactory.CastAsFunc().Reverse())
|
||||
if (IsAlive is false)
|
||||
{
|
||||
damage = x.Invoke(damageMessage, damage);
|
||||
if (damage <= 0) break;
|
||||
OnDamageVoid?.Invoke(damageMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
var damage = damageMessage.Damage;
|
||||
foreach (var x in OnDamageFactory.CastAsFunc())
|
||||
{
|
||||
damage = x.Invoke(damageMessage, damage);
|
||||
if (damage <= 0)
|
||||
{
|
||||
OnDamageVoid?.Invoke(damageMessage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Data.Get<bool>("god") is false)
|
||||
AddHP(-damage);
|
||||
|
||||
damageMessage.Damage = damage;
|
||||
OnDamageRelease?.Invoke(damageMessage);
|
||||
}
|
||||
if (Data.Get<bool>("god") is false)
|
||||
AddHP(-damage);
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
[BIT]
|
||||
@@ -109,6 +136,17 @@ namespace BITKit.Entities
|
||||
OnHealthPointChangedInternal(100, -1);
|
||||
}
|
||||
#endif
|
||||
|
||||
public void Serialize(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(HealthPoint);
|
||||
}
|
||||
|
||||
public void Deserialize(BinaryReader reader)
|
||||
{
|
||||
var newHealthPoint = reader.ReadInt32();
|
||||
if (HealthPoint != newHealthPoint)
|
||||
HealthPoint = newHealthPoint;
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,15 +4,52 @@ using UnityEngine;
|
||||
using BITKit;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public class EntityHitbox : EntityBehavior,IDamagable
|
||||
public class EntityHitbox : MonoBehaviour,IDamagable
|
||||
{
|
||||
IUnityEntity IDamagable.UnityEntity => UnityEntity;
|
||||
public Rigidbody Rigidbody => m_rigidbody;
|
||||
public IHealth Health
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureConfigure();
|
||||
return _health;
|
||||
}
|
||||
}
|
||||
|
||||
public IUnityEntity UnityEntity
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureConfigure();
|
||||
return _unityEntity;
|
||||
}
|
||||
}
|
||||
public Rigidbody Rigidbody
|
||||
{
|
||||
get=>m_rigidbody;
|
||||
set=>m_rigidbody=value;
|
||||
}
|
||||
|
||||
public void GiveDamage(DamageMessage message)
|
||||
{
|
||||
UnityEntity.Invoke(message);
|
||||
if (_unityEntity is not null)
|
||||
UnityEntity.Invoke(message);
|
||||
}
|
||||
|
||||
[SerializeField]private Rigidbody m_rigidbody;
|
||||
|
||||
|
||||
[Inject(true)]
|
||||
private IHealth _health;
|
||||
|
||||
private IUnityEntity _unityEntity;
|
||||
|
||||
private bool _initialized;
|
||||
|
||||
private void EnsureConfigure()
|
||||
{
|
||||
if (_initialized) return;
|
||||
_unityEntity = GetComponentInParent<IUnityEntity>(true);
|
||||
_unityEntity?.Inject(this);
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using BITFALL.Rig;
|
||||
using BITKit.Entities;
|
||||
using Cysharp.Threading.Tasks.Triggers;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit
|
||||
{
|
||||
public class EntityHitboxBuilder : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Collider[] colliders;
|
||||
[SerializeField] private EntityHitbox[] hitboxes;
|
||||
|
||||
[SerializeReference,SubclassSelector] private IReference[] tagReferences;
|
||||
[BIT]
|
||||
private void Build()
|
||||
{
|
||||
foreach (var x in hitboxes)
|
||||
{
|
||||
DestroyImmediate(x.gameObject);
|
||||
}
|
||||
hitboxes = new EntityHitbox[colliders.Length];
|
||||
for (var i = 0; i < colliders.Length; i++)
|
||||
{
|
||||
var collider = colliders[i];
|
||||
var newGameObject = new GameObject($"Hitbox_{collider.gameObject.name}");
|
||||
|
||||
newGameObject.layer = gameObject.layer;
|
||||
|
||||
newGameObject.transform.SetParent(transform);
|
||||
var transform1 = collider.transform;
|
||||
newGameObject.transform.position = transform1.position;
|
||||
newGameObject.transform.rotation = transform1.rotation;
|
||||
var hitbox =hitboxes[i] = newGameObject.AddComponent<EntityHitbox>();
|
||||
var tag = newGameObject.AddComponent<Tag>();
|
||||
|
||||
var tickOverride = newGameObject.AddComponent<TickOverrideTransform>();
|
||||
|
||||
tickOverride.Source = newGameObject.transform;
|
||||
tickOverride.Target = collider.transform;
|
||||
|
||||
if (collider.TryGetComponent<Rigidbody>(out var newRigidbody))
|
||||
{
|
||||
hitbox.Rigidbody = newRigidbody;
|
||||
}
|
||||
|
||||
switch (collider)
|
||||
{
|
||||
case BoxCollider boxCollider:
|
||||
var box = newGameObject.AddComponent<BoxCollider>();
|
||||
box.size = boxCollider.size;
|
||||
box.center = boxCollider.center;
|
||||
break;
|
||||
case SphereCollider sphereCollider:
|
||||
var sphere = newGameObject.AddComponent<SphereCollider>();
|
||||
sphere.radius = sphereCollider.radius;
|
||||
sphere.center = sphereCollider.center;
|
||||
break;
|
||||
case CapsuleCollider capsuleCollider:
|
||||
var capsule = newGameObject.AddComponent<CapsuleCollider>();
|
||||
capsule.radius = capsuleCollider.radius;
|
||||
capsule.height = capsuleCollider.height;
|
||||
capsule.direction = capsuleCollider.direction;
|
||||
capsule.center = capsuleCollider.center;
|
||||
break;
|
||||
}
|
||||
|
||||
tag.SetTags(tagReferences);
|
||||
EditorUtility.SetDirty(hitbox);
|
||||
EditorUtility.SetDirty(tag);
|
||||
}
|
||||
EditorUtility.SetDirty(this);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c8cf20e38c0584247ab1573e085274d4
|
||||
guid: 21e16997211c6f44c837beae9450cb58
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@@ -13,7 +13,8 @@ namespace BITKit.Entities.InputSystem
|
||||
{
|
||||
protected readonly InputActionGroup inputActionGroup = new()
|
||||
{
|
||||
allowGlobalActivation = true
|
||||
allowGlobalActivation = true,
|
||||
Source = nameof(EntityInputSystem)
|
||||
};
|
||||
[Inject(true)]
|
||||
private IHealth _health;
|
||||
|
@@ -1,141 +0,0 @@
|
||||
using System;
|
||||
using BITKit.PlayerCamera;
|
||||
using BITKit.Selection;
|
||||
using BITKit.Sensors;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.Interactions;
|
||||
namespace BITKit.Entities.Player
|
||||
{
|
||||
[CustomType(typeof(ISelector))]
|
||||
public class EntityInteractive : EntityPlayerBehavior,ISelector
|
||||
{
|
||||
[Header(Constant.Header.Settings)]
|
||||
[SerializeReference, SubclassSelector] private ISensor sensor;
|
||||
|
||||
[Header(Constant.Header.Gameobjects)]
|
||||
[SerializeField] private Transform sensorTransform;
|
||||
|
||||
[Header(Constant.Header.InternalVariables)]
|
||||
private ISelectable selected;
|
||||
private IntervalUpdate cd = new(0.08f);
|
||||
[Inject]
|
||||
private IHealth _health;
|
||||
|
||||
[Inject(true)] private IEntityMovement _movement;
|
||||
|
||||
[Inject(true)] IPlayerCameraService _cameraService;
|
||||
|
||||
public override void OnStart()
|
||||
{
|
||||
_health.OnSetAlive += OnSetAlive;
|
||||
}
|
||||
|
||||
private void OnSetAlive(bool obj)
|
||||
{
|
||||
TryDeSelected();
|
||||
}
|
||||
|
||||
public override void OnUpdate(float deltaTime)
|
||||
{
|
||||
if (_cameraService is not null && _movement is not null)
|
||||
{
|
||||
if (_cameraService.IsCameraActivated)
|
||||
{
|
||||
sensorTransform.SetPositionAndRotation(_cameraService.CameraPosition, _cameraService.CameraRotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
sensorTransform.position = _movement.Position + _movement.Rotation * _movement.ViewCenter;
|
||||
sensorTransform.rotation = _movement.ViewRotation;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//if (sensor.Get().TryGetAny(x=>x.TryGetComponentAny<ISelectable>(out _),out var detected))
|
||||
try
|
||||
{
|
||||
if (sensor.Get().TryGetAny(x=>x.GetComponentInParent<ISelectable>() is not null,out var detected))
|
||||
{
|
||||
if (detected.TryGetComponentAny<ISelectable>(out var _detected))
|
||||
{
|
||||
if (_detected == selected)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
TryDeSelected();
|
||||
|
||||
Detected(_detected);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TryDeSelected();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TryDeSelected();
|
||||
}
|
||||
}
|
||||
catch(MissingReferenceException e)
|
||||
{}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
private void TryDeSelected()
|
||||
{
|
||||
if (selected is null) return;
|
||||
selected.SetSelectionState(SelectionState.None);
|
||||
OnInactive?.Invoke(selected);
|
||||
selected = null;
|
||||
}
|
||||
private void Detected(ISelectable detected)
|
||||
{
|
||||
selected = detected;
|
||||
detected.SetSelectionState(SelectionState.Hover);
|
||||
OnSelected?.Invoke(selected);
|
||||
}
|
||||
|
||||
public void Interactive(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context.interaction is not PressInteraction || !context.performed ) return;
|
||||
if (cd.AllowUpdate is false) return;
|
||||
var _selected = selected;
|
||||
if (_selected is not MonoBehaviour monoBehaviour) return;
|
||||
if (monoBehaviour.TryGetComponentAny<IAction>(out var action))
|
||||
{
|
||||
action.Execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
selected.SetSelectionState(SelectionState.Active);
|
||||
OnActive?.Invoke(selected);
|
||||
}
|
||||
|
||||
public bool TryGetCurrentSelectable(out ISelectable selectable)
|
||||
{
|
||||
selectable = selected;
|
||||
return selected?.Transform;
|
||||
}
|
||||
|
||||
public event Action<ISelectable> OnNone;
|
||||
public event Action<ISelectable> OnHover;
|
||||
public event Action<ISelectable> OnActive;
|
||||
public event Action<ISelectable> OnInactive;
|
||||
public event Action<ISelectable> OnFocus;
|
||||
public event Action<ISelectable> OnSelected;
|
||||
public event Action<ISelectable> OnEnabled;
|
||||
public event Action<ISelectable> OnChecked;
|
||||
public event Action<ISelectable> OnRoot;
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8de7270cf1d43f64fafdc3413158cea3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b8ff0f400ff5fd44b5205e0adaa1969
|
||||
guid: 0dcb052e1b8841743aaa68d522200c5e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -1,118 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BITKit.Entities.Physics;
|
||||
using UnityEngine;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
[CustomType(typeof(IEntityPhysics))]
|
||||
public class EntityPhysics : EntityBehavior,IEntityPhysics
|
||||
{
|
||||
[SerializeField] private Animator animator;
|
||||
[SerializeField] private Rigidbody[] rigidbodies;
|
||||
[SerializeField] private Collider[] ragdollColliders;
|
||||
[SerializeField] private Joint[] joints;
|
||||
[SerializeField] private new Rigidbody rigidbody;
|
||||
[Inject]
|
||||
private IHealth _health;
|
||||
private readonly Dictionary<Joint,ConfigurableJointMotion> _jointXMotions=new();
|
||||
private readonly Dictionary<Joint,ConfigurableJointMotion> _jointYMotions=new();
|
||||
private readonly Dictionary<Joint,ConfigurableJointMotion> _jointZMotions=new();
|
||||
private readonly Dictionary<Joint,ConfigurableJointMotion> _jointAngularXMotions=new();
|
||||
private readonly Dictionary<Joint,ConfigurableJointMotion> _jointAngularYMotions=new();
|
||||
private readonly Dictionary<Joint,ConfigurableJointMotion> _jointAngularZMotions=new();
|
||||
|
||||
public override void OnAwake()
|
||||
{
|
||||
_health.OnSetAlive += OnSetAlive;
|
||||
_health.OnSetHealthPoint += OnSetHP;
|
||||
foreach (var x in joints)
|
||||
{
|
||||
switch (x)
|
||||
{
|
||||
case ConfigurableJoint configurableJoint:
|
||||
_jointXMotions.Add(configurableJoint,configurableJoint.xMotion);
|
||||
_jointYMotions.Add(configurableJoint,configurableJoint.yMotion);
|
||||
_jointZMotions.Add(configurableJoint,configurableJoint.zMotion);
|
||||
_jointAngularXMotions.Add(configurableJoint,configurableJoint.angularXMotion);
|
||||
_jointAngularYMotions.Add(configurableJoint,configurableJoint.angularYMotion);
|
||||
_jointAngularZMotions.Add(configurableJoint,configurableJoint.angularZMotion);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnSetAlive(bool alive)
|
||||
{
|
||||
IsPhysics = !alive;
|
||||
if (animator)
|
||||
animator.enabled = alive;
|
||||
try
|
||||
{
|
||||
await Task.Delay(10, destroyCancellationToken);
|
||||
if (destroyCancellationToken.IsCancellationRequested) return;
|
||||
rigidbodies.ForEach(x => { x.isKinematic = alive; });
|
||||
ragdollColliders.ForEach(x => { x.enabled = !alive; });
|
||||
OnSetPhysics?.Invoke(!alive);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
foreach (var joint in joints)
|
||||
{
|
||||
switch (joint)
|
||||
{
|
||||
case ConfigurableJoint configurableJoint:
|
||||
configurableJoint.xMotion = alive ? _jointXMotions[joint] : ConfigurableJointMotion.Free;
|
||||
configurableJoint.yMotion = alive ? _jointYMotions[joint] : ConfigurableJointMotion.Free;
|
||||
configurableJoint.zMotion = alive ? _jointZMotions[joint] : ConfigurableJointMotion.Free;
|
||||
configurableJoint.angularXMotion =
|
||||
alive ? _jointAngularXMotions[joint] : ConfigurableJointMotion.Free;
|
||||
configurableJoint.angularYMotion =
|
||||
alive ? _jointAngularYMotions[joint] : ConfigurableJointMotion.Free;
|
||||
configurableJoint.angularZMotion =
|
||||
alive ? _jointAngularZMotions[joint] : ConfigurableJointMotion.Free;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void OnSetHP(int hp)
|
||||
{
|
||||
}
|
||||
|
||||
public Vector3 Center => rigidbody.worldCenterOfMass;
|
||||
public bool IsPhysics { get; private set; }
|
||||
public Vector3 Velocity
|
||||
{
|
||||
get=>rigidbody.velocity;
|
||||
set
|
||||
{
|
||||
foreach (var x in rigidbodies)
|
||||
{
|
||||
x.velocity = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
public Action<bool> OnSetPhysics { get; set; }
|
||||
public void AddForce(Vector3 force, ForceMode mode = ForceMode.Force)
|
||||
{
|
||||
foreach (var x in rigidbodies)
|
||||
{
|
||||
x.AddForce(force, mode);
|
||||
}
|
||||
}
|
||||
public void AddTorque(Vector3 torque, ForceMode mode = ForceMode.Force)
|
||||
{
|
||||
foreach (var x in rigidbodies)
|
||||
{
|
||||
x.AddTorque(torque, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c78fe9fd58f5efc4abdeb6d193bf258b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -7,15 +7,20 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using BITKit.Entities;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine.Profiling;
|
||||
using UnityEngine.UIElements;
|
||||
// ReSharper disable RedundantTypeArgumentsOfMethod
|
||||
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
[CustomType(typeof(IUnityEntity))]
|
||||
[CustomType(typeof(IEntity))]
|
||||
public class Entity : MonoBehaviour, IUnityEntity
|
||||
{
|
||||
private readonly GenericEvent genericEvent = new();
|
||||
public ulong Id { get; private set; }
|
||||
|
||||
|
||||
public ulong Id { get; set; }
|
||||
public CancellationToken CancellationToken { get; private set; }
|
||||
public IEntityBehavior[] Behaviors { get;private set; }
|
||||
public IEntityComponent[] Components => Behaviors.Cast<IEntityComponent>().ToArray();
|
||||
@@ -31,7 +36,7 @@ namespace BITKit.Entities
|
||||
foreach (var fieldInfo in obj
|
||||
.GetType()
|
||||
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(fieldInfo=>fieldInfo.GetCustomAttribute<InjectAttribute>() is not null))
|
||||
.Where(fieldInfo=>fieldInfo.GetCustomAttribute<InjectAttribute>(true) is not null))
|
||||
{
|
||||
var type = fieldInfo.FieldType;
|
||||
var attribute = fieldInfo.GetCustomAttribute<InjectAttribute>();
|
||||
@@ -83,19 +88,30 @@ namespace BITKit.Entities
|
||||
}
|
||||
|
||||
private bool isInitialized;
|
||||
|
||||
public void WaitForInitializationComplete()
|
||||
{
|
||||
if (isInitialized) return;
|
||||
Start();
|
||||
isInitialized = true;
|
||||
}
|
||||
private void Awake()
|
||||
{
|
||||
Id = (ulong)Guid.NewGuid().GetHashCode();
|
||||
if (Id.IsDefault())
|
||||
Id = (ulong)Guid.NewGuid().GetHashCode();
|
||||
CancellationToken = gameObject.GetCancellationTokenOnDestroy();
|
||||
Set(CancellationToken);
|
||||
Behaviors = GetComponentsInChildren<IEntityBehavior>(true).Distinct().ToArray();
|
||||
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (isInitialized) return;
|
||||
try
|
||||
{
|
||||
AddService<IEntity>(this);
|
||||
AddService<Entity>(this);
|
||||
AddService<IUnityEntity>(this);
|
||||
|
||||
Behaviors = GetComponentsInChildren<IEntityBehavior>(true).Distinct().ToArray();
|
||||
var monoBehaviours = GetComponentsInChildren<MonoBehaviour>(true);
|
||||
Behaviors.ForEach(x => x.Initialize(this));
|
||||
foreach (var x in monoBehaviours)
|
||||
@@ -108,8 +124,11 @@ namespace BITKit.Entities
|
||||
.OfType<CustomTypeAttribute>()
|
||||
)
|
||||
{
|
||||
AddService(att.Type, x);
|
||||
AddService(att.Type, x);
|
||||
if (att.AsGlobal)
|
||||
DI.Register(att.Type, x);
|
||||
}
|
||||
|
||||
genericEvent.Set(x.GetType(),x);
|
||||
}
|
||||
foreach (var x in monoBehaviours)
|
||||
@@ -143,23 +162,26 @@ namespace BITKit.Entities
|
||||
|
||||
private void Update()
|
||||
{
|
||||
var deltaTime = Time.fixedDeltaTime;
|
||||
foreach (var x in Behaviors)
|
||||
{
|
||||
x.OnUpdate(Time.deltaTime);
|
||||
x.OnUpdate(deltaTime);
|
||||
}
|
||||
}
|
||||
private void FixedUpdate()
|
||||
{
|
||||
var deltaTime = Time.fixedDeltaTime;
|
||||
foreach (var x in Behaviors)
|
||||
{
|
||||
x.OnFixedUpdate(Time.fixedDeltaTime);
|
||||
x.OnFixedUpdate(deltaTime);
|
||||
}
|
||||
}
|
||||
private void LateUpdate()
|
||||
{
|
||||
var deltaTime = Time.fixedDeltaTime;
|
||||
foreach (var x in Behaviors)
|
||||
{
|
||||
x.OnLateUpdate(Time.deltaTime);
|
||||
x.OnLateUpdate(deltaTime);
|
||||
}
|
||||
}
|
||||
public void AddListener<T>(Action<T> action) => genericEvent.AddListener<T>(action);
|
||||
|
17
Src/Unity/Scripts/Entity/Core/EntityAddressableComponent.cs
Normal file
17
Src/Unity/Scripts/Entity/Core/EntityAddressableComponent.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
[CustomType(typeof(IAddressable))]
|
||||
public class EntityAddressableComponent : MonoBehaviour,IAddressable
|
||||
{
|
||||
[SerializeField] private string addressablePath;
|
||||
[SerializeField] private ulong addressableId;
|
||||
|
||||
public string AddressablePath => addressablePath;
|
||||
public ulong AddressableId => addressableId;
|
||||
}
|
||||
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b1d23c488f41754ea714f972c248130
|
||||
guid: 22c8a583a4eb6504ab5a732954c0855c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using BITKit.Entities;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
|
73
Src/Unity/Scripts/Entity/Core/EntityBinaryHeader.cs
Normal file
73
Src/Unity/Scripts/Entity/Core/EntityBinaryHeader.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
[CustomType(typeof(IEntityBinaryHeader))]
|
||||
public class EntityBinaryHeader : EntityBehavior,IEntityBinaryHeader
|
||||
{
|
||||
public int Id => (int)Entity.Id;
|
||||
public IDictionary<int, IEntityBinaryComponent> ComponentDictionary { get; } =
|
||||
new Dictionary<int, IEntityBinaryComponent>();
|
||||
|
||||
public override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
foreach (var component in Entity.Components.OfType<IEntityBinaryComponent>())
|
||||
{
|
||||
ComponentDictionary.Add(component.Id, component);
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(BinaryWriter writer)
|
||||
{
|
||||
//写入组件数量
|
||||
//写入组件ID
|
||||
//写入组件数据
|
||||
//写入组件数据长度
|
||||
var length = ComponentDictionary.Count;
|
||||
writer.Write(length);
|
||||
foreach (var component in ComponentDictionary.Values)
|
||||
{
|
||||
writer.Write(component.Id);
|
||||
}
|
||||
foreach (var component in ComponentDictionary.Values)
|
||||
{
|
||||
using var ms = new MemoryStream();
|
||||
using var binaryWriter = new BinaryWriter(ms);
|
||||
component.Serialize(binaryWriter);
|
||||
binaryWriter.Flush();
|
||||
ms.Flush();
|
||||
var bytes = ms.ToArray();
|
||||
writer.Write(bytes.Length);
|
||||
writer.Write(bytes);
|
||||
}
|
||||
}
|
||||
public void Deserialize(BinaryReader reader)
|
||||
{
|
||||
//BIT4Log.Log<EntityBinaryHeader>("源数据长度:"+reader.BaseStream.Length);
|
||||
//读取组件数量
|
||||
//读取组件ID
|
||||
//读取组件数据
|
||||
var count = reader.ReadInt32();
|
||||
//BIT4Log.Log<EntityBinaryHeader>($"count:{count}");
|
||||
var ids = new int[count];
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
ids[i] = reader.ReadInt32();
|
||||
}
|
||||
foreach (var id in ids)
|
||||
{
|
||||
var length = reader.ReadInt32();
|
||||
var bytes = reader.ReadBytes(length);
|
||||
using var stream = new MemoryStream(bytes);
|
||||
using var binaryReader = new BinaryReader(stream);
|
||||
//BIT4Log.Log<EntityBinaryHeader>($"id:{id},length:{length},bytes:\n{JsonHelper.Get(bytes)}");
|
||||
ComponentDictionary[id].Deserialize(binaryReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Src/Unity/Scripts/Entity/Core/EntityBinaryHeader.cs.meta
Normal file
11
Src/Unity/Scripts/Entity/Core/EntityBinaryHeader.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ff33423878ac11439fbf15f38dbe628
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -4,21 +4,52 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
|
||||
public interface IEntityOverride
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否正在被覆盖
|
||||
/// </summary>
|
||||
bool IsOvering { get; }
|
||||
void AddOverride(object key);
|
||||
void RemoveOverride(object key);
|
||||
/// <summary>
|
||||
/// 当前对象,用于判断是否是自己的覆盖
|
||||
/// </summary>
|
||||
object CurrentObject { get; }
|
||||
/// <summary>
|
||||
/// 当开始覆盖或者结束覆盖时触发
|
||||
/// </summary>
|
||||
event Action<bool> OnOverride;
|
||||
/// <summary>
|
||||
/// 添加覆盖
|
||||
/// </summary>
|
||||
void AddOverride(object key,int priority=0);
|
||||
/// <summary>
|
||||
/// 移除覆盖
|
||||
/// </summary>
|
||||
void RemoveOverride(object key,int priority=0);
|
||||
|
||||
}
|
||||
[CustomType(typeof(IEntityOverride))]
|
||||
public class EntityOverride : EntityBehavior,IEntityOverride
|
||||
{
|
||||
[SerializeField,ReadOnly] private bool isOvering;
|
||||
[SerializeField, ReadOnly(HideLabel = true)] private string overrideKeys;
|
||||
public bool IsOvering => _allowOverrideHandle;
|
||||
public object CurrentObject => _prioritySelector.Current;
|
||||
private readonly ValidHandle _allowOverrideHandle = new();
|
||||
public void AddOverride(object key) => _allowOverrideHandle.AddElement(key);
|
||||
public void RemoveOverride(object key)=>_allowOverrideHandle.RemoveElement(key);
|
||||
|
||||
private readonly PrioritySelector<object> _prioritySelector = new();
|
||||
public void AddOverride(object key,int priority=0)
|
||||
{
|
||||
_prioritySelector.Set(priority,key);
|
||||
_allowOverrideHandle.AddElement(key);
|
||||
}
|
||||
public void RemoveOverride(object key,int priority=0)
|
||||
{
|
||||
_prioritySelector.Remove(priority);
|
||||
_allowOverrideHandle.RemoveElement(key);
|
||||
}
|
||||
|
||||
public event Action<bool> OnOverride;
|
||||
|
||||
public override void Initialize(IEntity entity)
|
||||
@@ -35,6 +66,7 @@ namespace BITKit.Entities
|
||||
{
|
||||
OnOverride?.Invoke(@override);
|
||||
isOvering=@override;
|
||||
overrideKeys = _allowOverrideHandle.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BITKit.Entities;
|
||||
using BITKit.StateMachine;
|
||||
using UnityEngine;
|
||||
@@ -27,20 +28,27 @@ namespace BITKit.Entities
|
||||
add => stateMachine.OnStateChanged += value;
|
||||
remove => stateMachine.OnStateChanged -= value;
|
||||
}
|
||||
|
||||
public event Action<T> OnStateRegistered;
|
||||
public event Action<T> OnStateUnRegistered;
|
||||
public IDictionary<Type, T> StateDictionary => stateMachine.StateDictionary;
|
||||
public override void Initialize(IEntity entity)
|
||||
public override void OnAwake()
|
||||
{
|
||||
base.Initialize(entity);
|
||||
base.OnAwake();
|
||||
if (stateMachine is null)
|
||||
{
|
||||
Debug.LogWarning(GetType().Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var x in stateMachine.states)
|
||||
{
|
||||
Entity.Inject(x);
|
||||
}
|
||||
stateMachine.Initialize();
|
||||
}
|
||||
}
|
||||
void IStateMachine<T>.Initialize()
|
||||
void IStateMachine<T>.Initialize()
|
||||
{
|
||||
stateMachine.Initialize();
|
||||
}
|
||||
@@ -62,6 +70,23 @@ namespace BITKit.Entities
|
||||
{
|
||||
stateMachine.TransitionState(state);
|
||||
}
|
||||
|
||||
public virtual void Register(T newState)
|
||||
{
|
||||
Entity.Inject(newState);
|
||||
StateMachineUtils.Register(this, newState);
|
||||
}
|
||||
|
||||
public virtual void UnRegister(T newState)=>StateMachineUtils.UnRegister(this,newState);
|
||||
public void InvokeOnStateRegistered(T state)
|
||||
{
|
||||
OnStateRegistered?.Invoke(state);
|
||||
}
|
||||
|
||||
public void InvokeOnStateUnRegistered(T state)
|
||||
{
|
||||
OnStateUnRegistered?.Invoke(state);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -39,6 +39,10 @@ public class UnityEntitiesServiceSingleton:IEntitiesService
|
||||
public CancellationToken CancellationToken => UnityEntitiesService.CancellationToken;
|
||||
|
||||
public IEntity Get(ulong id) => UnityEntitiesService.Get(id);
|
||||
public bool TryGetEntity(ulong id, out IEntity entity) => UnityEntitiesService.TryGetEntity(id, out entity);
|
||||
|
||||
public IEntity GetOrAdd(ulong id, Func<ulong, IEntity> factory)=>UnityEntitiesService.GetOrAdd(id,factory);
|
||||
|
||||
|
||||
public IEntity[] Query<T>()
|
||||
{
|
||||
@@ -124,6 +128,17 @@ public class UnityEntitiesService : MonoBehaviour,IEntitiesService
|
||||
CancellationToken IEntitiesService.CancellationToken => CancellationToken;
|
||||
public static IEntity Get(ulong id)=>Dictionary[id];
|
||||
IEntity IEntitiesService.Get(ulong id)=>Get(id);
|
||||
public static bool TryGetEntity(ulong id, out IEntity entity)
|
||||
{
|
||||
return Dictionary.TryGetValue(id, out entity);
|
||||
}
|
||||
bool IEntitiesService.TryGetEntity(ulong id, out IEntity entity)=>TryGetEntity(id,out entity);
|
||||
public static IEntity GetOrAdd(ulong id, Func<ulong, IEntity> factory)
|
||||
{
|
||||
return Dictionary.GetOrAdd(id, factory);
|
||||
}
|
||||
IEntity IEntitiesService.GetOrAdd(ulong id, Func<ulong, IEntity> factory)=>GetOrAdd(id,factory);
|
||||
|
||||
IEntity[] IEntitiesService.Query<T>()=>Query<T>();
|
||||
public static IEntity[] Query<T>()
|
||||
{
|
||||
|
74
Src/Unity/Scripts/Entity/Editor/UnityEntitiesBinaryEditor.cs
Normal file
74
Src/Unity/Scripts/Entity/Editor/UnityEntitiesBinaryEditor.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace BITKit.Entities.GameEditor
|
||||
{
|
||||
public class UnityEntitiesBinaryEditor : EditorWindow
|
||||
{
|
||||
[MenuItem("Tools/Entities/EntitiesBinaryEditor")]
|
||||
public static void Open()
|
||||
{
|
||||
var window = GetWindow<UnityEntitiesBinaryEditor>();
|
||||
window.Show();
|
||||
}
|
||||
|
||||
private Label _base64Label;
|
||||
private void OnEnable()
|
||||
{
|
||||
rootVisualElement.Clear();
|
||||
|
||||
var button = rootVisualElement.Create<Button>();
|
||||
button.clicked += PrintBytes;
|
||||
|
||||
button.text = "获取二进制数据";
|
||||
|
||||
_base64Label = rootVisualElement.Create<Label>();
|
||||
|
||||
var copyButton = rootVisualElement.Create<Button>();
|
||||
copyButton.text = "复制到剪切板";
|
||||
copyButton.clicked += () =>
|
||||
{
|
||||
EditorGUIUtility.systemCopyBuffer = _base64Label.text;
|
||||
};
|
||||
|
||||
var inputField = rootVisualElement.Create<TextField>();
|
||||
inputField.multiline = true;
|
||||
inputField.label = "输入二进制数据";
|
||||
var applyButton = rootVisualElement.Create<Button>();
|
||||
applyButton.text = "应用数据";
|
||||
applyButton.clicked += () =>
|
||||
{
|
||||
|
||||
var bytes = JsonHelper.Get<byte[]>(inputField.value);
|
||||
|
||||
using var ms = new System.IO.MemoryStream(bytes);
|
||||
using var reader = new System.IO.BinaryReader(ms);
|
||||
Debug.Log($"应用数据中,长度为:{ms.Length}");
|
||||
foreach (var header in UnityEntitiesService.QueryComponents<IEntityBinaryHeader>())
|
||||
{
|
||||
header.Deserialize(reader);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void PrintBytes()
|
||||
{
|
||||
using var ms = new System.IO.MemoryStream();
|
||||
using var writer = new System.IO.BinaryWriter(ms);
|
||||
foreach (var header in UnityEntitiesService.QueryComponents<IEntityBinaryHeader>())
|
||||
{
|
||||
header.Serialize(writer);
|
||||
}
|
||||
var bytes = ms.ToArray();
|
||||
writer.Dispose();
|
||||
ms.Dispose();
|
||||
|
||||
_base64Label.text = JsonHelper.Get(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ace44c921aa7cae419c70332a5c75122
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -6,11 +6,11 @@ using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace BITKit.Entities.Editor
|
||||
namespace BITKit.Entities.GameEditor
|
||||
{
|
||||
public class UnityEntitiesServiceEditor : EditorWindow
|
||||
{
|
||||
[MenuItem("Tools/Entities/UnityEntitiesService")]
|
||||
[MenuItem("Tools/Entities/EntitiesService")]
|
||||
public static void Open()
|
||||
{
|
||||
var window = GetWindow<UnityEntitiesServiceEditor>();
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b084884b824dece40b35759eb218d5c4
|
||||
guid: 75d594a25b599204691b487a447d6e68
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
@@ -1,15 +1,13 @@
|
||||
{
|
||||
"name": "BITKit.Entities.Player.Character",
|
||||
"name": "BITKit.Entities.Net",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
|
||||
"GUID:f822dbf6fdfd4a5469cccaa2e4eed3b6",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:d525ad6bd40672747bde77962f1c401e",
|
||||
"GUID:49b49c76ee64f6b41bf28ef951cb0e50",
|
||||
"GUID:7efac18f239530141802fb139776f333",
|
||||
"GUID:9354affc93e0f3e4a904785e7d4c0f59"
|
||||
"GUID:9354affc93e0f3e4a904785e7d4c0f59",
|
||||
"GUID:c56f2ae4d67b9b947a600c84225206a2"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05850b7e403af6d48bc240ab3c2bc8f4
|
||||
guid: c27e9384ceefce34796410b6135e54a5
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
172
Src/Unity/Scripts/Entity/Net/EntitiesNetService.cs
Normal file
172
Src/Unity/Scripts/Entity/Net/EntitiesNetService.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Timers;
|
||||
using BITKit.Entities.Player;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
[Serializable]
|
||||
public struct EntitiesNetSyncCommand
|
||||
{
|
||||
public byte[] Data;
|
||||
}
|
||||
[Serializable]
|
||||
public struct EntitiesNetSyncBatchCommand
|
||||
{
|
||||
public int Length;
|
||||
public ulong[] Ids;
|
||||
public ulong[] AddressablePaths;
|
||||
public EntitiesNetSyncCommand[] Commands;
|
||||
}
|
||||
|
||||
public class EntitiesNetService : MonoBehaviour
|
||||
{
|
||||
[Header(Constant.Header.Services)]
|
||||
[SerializeReference, SubclassSelector] private ITicker ticker;
|
||||
[SerializeReference, SubclassSelector] private IEntitiesService entitiesService;
|
||||
[SerializeReference, SubclassSelector] private IPlayerService playerService;
|
||||
|
||||
[SerializeReference, SubclassSelector]private INetClient client;
|
||||
[SerializeReference, SubclassSelector]private INetServer server;
|
||||
|
||||
private INetProvider clientNetProvider => client.Source as INetProvider;
|
||||
private INetProvider serverNetProvider => server.Source as INetProvider;
|
||||
|
||||
[Inject]
|
||||
private IEntityBinaryHeader _playerHeader;
|
||||
[Inject] private IAddressable _playerAddressable;
|
||||
[Inject]
|
||||
private IEntity _playerEntity;
|
||||
|
||||
private readonly ConcurrentQueue<EntitiesNetSyncBatchCommand> _batchCommands = new();
|
||||
private readonly ConcurrentQueue<EntitiesNetSyncCommand> _syncCommands = new();
|
||||
|
||||
private void Start()
|
||||
{
|
||||
ticker.Add(Tick);
|
||||
|
||||
clientNetProvider.AddCommandListener<EntitiesNetSyncBatchCommand>(_batchCommands.Enqueue);
|
||||
|
||||
serverNetProvider.AddCommandListener<EntitiesNetSyncCommand>(_syncCommands.Enqueue);
|
||||
|
||||
playerService.OnPlayerInitialized+=OnPlayerInitialized;
|
||||
playerService.OnPlayerDisposed += OnPlayerDisposed;
|
||||
|
||||
destroyCancellationToken.Register(() =>
|
||||
{
|
||||
ticker.Remove(Tick);
|
||||
playerService.OnPlayerInitialized-=OnPlayerInitialized;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void OnPlayerDisposed(Entity obj)
|
||||
{
|
||||
_playerHeader = null;
|
||||
_playerAddressable = null;
|
||||
_playerEntity = null;
|
||||
}
|
||||
|
||||
private void OnPlayerInitialized(Entity obj)
|
||||
{
|
||||
obj.Inject(this);
|
||||
}
|
||||
|
||||
private void OnSyncCommand(EntitiesNetSyncCommand obj)
|
||||
{
|
||||
using var ms = new MemoryStream(obj.Data);
|
||||
using var reader = new BinaryReader(ms);
|
||||
var id = reader.ReadUInt64();
|
||||
var path = reader.ReadUInt64();
|
||||
entitiesService.GetOrAdd(id, x => AddEntity(id, path)).TryGetComponent<IEntityBinaryHeader>(out var header);
|
||||
header.Deserialize(reader);
|
||||
}
|
||||
private void OnBatchCommand(EntitiesNetSyncBatchCommand obj)
|
||||
{
|
||||
for (var i = 0; i < obj.Length; i++)
|
||||
{
|
||||
var id = obj.Ids[i];
|
||||
var path = obj.AddressablePaths[i];
|
||||
var command = obj.Commands[i];
|
||||
var entity = entitiesService.GetOrAdd(id,x=>AddEntity(id,path));
|
||||
entity.TryGetComponent<IEntityBinaryHeader>(out var header);
|
||||
using var ms = new MemoryStream(command.Data);
|
||||
using var reader = new BinaryReader(ms);
|
||||
header.Deserialize(reader);
|
||||
}
|
||||
}
|
||||
private static IEntity AddEntity(ulong id,ulong addressableId)
|
||||
{
|
||||
var entity = AddressableHelper.Get<GameObject>(addressableId);
|
||||
var instance = Instantiate(entity).GetComponent<Entity>();
|
||||
instance.Id = id;
|
||||
instance.WaitForInitializationComplete();
|
||||
return instance;
|
||||
}
|
||||
private void Tick(float deltaTime)
|
||||
{
|
||||
while (_batchCommands.TryDequeue(out var command))
|
||||
{
|
||||
OnBatchCommand(command);
|
||||
}
|
||||
|
||||
while (_syncCommands.TryDequeue(out var command))
|
||||
{
|
||||
OnSyncCommand(command);
|
||||
}
|
||||
|
||||
|
||||
if (client.IsConnected is false && server.IsRunningServer is false) return;
|
||||
using var memoryStream = new MemoryStream();
|
||||
if (client.IsConnected && _playerEntity as Entity && _playerHeader != null)
|
||||
{
|
||||
using var writer = new BinaryWriter(memoryStream);
|
||||
|
||||
writer.Write(_playerEntity.Id);
|
||||
writer.Write(_playerAddressable.AddressableId);
|
||||
|
||||
_playerHeader.Serialize(writer);
|
||||
var command = new EntitiesNetSyncCommand
|
||||
{
|
||||
Data = memoryStream.ToArray()
|
||||
};
|
||||
clientNetProvider.ServerCommand(command);
|
||||
}
|
||||
else if (server.IsRunningServer)
|
||||
{
|
||||
using var writer = new BinaryWriter(memoryStream);
|
||||
|
||||
var headers = entitiesService.QueryComponents<IEntity, IEntityBinaryHeader, IAddressable>();
|
||||
|
||||
var batchCommand = new EntitiesNetSyncBatchCommand()
|
||||
{
|
||||
Length = headers.Length,
|
||||
Ids = new ulong[headers.Length],
|
||||
AddressablePaths = new ulong[headers.Length],
|
||||
Commands = new EntitiesNetSyncCommand[headers.Length]
|
||||
};
|
||||
|
||||
var count = -1;
|
||||
foreach (var (entity, header, addressable) in headers)
|
||||
{
|
||||
count++;
|
||||
using var ms = new MemoryStream();
|
||||
using var entityWriter = new BinaryWriter(ms);
|
||||
|
||||
header.Serialize(entityWriter);
|
||||
entityWriter.Flush();
|
||||
|
||||
batchCommand.Ids[count] = entity.Id;
|
||||
batchCommand.AddressablePaths[count] = addressable.AddressableId;
|
||||
batchCommand.Commands[count] = new EntitiesNetSyncCommand { Data = ms.ToArray() };
|
||||
}
|
||||
serverNetProvider.AllClientCommand(batchCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Src/Unity/Scripts/Entity/Net/EntitiesNetService.cs.meta
Normal file
11
Src/Unity/Scripts/Entity/Net/EntitiesNetService.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eac64f495178d7844bf83d3b03736ea1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
32
Src/Unity/Scripts/Entity/Net/EntityNetConfig.cs
Normal file
32
Src/Unity/Scripts/Entity/Net/EntityNetConfig.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit.Entities
|
||||
{
|
||||
public sealed class EntityNetConfig : EntityBehavior
|
||||
{
|
||||
[SerializeField] private bool serverOnly;
|
||||
[SerializeReference,SubclassSelector] private INetClient netClient;
|
||||
[SerializeReference,SubclassSelector] private INetServer netServer;
|
||||
[SerializeReference,SubclassSelector] private ITicker ticker;
|
||||
public override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
ticker?.Add(OnTick);
|
||||
}
|
||||
private void OnDestroy()
|
||||
{
|
||||
ticker?.Remove(OnTick);
|
||||
}
|
||||
private void OnTick(float deltaTime)
|
||||
{
|
||||
if (netClient.IsConnected && serverOnly)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Src/Unity/Scripts/Entity/Net/EntityNetConfig.cs.meta
Normal file
11
Src/Unity/Scripts/Entity/Net/EntityNetConfig.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 58fae32cecb66cc42925dedf4fde21bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,16 +1,20 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit.Entities.Player
|
||||
{
|
||||
public class LocalPlayerBehavior : EntityBehavior
|
||||
public class LocalPlayerBehavior : EntityBehavior,IEntityBinaryComponent
|
||||
{
|
||||
public int Id { get; }= new ConstantHash(nameof(LocalPlayerBehavior));
|
||||
|
||||
private IEntityPlayerComponent[] playerComponents;
|
||||
private CancellationTokenSource initializeCancellationTokenSource;
|
||||
private CancellationTokenSource disposeCancellationTokenSource;
|
||||
|
||||
public override async void OnStart()
|
||||
{
|
||||
initializeCancellationTokenSource = new CancellationTokenSource();
|
||||
@@ -51,5 +55,13 @@ namespace BITKit.Entities.Player
|
||||
disposeCancellationTokenSource.Dispose();
|
||||
UnityPlayerServiceService.UnRegister((Entity)UnityEntity);
|
||||
}
|
||||
public void Serialize(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
}
|
||||
public void Deserialize(BinaryReader reader)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
36
Src/Unity/Scripts/Entity/Player/ProxyPlayerComponent.cs
Normal file
36
Src/Unity/Scripts/Entity/Player/ProxyPlayerComponent.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit.Entities.Player
|
||||
{
|
||||
public class ProxyPlayerComponent : EntityBehavior,IEntityBinaryComponent
|
||||
{
|
||||
public int Id { get; } = new ConstantHash(nameof(LocalPlayerBehavior));
|
||||
private readonly IntervalUpdate _timeout = new(8);
|
||||
public override void OnStart()
|
||||
{
|
||||
base.OnStart();
|
||||
_timeout.Reset();
|
||||
}
|
||||
public void Serialize(BinaryWriter writer)
|
||||
{
|
||||
}
|
||||
public void Deserialize(BinaryReader reader)
|
||||
{
|
||||
reader.ReadInt32();
|
||||
_timeout.Reset();
|
||||
}
|
||||
public override void OnUpdate(float deltaTime)
|
||||
{
|
||||
base.OnUpdate(deltaTime);
|
||||
if (_timeout.AllowUpdate)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Src/Unity/Scripts/Entity/Player/ProxyPlayerComponent.cs.meta
Normal file
11
Src/Unity/Scripts/Entity/Player/ProxyPlayerComponent.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e25b0e453185f74428146cbe5a5f99fa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BITKit.StateMachine;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -36,6 +37,9 @@ namespace BITKit.Entities.Player
|
||||
remove => stateMachine.OnStateChanged -= value;
|
||||
}
|
||||
|
||||
public event Action<T> OnStateRegistered;
|
||||
public event Action<T> OnStateUnRegistered;
|
||||
|
||||
public IDictionary<Type, T> StateDictionary => stateMachine.StateDictionary;
|
||||
|
||||
void IStateMachine<T>.Initialize()
|
||||
@@ -62,5 +66,16 @@ namespace BITKit.Entities.Player
|
||||
{
|
||||
stateMachine.TransitionState(state);
|
||||
}
|
||||
public virtual void Register(T newState)=>StateMachineUtils.Register(this,newState);
|
||||
public virtual void UnRegister(T newState)=>StateMachineUtils.UnRegister(this,newState);
|
||||
void IStateMachine<T>.InvokeOnStateRegistered(T state)
|
||||
{
|
||||
OnStateRegistered?.Invoke(state);
|
||||
}
|
||||
|
||||
void IStateMachine<T>.InvokeOnStateUnRegistered(T state)
|
||||
{
|
||||
OnStateUnRegistered?.Invoke(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80d35d9e6778dc84b88662124834dd35
|
||||
guid: ea9ee800e8536fe45a4868de4bc936d9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
@@ -1,10 +1,9 @@
|
||||
{
|
||||
"name": "BITKit.WorkdChunk",
|
||||
"name": "BITKit.Entities.Variable",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:a209c53514018594f9f482516f2a6781",
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||
"GUID:9400d40641bab5b4a9702f65bf5c6eb5"
|
||||
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e144f3bb79485843b0a2df56bef0900
|
||||
guid: f602b6f914f91d4499383d874af1decd
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
105
Src/Unity/Scripts/Entity/Variable/EntityVariable.cs
Normal file
105
Src/Unity/Scripts/Entity/Variable/EntityVariable.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Pool;
|
||||
|
||||
namespace BITKit.Entities.Variables
|
||||
{
|
||||
public interface IVariable
|
||||
{
|
||||
string Variable { get; set; }
|
||||
string[] Variables { get; }
|
||||
event Action<string,string> OnVariableChanged;
|
||||
event Func<string,bool> TryChangeVariable;
|
||||
event Func<string> CollectVariables;
|
||||
|
||||
}
|
||||
[Serializable]
|
||||
public sealed class IVariableFromDI : InjectFromDI<IVariable>,IVariable
|
||||
{
|
||||
private IVariable _variableImplementation => Value;
|
||||
public string Variable
|
||||
{
|
||||
get => _variableImplementation.Variable;
|
||||
set => _variableImplementation.Variable = value;
|
||||
}
|
||||
|
||||
public string[] Variables => _variableImplementation.Variables;
|
||||
|
||||
public event Action<string, string> OnVariableChanged
|
||||
{
|
||||
add => _variableImplementation.OnVariableChanged += value;
|
||||
remove => _variableImplementation.OnVariableChanged -= value;
|
||||
}
|
||||
|
||||
public event Func<string, bool> TryChangeVariable
|
||||
{
|
||||
add => _variableImplementation.TryChangeVariable += value;
|
||||
remove => _variableImplementation.TryChangeVariable -= value;
|
||||
}
|
||||
|
||||
public event Func<string> CollectVariables
|
||||
{
|
||||
add => _variableImplementation.CollectVariables += value;
|
||||
remove => _variableImplementation.CollectVariables -= value;
|
||||
}
|
||||
}
|
||||
|
||||
[CustomType(typeof(IVariable),true)]
|
||||
public sealed class EntityVariable:MonoBehaviour,IVariable
|
||||
{
|
||||
public string Variable
|
||||
{
|
||||
get => _variable;
|
||||
set
|
||||
{
|
||||
if (TryChangeVariable is null || TryChangeVariable.CastAsFunc().All(Yes))
|
||||
{
|
||||
OnVariableChanged?.Invoke(_variable, _variable = value);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
bool Yes(Func<string, bool> arg)
|
||||
{
|
||||
return arg.Invoke(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string[] Variables {
|
||||
get
|
||||
{
|
||||
if (CollectVariables is null)
|
||||
{
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
var listPool=ListPool<string>.Get();
|
||||
foreach (var x in CollectVariables.CastAsFunc())
|
||||
{
|
||||
listPool.Add(x.Invoke());
|
||||
}
|
||||
var result = listPool.ToArray();
|
||||
ListPool<string>.Release(listPool);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
public event Action<string,string> OnVariableChanged;
|
||||
public event Func<string,bool> TryChangeVariable;
|
||||
public event Func<string> CollectVariables;
|
||||
|
||||
private string _variable="Default";
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (GetType().GetCustomAttribute<CustomTypeAttribute>() is { AsGlobal: true })
|
||||
{
|
||||
DI.Register<IVariable>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Src/Unity/Scripts/Entity/Variable/EntityVariable.cs.meta
Normal file
11
Src/Unity/Scripts/Entity/Variable/EntityVariable.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f0c6c2d406bfdaf46ba4ab9883f71066
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Src/Unity/Scripts/Entity/World.meta
Normal file
8
Src/Unity/Scripts/Entity/World.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14bb579de4539df4caa9a3af10e10715
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,12 +1,11 @@
|
||||
{
|
||||
"name": "BITKit.Entities.Physics.Runtime",
|
||||
"name": "BITKit.Entities.World.Runtime",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:709caf8d7fb6ef24bbba0ab9962a3ad0",
|
||||
"GUID:a3de65b07192e7d49bad7b4032d681de",
|
||||
"GUID:7efac18f239530141802fb139776f333"
|
||||
"GUID:1193c2664d97cc049a6e4c486c6bce71",
|
||||
"GUID:bdb069e155d2f944cb1bf28602b6d4c1"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be39401f40b20344a8e59d5ddab532bc
|
||||
guid: 5835538f89758aa42ab9ebe7a5de98fb
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
24
Src/Unity/Scripts/Entity/World/EntityLOD.cs
Normal file
24
Src/Unity/Scripts/Entity/World/EntityLOD.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using BITKit.Entities;
|
||||
using Quadtree;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit.OpenWorld
|
||||
{
|
||||
public class EntityLOD : EntityBehavior,IWorldChunkObject
|
||||
{
|
||||
public Bounds GetBounds()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public Node<IWorldChunkObject> ParentNode { get; set; }
|
||||
public void QuadTree_Root_Initialized(IQuadtreeRoot<IWorldChunkObject, Node<IWorldChunkObject>> root)
|
||||
{
|
||||
}
|
||||
|
||||
public int Id { get; set; }
|
||||
public int Lod { get; set; }
|
||||
}
|
||||
}
|
11
Src/Unity/Scripts/Entity/World/EntityLOD.cs.meta
Normal file
11
Src/Unity/Scripts/Entity/World/EntityLOD.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bcd183d2a785322429c5e0e964591d82
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -26,6 +26,10 @@ namespace BITKit.Events
|
||||
{
|
||||
public List<UnityEventData> Targets = new List<UnityEventData>();
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
Invoke(Array.Empty<object>());
|
||||
}
|
||||
public void Invoke(params object[] objects)
|
||||
{
|
||||
foreach (var x in Targets)
|
||||
@@ -170,6 +174,7 @@ namespace BITKit.Events
|
||||
{
|
||||
x.MethodName = changeEvent.newValue;
|
||||
EditorUtility.SetDirty(_property.serializedObject.targetObject);
|
||||
Update();
|
||||
});
|
||||
|
||||
field.value = x.MethodName;
|
||||
|
@@ -1,88 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Collections.Concurrent;
|
||||
using Cysharp.Threading.Tasks;
|
||||
namespace BITKit
|
||||
{
|
||||
public class BehaviourHelper : MonoBehaviour, IMainTicker
|
||||
{
|
||||
public static Action OnStop;
|
||||
public static bool Actived;
|
||||
static BehaviourHelper Singleton;
|
||||
ConcurrentQueue<Action> queue = new();
|
||||
List<Action<float>> Updates = new();
|
||||
List<Action<float>> FixedUpdates = new();
|
||||
public void Add(Action action)
|
||||
{
|
||||
queue.Enqueue(action);
|
||||
}
|
||||
public void AddAsUpdate(Action<float> action)
|
||||
{
|
||||
Updates.Add(action);
|
||||
}
|
||||
public void AddAsFixedUpdate(Action<float> action)
|
||||
{
|
||||
FixedUpdates.Add(action);
|
||||
}
|
||||
public void RemoveAsUpdate(Action<float> action)
|
||||
{
|
||||
Updates.Remove(action);
|
||||
}
|
||||
public void RemoveAsFixedUpdate(Action<float> action)
|
||||
{
|
||||
FixedUpdates.Remove(action);
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
lock (queue)
|
||||
{
|
||||
while (queue.TryDequeue(out var action))
|
||||
{
|
||||
try
|
||||
{
|
||||
action.Invoke();
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var update in Updates.ToArray())
|
||||
{
|
||||
update.Invoke(Time.deltaTime);
|
||||
}
|
||||
}
|
||||
void FixedUpdate()
|
||||
{
|
||||
foreach (var fixedUpdate in FixedUpdates.ToArray())
|
||||
{
|
||||
fixedUpdate.Invoke(Time.fixedDeltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
OnStop?.Invoke();
|
||||
}
|
||||
[RuntimeInitializeOnLoadMethod]
|
||||
static void Initialize()
|
||||
{
|
||||
GameObject go = new();
|
||||
GameObject.DontDestroyOnLoad(go);
|
||||
var behaviourHelper = go.AddComponent<BehaviourHelper>();
|
||||
Singleton = behaviourHelper;
|
||||
DI.Register<IMainTicker>(behaviourHelper);
|
||||
Debug.Log($"{nameof(IMainTicker)}已创建");
|
||||
go.name = nameof(BehaviourHelper);
|
||||
go.hideFlags = HideFlags.NotEditable;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d40f7cbccced56a44913d38b56e9810c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Src/Unity/Scripts/I18N.meta
Normal file
8
Src/Unity/Scripts/I18N.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f50549879226e640a00e464b2eeabd3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
Src/Unity/Scripts/I18N/I18N.CJK.dll
Normal file
BIN
Src/Unity/Scripts/I18N/I18N.CJK.dll
Normal file
Binary file not shown.
33
Src/Unity/Scripts/I18N/I18N.CJK.dll.meta
Normal file
33
Src/Unity/Scripts/I18N/I18N.CJK.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec150d05173af9444b6402522b4973a5
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
Src/Unity/Scripts/I18N/I18N.MidEast.dll
Normal file
BIN
Src/Unity/Scripts/I18N/I18N.MidEast.dll
Normal file
Binary file not shown.
33
Src/Unity/Scripts/I18N/I18N.MidEast.dll.meta
Normal file
33
Src/Unity/Scripts/I18N/I18N.MidEast.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 51cf551d5913a5845904cd97ea20fef8
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
Src/Unity/Scripts/I18N/I18N.Other.dll
Normal file
BIN
Src/Unity/Scripts/I18N/I18N.Other.dll
Normal file
Binary file not shown.
33
Src/Unity/Scripts/I18N/I18N.Other.dll.meta
Normal file
33
Src/Unity/Scripts/I18N/I18N.Other.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 175790c6a1317e142a19b1a043c90bc8
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
Src/Unity/Scripts/I18N/I18N.Rare.dll
Normal file
BIN
Src/Unity/Scripts/I18N/I18N.Rare.dll
Normal file
Binary file not shown.
33
Src/Unity/Scripts/I18N/I18N.Rare.dll.meta
Normal file
33
Src/Unity/Scripts/I18N/I18N.Rare.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8dc9a73c7b6d1914bb23eeb4a8a8c00b
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
Src/Unity/Scripts/I18N/I18N.West.dll
Normal file
BIN
Src/Unity/Scripts/I18N/I18N.West.dll
Normal file
Binary file not shown.
33
Src/Unity/Scripts/I18N/I18N.West.dll.meta
Normal file
33
Src/Unity/Scripts/I18N/I18N.West.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b527abeeb65148439f8220d1e8009da
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
Src/Unity/Scripts/I18N/I18N.dll
Normal file
BIN
Src/Unity/Scripts/I18N/I18N.dll
Normal file
Binary file not shown.
33
Src/Unity/Scripts/I18N/I18N.dll.meta
Normal file
33
Src/Unity/Scripts/I18N/I18N.dll.meta
Normal file
@@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60d68942ff0240446b74e7f32a1945ae
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
16
Src/Unity/Scripts/I18N/Plugins.I18N.asmdef
Normal file
16
Src/Unity/Scripts/I18N/Plugins.I18N.asmdef
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "Plugins.I18N",
|
||||
"rootNamespace": "",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
7
Src/Unity/Scripts/I18N/Plugins.I18N.asmdef.meta
Normal file
7
Src/Unity/Scripts/I18N/Plugins.I18N.asmdef.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d2740ce45cd8814e84965d80405bb7d
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Src/Unity/Scripts/IO.meta
Normal file
8
Src/Unity/Scripts/IO.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cac7e494c3644094590640578295e381
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
53
Src/Unity/Scripts/IO/FileDlg.cs
Normal file
53
Src/Unity/Scripts/IO/FileDlg.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Runtime.InteropServices;
|
||||
using System;
|
||||
|
||||
namespace System.IO
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
public class OpenFileName
|
||||
{
|
||||
public int structSize = 0;
|
||||
public IntPtr dlgOwner = IntPtr.Zero;
|
||||
public IntPtr instance = IntPtr.Zero;
|
||||
public String filter = null;
|
||||
public String customFilter = null;
|
||||
public int maxCustFilter = 0;
|
||||
public int filterIndex = 0;
|
||||
public String file = null;
|
||||
public int maxFile = 0;
|
||||
public String fileTitle = null;
|
||||
public int maxFileTitle = 0;
|
||||
public String initialDir = null;
|
||||
public String title = null;
|
||||
public int flags = 0;
|
||||
public short fileOffset = 0;
|
||||
public short fileExtension = 0;
|
||||
public String defExt = null;
|
||||
public IntPtr custData = IntPtr.Zero;
|
||||
public IntPtr hook = IntPtr.Zero;
|
||||
public String templateName = null;
|
||||
public IntPtr reservedPtr = IntPtr.Zero;
|
||||
public int reservedInt = 0;
|
||||
public int flagsEx = 0;
|
||||
}
|
||||
public class LocalDialog
|
||||
{
|
||||
//链接指定系统函数 打开文件对话框
|
||||
[DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
|
||||
public static extern bool GetOpenFileName([In, Out] OpenFileName ofn);
|
||||
public static bool GetOFN([In, Out] OpenFileName ofn)
|
||||
{
|
||||
return GetOpenFileName(ofn);
|
||||
}
|
||||
|
||||
//链接指定系统函数 另存为对话框
|
||||
[DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
|
||||
public static extern bool GetSaveFileName([In, Out] OpenFileName ofn);
|
||||
public static bool GetSFN([In,Out] OpenFileName ofn)
|
||||
{
|
||||
return GetSaveFileName(ofn);
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user