This commit is contained in:
CortexCore
2023-12-03 17:35:43 +08:00
parent ba342d6627
commit ba9f4eda80
702 changed files with 162078 additions and 21050 deletions

View File

@@ -20,7 +20,7 @@ namespace BITKit
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true, Inherited = true)]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = true, Inherited = true)]
public class CustomTypeAttribute : System.Attribute
{
public readonly Type Type;

View File

@@ -40,7 +40,7 @@ namespace BITKit
/// <summary>
/// 基础物品
/// </summary>
public interface IBasicItem :IPropertable
public interface IBasicItem :IPropertable,ICloneable
{
/// <summary>
/// 唯一Id
@@ -76,7 +76,7 @@ namespace BITKit
/// 被托管的物品
/// </summary>
[Serializable]
public record ManagedItem : IBasicItem
public class ManagedItem : IBasicItem
{
#region
public int Id;
@@ -135,8 +135,14 @@ namespace BITKit
{
return property.CopyPropertiesFrom(propertable);
}
#endregion
public object Clone()
{
var item = MemberwiseClone() as ManagedItem;
item!.Id = Id;
return item;
}
}
#endregion
}

View File

@@ -0,0 +1,102 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace BITKit.Modification
{
/// <summary>
/// 不兼容的改装
/// </summary>
public class IncompatibleModifyException : InGameException
{
public IncompatibleModifyException(IModifyElement[] errorElements) : base()
{
}
}
/// <summary>
/// 没有前置改装
/// </summary>
public class NotRequireModifyException : InGameException
{
public NotRequireModifyException(IModifyElement[] errorElements) : base()
{
}
}
/// <summary>
/// 不支持的改装
/// </summary>
public class NotSupportModifyException : InGameException
{
public NotSupportModifyException(IModifyElement[] errorElements) : base()
{
}
}
/// <summary>
/// 改装元素
/// </summary>
public interface IModifyElement
{
IModifyElement[] Require { get; }
IModifyElement[] Incompatible { get; }
}
/// <summary>
/// 改装管理器
/// </summary>
public interface IModifyManager
{
/// <summary>
/// 获取所有改装
/// </summary>
IDictionary<IModifyElement,object> Modifies { get; }
/// <summary>
/// 获取所有已改装
/// </summary>
IDictionary<IModifyElement,object> Modified { get; }
/// <summary>
/// 添加改装
/// </summary>
/// <param name="modify"></param>
void Add(IModifyElement modify,object obj);
/// <summary>
/// 移除改装
/// </summary>
/// <param name="modify"></param>
void Remove(IModifyElement modify,out object obj);
}
public class ModifyManager : IModifyManager
{
public virtual IDictionary<IModifyElement, object> Modifies { get;private set; } =new Dictionary<IModifyElement,object>();
public virtual IDictionary<IModifyElement, object> Modified => new Dictionary<IModifyElement, object>(Modifies.Where(x=>x.Value is not null));
public virtual void Add(IModifyElement modify, object obj)
{
var list = new List<IModifyElement>();
list.AddRange(Modified.Keys);
list.Add(modify);
if(list.All(x=>x.Require?.Any(y=>list.Contains(y)) is false))
throw new NotRequireModifyException(list.ToArray());
var incompatible = list.Where(x=>x.Incompatible is not null).SelectMany(x => x.Incompatible).ToArray();
if(MathE.Contains(incompatible,list))
throw new IncompatibleModifyException(incompatible);
Modified.Add(modify,obj);
}
public virtual void Remove(IModifyElement modify,out object obj)
{
var list = new List<IModifyElement>();
list.AddRange(Modified.Keys);
list.Remove(modify);
var requires = list.Where(x=>x.Require is not null).SelectMany(x => x.Require).ToArray();
if(requires.Contains(modify))
throw new NotRequireModifyException(requires);
obj = Modified[modify];
Modified.Remove(modify);
}
}
}

View File

@@ -11,7 +11,6 @@ namespace BITKit
/// </summary>
public interface IProperty
{
}
/// <summary>
/// 属性接口
@@ -71,11 +70,7 @@ namespace BITKit
{
foreach (var x in factory)
{
properties.Add(x.GetType()!.FullName, x);
foreach (var att in x.GetType().GetCustomAttributes<CustomTypeAttribute>())
{
properties.Add(att.Type!.FullName, x);
}
AddPropertyInternal(x);
}
}
Dictionary<string, object> properties=new();
@@ -104,7 +99,8 @@ namespace BITKit
}
else
{
properties.Add(typeof(T).FullName, x = addFactory.Invoke());
AddPropertyInternal(addFactory.Invoke());
//properties.Add(typeof(T).FullName, x = addFactory.Invoke());
return (T)x;
}
}
@@ -132,17 +128,24 @@ namespace BITKit
}
public bool TrySetProperty<T>(T value)
{
if (properties.TryGetValue(typeof(T).FullName, out var x))
bool result = false;
foreach (var pair in properties.Where(x=>x.Value is T).ToArray())
{
properties[typeof(T).FullName] = value;
return true;
}
else
{
return false;
properties[pair.Key] = value;
result = true;
}
return result;
// if (properties.TryGetValue(typeof(T).FullName, out var x))
// {
// properties[typeof(T).FullName] = value;
// return true;
// }
// else
// {
// return false;
// }
}
public object[] GetProperties()=>properties.Values.ToArray();
public object[] GetProperties()=>properties.Values.Distinct().ToArray();
public void Read(BinaryReader r)
{
@@ -168,9 +171,21 @@ namespace BITKit
ClearProperties();
foreach (var x in propertable.GetProperties())
{
properties.Add(x.GetType().FullName, x);
AddPropertyInternal(x);
}
return true;
}
private void AddPropertyInternal(object value)
{
if (value is ICloneable cloneable)
{
value = cloneable.Clone();
}
properties.Set(value.GetType().FullName, value);
foreach (var att in value.GetType().GetCustomAttributes<CustomTypeAttribute>())
{
properties.Set(att.Type!.FullName, value);
}
}
}
}

