轨迹插件引入
This commit is contained in:
1 parent
89b5275efd
commit
195893a1b0
1023 files changed
+378944
-18404
No files matched your search
@@ -0,0 +1,814 @@
|
||||
// =====================================================================
|
||||
// Copyright 2013-2017 Fluffy Underware
|
||||
// All rights reserved
|
||||
//
|
||||
// http://www.fluffyunderware.com
|
||||
// =====================================================================
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace FluffyUnderware.DevTools
|
||||
{
|
||||
[System.Serializable]
|
||||
public struct FloatRegion : IEquatable<FloatRegion>
|
||||
{
|
||||
public float From;
|
||||
public float To;
|
||||
public bool SimpleValue;
|
||||
|
||||
public FloatRegion(float value)
|
||||
{
|
||||
From = value;
|
||||
To = value;
|
||||
SimpleValue = true;
|
||||
}
|
||||
|
||||
public FloatRegion(float A, float B)
|
||||
{
|
||||
this.From = A;
|
||||
this.To = B;
|
||||
SimpleValue = false;
|
||||
}
|
||||
|
||||
public static FloatRegion ZeroOne
|
||||
{
|
||||
get { return new FloatRegion(0, 1); }
|
||||
}
|
||||
|
||||
public void MakePositive()
|
||||
{
|
||||
if (To < From)
|
||||
{
|
||||
float temp = To;
|
||||
To = From;
|
||||
From = temp;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clamp(float low, float high)
|
||||
{
|
||||
Low = Mathf.Clamp(Low, low, high);
|
||||
High = Mathf.Clamp(High, low, high);
|
||||
}
|
||||
|
||||
public bool Positive
|
||||
{
|
||||
get { return From <= To; }
|
||||
}
|
||||
|
||||
public float Low
|
||||
{
|
||||
get { return (Positive) ? From : To; }
|
||||
set
|
||||
{
|
||||
if (Positive)
|
||||
From = value;
|
||||
else
|
||||
To = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float High
|
||||
{
|
||||
get { return (Positive) ? To : From; }
|
||||
set
|
||||
{
|
||||
if (Positive)
|
||||
To = value;
|
||||
else
|
||||
From = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float Random
|
||||
{
|
||||
get
|
||||
{
|
||||
return UnityEngine.Random.Range(From, To);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next value in the range
|
||||
/// <remarks>Depending on the value of <see cref="SimpleValue"/>, this call will or will not make the Random generator's seed progress</remarks>
|
||||
/// </summary>
|
||||
public float Next
|
||||
{
|
||||
get
|
||||
{
|
||||
if (SimpleValue)
|
||||
return From;
|
||||
else
|
||||
return Random;
|
||||
}
|
||||
}
|
||||
|
||||
public float Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return To - From;
|
||||
}
|
||||
}
|
||||
|
||||
public float LengthPositive
|
||||
{
|
||||
get { return (Positive) ? To - From : From - To; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("({0:F2}-{1:F2})", From, To);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return From.GetHashCode() ^ To.GetHashCode() << 2;
|
||||
}
|
||||
|
||||
public bool Equals(FloatRegion other)
|
||||
{
|
||||
return From.Equals(other.From) && To.Equals(other.To);
|
||||
}
|
||||
|
||||
public override bool Equals(object other)
|
||||
{
|
||||
if (!(other is FloatRegion))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
FloatRegion r = (FloatRegion)other;
|
||||
return From.Equals(r.From) && To.Equals(r.To);
|
||||
}
|
||||
|
||||
public static FloatRegion operator +(FloatRegion a, FloatRegion b)
|
||||
{
|
||||
return new FloatRegion(a.From + b.From, a.To + b.To);
|
||||
}
|
||||
|
||||
public static FloatRegion operator -(FloatRegion a, FloatRegion b)
|
||||
{
|
||||
return new FloatRegion(a.From - b.From, a.To - b.To);
|
||||
}
|
||||
|
||||
public static FloatRegion operator -(FloatRegion a)
|
||||
{
|
||||
return new FloatRegion(-a.From, -a.To);
|
||||
}
|
||||
|
||||
public static FloatRegion operator *(FloatRegion a, float v)
|
||||
{
|
||||
return new FloatRegion(a.From * v, a.To * v);
|
||||
}
|
||||
|
||||
public static FloatRegion operator *(float v, FloatRegion a)
|
||||
{
|
||||
return new FloatRegion(a.From * v, a.To * v);
|
||||
}
|
||||
|
||||
public static FloatRegion operator /(FloatRegion a, float v)
|
||||
{
|
||||
return new FloatRegion(a.From / v, a.To / v);
|
||||
}
|
||||
|
||||
public static bool operator ==(FloatRegion lhs, FloatRegion rhs)
|
||||
{
|
||||
return lhs.SimpleValue == rhs.SimpleValue && Mathf.Approximately(lhs.From, rhs.From) && Mathf.Approximately(lhs.To, rhs.To);
|
||||
}
|
||||
public static bool operator !=(FloatRegion lhs, FloatRegion rhs)
|
||||
{
|
||||
return lhs.SimpleValue != rhs.SimpleValue || !Mathf.Approximately(lhs.From, rhs.From) || !Mathf.Approximately(lhs.To, rhs.To);
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct IntRegion : IEquatable<IntRegion>
|
||||
{
|
||||
public int From;
|
||||
public int To;
|
||||
public bool SimpleValue;
|
||||
|
||||
|
||||
public IntRegion(int value)
|
||||
{
|
||||
From = value;
|
||||
To = value;
|
||||
SimpleValue = true;
|
||||
|
||||
}
|
||||
|
||||
public IntRegion(int A, int B)
|
||||
{
|
||||
this.From = A;
|
||||
this.To = B;
|
||||
SimpleValue = false;
|
||||
|
||||
}
|
||||
|
||||
public static IntRegion ZeroOne
|
||||
{
|
||||
get { return new IntRegion(0, 1); }
|
||||
}
|
||||
|
||||
public void MakePositive()
|
||||
{
|
||||
if (To < From)
|
||||
{
|
||||
int temp = To;
|
||||
To = From;
|
||||
From = temp;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clamp(int low, int high)
|
||||
{
|
||||
Low = Mathf.Clamp(Low, low, high);
|
||||
High = Mathf.Clamp(High, low, high);
|
||||
}
|
||||
|
||||
public bool Positive
|
||||
{
|
||||
get { return From <= To; }
|
||||
}
|
||||
|
||||
public int Low
|
||||
{
|
||||
get { return (Positive) ? From : To; }
|
||||
set
|
||||
{
|
||||
if (Positive)
|
||||
From = value;
|
||||
else
|
||||
To = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int High
|
||||
{
|
||||
get { return (Positive) ? To : From; }
|
||||
set
|
||||
{
|
||||
if (Positive)
|
||||
To = value;
|
||||
else
|
||||
From = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Random
|
||||
{
|
||||
get
|
||||
{
|
||||
return UnityEngine.Random.Range(From, To);
|
||||
}
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return To - From;
|
||||
}
|
||||
}
|
||||
|
||||
public int LengthPositive
|
||||
{
|
||||
get { return (Positive) ? To - From : From - To; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("({0}-{1})", From, To);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return From.GetHashCode() ^ To.GetHashCode() << 2;
|
||||
}
|
||||
|
||||
public bool Equals(IntRegion other)
|
||||
{
|
||||
return From.Equals(other.From) && To.Equals(other.To);
|
||||
}
|
||||
|
||||
public override bool Equals(object other)
|
||||
{
|
||||
if (!(other is IntRegion))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
IntRegion r = (IntRegion)other;
|
||||
return From.Equals(r.From) && To.Equals(r.To);
|
||||
}
|
||||
|
||||
public static IntRegion operator +(IntRegion a, IntRegion b)
|
||||
{
|
||||
return new IntRegion(a.From + b.From, a.To + b.To);
|
||||
}
|
||||
|
||||
public static IntRegion operator -(IntRegion a, IntRegion b)
|
||||
{
|
||||
return new IntRegion(a.From - b.From, a.To - b.To);
|
||||
}
|
||||
|
||||
public static IntRegion operator -(IntRegion a)
|
||||
{
|
||||
return new IntRegion(-a.From, -a.To);
|
||||
}
|
||||
|
||||
public static IntRegion operator *(IntRegion a, int v)
|
||||
{
|
||||
return new IntRegion(a.From * v, a.To * v);
|
||||
}
|
||||
|
||||
public static IntRegion operator *(int v, IntRegion a)
|
||||
{
|
||||
return new IntRegion(a.From * v, a.To * v);
|
||||
}
|
||||
|
||||
public static IntRegion operator /(IntRegion a, int v)
|
||||
{
|
||||
return new IntRegion(a.From / v, a.To / v);
|
||||
}
|
||||
|
||||
public static bool operator ==(IntRegion lhs, IntRegion rhs)
|
||||
{
|
||||
return lhs.From == rhs.From && lhs.To == rhs.To && lhs.SimpleValue != rhs.SimpleValue;
|
||||
}
|
||||
public static bool operator !=(IntRegion lhs, IntRegion rhs)
|
||||
{
|
||||
return lhs.From != rhs.From || lhs.To != rhs.To || lhs.SimpleValue != rhs.SimpleValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simple but effective ShuffleBag<T> implementation
|
||||
/// </summary>
|
||||
public class WeightedRandom<T>
|
||||
{
|
||||
List<T> mData;
|
||||
int mCurrentPosition = -1;
|
||||
T mCurrentItem;
|
||||
|
||||
public int Seed { get; set; }
|
||||
|
||||
public bool RandomizeSeed { get; set; }
|
||||
|
||||
private int Capacity { get { return mData.Capacity; } }
|
||||
public int Size { get { return mData.Count; } }
|
||||
|
||||
public WeightedRandom(int initCapacity = 0)
|
||||
{
|
||||
mData = new List<T>(initCapacity);
|
||||
}
|
||||
|
||||
public WeightedRandom(int initCapacity, int seed):this(initCapacity)
|
||||
{
|
||||
Seed = seed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds items to the bag
|
||||
/// </summary>
|
||||
/// <param name="item">the item</param>
|
||||
/// <param name="amount">number of times this item should be added</param>
|
||||
public void Add(T item, int amount)
|
||||
{
|
||||
for (int i = 0; i < amount; i++)
|
||||
mData.Add(item);
|
||||
mCurrentPosition = Size - 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a random item from the bag
|
||||
/// </summary>
|
||||
/// <returns>an item</returns>
|
||||
public T Next()
|
||||
{
|
||||
if (mCurrentPosition < 1)
|
||||
{
|
||||
mCurrentPosition = Size - 1;
|
||||
mCurrentItem = mData[0];
|
||||
return mCurrentItem;
|
||||
}
|
||||
Random.State s = Random.state;
|
||||
if (RandomizeSeed)
|
||||
Seed = Random.Range(0, int.MaxValue);
|
||||
Random.InitState(Seed);
|
||||
int idx = Random.Range(0, mCurrentPosition);
|
||||
Random.state = s;
|
||||
|
||||
mCurrentItem = mData[idx];
|
||||
mData[idx] = mData[mCurrentPosition];
|
||||
mData[mCurrentPosition] = mCurrentItem;
|
||||
mCurrentPosition--;
|
||||
return mCurrentItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refill the bag
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
mCurrentPosition = Size - 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the bag
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
mData.Clear();
|
||||
mCurrentPosition = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Ring<T> : IList<T>
|
||||
{
|
||||
List<T> mList;
|
||||
public int Size { get; private set; }
|
||||
|
||||
int mIndex;
|
||||
|
||||
public Ring(int size)
|
||||
{
|
||||
mList = new List<T>(size);
|
||||
Size = size;
|
||||
}
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
if (mList.Count == Size)
|
||||
{
|
||||
mList[mIndex++] = item;
|
||||
if (mIndex == mList.Count)
|
||||
mIndex = 0;
|
||||
}
|
||||
else
|
||||
mList.Add(item);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
mList.Clear();
|
||||
mIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
public int IndexOf(T item)
|
||||
{
|
||||
return mList.IndexOf(item);
|
||||
}
|
||||
|
||||
public void Insert(int index, T item)
|
||||
{
|
||||
throw new System.NotSupportedException();
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
throw new System.NotSupportedException();
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return mList[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
mList[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
return mList.GetEnumerator();
|
||||
}
|
||||
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
return mList.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
mList.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return mList.Count; }
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { throw new System.NotSupportedException(); }
|
||||
}
|
||||
|
||||
public bool Remove(T item)
|
||||
{
|
||||
return mList.Remove(item);
|
||||
}
|
||||
|
||||
IEnumerator<T> IEnumerable<T>.GetEnumerator()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class Pool<T> : IPool
|
||||
{
|
||||
List<T> mObjects = new List<T>();
|
||||
|
||||
public string Identifier { get; set; }
|
||||
|
||||
public PoolSettings Settings { get; protected set; }
|
||||
|
||||
public System.Type Type
|
||||
{
|
||||
get { return typeof(T); }
|
||||
}
|
||||
|
||||
double mLastTime;
|
||||
double mDeltaTime;
|
||||
|
||||
|
||||
public Pool(PoolSettings settings = null)
|
||||
{
|
||||
Settings = settings ?? new PoolSettings();
|
||||
Identifier = typeof(T).FullName;
|
||||
mLastTime = DTTime.TimeSinceStartup + UnityEngine.Random.Range(0, Settings.Speed);
|
||||
if (Settings.Prewarm)
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
mDeltaTime += DTTime.TimeSinceStartup - mLastTime;
|
||||
mLastTime = DTTime.TimeSinceStartup;
|
||||
|
||||
if (Settings.Speed > 0)
|
||||
{
|
||||
int c = (int)(mDeltaTime / Settings.Speed);
|
||||
mDeltaTime -= c;
|
||||
|
||||
if (Count > Settings.Threshold)
|
||||
{
|
||||
c = Mathf.Min(c, Count - Settings.Threshold);
|
||||
while (c-- > 0)
|
||||
{
|
||||
destroy(mObjects[0]);
|
||||
mObjects.RemoveAt(0);
|
||||
log("Threshold exceeded: Deleting item");
|
||||
}
|
||||
}
|
||||
else if (Count < Settings.MinItems)
|
||||
{
|
||||
c = Mathf.Min(c, Settings.MinItems - Count);
|
||||
while (c-- > 0)
|
||||
{
|
||||
mObjects.Add(create());
|
||||
log("Below MinItems: Adding item");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
mDeltaTime = 0;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
while (Count < Settings.MinItems)
|
||||
{
|
||||
mObjects.Add(create());
|
||||
}
|
||||
while (Count > Settings.Threshold)
|
||||
{
|
||||
destroy(mObjects[0]);
|
||||
mObjects.RemoveAt(0);
|
||||
}
|
||||
log("Prewarm/Reset");
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
log("Clear");
|
||||
for (int i = 0; i < Count; i++)
|
||||
destroy(mObjects[i]);
|
||||
mObjects.Clear();
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return mObjects.Count; }
|
||||
}
|
||||
|
||||
public virtual T Pop(Transform parent = null)
|
||||
{
|
||||
T item = default(T);
|
||||
if (Count > 0)
|
||||
{
|
||||
item = mObjects[0];
|
||||
mObjects.RemoveAt(0);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Settings.AutoCreate || !Application.isPlaying)
|
||||
{
|
||||
log("Auto create item");
|
||||
item = create();
|
||||
|
||||
}
|
||||
}
|
||||
if (item != null)
|
||||
{
|
||||
sendAfterPop(item);
|
||||
setParent(item, parent);
|
||||
log("Pop " + item);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public virtual void Push(T item)
|
||||
{
|
||||
log("Push " + item);
|
||||
if (Application.isPlaying && item != null)
|
||||
{
|
||||
sendBeforePush(item);
|
||||
mObjects.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void sendBeforePush(T item)
|
||||
{
|
||||
if (item is IPoolable)
|
||||
((IPoolable)item).OnBeforePush();
|
||||
}
|
||||
|
||||
protected virtual void sendAfterPop(T item)
|
||||
{
|
||||
if (item is IPoolable)
|
||||
((IPoolable)item).OnAfterPop();
|
||||
}
|
||||
|
||||
protected virtual void setParent(T item, Transform parent)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual T create()
|
||||
{
|
||||
return System.Activator.CreateInstance<T>();
|
||||
}
|
||||
|
||||
protected virtual void destroy(T item)
|
||||
{
|
||||
}
|
||||
|
||||
void log(string msg)
|
||||
{
|
||||
if (Settings.Debug)
|
||||
Debug.Log(string.Format("[{0}] ({1} items) {2}", Identifier, Count, msg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class PoolSettings
|
||||
{
|
||||
[SerializeField]
|
||||
bool m_Prewarm = false;
|
||||
[SerializeField]
|
||||
bool m_AutoCreate = true;
|
||||
[SerializeField]
|
||||
bool m_AutoEnableDisable = true;
|
||||
[Positive]
|
||||
[SerializeField]
|
||||
int m_MinItems = 0;
|
||||
|
||||
[Positive]
|
||||
[SerializeField]
|
||||
int m_Threshold = 0;
|
||||
|
||||
[Positive]
|
||||
[SerializeField]
|
||||
float m_Speed = 1;
|
||||
|
||||
|
||||
|
||||
|
||||
public bool Debug;
|
||||
|
||||
public PoolSettings() { }
|
||||
|
||||
public PoolSettings(PoolSettings src)
|
||||
{
|
||||
Prewarm = src.Prewarm;
|
||||
AutoCreate = src.AutoCreate;
|
||||
MinItems = src.MinItems;
|
||||
Threshold = src.Threshold;
|
||||
Speed = src.Speed;
|
||||
Debug = src.Debug;
|
||||
}
|
||||
|
||||
public bool Prewarm
|
||||
{
|
||||
get { return m_Prewarm; }
|
||||
set
|
||||
{
|
||||
if (m_Prewarm != value)
|
||||
m_Prewarm = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool AutoCreate
|
||||
{
|
||||
get { return m_AutoCreate; }
|
||||
set
|
||||
{
|
||||
if (m_AutoCreate != value)
|
||||
m_AutoCreate = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool AutoEnableDisable
|
||||
{
|
||||
get { return m_AutoEnableDisable; }
|
||||
set
|
||||
{
|
||||
if (m_AutoEnableDisable != value)
|
||||
m_AutoEnableDisable = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int MinItems
|
||||
{
|
||||
get { return m_MinItems; }
|
||||
set
|
||||
{
|
||||
int v = Mathf.Max(0, value);
|
||||
if (m_MinItems != v)
|
||||
m_MinItems = v;
|
||||
}
|
||||
}
|
||||
|
||||
public int Threshold
|
||||
{
|
||||
get { return m_Threshold; }
|
||||
set
|
||||
{
|
||||
int v = Mathf.Max(MinItems, value);
|
||||
if (m_Threshold != v)
|
||||
m_Threshold = v;
|
||||
}
|
||||
}
|
||||
|
||||
public float Speed
|
||||
{
|
||||
get { return m_Speed; }
|
||||
set
|
||||
{
|
||||
float v = Mathf.Max(0, value);
|
||||
if (m_Speed != v)
|
||||
m_Speed = v;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnValidate()
|
||||
{
|
||||
MinItems = m_MinItems;
|
||||
Threshold = m_Threshold;
|
||||
Speed = m_Speed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface IPool
|
||||
{
|
||||
string Identifier { get; set; }
|
||||
PoolSettings Settings { get; }
|
||||
void Clear();
|
||||
void Reset();
|
||||
void Update();
|
||||
int Count { get; }
|
||||
}
|
||||
|
||||
public interface IPoolable
|
||||
{
|
||||
void OnBeforePush();
|
||||
|
||||
void OnAfterPop();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user