BITKit/Packages/Runtime~/Unity/Common/Scripts/Utility/Utility.cs

259 lines
7.2 KiB
C#
Raw Normal View History

2023-06-05 19:57:17 +08:00
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UIElements;
2023-06-29 14:57:11 +08:00
2023-06-05 19:57:17 +08:00
namespace BITKit
{
public abstract class Provider : MonoBehaviour, IProvider
{
public virtual T Get<T>()
{
throw new NotImplementedException();
}
public abstract void Set<T>(T obj);
}
public abstract class Provider<T> : Provider, IProvider<T>
{
public abstract T Get();
public abstract void Set(T t);
public override void Set<Unknow>(Unknow obj)
{
if (obj is T t)
{
Set(t);
}
}
}
public abstract class BITAction : MonoBehaviour, IAction
{
2023-06-29 14:57:11 +08:00
public abstract void Execute();
2023-06-05 19:57:17 +08:00
}
public interface ICustomInspector
{
VisualElement GetVisualElement();
}
[System.Serializable]
public struct FrameUpdate
{
float prevframe;
bool updatedThisFrame;
public static implicit operator bool(FrameUpdate self)
{
2023-06-29 14:57:11 +08:00
var updatedThisFrame = BITApp.Time.DeltaTime <= self.prevframe;
2023-06-05 19:57:17 +08:00
if (updatedThisFrame)
{
return false;
}
else
{
2023-06-29 14:57:11 +08:00
self.prevframe = BITApp.Time.DeltaTime;
2023-06-05 19:57:17 +08:00
return true;
}
}
}
[System.Serializable]
public class CompletionRate
{
public IntervalUpdate resetInterval = new(1);
int requestCount;
int successCount;
public float rate;
public int resetWhen = 64;
public static implicit operator float(CompletionRate cr)
{
return cr.rate;
}
public void Get()
{
requestCount++;
}
public void Release()
{
successCount++;
rate = (float)successCount / (float)requestCount;
if (requestCount > resetWhen)
{
requestCount = successCount = 0;
}
}
}
[System.Serializable]
public class Counter
{
public int count;
int currentCount;
public IntervalUpdate updater = new(1);
public static implicit operator int(Counter self) => self.Get();
public int Excute()
{
2023-06-29 14:57:11 +08:00
if (updater.AllowUpdate)
2023-06-05 19:57:17 +08:00
{
count = currentCount;
currentCount = 0;
}
currentCount++;
return count;
}
public int Get() => currentCount;
}
[System.Serializable]
public class IntervalUpdate
{
2023-06-29 14:57:11 +08:00
public IntervalUpdate(){}
public IntervalUpdate(float interval)
2023-06-05 19:57:17 +08:00
{
2023-06-29 14:57:11 +08:00
Interval = interval;
2023-06-05 19:57:17 +08:00
}
2023-06-29 14:57:11 +08:00
public double Interval=1;
private double allowUpdateTime=0;
public bool AllowUpdate
2023-06-05 19:57:17 +08:00
{
2023-06-29 14:57:11 +08:00
get
2023-06-05 19:57:17 +08:00
{
2023-06-29 14:57:11 +08:00
if (!AllowUpdateWithoutReset) return false;
2023-06-05 19:57:17 +08:00
Reset();
2023-06-29 14:57:11 +08:00
return true;
2023-06-05 19:57:17 +08:00
}
}
2023-06-29 14:57:11 +08:00
public bool AllowUpdateWithoutReset => BITApp.Time.TimeAsDouble >= allowUpdateTime;
2023-06-05 19:57:17 +08:00
public void Reset(bool immediately = false)
{
2023-06-29 14:57:11 +08:00
allowUpdateTime = BITApp.Time.TimeAsDouble + (immediately ? 0 : Interval);
2023-06-05 19:57:17 +08:00
}
2023-06-29 14:57:11 +08:00
public void AddDelay(double interval,bool increment = false)
2023-06-05 19:57:17 +08:00
{
2023-06-29 14:57:11 +08:00
var currentTime = BITApp.Time.TimeAsDouble;
if (increment)
{
var remaining = allowUpdateTime - currentTime;
if (remaining < 0)
{
allowUpdateTime = currentTime + Interval + interval;
}
}
else
{
allowUpdateTime = currentTime + interval;
}
2023-06-05 19:57:17 +08:00
}
}
public struct Location
{
public Location(Transform transform, bool local = false)
{
if (local)
{
position = transform.localPosition;
rotation = transform.localRotation;
}
else
{
position = transform.position;
rotation = transform.rotation;
}
forward = transform.forward;
}
public Location(Component component)
{
var transform = component.transform;
position = transform.position;
rotation = transform.rotation;
forward = transform.forward;
}
public Vector3 position;
public Vector3 forward;
public Quaternion rotation;
public Location Set(Vector3 value)
{
position = value;
return this;
}
public Location Set(Quaternion value)
{
rotation = value;
return this;
}
public Location Set(Transform value, bool isLocal)
{
if (isLocal)
{
position = value.localPosition; rotation = value.localRotation;
}
else
{
Set(value);
}
return this;
}
public Location Set(Transform value)
{
position = value.position; rotation = value.rotation;
return this;
}
public static Location Lerp(Location a, Location b, float t)
{
if (Quaternion.Dot(a, a) < Quaternion.kEpsilon)
a.rotation = Quaternion.identity;
if (Quaternion.Dot(b, b) < Quaternion.kEpsilon)
b.rotation = Quaternion.identity;
return new()
{
position = Vector3.Lerp(a.position, b.position, t),
rotation = Quaternion.Lerp(a.rotation, b.rotation, t)
};
}
public static implicit operator Vector3(Location self)
{
return self.position;
}
public static implicit operator Quaternion(Location self)
{
return self.rotation;
}
public static Location operator +(Location self, Location b)
{
return new()
{
position = self.position + b.position,
rotation = Quaternion.Euler(self.rotation.eulerAngles + b.rotation.eulerAngles),
};
}
public static Location operator -(Location self, Location b)
{
return new()
{
position = self.position - b.position,
rotation = Quaternion.Euler(self.rotation.eulerAngles - b.rotation.eulerAngles),
};
}
public static Location operator *(Location self, float weight)
{
return new()
{
position = self.position * weight,
rotation = Quaternion.Euler(self.rotation.eulerAngles * weight),
};
}
public static Location operator /(Location self, float weight)
{
return new()
{
position = self.position / weight,
rotation = Quaternion.Euler(self.rotation.eulerAngles / weight),
};
}
public bool isNull
{
get
{
return position == Vector3.zero && rotation == Quaternion.identity;
}
}
}
}