View File

@@ -0,0 +1,11 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BITKit.UX
{
public interface IUXPopup
{
void Popup(string content,float duration=3f);
}
}

View File

@@ -0,0 +1,53 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!74 &7400000
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Emety_Inspect
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves: []
m_ScaleCurves: []
m_FloatCurves: []
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings: []
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 1
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 0
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves: []
m_EulerEditorCurves: []
m_HasGenericRootTransform: 0
m_HasMotionFloatCurves: 0
m_Events: []

View File

@@ -229,6 +229,15 @@
"processors": "",
"interactions": "Press",
"initialStateCheck": false
},
{
"name": "Inspect",
"type": "Button",
"id": "69a6c6fe-6caf-478d-aef5-e51e17372a83",
"expectedControlType": "Button",
"processors": "",
"interactions": "Hold,Press",
"initialStateCheck": false
}
],
"bindings": [
@@ -550,6 +559,17 @@
"action": "ToggleCamera",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "c7bf69ae-febf-4280-b153-d529229f82b5",
"path": "<Keyboard>/i",
"interactions": "",
"processors": "",
"groups": "",
"action": "Inspect",
"isComposite": false,
"isPartOfComposite": false
}
]
},

View File

@@ -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;
}
}

View File

@@ -61,7 +61,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)
{

View File

@@ -48,6 +48,9 @@ namespace BITKit
{
currentEuler = Vector3.Scale(currentEuler, rotationWeight);
currentPosition = Vector3.Scale(currentPosition, positionWeight);
currentEuler = Vector3.ClampMagnitude(currentEuler, 4096);
currentPosition = Vector3.ClampMagnitude(currentPosition, 4096);
if (disabledRotation is false)
switch (currentEuler, globalRotation)

View File

@@ -7,6 +7,7 @@ namespace BITKit
{
public class LocationAdditiveElement : MonoBehaviour
{
[SerializeField] private bool useLateUpdate;
[SerializeField] private LocationAdditive locationAdditive;
[SerializeField] private Vector3 positionWeight = Vector3.one;
[SerializeField] private Vector3 eulerWeight = Vector3.one;
@@ -18,6 +19,18 @@ namespace BITKit
}
private void Update()
{
if (useLateUpdate) return;
Tick();
}
private void LateUpdate()
{
if (!useLateUpdate) return;
Tick();
}
private void Tick()
{
var localPosition = Transform.localPosition;
var localEulerAngles = Transform.localEulerAngles;

View File

@@ -9,14 +9,29 @@ namespace BITKit.Sensors
public class RaySensor : Sensor
{
[Header(Constant.Header.Settings)]
[SerializeField] private float radius = 0.16f;
public float distance;
public override IEnumerable<Transform> Get() => detected;
private readonly RaycastHit[] raycasts = new RaycastHit[16];
public override UniTask Execute()
{
var _transform = transform;
var ray = new Ray(_transform.position,_transform.forward);
var size = Physics.RaycastNonAlloc(ray, raycasts, distance, detectLayer);
var forward = _transform.forward;
var position = _transform.position;
var size = 0;
if (radius is not 0)
{
size = Physics.CapsuleCastNonAlloc(position, position + forward * distance, radius, forward,
raycasts
, distance, detectLayer);
}
else
{
var ray = new Ray(_transform.position,_transform.forward);
size = Physics.RaycastNonAlloc(ray, raycasts, distance, detectLayer);
}
detected = raycasts
.Take(size)
.Select(x => x.collider)

View File

@@ -28,20 +28,21 @@ namespace BITKit.Sensors
[Header(Constant.Header.InternalVariables)]
// ReSharper disable once FieldCanBeMadeReadOnly.Local
private List<Collider> detected = new();
private readonly Queue<Collider> triggerEnterQueue=new();
private readonly Queue<Collider> triggerExitQueue=new();
private readonly Queue<Collider> triggerEnterQueue = new();
private readonly Queue<Collider> triggerExitQueue = new();
private bool diagnosisNextFrame;
private void OnTriggerEnter(Collider _collider)
{
triggerEnterQueue.Enqueue(_collider);
if(immediately)Rebuild();
if (immediately) Rebuild();
}
private void OnTriggerExit(Collider _collider)
{
triggerExitQueue.Enqueue(_collider);
if(immediately)Rebuild();
if (immediately) Rebuild();
}
private void OnCollisionEnter(Collision collision)
@@ -63,24 +64,17 @@ namespace BITKit.Sensors
public IEnumerable<Transform> Get()
{
if(BITAppForUnity.IsPlaying is false)return ArraySegment<Transform>.Empty;
try
{
return detected.Select(x => x.transform).ToArray();
return detected.Select(x => x.transform).ToArray();
}
catch (MissingReferenceException)
{
List<Transform> list = new();
foreach (var x in detected)
{
try
{
list.Add(x.transform);
}
catch (MissingReferenceException){}
}
return list.ToArray();
detected = detected.Where(x => x).ToList();
}
}
return detected.Select(x => x.transform).ToArray();
}
//public bool IsValid(Collider _collider) => ignores.Contains(_collider.gameObject) is false;
public bool IsValid(Collider _collider)
@@ -177,6 +171,7 @@ namespace BITKit.Sensors
protected override void OnUpdate()
{
if (!agent || detectedContainer is null) return;
if (BITAppForUnity.IsPlaying is false) return;
detectedContainer.Clear();
foreach (var x in agent.Get())
{

View File

@@ -13,6 +13,19 @@ namespace BITKit.UX
public string message = "message";
}
[Serializable]
public sealed class UXAlertPopup : IUXPopup
{
public void Popup(string content, float duration = 3f)
{
Alert.Print(new AlertMessage()
{
title = "Alert",
message = content
});
}
}
public static class Alert
{
public static void Print(AlertMessage message)

View File

@@ -22,7 +22,7 @@ namespace BITKit.UX
this.visualElement = visualElement;
contextLabel = visualElement.Q<Label>(UXConstant.ContextLabel);
titleLabel = visualElement.Q<Label>(UXConstant.TitleLabel);
numberLabel = visualElement.Q<Label>(UXConstant.TitleLabel);
numberLabel = visualElement.Q<Label>(UXConstant.NumberLabel);
descriptionLabel = visualElement.Q<Label>(UXConstant.DescriptionLabel);
button = visualElement.Q<Button>(UXConstant.MainButton);
secButton = visualElement.Q<Button>(UXConstant.SecButton);

View File

@@ -0,0 +1,83 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BITKit;
using BITKit.UX;
using UnityEngine;
using UnityEngine.UIElements;
namespace BITKit.UX
{
[Serializable]
public class UXPopupSelector:IUXPopup
{
[SerializeReference,SubclassSelector] private IReference popupPath;
public void Popup(string content, float duration = 3)
{
UXPopup.Dictionary[popupPath.Value].Popup(content,duration);
}
}
public sealed class UXPopup : MonoBehaviour,IUXPopup
{
internal static readonly Dictionary<string,UXPopup> Dictionary=new();
[SerializeField] private UIDocument document;
[SerializeReference, SubclassSelector] private IReference containerPath;
[SerializeReference, SubclassSelector] private IReference popupPath;
[SerializeField] private VisualTreeAsset popupTemplate;
private VisualElement container;
private readonly List<ViewModel> instances = new();
private class ViewModel
{
public VisualElement visualElement;
public float exitTime;
public bool disposed;
}
private void Start()
{
container = document.rootVisualElement.Q<VisualElement>(containerPath.Value);
Dictionary.Add(popupPath.Value,this);
destroyCancellationToken.Register(() => Dictionary.Remove(popupPath.Value));
container.Clear();
}
private void Update()
{
foreach (var x in instances.Where(x=>Time.time > x.exitTime))
{
x.visualElement.RemoveFromHierarchy();
x.visualElement.SetOpacity(
Mathf.MoveTowards(x.visualElement.GetOpacity(),0,Time.deltaTime)
);
x.disposed = x.visualElement.GetOpacity() is 0;
}
instances.RemoveAll(x =>x.disposed);
container.SetActive(container.childCount > 0);
}
public void Popup(string content, float duration = 3)
{
var visualElement =new UXContainer(container.Create<VisualElement>(popupTemplate.CloneTree))
{
contextLabel =
{
text = content
}
};
instances.Add(new ViewModel()
{
visualElement = visualElement,
exitTime = Time.time + duration
});
}
}
}

View File

@@ -192,7 +192,7 @@ namespace BITKit
// }
} while (property.NextVisible(false));
foreach (var method in serializedObject.targetObject.GetType().GetMethods())
foreach (var method in serializedObject.targetObject.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
if (method.GetCustomAttribute<BITAttribute>() is null) continue;
if (method.GetParameters().Length is not 0) continue;

View File

@@ -614,6 +614,10 @@ namespace BITKit
{
self.style.display = new(active ? DisplayStyle.Flex : DisplayStyle.None);
}
public static void SetVisible(this VisualElement self, bool visible)
{
self.style.visibility = new(visible ? Visibility.Visible : Visibility.Hidden);
}
public static float GetOpacity(this VisualElement self) => self.style.opacity.value;
public static void SetOpacity(this VisualElement self, float value) => self.style.opacity = new(value);
public static void ScrollToBottom(this ScrollView self)

View File

@@ -119,6 +119,8 @@ namespace BITKit
}
public double Interval=1;
private double allowUpdateTime=0;
public bool AllowUpdateWithoutReset => BITApp.Time.TimeAsDouble >= allowUpdateTime;
public double Remaining => allowUpdateTime - BITApp.Time.TimeAsDouble;
public bool AllowUpdate
{
get
@@ -128,7 +130,7 @@ namespace BITKit
return true;
}
}
public bool AllowUpdateWithoutReset => BITApp.Time.TimeAsDouble >= allowUpdateTime;
public void Reset(bool immediately = false)
{
allowUpdateTime = BITApp.Time.TimeAsDouble + (immediately ? 0 : Interval);

View File

@@ -26,6 +26,8 @@ namespace BITKit.Vehicles
public sealed class Vehicle : EntityBehavior
{
[Header(Constant.Header.Services)] public bool Enabled;
[Header(Constant.Header.Settings)] public float maxMotorTorque = 64;
[SerializeField] private float maxSteeringAngle = 45;
[SerializeField] private float brakeTorque;
@@ -98,6 +100,8 @@ namespace BITKit.Vehicles
}
public override void OnUpdate(float deltaTime)
{
if (Enabled is false) return;
var torque = maxMotorTorque *(optionalVertical.Allow ? optionalVertical.Value : vertical);
var steel =maxSteeringAngle * (optionalHorizontal.Allow ? optionalHorizontal.Value : horizontal);
axisInfos.ForEach(x =>