mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-11-11 08:38:45 +00:00
提交Unity 联机Pro
This commit is contained in:
5
JNFrame2/Assets/Plugins/SRF/Scripts/Collections.meta
Normal file
5
JNFrame2/Assets/Plugins/SRF/Scripts/Collections.meta
Normal file
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 713ffa030c417a84190555e6aef2e0b2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
346
JNFrame2/Assets/Plugins/SRF/Scripts/Collections/SRList.cs
Normal file
346
JNFrame2/Assets/Plugins/SRF/Scripts/Collections/SRList.cs
Normal file
@@ -0,0 +1,346 @@
|
||||
namespace SRF
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// IList implementation which does not release the buffer when clearing/removing elements. Based on the NGUI BetterList
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SRList<T> : IList<T>, ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField] private T[] _buffer;
|
||||
[SerializeField] private int _count;
|
||||
private EqualityComparer<T> _equalityComparer;
|
||||
private ReadOnlyCollection<T> _readOnlyWrapper;
|
||||
public SRList() {}
|
||||
|
||||
public SRList(int capacity)
|
||||
{
|
||||
Buffer = new T[capacity];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new list with the range of values. Contains a foreach loop, which will allocate garbage when used with most
|
||||
/// generic collection types.
|
||||
/// </summary>
|
||||
public SRList(IEnumerable<T> source)
|
||||
{
|
||||
AddRange(source);
|
||||
}
|
||||
|
||||
public T[] Buffer
|
||||
{
|
||||
get { return _buffer; }
|
||||
private set { _buffer = value; }
|
||||
}
|
||||
|
||||
private EqualityComparer<T> EqualityComparer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_equalityComparer == null)
|
||||
{
|
||||
_equalityComparer = EqualityComparer<T>.Default;
|
||||
}
|
||||
|
||||
return _equalityComparer;
|
||||
}
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _count; }
|
||||
private set { _count = value; }
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
if (Buffer != null)
|
||||
{
|
||||
for (var i = 0; i < Count; ++i)
|
||||
{
|
||||
yield return Buffer[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
if (Buffer == null || Count == Buffer.Length)
|
||||
{
|
||||
Expand();
|
||||
}
|
||||
|
||||
Buffer[Count++] = item;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
if (Buffer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < Count; ++i)
|
||||
{
|
||||
if (EqualityComparer.Equals(Buffer[i], item))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
Trim();
|
||||
Buffer.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool Remove(T item)
|
||||
{
|
||||
if (Buffer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var index = IndexOf(item);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RemoveAt(index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public int IndexOf(T item)
|
||||
{
|
||||
if (Buffer == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (var i = 0; i < Count; ++i)
|
||||
{
|
||||
if (EqualityComparer.Equals(Buffer[i], item))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void Insert(int index, T item)
|
||||
{
|
||||
if (Buffer == null || Count == Buffer.Length)
|
||||
{
|
||||
Expand();
|
||||
}
|
||||
|
||||
if (index < Count)
|
||||
{
|
||||
for (var i = Count; i > index; --i)
|
||||
{
|
||||
Buffer[i] = Buffer[i - 1];
|
||||
}
|
||||
Buffer[index] = item;
|
||||
++Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
if (Buffer != null && index < Count)
|
||||
{
|
||||
--Count;
|
||||
Buffer[index] = default(T);
|
||||
for (var b = index; b < Count; ++b)
|
||||
{
|
||||
Buffer[b] = Buffer[b + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Buffer == null)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
return Buffer[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Buffer == null)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
Buffer[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
// Clean buffer of unused elements before serializing
|
||||
Clean();
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add range of values to the list. Contains a foreach loop, which will allocate garbage when used with most
|
||||
/// generic collection types.
|
||||
/// </summary>
|
||||
/// <param name="range"></param>
|
||||
public void AddRange(IEnumerable<T> range)
|
||||
{
|
||||
foreach (var item in range)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the list, optionally setting each element to default(T)
|
||||
/// </summary>
|
||||
public void Clear(bool clean)
|
||||
{
|
||||
Clear();
|
||||
|
||||
if (!clean)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Clean();
|
||||
}
|
||||
|
||||
public void Clean()
|
||||
{
|
||||
if (Buffer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = Count; i < _buffer.Length; i++)
|
||||
{
|
||||
_buffer[i] = default(T);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a read-only wrapper of this list. This is cached, so very little cost after first called.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ReadOnlyCollection<T> AsReadOnly()
|
||||
{
|
||||
if (_readOnlyWrapper == null)
|
||||
{
|
||||
_readOnlyWrapper = new ReadOnlyCollection<T>(this);
|
||||
}
|
||||
|
||||
return _readOnlyWrapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function that expands the size of the array, maintaining the content.
|
||||
/// </summary>
|
||||
private void Expand()
|
||||
{
|
||||
var newList = (Buffer != null) ? new T[Mathf.Max(Buffer.Length << 1, 32)] : new T[32];
|
||||
|
||||
if (Buffer != null && Count > 0)
|
||||
{
|
||||
Buffer.CopyTo(newList, 0);
|
||||
}
|
||||
|
||||
Buffer = newList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trim the unnecessary memory, resizing the buffer to be of 'Length' size.
|
||||
/// Call this function only if you are sure that the buffer won't need to resize anytime soon.
|
||||
/// </summary>
|
||||
public void Trim()
|
||||
{
|
||||
if (Count > 0)
|
||||
{
|
||||
if (Count >= Buffer.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var newList = new T[Count];
|
||||
|
||||
for (var i = 0; i < Count; ++i)
|
||||
{
|
||||
newList[i] = Buffer[i];
|
||||
}
|
||||
|
||||
Buffer = newList;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer = new T[0];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List.Sort equivalent.
|
||||
/// </summary>
|
||||
public void Sort(Comparison<T> comparer)
|
||||
{
|
||||
var changed = true;
|
||||
|
||||
while (changed)
|
||||
{
|
||||
changed = false;
|
||||
|
||||
for (var i = 1; i < Count; ++i)
|
||||
{
|
||||
if (comparer.Invoke(Buffer[i - 1], Buffer[i]) > 0)
|
||||
{
|
||||
var temp = Buffer[i];
|
||||
Buffer[i] = Buffer[i - 1];
|
||||
Buffer[i - 1] = temp;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5201015973137a64986d1c3a21aa95bd
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
5
JNFrame2/Assets/Plugins/SRF/Scripts/Components.meta
Normal file
5
JNFrame2/Assets/Plugins/SRF/Scripts/Components.meta
Normal file
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b492ab4aeb29c06468a92411414d3647
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@@ -0,0 +1,74 @@
|
||||
namespace SRF.Components
|
||||
{
|
||||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
/// <summary>
|
||||
/// Singleton MonoBehaviour class which automatically creates an instance if one does not already exist.
|
||||
/// </summary>
|
||||
public abstract class SRAutoSingleton<T> : SRMonoBehaviour where T : SRAutoSingleton<T>
|
||||
{
|
||||
private static T _instance;
|
||||
|
||||
/// <summary>
|
||||
/// Get (or create) the instance of this Singleton
|
||||
/// </summary>
|
||||
public static T Instance
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
get
|
||||
{
|
||||
// Instance required for the first time, we look for it
|
||||
if (_instance == null && Application.isPlaying)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
// Support reloading scripts after a recompile - static reference will be cleared, but we can find it again.
|
||||
T autoSingleton = FindObjectOfType<T>();
|
||||
if (autoSingleton != null)
|
||||
{
|
||||
_instance = autoSingleton;
|
||||
return _instance;
|
||||
}
|
||||
#endif
|
||||
|
||||
var go = new GameObject("_" + typeof (T).Name);
|
||||
go.AddComponent<T>(); // _instance set by Awake() constructor
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasInstance
|
||||
{
|
||||
get { return _instance != null; }
|
||||
}
|
||||
|
||||
// If no other monobehaviour request the instance in an awake function
|
||||
// executing before this one, no need to search the object.
|
||||
protected virtual void Awake()
|
||||
{
|
||||
if (_instance != null)
|
||||
{
|
||||
Debug.LogWarning("More than one singleton object of type {0} exists.".Fmt(typeof (T).Name));
|
||||
return;
|
||||
}
|
||||
|
||||
_instance = (T) this;
|
||||
}
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
// Restore reference after C# recompile.
|
||||
_instance = (T) this;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Make sure the instance isn't referenced anymore when the user quit, just in case.
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
_instance = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73f72db4fa1856540bbe92740280c8e2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,202 @@
|
||||
namespace SRF
|
||||
{
|
||||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Base MonoBehaviour which provides useful common functionality
|
||||
/// </summary>
|
||||
public abstract class SRMonoBehaviour : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the Transform component, using a cached reference if possible.
|
||||
/// </summary>
|
||||
public Transform CachedTransform
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
[DebuggerNonUserCode]
|
||||
get
|
||||
{
|
||||
if (_transform == null)
|
||||
{
|
||||
_transform = base.transform;
|
||||
}
|
||||
|
||||
return _transform;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Collider component, using a cached reference if possible.
|
||||
/// </summary>
|
||||
public Collider CachedCollider
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
[DebuggerNonUserCode]
|
||||
get
|
||||
{
|
||||
if (_collider == null)
|
||||
{
|
||||
_collider = GetComponent<Collider>();
|
||||
}
|
||||
|
||||
return _collider;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Collider component, using a cached reference if possible.
|
||||
/// </summary>
|
||||
public Collider2D CachedCollider2D
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
[DebuggerNonUserCode]
|
||||
get
|
||||
{
|
||||
if (_collider2D == null)
|
||||
{
|
||||
_collider2D = GetComponent<Collider2D>();
|
||||
}
|
||||
|
||||
return _collider2D;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Rigidbody component, using a cached reference if possible.
|
||||
/// </summary>
|
||||
public Rigidbody CachedRigidBody
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
[DebuggerNonUserCode]
|
||||
get
|
||||
{
|
||||
if (_rigidBody == null)
|
||||
{
|
||||
_rigidBody = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
return _rigidBody;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Rigidbody2D component, using a cached reference if possible.
|
||||
/// </summary>
|
||||
public Rigidbody2D CachedRigidBody2D
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
[DebuggerNonUserCode]
|
||||
get
|
||||
{
|
||||
if (_rigidbody2D == null)
|
||||
{
|
||||
_rigidbody2D = GetComponent<Rigidbody2D>();
|
||||
}
|
||||
|
||||
return _rigidbody2D;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the GameObject this behaviour is attached to, using a cached reference if possible.
|
||||
/// </summary>
|
||||
public GameObject CachedGameObject
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
[DebuggerNonUserCode]
|
||||
get
|
||||
{
|
||||
if (_gameObject == null)
|
||||
{
|
||||
_gameObject = base.gameObject;
|
||||
}
|
||||
|
||||
return _gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
// Override existing getters for legacy usage
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
public new Transform transform
|
||||
{
|
||||
get { return CachedTransform; }
|
||||
}
|
||||
|
||||
#if !UNITY_5 && !UNITY_2017_1_OR_NEWER
|
||||
|
||||
public new Collider collider
|
||||
{
|
||||
get { return CachedCollider; }
|
||||
}
|
||||
public new Collider2D collider2D
|
||||
{
|
||||
get { return CachedCollider2D; }
|
||||
}
|
||||
public new Rigidbody rigidbody
|
||||
{
|
||||
get { return CachedRigidBody; }
|
||||
}
|
||||
public new Rigidbody2D rigidbody2D
|
||||
{
|
||||
get { return CachedRigidBody2D; }
|
||||
}
|
||||
public new GameObject gameObject
|
||||
{
|
||||
get { return CachedGameObject; }
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ReSharper restore InconsistentNaming
|
||||
|
||||
private Collider _collider;
|
||||
private Transform _transform;
|
||||
private Rigidbody _rigidBody;
|
||||
private GameObject _gameObject;
|
||||
private Rigidbody2D _rigidbody2D;
|
||||
private Collider2D _collider2D;
|
||||
|
||||
/// <summary>
|
||||
/// Assert that the value is not null, disable the object and print a debug error message if it is.
|
||||
/// </summary>
|
||||
/// <param name="value">Object to check</param>
|
||||
/// <param name="fieldName">Debug name to pass in</param>
|
||||
[DebuggerNonUserCode]
|
||||
[DebuggerStepThrough]
|
||||
protected void AssertNotNull(object value, string fieldName = null)
|
||||
{
|
||||
SRDebugUtil.AssertNotNull(value, fieldName, this);
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[DebuggerStepThrough]
|
||||
protected void Assert(bool condition, string message = null)
|
||||
{
|
||||
SRDebugUtil.Assert(condition, message, this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assert that the value is not null, disable the object and print a debug error message if it is.
|
||||
/// </summary>
|
||||
/// <param name="value">Object to check</param>
|
||||
/// <param name="fieldName">Debug name to pass in</param>
|
||||
/// <returns>True if object is not null</returns>
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
[DebuggerNonUserCode]
|
||||
[DebuggerStepThrough]
|
||||
protected void EditorAssertNotNull(object value, string fieldName = null)
|
||||
{
|
||||
AssertNotNull(value, fieldName);
|
||||
}
|
||||
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
[DebuggerNonUserCode]
|
||||
[DebuggerStepThrough]
|
||||
protected void EditorAssert(bool condition, string message = null)
|
||||
{
|
||||
Assert(condition, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a97a8611d5d683b4aa89a5054bc3774e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,215 @@
|
||||
// ReSharper disable once RedundantUsingDirective
|
||||
using System.Linq;
|
||||
|
||||
namespace SRF
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Helpers;
|
||||
using Service;
|
||||
using UnityEngine;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field)]
|
||||
public sealed class RequiredFieldAttribute : Attribute
|
||||
{
|
||||
private bool _autoCreate;
|
||||
private bool _autoSearch;
|
||||
private bool _editorOnly = true;
|
||||
|
||||
public RequiredFieldAttribute(bool autoSearch)
|
||||
{
|
||||
AutoSearch = autoSearch;
|
||||
}
|
||||
|
||||
public RequiredFieldAttribute() {}
|
||||
|
||||
public bool AutoSearch
|
||||
{
|
||||
get { return _autoSearch; }
|
||||
set { _autoSearch = value; }
|
||||
}
|
||||
|
||||
public bool AutoCreate
|
||||
{
|
||||
get { return _autoCreate; }
|
||||
set { _autoCreate = value; }
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public bool EditorOnly
|
||||
{
|
||||
get { return _editorOnly; }
|
||||
set { _editorOnly = value; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add to a field to attempt to use SRServiceManager to get an instance of the field type
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class ImportAttribute : Attribute
|
||||
{
|
||||
public readonly Type Service;
|
||||
public ImportAttribute() {}
|
||||
|
||||
public ImportAttribute(Type serviceType)
|
||||
{
|
||||
Service = serviceType;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class SRMonoBehaviourEx : SRMonoBehaviour
|
||||
{
|
||||
private static Dictionary<Type, IList<FieldInfo>> _checkedFields;
|
||||
|
||||
private static void CheckFields(SRMonoBehaviourEx instance, bool justSet = false)
|
||||
{
|
||||
if (_checkedFields == null)
|
||||
{
|
||||
_checkedFields = new Dictionary<Type, IList<FieldInfo>>();
|
||||
}
|
||||
|
||||
var t = instance.GetType();
|
||||
|
||||
IList<FieldInfo> cache;
|
||||
|
||||
if (!_checkedFields.TryGetValue(instance.GetType(), out cache))
|
||||
{
|
||||
cache = ScanType(t);
|
||||
|
||||
_checkedFields.Add(t, cache);
|
||||
}
|
||||
|
||||
PopulateObject(cache, instance, justSet);
|
||||
}
|
||||
|
||||
private static void PopulateObject(IList<FieldInfo> cache, SRMonoBehaviourEx instance, bool justSet)
|
||||
{
|
||||
for (var i = 0; i < cache.Count; i++)
|
||||
{
|
||||
var f = cache[i];
|
||||
|
||||
if (!EqualityComparer<object>.Default.Equals(f.Field.GetValue(instance), null))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// If import is enabled, use SRServiceManager to import the reference
|
||||
if (f.Import)
|
||||
{
|
||||
var t = f.ImportType ?? f.Field.FieldType;
|
||||
|
||||
var service = SRServiceManager.GetService(t);
|
||||
|
||||
if (service == null)
|
||||
{
|
||||
Debug.LogWarning("Field {0} import failed (Type {1})".Fmt(f.Field.Name, t));
|
||||
continue;
|
||||
}
|
||||
|
||||
f.Field.SetValue(instance, service);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// If autoset is enabled on field, try and find the component on the GameObject
|
||||
|
||||
if (f.AutoSet)
|
||||
{
|
||||
var newValue = instance.GetComponent(f.Field.FieldType);
|
||||
|
||||
if (!EqualityComparer<object>.Default.Equals(newValue, null))
|
||||
{
|
||||
f.Field.SetValue(instance, newValue);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (justSet)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (f.AutoCreate)
|
||||
{
|
||||
var newValue = instance.CachedGameObject.AddComponent(f.Field.FieldType);
|
||||
f.Field.SetValue(instance, newValue);
|
||||
}
|
||||
|
||||
throw new UnassignedReferenceException(
|
||||
"Field {0} is unassigned, but marked with RequiredFieldAttribute".Fmt(f.Field.Name));
|
||||
}
|
||||
}
|
||||
|
||||
private static List<FieldInfo> ScanType(Type t)
|
||||
{
|
||||
var cache = new List<FieldInfo>();
|
||||
|
||||
// Check for attribute added to the class
|
||||
var globalAttr = SRReflection.GetAttribute<RequiredFieldAttribute>(t);
|
||||
|
||||
#if NETFX_CORE
|
||||
var fields = t.GetTypeInfo().DeclaredFields.Where(f => !f.IsStatic);
|
||||
#else
|
||||
// Check each field for the attribute
|
||||
var fields = t.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
#endif
|
||||
|
||||
foreach (var f in fields)
|
||||
{
|
||||
var requiredFieldAttribute = SRReflection.GetAttribute<RequiredFieldAttribute>(f);
|
||||
var importAttribute = SRReflection.GetAttribute<ImportAttribute>(f);
|
||||
|
||||
if (globalAttr == null && requiredFieldAttribute == null && importAttribute == null)
|
||||
{
|
||||
continue; // Early out if no attributes found.
|
||||
}
|
||||
|
||||
var info = new FieldInfo();
|
||||
info.Field = f;
|
||||
|
||||
if (importAttribute != null)
|
||||
{
|
||||
info.Import = true;
|
||||
info.ImportType = importAttribute.Service;
|
||||
}
|
||||
else if (requiredFieldAttribute != null)
|
||||
{
|
||||
info.AutoSet = requiredFieldAttribute.AutoSearch;
|
||||
info.AutoCreate = requiredFieldAttribute.AutoCreate;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.AutoSet = globalAttr.AutoSearch;
|
||||
info.AutoCreate = globalAttr.AutoCreate;
|
||||
}
|
||||
|
||||
cache.Add(info);
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
CheckFields(this);
|
||||
}
|
||||
|
||||
protected virtual void Start() {}
|
||||
protected virtual void Update() {}
|
||||
protected virtual void FixedUpdate() {}
|
||||
protected virtual void OnEnable() {}
|
||||
protected virtual void OnDisable() {}
|
||||
protected virtual void OnDestroy() {}
|
||||
|
||||
private struct FieldInfo
|
||||
{
|
||||
public bool AutoCreate;
|
||||
public bool AutoSet;
|
||||
public System.Reflection.FieldInfo Field;
|
||||
public bool Import;
|
||||
public Type ImportType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82088ea802108344da1e919daa6881fd
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,82 @@
|
||||
namespace SRF.Components
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
/// <summary>
|
||||
/// Inherit from this component to easily create a singleton gameobject.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class SRSingleton<T> : SRMonoBehaviour where T : SRSingleton<T>
|
||||
{
|
||||
private static T _instance;
|
||||
|
||||
/// <summary>
|
||||
/// Get the instance of this singleton.
|
||||
/// </summary
|
||||
public static T Instance
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
get
|
||||
{
|
||||
// Instance requiered for the first time, we look for it
|
||||
if (_instance == null)
|
||||
{
|
||||
throw new InvalidOperationException("No instance of {0} present in scene".Fmt(typeof (T).Name));
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasInstance
|
||||
{
|
||||
[DebuggerStepThrough] get { return _instance != null; }
|
||||
}
|
||||
|
||||
private void Register()
|
||||
{
|
||||
if (_instance != null)
|
||||
{
|
||||
Debug.LogWarning("More than one singleton object of type {0} exists.".Fmt(typeof (T).Name));
|
||||
|
||||
// Check if gameobject only contains Transform and this component
|
||||
if (GetComponents<Component>().Length == 2)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(this);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_instance = (T) this;
|
||||
}
|
||||
|
||||
// If no other monobehaviour request the instance in an awake function
|
||||
// executing before this one, no need to search the object.
|
||||
protected virtual void Awake()
|
||||
{
|
||||
Register();
|
||||
}
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
// In case of code-reload, this should restore the single instance
|
||||
if (_instance == null)
|
||||
{
|
||||
Register();
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the instance isn't referenced anymore when the user quit, just in case.
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
_instance = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca9e6e61f807f3442b520b02db3a48c7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
18
JNFrame2/Assets/Plugins/SRF/Scripts/Coroutines.cs
Normal file
18
JNFrame2/Assets/Plugins/SRF/Scripts/Coroutines.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace SRF
|
||||
{
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
public static class Coroutines
|
||||
{
|
||||
public static IEnumerator WaitForSecondsRealTime(float time)
|
||||
{
|
||||
var endTime = Time.realtimeSinceStartup + time;
|
||||
|
||||
while (Time.realtimeSinceStartup < endTime)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
JNFrame2/Assets/Plugins/SRF/Scripts/Coroutines.cs.meta
Normal file
8
JNFrame2/Assets/Plugins/SRF/Scripts/Coroutines.cs.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83ca528cafb0d2e40866729c49dc2d76
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
5
JNFrame2/Assets/Plugins/SRF/Scripts/Extensions.meta
Normal file
5
JNFrame2/Assets/Plugins/SRF/Scripts/Extensions.meta
Normal file
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a242390cef216543a4fa08843e88004
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@@ -0,0 +1,27 @@
|
||||
namespace SRF
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
public static class SRFFloatExtensions
|
||||
{
|
||||
public static float Sqr(this float f)
|
||||
{
|
||||
return f*f;
|
||||
}
|
||||
|
||||
public static float SqrRt(this float f)
|
||||
{
|
||||
return Mathf.Sqrt(f);
|
||||
}
|
||||
|
||||
public static bool ApproxZero(this float f)
|
||||
{
|
||||
return Mathf.Approximately(0, f);
|
||||
}
|
||||
|
||||
public static bool Approx(this float f, float f2)
|
||||
{
|
||||
return Mathf.Approximately(f, f2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb221a6020786a841a6f7f1ea19a7eb7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,100 @@
|
||||
namespace SRF
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
public static class SRFGameObjectExtensions
|
||||
{
|
||||
public static T GetIComponent<T>(this GameObject t) where T : class
|
||||
{
|
||||
return t.GetComponent(typeof (T)) as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the component T, or add it to the GameObject if none exists
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static T GetComponentOrAdd<T>(this GameObject obj) where T : Component
|
||||
{
|
||||
var t = obj.GetComponent<T>();
|
||||
|
||||
if (t == null)
|
||||
{
|
||||
t = obj.AddComponent<T>();
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removed component of type T if it exists on the GameObject
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="obj"></param>
|
||||
public static void RemoveComponentIfExists<T>(this GameObject obj) where T : Component
|
||||
{
|
||||
var t = obj.GetComponent<T>();
|
||||
|
||||
if (t != null)
|
||||
{
|
||||
Object.Destroy(t);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removed components of type T if it exists on the GameObject
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="obj"></param>
|
||||
public static void RemoveComponentsIfExists<T>(this GameObject obj) where T : Component
|
||||
{
|
||||
var t = obj.GetComponents<T>();
|
||||
|
||||
for (var i = 0; i < t.Length; i++)
|
||||
{
|
||||
Object.Destroy(t[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set enabled property MonoBehaviour of type T if it exists
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="obj"></param>
|
||||
/// <param name="enable"></param>
|
||||
/// <returns>True if the component exists</returns>
|
||||
public static bool EnableComponentIfExists<T>(this GameObject obj, bool enable = true) where T : MonoBehaviour
|
||||
{
|
||||
var t = obj.GetComponent<T>();
|
||||
|
||||
if (t == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
t.enabled = enable;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the layer of a gameobject and all child objects
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
/// <param name="layer"></param>
|
||||
public static void SetLayerRecursive(this GameObject o, int layer)
|
||||
{
|
||||
SetLayerInternal(o.transform, layer);
|
||||
}
|
||||
|
||||
private static void SetLayerInternal(Transform t, int layer)
|
||||
{
|
||||
t.gameObject.layer = layer;
|
||||
|
||||
foreach (Transform o in t)
|
||||
{
|
||||
SetLayerInternal(o, layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57a08f4d800e4384fac80b0ecf63a7a0
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,47 @@
|
||||
namespace SRF
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public static class SRFIListExtensions
|
||||
{
|
||||
public static T Random<T>(this IList<T> list)
|
||||
{
|
||||
if (list.Count == 0)
|
||||
{
|
||||
throw new IndexOutOfRangeException("List needs at least one entry to call Random()");
|
||||
}
|
||||
|
||||
if (list.Count == 1)
|
||||
{
|
||||
return list[0];
|
||||
}
|
||||
|
||||
return list[UnityEngine.Random.Range(0, list.Count)];
|
||||
}
|
||||
|
||||
public static T RandomOrDefault<T>(this IList<T> list)
|
||||
{
|
||||
if (list.Count == 0)
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
return list.Random();
|
||||
}
|
||||
|
||||
public static T PopLast<T>(this IList<T> list)
|
||||
{
|
||||
if (list.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
var t = list[list.Count - 1];
|
||||
|
||||
list.RemoveAt(list.Count - 1);
|
||||
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c196b9d1bba9e9e44939cf8776545577
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,32 @@
|
||||
|
||||
#if NETFX_CORE
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace SRF
|
||||
{
|
||||
|
||||
public static class NetFxExtensions
|
||||
{
|
||||
|
||||
|
||||
public static bool IsAssignableFrom(this Type @this, Type t)
|
||||
{
|
||||
|
||||
return @this.GetTypeInfo().IsAssignableFrom(t.GetTypeInfo());
|
||||
|
||||
}
|
||||
|
||||
public static bool IsInstanceOfType(this Type @this, object obj)
|
||||
{
|
||||
|
||||
return @this.IsAssignableFrom(obj.GetType());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f503b1a2564101f4f96417c97debaaf5
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace SRF
|
||||
{
|
||||
public static class SRFStringExtensions
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[JetBrains.Annotations.StringFormatMethod("formatString")]
|
||||
#endif
|
||||
public static string Fmt(this string formatString, params object[] args)
|
||||
{
|
||||
return string.Format(formatString, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71e45638ff7335744a6554752b778f39
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,91 @@
|
||||
namespace SRF
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public static class SRFTransformExtensions
|
||||
{
|
||||
public static IEnumerable<Transform> GetChildren(this Transform t)
|
||||
{
|
||||
var i = 0;
|
||||
|
||||
while (i < t.childCount)
|
||||
{
|
||||
yield return t.GetChild(i);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset all local values on a transform to identity
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
public static void ResetLocal(this Transform t)
|
||||
{
|
||||
t.localPosition = Vector3.zero;
|
||||
t.localRotation = Quaternion.identity;
|
||||
t.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an empty child object of this transform
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static GameObject CreateChild(this Transform t, string name)
|
||||
{
|
||||
var go = new GameObject(name);
|
||||
go.transform.parent = t;
|
||||
go.transform.ResetLocal();
|
||||
go.gameObject.layer = t.gameObject.layer;
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the parent of this transform, but maintain the localScale, localPosition, localRotation values.
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <param name="parent"></param>
|
||||
public static void SetParentMaintainLocals(this Transform t, Transform parent)
|
||||
{
|
||||
t.SetParent(parent, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy local position,rotation,scale from other transform
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <param name="from"></param>
|
||||
public static void SetLocals(this Transform t, Transform from)
|
||||
{
|
||||
t.localPosition = from.localPosition;
|
||||
t.localRotation = from.localRotation;
|
||||
t.localScale = from.localScale;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set position/rotation to from. Scale is unchanged
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <param name="from"></param>
|
||||
public static void Match(this Transform t, Transform from)
|
||||
{
|
||||
t.position = from.position;
|
||||
t.rotation = from.rotation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroy all child game objects
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
public static void DestroyChildren(this Transform t)
|
||||
{
|
||||
foreach (var child in t)
|
||||
{
|
||||
Object.Destroy(((Transform) child).gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 891f8206d8bca304fbbf298c6a37648e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
5
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers.meta
Normal file
5
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers.meta
Normal file
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5354a62e7d1e47949b07ff9e9b123080
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
63
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/AssetUtil.cs
Normal file
63
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/AssetUtil.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
|
||||
#endif
|
||||
|
||||
namespace SRF.Helpers
|
||||
{
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
public static class AssetUtil
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
|
||||
// This makes it easy to create, name and place unique new ScriptableObject asset files.
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public static T CreateAsset<T>() where T : ScriptableObject
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(Selection.activeObject);
|
||||
|
||||
if (path == "")
|
||||
{
|
||||
path = "Assets";
|
||||
}
|
||||
else if (Path.GetExtension(path) != "")
|
||||
{
|
||||
path = path.Replace(Path.GetFileName(path), "");
|
||||
}
|
||||
|
||||
return CreateAsset<T>(path, "New " + typeof (T).Name);
|
||||
}
|
||||
|
||||
public static T CreateAsset<T>(string path, string name) where T : ScriptableObject
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
path = "Assets";
|
||||
}
|
||||
|
||||
if (!name.EndsWith(".asset"))
|
||||
{
|
||||
name += ".asset";
|
||||
}
|
||||
|
||||
var assetPathAndName = AssetDatabase.GenerateUniqueAssetPath(path + "/" + name);
|
||||
|
||||
var asset = ScriptableObject.CreateInstance<T>();
|
||||
AssetDatabase.CreateAsset(asset, assetPathAndName);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
public static void SelectAssetInProjectView(Object asset)
|
||||
{
|
||||
EditorUtility.FocusProjectWindow();
|
||||
Selection.activeObject = asset;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de28cc9633260c54a9ba062b7ad82e63
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
73
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/Hierarchy.cs
Normal file
73
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/Hierarchy.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
namespace SRF
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class Hierarchy
|
||||
{
|
||||
private static readonly char[] Seperator = {'/'};
|
||||
private static readonly Dictionary<string, Transform> Cache = new Dictionary<string, Transform>();
|
||||
|
||||
[Obsolete("Use static Get() instead")]
|
||||
public Transform this[string key]
|
||||
{
|
||||
get { return Get(key); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pass in a path (e.g. /Test/Me/One) and get a transform with the hierarchy Test->Me->One.
|
||||
/// Any Transforms required below this path will be auto-created.
|
||||
/// This is a very slow method, so use only on initialisation.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static Transform Get(string key)
|
||||
{
|
||||
Transform t;
|
||||
|
||||
// Check cache
|
||||
if (Cache.TryGetValue(key, out t))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
var find = GameObject.Find(key);
|
||||
|
||||
if (find)
|
||||
{
|
||||
t = find.transform;
|
||||
Cache.Add(key, t);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// Find container parent
|
||||
var elements = key.Split(Seperator, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
// Create new container
|
||||
t = new GameObject(elements.Last()).transform;
|
||||
Cache.Add(key, t);
|
||||
|
||||
// If root
|
||||
if (elements.Length == 1)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
t.parent = Get(string.Join("/", elements, 0, elements.Length - 1));
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
#if (!UNITY_2017 && !UNITY_2018 && !UNITY_2019) || UNITY_2019_3_OR_NEWER
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||
public static void RuntimeInitialize()
|
||||
{
|
||||
// To handle entering play mode without a domain reload, need to reset the state of the service manager.
|
||||
Cache.Clear();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ecf392c4c08d14543b90300c27422d60
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace SRF.Helpers
|
||||
{
|
||||
using System.Reflection;
|
||||
|
||||
public sealed class MethodReference
|
||||
{
|
||||
private readonly Func<object[], object> _method;
|
||||
|
||||
public MethodReference(object target, MethodInfo method)
|
||||
{
|
||||
SRDebugUtil.AssertNotNull(target);
|
||||
|
||||
_method = o => method.Invoke(target, o);
|
||||
}
|
||||
|
||||
public MethodReference(Func<object[], object> method)
|
||||
{
|
||||
_method = method;
|
||||
}
|
||||
|
||||
public object Invoke(object[] parameters)
|
||||
{
|
||||
return _method.Invoke(parameters);
|
||||
}
|
||||
|
||||
public static implicit operator MethodReference(Action action)
|
||||
{
|
||||
return new MethodReference(args =>
|
||||
{
|
||||
action();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ed7f46979ff4b3418a838a6b940a9ab
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
208
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/PropertyReference.cs
Normal file
208
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/PropertyReference.cs
Normal file
@@ -0,0 +1,208 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using JetBrains.Annotations;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SRF.Helpers
|
||||
{
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
public delegate void PropertyValueChangedHandler(PropertyReference property);
|
||||
|
||||
public sealed class PropertyReference
|
||||
{
|
||||
public event PropertyValueChangedHandler ValueChanged
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_valueChangedListeners == null)
|
||||
{
|
||||
_valueChangedListeners = new List<PropertyValueChangedHandler>();
|
||||
}
|
||||
|
||||
_valueChangedListeners.Add(value);
|
||||
if (_valueChangedListeners.Count == 1 && _target is INotifyPropertyChanged)
|
||||
{
|
||||
// Subscribe to value changed event on target.
|
||||
((INotifyPropertyChanged)_target).PropertyChanged += OnTargetPropertyChanged;
|
||||
}
|
||||
}
|
||||
|
||||
remove
|
||||
{
|
||||
if (_valueChangedListeners == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_valueChangedListeners.Remove(value) && _valueChangedListeners.Count == 0 &&
|
||||
_target is INotifyPropertyChanged)
|
||||
{
|
||||
// Unsubscribe from value changed event on target.
|
||||
((INotifyPropertyChanged) _target).PropertyChanged -= OnTargetPropertyChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CanBeNull] private readonly PropertyInfo _property;
|
||||
[CanBeNull] private readonly object _target;
|
||||
|
||||
[CanBeNull] private readonly Attribute[] _attributes;
|
||||
|
||||
[CanBeNull] private readonly Func<object> _getter;
|
||||
|
||||
[CanBeNull] private readonly Action<object> _setter;
|
||||
|
||||
[CanBeNull] private List<PropertyValueChangedHandler> _valueChangedListeners;
|
||||
|
||||
|
||||
public static PropertyReference FromLambda<T>(Func<T> getter, Action<T> setter = null, params Attribute[] attributes)
|
||||
{
|
||||
Action<object> internalSetter = null;
|
||||
if (setter != null)
|
||||
{
|
||||
internalSetter = o => setter((T)o);
|
||||
}
|
||||
return new PropertyReference(typeof(T), () => getter(), internalSetter, attributes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a property reference from an object target and reflection PropertyInfo.
|
||||
/// This represents a property on an object.
|
||||
/// </summary>
|
||||
public PropertyReference(object target, PropertyInfo property)
|
||||
{
|
||||
SRDebugUtil.AssertNotNull(target);
|
||||
SRDebugUtil.AssertNotNull(property);
|
||||
|
||||
PropertyType = property.PropertyType;
|
||||
_property = property;
|
||||
_target = target;
|
||||
|
||||
#if NETFX_CORE
|
||||
if(_property.GetMethod != null && _property.GetMethod.IsPublic)
|
||||
#else
|
||||
if (property.GetGetMethod() != null)
|
||||
#endif
|
||||
{
|
||||
_getter = () => SRReflection.GetPropertyValue(target, property);
|
||||
}
|
||||
|
||||
|
||||
#if NETFX_CORE
|
||||
if(_property.SetMethod != null && _property.SetMethod.IsPublic)
|
||||
#else
|
||||
if (property.GetSetMethod() != null)
|
||||
#endif
|
||||
{
|
||||
_setter = (v) => SRReflection.SetPropertyValue(target, property, v);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a property reference from lambdas. This has no underlying reflection or object associated with it.
|
||||
/// </summary>
|
||||
public PropertyReference(Type type, Func<object> getter = null, Action<object> setter = null, Attribute[] attributes = null)
|
||||
{
|
||||
SRDebugUtil.AssertNotNull(type);
|
||||
|
||||
PropertyType = type;
|
||||
_attributes = attributes;
|
||||
_getter = getter;
|
||||
_setter = setter;
|
||||
}
|
||||
|
||||
public Type PropertyType { get; private set; }
|
||||
|
||||
public bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return _getter != null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return _setter != null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notify any listeners to <see cref="ValueChanged"/> that the value has been updated.
|
||||
/// </summary>
|
||||
public void NotifyValueChanged()
|
||||
{
|
||||
if (_valueChangedListeners == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var handler in _valueChangedListeners)
|
||||
{
|
||||
handler(this);
|
||||
}
|
||||
}
|
||||
|
||||
public object GetValue()
|
||||
{
|
||||
if (_getter != null)
|
||||
{
|
||||
return _getter();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetValue(object value)
|
||||
{
|
||||
if (_setter != null)
|
||||
{
|
||||
_setter(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Can not write to property");
|
||||
}
|
||||
}
|
||||
|
||||
public T GetAttribute<T>() where T : Attribute
|
||||
{
|
||||
if (_attributes != null)
|
||||
{
|
||||
return _attributes.FirstOrDefault(p => p is T) as T;
|
||||
}
|
||||
|
||||
if (_property != null)
|
||||
{
|
||||
return _property.GetCustomAttributes(typeof(T), true).FirstOrDefault() as T;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
private void OnTargetPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (_valueChangedListeners == null || _valueChangedListeners.Count == 0)
|
||||
{
|
||||
Debug.LogWarning("[PropertyReference] Received property value changed event when there are no listeners. Did the event not get unsubscribed correctly?");
|
||||
return;
|
||||
}
|
||||
|
||||
NotifyValueChanged();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (_property != null)
|
||||
{
|
||||
return "{0}.{1}".Fmt(_property.DeclaringType.Name, _property.Name);
|
||||
}
|
||||
|
||||
return "<delegate>";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dedbd84f93f7d4c4e86f2d3a238916c4
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
64
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/SRDebugUtil.cs
Normal file
64
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/SRDebugUtil.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using SRF;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
public static class SRDebugUtil
|
||||
{
|
||||
public const int LineBufferCount = 512;
|
||||
public static bool IsFixedUpdate { get; set; }
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[DebuggerStepThrough]
|
||||
public static void AssertNotNull(object value, string message = null, MonoBehaviour instance = null)
|
||||
{
|
||||
if (!EqualityComparer<object>.Default.Equals(value, null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
message = message != null ? "NotNullAssert Failed: {0}".Fmt(message) : "Assert Failed";
|
||||
|
||||
Debug.LogError(message, instance);
|
||||
|
||||
if (instance != null)
|
||||
{
|
||||
instance.enabled = false;
|
||||
}
|
||||
|
||||
throw new NullReferenceException(message);
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[DebuggerStepThrough]
|
||||
public static void Assert(bool condition, string message = null, MonoBehaviour instance = null)
|
||||
{
|
||||
if (condition)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
message = message != null ? "Assert Failed: {0}".Fmt(message) : "Assert Failed";
|
||||
|
||||
Debug.LogError(message, instance);
|
||||
throw new Exception(message);
|
||||
}
|
||||
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
[DebuggerNonUserCode]
|
||||
[DebuggerStepThrough]
|
||||
public static void EditorAssertNotNull(object value, string message = null, MonoBehaviour instance = null)
|
||||
{
|
||||
AssertNotNull(value, message, instance);
|
||||
}
|
||||
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
[DebuggerNonUserCode]
|
||||
[DebuggerStepThrough]
|
||||
public static void EditorAssert(bool condition, string message = null, MonoBehaviour instance = null)
|
||||
{
|
||||
Assert(condition, message, instance);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f74f500c46d2b60419e95b8bd0cb87b6
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
73
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/SRFileUtil.cs
Normal file
73
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/SRFileUtil.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
public static class SRFileUtil
|
||||
{
|
||||
#if !UNITY_WEBPLAYER && !NETFX_CORE
|
||||
|
||||
public static void DeleteDirectory(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(path, true);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
Thread.Sleep(0);
|
||||
Directory.Delete(path, true);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns the human-readable file size for an arbitrary, 64-bit file size
|
||||
/// The default format is "0.### XB", e.g. "4.2 KB" or "1.434 GB"
|
||||
/// </summary>
|
||||
/// <param name="i"></param>
|
||||
/// <remarks>http://stackoverflow.com/a/281684/147003</remarks>
|
||||
/// <returns></returns>
|
||||
public static string GetBytesReadable(long i)
|
||||
{
|
||||
var sign = (i < 0 ? "-" : "");
|
||||
double readable = (i < 0 ? -i : i);
|
||||
string suffix;
|
||||
if (i >= 0x1000000000000000) // Exabyte
|
||||
{
|
||||
suffix = "EB";
|
||||
readable = i >> 50;
|
||||
}
|
||||
else if (i >= 0x4000000000000) // Petabyte
|
||||
{
|
||||
suffix = "PB";
|
||||
readable = i >> 40;
|
||||
}
|
||||
else if (i >= 0x10000000000) // Terabyte
|
||||
{
|
||||
suffix = "TB";
|
||||
readable = i >> 30;
|
||||
}
|
||||
else if (i >= 0x40000000) // Gigabyte
|
||||
{
|
||||
suffix = "GB";
|
||||
readable = i >> 20;
|
||||
}
|
||||
else if (i >= 0x100000) // Megabyte
|
||||
{
|
||||
suffix = "MB";
|
||||
readable = i >> 10;
|
||||
}
|
||||
else if (i >= 0x400) // Kilobyte
|
||||
{
|
||||
suffix = "KB";
|
||||
readable = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
return i.ToString(sign + "0 B"); // Byte
|
||||
}
|
||||
readable /= 1024;
|
||||
|
||||
return sign + readable.ToString("0.### ") + suffix;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c5dd64a3a7854e4f948daaec7d318fa
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
19
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/SRInstantiate.cs
Normal file
19
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/SRInstantiate.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using UnityEngine;
|
||||
|
||||
public static class SRInstantiate
|
||||
{
|
||||
public static T Instantiate<T>(T prefab) where T : Component
|
||||
{
|
||||
return (T) Object.Instantiate(prefab);
|
||||
}
|
||||
|
||||
public static GameObject Instantiate(GameObject prefab)
|
||||
{
|
||||
return (GameObject) Object.Instantiate(prefab);
|
||||
}
|
||||
|
||||
public static T Instantiate<T>(T prefab, Vector3 position, Quaternion rotation) where T : Component
|
||||
{
|
||||
return (T) Object.Instantiate(prefab, position, rotation);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b2502558f76a9a4b9d3fd4d26d4d2a6
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,788 @@
|
||||
using UnityEngine;
|
||||
|
||||
public static partial class SRMath
|
||||
{
|
||||
/**
|
||||
*
|
||||
* These tweening functions taken from https://wpf-animation.googlecode.com/svn/trunk/src/WPF/Animation/PennerDoubleAnimation.cs
|
||||
* Licensed under the new BSD License
|
||||
*
|
||||
* @author Darren David darren-code@lookorfeel.com
|
||||
* @version 1.0
|
||||
*
|
||||
* Credit/Thanks:
|
||||
* Robert Penner - The easing equations we all know and love
|
||||
* (http://robertpenner.com/easing/) [See License.txt for license info]
|
||||
*
|
||||
* Lee Brimelow - initial port of Penner's equations to WPF
|
||||
* (http://thewpfblog.com/?p=12)
|
||||
*
|
||||
* Zeh Fernando - additional equations (out/in) from
|
||||
* caurina.transitions.Tweener (http://code.google.com/p/tweener/)
|
||||
* [See License.txt for license info]
|
||||
*
|
||||
*/
|
||||
|
||||
private static class TweenFunctions
|
||||
{
|
||||
#region Equations
|
||||
|
||||
#region Linear
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a simple linear tweening, with no easing.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float Linear(float t, float b, float c, float d)
|
||||
{
|
||||
return c*t/d + b;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Expo
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for an exponential (2^t) easing out:
|
||||
/// decelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float ExpoEaseOut(float t, float b, float c, float d)
|
||||
{
|
||||
return (t == d) ? b + c : c*(-Mathf.Pow(2, -10*t/d) + 1) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for an exponential (2^t) easing in:
|
||||
/// accelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float ExpoEaseIn(float t, float b, float c, float d)
|
||||
{
|
||||
return (t == 0) ? b : c*Mathf.Pow(2, 10*(t/d - 1)) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for an exponential (2^t) easing in/out:
|
||||
/// acceleration until halfway, then deceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float ExpoEaseInOut(float t, float b, float c, float d)
|
||||
{
|
||||
if (t == 0)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
|
||||
if (t == d)
|
||||
{
|
||||
return b + c;
|
||||
}
|
||||
|
||||
if ((t /= d/2) < 1)
|
||||
{
|
||||
return c/2*Mathf.Pow(2, 10*(t - 1)) + b;
|
||||
}
|
||||
|
||||
return c/2*(-Mathf.Pow(2, -10*--t) + 2) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for an exponential (2^t) easing out/in:
|
||||
/// deceleration until halfway, then acceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float ExpoEaseOutIn(float t, float b, float c, float d)
|
||||
{
|
||||
if (t < d/2)
|
||||
{
|
||||
return ExpoEaseOut(t*2, b, c/2, d);
|
||||
}
|
||||
|
||||
return ExpoEaseIn((t*2) - d, b + c/2, c/2, d);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Circular
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a circular (sqrt(1-t^2)) easing out:
|
||||
/// decelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float CircEaseOut(float t, float b, float c, float d)
|
||||
{
|
||||
return c*Mathf.Sqrt(1 - (t = t/d - 1)*t) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a circular (sqrt(1-t^2)) easing in:
|
||||
/// accelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float CircEaseIn(float t, float b, float c, float d)
|
||||
{
|
||||
return -c*(Mathf.Sqrt(1 - (t /= d)*t) - 1) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a circular (sqrt(1-t^2)) easing in/out:
|
||||
/// acceleration until halfway, then deceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float CircEaseInOut(float t, float b, float c, float d)
|
||||
{
|
||||
if ((t /= d/2) < 1)
|
||||
{
|
||||
return -c/2*(Mathf.Sqrt(1 - t*t) - 1) + b;
|
||||
}
|
||||
|
||||
return c/2*(Mathf.Sqrt(1 - (t -= 2)*t) + 1) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a circular (sqrt(1-t^2)) easing in/out:
|
||||
/// acceleration until halfway, then deceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float CircEaseOutIn(float t, float b, float c, float d)
|
||||
{
|
||||
if (t < d/2)
|
||||
{
|
||||
return CircEaseOut(t*2, b, c/2, d);
|
||||
}
|
||||
|
||||
return CircEaseIn((t*2) - d, b + c/2, c/2, d);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Quad
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a quadratic (t^2) easing out:
|
||||
/// decelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float QuadEaseOut(float t, float b, float c, float d)
|
||||
{
|
||||
return -c*(t /= d)*(t - 2) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a quadratic (t^2) easing in:
|
||||
/// accelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float QuadEaseIn(float t, float b, float c, float d)
|
||||
{
|
||||
return c*(t /= d)*t + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a quadratic (t^2) easing in/out:
|
||||
/// acceleration until halfway, then deceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float QuadEaseInOut(float t, float b, float c, float d)
|
||||
{
|
||||
if ((t /= d/2) < 1)
|
||||
{
|
||||
return c/2*t*t + b;
|
||||
}
|
||||
|
||||
return -c/2*((--t)*(t - 2) - 1) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a quadratic (t^2) easing out/in:
|
||||
/// deceleration until halfway, then acceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float QuadEaseOutIn(float t, float b, float c, float d)
|
||||
{
|
||||
if (t < d/2)
|
||||
{
|
||||
return QuadEaseOut(t*2, b, c/2, d);
|
||||
}
|
||||
|
||||
return QuadEaseIn((t*2) - d, b + c/2, c/2, d);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Sine
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a sinusoidal (sin(t)) easing out:
|
||||
/// decelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float SineEaseOut(float t, float b, float c, float d)
|
||||
{
|
||||
return c*Mathf.Sin(t/d*(Mathf.PI/2)) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a sinusoidal (sin(t)) easing in:
|
||||
/// accelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float SineEaseIn(float t, float b, float c, float d)
|
||||
{
|
||||
return -c*Mathf.Cos(t/d*(Mathf.PI/2)) + c + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a sinusoidal (sin(t)) easing in/out:
|
||||
/// acceleration until halfway, then deceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float SineEaseInOut(float t, float b, float c, float d)
|
||||
{
|
||||
if ((t /= d/2) < 1)
|
||||
{
|
||||
return c/2*(Mathf.Sin(Mathf.PI*t/2)) + b;
|
||||
}
|
||||
|
||||
return -c/2*(Mathf.Cos(Mathf.PI*--t/2) - 2) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a sinusoidal (sin(t)) easing in/out:
|
||||
/// deceleration until halfway, then acceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float SineEaseOutIn(float t, float b, float c, float d)
|
||||
{
|
||||
if (t < d/2)
|
||||
{
|
||||
return SineEaseOut(t*2, b, c/2, d);
|
||||
}
|
||||
|
||||
return SineEaseIn((t*2) - d, b + c/2, c/2, d);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Cubic
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a cubic (t^3) easing out:
|
||||
/// decelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float CubicEaseOut(float t, float b, float c, float d)
|
||||
{
|
||||
return c*((t = t/d - 1)*t*t + 1) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a cubic (t^3) easing in:
|
||||
/// accelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float CubicEaseIn(float t, float b, float c, float d)
|
||||
{
|
||||
return c*(t /= d)*t*t + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a cubic (t^3) easing in/out:
|
||||
/// acceleration until halfway, then deceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float CubicEaseInOut(float t, float b, float c, float d)
|
||||
{
|
||||
if ((t /= d/2) < 1)
|
||||
{
|
||||
return c/2*t*t*t + b;
|
||||
}
|
||||
|
||||
return c/2*((t -= 2)*t*t + 2) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a cubic (t^3) easing out/in:
|
||||
/// deceleration until halfway, then acceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float CubicEaseOutIn(float t, float b, float c, float d)
|
||||
{
|
||||
if (t < d/2)
|
||||
{
|
||||
return CubicEaseOut(t*2, b, c/2, d);
|
||||
}
|
||||
|
||||
return CubicEaseIn((t*2) - d, b + c/2, c/2, d);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Quartic
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a quartic (t^4) easing out:
|
||||
/// decelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float QuartEaseOut(float t, float b, float c, float d)
|
||||
{
|
||||
return -c*((t = t/d - 1)*t*t*t - 1) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a quartic (t^4) easing in:
|
||||
/// accelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float QuartEaseIn(float t, float b, float c, float d)
|
||||
{
|
||||
return c*(t /= d)*t*t*t + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a quartic (t^4) easing in/out:
|
||||
/// acceleration until halfway, then deceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float QuartEaseInOut(float t, float b, float c, float d)
|
||||
{
|
||||
if ((t /= d/2) < 1)
|
||||
{
|
||||
return c/2*t*t*t*t + b;
|
||||
}
|
||||
|
||||
return -c/2*((t -= 2)*t*t*t - 2) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a quartic (t^4) easing out/in:
|
||||
/// deceleration until halfway, then acceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float QuartEaseOutIn(float t, float b, float c, float d)
|
||||
{
|
||||
if (t < d/2)
|
||||
{
|
||||
return QuartEaseOut(t*2, b, c/2, d);
|
||||
}
|
||||
|
||||
return QuartEaseIn((t*2) - d, b + c/2, c/2, d);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Quintic
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a quintic (t^5) easing out:
|
||||
/// decelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float QuintEaseOut(float t, float b, float c, float d)
|
||||
{
|
||||
return c*((t = t/d - 1)*t*t*t*t + 1) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a quintic (t^5) easing in:
|
||||
/// accelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float QuintEaseIn(float t, float b, float c, float d)
|
||||
{
|
||||
return c*(t /= d)*t*t*t*t + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a quintic (t^5) easing in/out:
|
||||
/// acceleration until halfway, then deceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float QuintEaseInOut(float t, float b, float c, float d)
|
||||
{
|
||||
if ((t /= d/2) < 1)
|
||||
{
|
||||
return c/2*t*t*t*t*t + b;
|
||||
}
|
||||
return c/2*((t -= 2)*t*t*t*t + 2) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a quintic (t^5) easing in/out:
|
||||
/// acceleration until halfway, then deceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float QuintEaseOutIn(float t, float b, float c, float d)
|
||||
{
|
||||
if (t < d/2)
|
||||
{
|
||||
return QuintEaseOut(t*2, b, c/2, d);
|
||||
}
|
||||
return QuintEaseIn((t*2) - d, b + c/2, c/2, d);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Elastic
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for an elastic (exponentially decaying sine wave) easing out:
|
||||
/// decelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float ElasticEaseOut(float t, float b, float c, float d)
|
||||
{
|
||||
if ((t /= d) == 1)
|
||||
{
|
||||
return b + c;
|
||||
}
|
||||
|
||||
var p = d*.3f;
|
||||
var s = p/4;
|
||||
|
||||
return (c*Mathf.Pow(2, -10*t)*Mathf.Sin((t*d - s)*(2*Mathf.PI)/p) + c + b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for an elastic (exponentially decaying sine wave) easing in:
|
||||
/// accelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float ElasticEaseIn(float t, float b, float c, float d)
|
||||
{
|
||||
if ((t /= d) == 1)
|
||||
{
|
||||
return b + c;
|
||||
}
|
||||
|
||||
var p = d*.3f;
|
||||
var s = p/4;
|
||||
|
||||
return -(c*Mathf.Pow(2, 10*(t -= 1))*Mathf.Sin((t*d - s)*(2*Mathf.PI)/p)) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for an elastic (exponentially decaying sine wave) easing in/out:
|
||||
/// acceleration until halfway, then deceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float ElasticEaseInOut(float t, float b, float c, float d)
|
||||
{
|
||||
if ((t /= d/2) == 2)
|
||||
{
|
||||
return b + c;
|
||||
}
|
||||
|
||||
var p = d*(.3f*1.5f);
|
||||
var s = p/4;
|
||||
|
||||
if (t < 1)
|
||||
{
|
||||
return -.5f*(c*Mathf.Pow(2, 10*(t -= 1))*Mathf.Sin((t*d - s)*(2*Mathf.PI)/p)) + b;
|
||||
}
|
||||
return c*Mathf.Pow(2, -10*(t -= 1))*Mathf.Sin((t*d - s)*(2*Mathf.PI)/p)*.5f + c + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for an elastic (exponentially decaying sine wave) easing out/in:
|
||||
/// deceleration until halfway, then acceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float ElasticEaseOutIn(float t, float b, float c, float d)
|
||||
{
|
||||
if (t < d/2)
|
||||
{
|
||||
return ElasticEaseOut(t*2, b, c/2, d);
|
||||
}
|
||||
return ElasticEaseIn((t*2) - d, b + c/2, c/2, d);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bounce
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out:
|
||||
/// decelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float BounceEaseOut(float t, float b, float c, float d)
|
||||
{
|
||||
if ((t /= d) < (1/2.75f))
|
||||
{
|
||||
return c*(7.5625f*t*t) + b;
|
||||
}
|
||||
if (t < (2/2.75))
|
||||
{
|
||||
return c*(7.5625f*(t -= (1.5f/2.75f))*t + .75f) + b;
|
||||
}
|
||||
if (t < (2.5/2.75))
|
||||
{
|
||||
return c*(7.5625f*(t -= (2.25f/2.75f))*t + .9375f) + b;
|
||||
}
|
||||
return c*(7.5625f*(t -= (2.625f/2.75f))*t + .984375f) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in:
|
||||
/// accelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float BounceEaseIn(float t, float b, float c, float d)
|
||||
{
|
||||
return c - BounceEaseOut(d - t, 0, c, d) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in/out:
|
||||
/// acceleration until halfway, then deceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float BounceEaseInOut(float t, float b, float c, float d)
|
||||
{
|
||||
if (t < d/2)
|
||||
{
|
||||
return BounceEaseIn(t*2, 0, c, d)*.5f + b;
|
||||
}
|
||||
return BounceEaseOut(t*2 - d, 0, c, d)*.5f + c*.5f + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out/in:
|
||||
/// deceleration until halfway, then acceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float BounceEaseOutIn(float t, float b, float c, float d)
|
||||
{
|
||||
if (t < d/2)
|
||||
{
|
||||
return BounceEaseOut(t*2, b, c/2, d);
|
||||
}
|
||||
return BounceEaseIn((t*2) - d, b + c/2, c/2, d);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Back
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out:
|
||||
/// decelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float BackEaseOut(float t, float b, float c, float d)
|
||||
{
|
||||
return c*((t = t/d - 1)*t*((1.70158f + 1)*t + 1.70158f) + 1) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in:
|
||||
/// accelerating from zero velocity.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float BackEaseIn(float t, float b, float c, float d)
|
||||
{
|
||||
return c*(t /= d)*t*((1.70158f + 1)*t - 1.70158f) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in/out:
|
||||
/// acceleration until halfway, then deceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float BackEaseInOut(float t, float b, float c, float d)
|
||||
{
|
||||
var s = 1.70158f;
|
||||
if ((t /= d/2) < 1)
|
||||
{
|
||||
return c/2*(t*t*(((s *= (1.525f)) + 1)*t - s)) + b;
|
||||
}
|
||||
return c/2*((t -= 2)*t*(((s *= (1.525f)) + 1)*t + s) + 2) + b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out/in:
|
||||
/// deceleration until halfway, then acceleration.
|
||||
/// </summary>
|
||||
/// <param name="t">Current time in seconds.</param>
|
||||
/// <param name="b">Starting value.</param>
|
||||
/// <param name="c">Final value.</param>
|
||||
/// <param name="d">Duration of animation.</param>
|
||||
/// <returns>The correct value.</returns>
|
||||
public static float BackEaseOutIn(float t, float b, float c, float d)
|
||||
{
|
||||
if (t < d/2)
|
||||
{
|
||||
return BackEaseOut(t*2, b, c/2, d);
|
||||
}
|
||||
return BackEaseIn((t*2) - d, b + c/2, c/2, d);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0be6d36a29af844fa2d7584d66b374c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
209
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/SRMath.Tweening.cs
Normal file
209
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/SRMath.Tweening.cs
Normal file
@@ -0,0 +1,209 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public static partial class SRMath
|
||||
{
|
||||
public enum EaseType
|
||||
{
|
||||
Linear,
|
||||
QuadEaseOut,
|
||||
QuadEaseIn,
|
||||
QuadEaseInOut,
|
||||
QuadEaseOutIn,
|
||||
ExpoEaseOut,
|
||||
ExpoEaseIn,
|
||||
ExpoEaseInOut,
|
||||
ExpoEaseOutIn,
|
||||
CubicEaseOut,
|
||||
CubicEaseIn,
|
||||
CubicEaseInOut,
|
||||
CubicEaseOutIn,
|
||||
QuartEaseOut,
|
||||
QuartEaseIn,
|
||||
QuartEaseInOut,
|
||||
QuartEaseOutIn,
|
||||
QuintEaseOut,
|
||||
QuintEaseIn,
|
||||
QuintEaseInOut,
|
||||
QuintEaseOutIn,
|
||||
CircEaseOut,
|
||||
CircEaseIn,
|
||||
CircEaseInOut,
|
||||
CircEaseOutIn,
|
||||
SineEaseOut,
|
||||
SineEaseIn,
|
||||
SineEaseInOut,
|
||||
SineEaseOutIn,
|
||||
ElasticEaseOut,
|
||||
ElasticEaseIn,
|
||||
ElasticEaseInOut,
|
||||
ElasticEaseOutIn,
|
||||
BounceEaseOut,
|
||||
BounceEaseIn,
|
||||
BounceEaseInOut,
|
||||
BounceEaseOutIn,
|
||||
BackEaseOut,
|
||||
BackEaseIn,
|
||||
BackEaseInOut,
|
||||
BackEaseOutIn
|
||||
}
|
||||
|
||||
public static float Ease(float from, float to, float t, EaseType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EaseType.Linear:
|
||||
return TweenFunctions.Linear(t, from, to, 1f);
|
||||
case EaseType.QuadEaseOut:
|
||||
return TweenFunctions.QuadEaseOut(t, from, to, 1f);
|
||||
case EaseType.QuadEaseIn:
|
||||
return TweenFunctions.QuadEaseIn(t, from, to, 1f);
|
||||
case EaseType.QuadEaseInOut:
|
||||
return TweenFunctions.QuadEaseInOut(t, from, to, 1f);
|
||||
case EaseType.QuadEaseOutIn:
|
||||
return TweenFunctions.QuadEaseOutIn(t, from, to, 1f);
|
||||
case EaseType.ExpoEaseOut:
|
||||
return TweenFunctions.ExpoEaseOut(t, from, to, 1f);
|
||||
case EaseType.ExpoEaseIn:
|
||||
return TweenFunctions.ExpoEaseIn(t, from, to, 1f);
|
||||
case EaseType.ExpoEaseInOut:
|
||||
return TweenFunctions.ExpoEaseInOut(t, from, to, 1f);
|
||||
case EaseType.ExpoEaseOutIn:
|
||||
return TweenFunctions.ExpoEaseOutIn(t, from, to, 1f);
|
||||
case EaseType.CubicEaseOut:
|
||||
return TweenFunctions.CubicEaseOut(t, from, to, 1f);
|
||||
case EaseType.CubicEaseIn:
|
||||
return TweenFunctions.CubicEaseIn(t, from, to, 1f);
|
||||
case EaseType.CubicEaseInOut:
|
||||
return TweenFunctions.CubicEaseInOut(t, from, to, 1f);
|
||||
case EaseType.CubicEaseOutIn:
|
||||
return TweenFunctions.CubicEaseOutIn(t, from, to, 1f);
|
||||
case EaseType.QuartEaseOut:
|
||||
return TweenFunctions.QuartEaseOut(t, from, to, 1f);
|
||||
case EaseType.QuartEaseIn:
|
||||
return TweenFunctions.QuartEaseIn(t, from, to, 1f);
|
||||
case EaseType.QuartEaseInOut:
|
||||
return TweenFunctions.QuartEaseInOut(t, from, to, 1f);
|
||||
case EaseType.QuartEaseOutIn:
|
||||
return TweenFunctions.QuartEaseOutIn(t, from, to, 1f);
|
||||
case EaseType.QuintEaseOut:
|
||||
return TweenFunctions.QuintEaseOut(t, from, to, 1f);
|
||||
case EaseType.QuintEaseIn:
|
||||
return TweenFunctions.QuintEaseIn(t, from, to, 1f);
|
||||
case EaseType.QuintEaseInOut:
|
||||
return TweenFunctions.QuintEaseInOut(t, from, to, 1f);
|
||||
case EaseType.QuintEaseOutIn:
|
||||
return TweenFunctions.QuintEaseOutIn(t, from, to, 1f);
|
||||
case EaseType.CircEaseOut:
|
||||
return TweenFunctions.CircEaseOut(t, from, to, 1f);
|
||||
case EaseType.CircEaseIn:
|
||||
return TweenFunctions.CircEaseIn(t, from, to, 1f);
|
||||
case EaseType.CircEaseInOut:
|
||||
return TweenFunctions.CircEaseInOut(t, from, to, 1f);
|
||||
case EaseType.CircEaseOutIn:
|
||||
return TweenFunctions.CircEaseOutIn(t, from, to, 1f);
|
||||
case EaseType.SineEaseOut:
|
||||
return TweenFunctions.SineEaseOut(t, from, to, 1f);
|
||||
case EaseType.SineEaseIn:
|
||||
return TweenFunctions.SineEaseIn(t, from, to, 1f);
|
||||
case EaseType.SineEaseInOut:
|
||||
return TweenFunctions.SineEaseInOut(t, from, to, 1f);
|
||||
case EaseType.SineEaseOutIn:
|
||||
return TweenFunctions.SineEaseOutIn(t, from, to, 1f);
|
||||
case EaseType.ElasticEaseOut:
|
||||
return TweenFunctions.ElasticEaseOut(t, from, to, 1f);
|
||||
case EaseType.ElasticEaseIn:
|
||||
return TweenFunctions.ElasticEaseIn(t, from, to, 1f);
|
||||
case EaseType.ElasticEaseInOut:
|
||||
return TweenFunctions.ElasticEaseInOut(t, from, to, 1f);
|
||||
case EaseType.ElasticEaseOutIn:
|
||||
return TweenFunctions.ElasticEaseOutIn(t, from, to, 1f);
|
||||
case EaseType.BounceEaseOut:
|
||||
return TweenFunctions.BounceEaseOut(t, from, to, 1f);
|
||||
case EaseType.BounceEaseIn:
|
||||
return TweenFunctions.BounceEaseIn(t, from, to, 1f);
|
||||
case EaseType.BounceEaseInOut:
|
||||
return TweenFunctions.BounceEaseInOut(t, from, to, 1f);
|
||||
case EaseType.BounceEaseOutIn:
|
||||
return TweenFunctions.BounceEaseOutIn(t, from, to, 1f);
|
||||
case EaseType.BackEaseOut:
|
||||
return TweenFunctions.BackEaseOut(t, from, to, 1f);
|
||||
case EaseType.BackEaseIn:
|
||||
return TweenFunctions.BackEaseIn(t, from, to, 1f);
|
||||
case EaseType.BackEaseInOut:
|
||||
return TweenFunctions.BackEaseInOut(t, from, to, 1f);
|
||||
case EaseType.BackEaseOutIn:
|
||||
return TweenFunctions.BackEaseOutIn(t, from, to, 1f);
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("type");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate a framerate-independent value to lerp by
|
||||
/// </summary>
|
||||
/// <param name="strength"></param>
|
||||
/// <param name="deltaTime"></param>
|
||||
/// <returns></returns>
|
||||
public static float SpringLerp(float strength, float deltaTime)
|
||||
{
|
||||
var ms = Mathf.RoundToInt(deltaTime*1000f);
|
||||
var step = 0.001f*strength;
|
||||
|
||||
var from = 0f;
|
||||
var to = 1f;
|
||||
|
||||
for (var i = 0; i < ms; i++)
|
||||
{
|
||||
from = Mathf.Lerp(from, to, step);
|
||||
}
|
||||
|
||||
return from;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A frame-rate independent way of doing Mathf.Lerp(from, to, Time.deltaTime * strength). Based on NGUIMath.SpringLerp
|
||||
/// </summary>
|
||||
/// <param name="from">Starting Value</param>
|
||||
/// <param name="to">End Value</param>
|
||||
/// <param name="strength">How fast the spring will complete</param>
|
||||
/// <param name="deltaTime">Pass in Time.deltaTime or RealTime.deltaTime</param>
|
||||
/// <returns>Interpolated value</returns>
|
||||
public static float SpringLerp(float from, float to, float strength, float deltaTime)
|
||||
{
|
||||
return Mathf.Lerp(from, to, SpringLerp(strength, deltaTime));
|
||||
}
|
||||
|
||||
public static Vector3 SpringLerp(Vector3 from, Vector3 to, float strength, float deltaTime)
|
||||
{
|
||||
return Vector3.Lerp(from, to, SpringLerp(strength, deltaTime));
|
||||
}
|
||||
|
||||
public static Quaternion SpringLerp(Quaternion from, Quaternion to, float strength, float deltaTime)
|
||||
{
|
||||
return Quaternion.Slerp(from, to, SpringLerp(strength, deltaTime));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Smoothly clamp value between 0 and max, smoothing between min and max
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="min"></param>
|
||||
/// <param name="max"></param>
|
||||
/// <param name="easeType"></param>
|
||||
/// <returns></returns>
|
||||
public static float SmoothClamp(float value, float min, float max, float scrollMax,
|
||||
EaseType easeType = EaseType.ExpoEaseOut)
|
||||
{
|
||||
if (value < min)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
var p = Mathf.Clamp01((value - min)/(scrollMax - min));
|
||||
|
||||
Debug.Log(p);
|
||||
|
||||
return Mathf.Clamp(min + Mathf.Lerp(value - min, max, Ease(0, 1f, p, easeType)), 0, max);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 810c2c875ec6af345a04174ff5828880
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
151
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/SRMath.cs
Normal file
151
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/SRMath.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public static partial class SRMath
|
||||
{
|
||||
/// <summary>
|
||||
/// Lerp from one value to another, without clamping t to 0-1.
|
||||
/// </summary>
|
||||
/// <param name="from"></param>
|
||||
/// <param name="to"></param>
|
||||
/// <param name="t"></param>
|
||||
/// <returns></returns>
|
||||
public static float LerpUnclamped(float from, float to, float t)
|
||||
{
|
||||
return (1.0f - t)*from + t*to;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lerp from one vector to another, without clamping t
|
||||
/// </summary>
|
||||
/// <param name="from"></param>
|
||||
/// <param name="to"></param>
|
||||
/// <param name="t"></param>
|
||||
/// <returns></returns>
|
||||
public static Vector3 LerpUnclamped(Vector3 from, Vector3 to, float t)
|
||||
{
|
||||
return new Vector3(
|
||||
LerpUnclamped(from.x, to.x, t),
|
||||
LerpUnclamped(from.y, to.y, t),
|
||||
LerpUnclamped(from.z, to.z, t)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Value from 0.0f-1.0f, 0 when facing fully away and 1.0f when facing fully towards
|
||||
/// </summary>
|
||||
public static float FacingNormalized(Vector3 dir1, Vector3 dir2)
|
||||
{
|
||||
dir1.Normalize();
|
||||
dir2.Normalize();
|
||||
|
||||
return Mathf.InverseLerp(-1, 1, Vector3.Dot(dir1, dir2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reduces a given angle to a value between 180 and -180.
|
||||
/// </summary>
|
||||
/// <param name="angle">The angle to reduce, in radians.</param>
|
||||
/// <returns>The new angle, in radians.</returns>
|
||||
/// https://github.com/mono/MonoGame/blob/develop/MonoGame.Framework/MathHelper.cs
|
||||
public static float WrapAngle(float angle)
|
||||
{
|
||||
if (angle <= -180f)
|
||||
{
|
||||
angle += 360f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (angle > 180f)
|
||||
{
|
||||
angle -= 360f;
|
||||
}
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the angle closest to 'to'
|
||||
/// </summary>
|
||||
/// <param name="to"></param>
|
||||
/// <param name="angle1"></param>
|
||||
/// <param name="angle2"></param>
|
||||
/// <returns></returns>
|
||||
public static float NearestAngle(float to, float angle1, float angle2)
|
||||
{
|
||||
if (Mathf.Abs(Mathf.DeltaAngle(to, angle1)) > Mathf.Abs(Mathf.DeltaAngle(to, angle2)))
|
||||
{
|
||||
return angle2;
|
||||
}
|
||||
return angle1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrap value to 0-max (non-inclusive)
|
||||
/// </summary>
|
||||
/// <param name="max">Max value (non-inclusive)</param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns>Value wrapped from 0-max</returns>
|
||||
public static int Wrap(int max, int value)
|
||||
{
|
||||
if (max < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("max", "max must be greater than 0");
|
||||
}
|
||||
|
||||
while (value < 0)
|
||||
{
|
||||
value += max;
|
||||
}
|
||||
|
||||
while (value >= max)
|
||||
{
|
||||
value -= max;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrap value to 0-max (non-inclusive)
|
||||
/// </summary>
|
||||
/// <param name="max">Max value (non-inclusive)</param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns>Value wrapped from 0-max</returns>
|
||||
public static float Wrap(float max, float value)
|
||||
{
|
||||
while (value < 0)
|
||||
{
|
||||
value += max;
|
||||
}
|
||||
|
||||
while (value >= max)
|
||||
{
|
||||
value -= max;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static float Average(float v1, float v2)
|
||||
{
|
||||
return (v1 + v2)*0.5f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return an angle in range -180, 180 based on direction vector
|
||||
/// </summary>
|
||||
/// <param name="direction"></param>
|
||||
/// <returns></returns>
|
||||
public static float Angle(Vector2 direction)
|
||||
{
|
||||
var angle = Vector3.Angle(Vector3.up, direction);
|
||||
|
||||
if (Vector3.Cross(direction, Vector3.up).z > 0f)
|
||||
{
|
||||
angle *= -1;
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc751da3d31975645847e0e4088ff560
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
46
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/SRReflection.cs
Normal file
46
JNFrame2/Assets/Plugins/SRF/Scripts/Helpers/SRReflection.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
namespace SRF.Helpers
|
||||
{
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
public static class SRReflection
|
||||
{
|
||||
public static void SetPropertyValue(object obj, PropertyInfo p, object value)
|
||||
{
|
||||
#if NETFX_CORE
|
||||
p.SetValue(obj, value, null);
|
||||
#else
|
||||
p.GetSetMethod().Invoke(obj, new[] {value});
|
||||
#endif
|
||||
}
|
||||
|
||||
public static object GetPropertyValue(object obj, PropertyInfo p)
|
||||
{
|
||||
#if NETFX_CORE
|
||||
return p.GetValue(obj, null);
|
||||
#else
|
||||
return p.GetGetMethod().Invoke(obj, null);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static T GetAttribute<T>(MemberInfo t) where T : Attribute
|
||||
{
|
||||
#if !NETFX_CORE
|
||||
return Attribute.GetCustomAttribute(t, typeof (T)) as T;
|
||||
#else
|
||||
return t.GetCustomAttribute(typeof (T), true) as T;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETFX_CORE
|
||||
|
||||
public static T GetAttribute<T>(Type t) where T : Attribute
|
||||
{
|
||||
|
||||
return GetAttribute<T>(t.GetTypeInfo());
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6aaf1b857713dd44a955633b6458f1c2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
5
JNFrame2/Assets/Plugins/SRF/Scripts/Service.meta
Normal file
5
JNFrame2/Assets/Plugins/SRF/Scripts/Service.meta
Normal file
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9107076f77b9a344d8c00028a350b6fb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
39
JNFrame2/Assets/Plugins/SRF/Scripts/Service/Attributes.cs
Normal file
39
JNFrame2/Assets/Plugins/SRF/Scripts/Service/Attributes.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using UnityEngine.Scripting;
|
||||
|
||||
namespace SRF.Service
|
||||
{
|
||||
using System;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public sealed class ServiceAttribute : PreserveAttribute
|
||||
{
|
||||
public ServiceAttribute(Type serviceType)
|
||||
{
|
||||
ServiceType = serviceType;
|
||||
}
|
||||
|
||||
public Type ServiceType { get; private set; }
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class ServiceSelectorAttribute : PreserveAttribute
|
||||
{
|
||||
public ServiceSelectorAttribute(Type serviceType)
|
||||
{
|
||||
ServiceType = serviceType;
|
||||
}
|
||||
|
||||
public Type ServiceType { get; private set; }
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class ServiceConstructorAttribute : PreserveAttribute
|
||||
{
|
||||
public ServiceConstructorAttribute(Type serviceType)
|
||||
{
|
||||
ServiceType = serviceType;
|
||||
}
|
||||
|
||||
public Type ServiceType { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 901f51b194db73d479d84ae26519fc20
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace SRF.Service
|
||||
{
|
||||
public interface IAsyncService
|
||||
{
|
||||
bool IsLoaded { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08e9b59ff0ffb22488411ef5134ee325
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,91 @@
|
||||
//#define ENABLE_LOGGING
|
||||
|
||||
namespace SRF.Service
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
/// <summary>
|
||||
/// A service which has async-loading dependencies
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class SRDependencyServiceBase<T> : SRServiceBase<T>, IAsyncService where T : class
|
||||
{
|
||||
private bool _isLoaded;
|
||||
protected abstract Type[] Dependencies { get; }
|
||||
|
||||
public bool IsLoaded
|
||||
{
|
||||
get { return _isLoaded; }
|
||||
}
|
||||
|
||||
[Conditional("ENABLE_LOGGING")]
|
||||
private void Log(string msg, Object target)
|
||||
{
|
||||
//#if ENABLE_LOGGING
|
||||
Debug.Log(msg, target);
|
||||
//#endif
|
||||
}
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
StartCoroutine(LoadDependencies());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked once all dependencies are loaded
|
||||
/// </summary>
|
||||
protected virtual void OnLoaded() {}
|
||||
|
||||
private IEnumerator LoadDependencies()
|
||||
{
|
||||
SRServiceManager.LoadingCount++;
|
||||
|
||||
Log("[Service] Loading service ({0})".Fmt(GetType().Name), this);
|
||||
|
||||
foreach (var d in Dependencies)
|
||||
{
|
||||
var hasService = SRServiceManager.HasService(d);
|
||||
|
||||
Log("[Service] Resolving Service ({0}) HasService: {1}".Fmt(d.Name, hasService), this);
|
||||
|
||||
if (hasService)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var service = SRServiceManager.GetService(d);
|
||||
|
||||
if (service == null)
|
||||
{
|
||||
Debug.LogError("[Service] Could not resolve dependency ({0})".Fmt(d.Name));
|
||||
enabled = false;
|
||||
yield break;
|
||||
}
|
||||
|
||||
var a = service as IAsyncService;
|
||||
|
||||
if (a != null)
|
||||
{
|
||||
while (!a.IsLoaded)
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log("[Service] Loading service ({0}) complete.".Fmt(GetType().Name), this);
|
||||
|
||||
_isLoaded = true;
|
||||
SRServiceManager.LoadingCount--;
|
||||
|
||||
OnLoaded();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c5aaa1711d009f48a19f2db87d71b82
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,128 @@
|
||||
//#define ENABLE_LOGGING
|
||||
|
||||
namespace SRF.Service
|
||||
{
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
public abstract class SRSceneServiceBase<T, TImpl> : SRServiceBase<T>, IAsyncService
|
||||
where T : class
|
||||
where TImpl : Component
|
||||
{
|
||||
private TImpl _rootObject;
|
||||
|
||||
/// <summary>
|
||||
/// Name of the scene this service's contents are within
|
||||
/// </summary>
|
||||
protected abstract string SceneName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Scene contents root object
|
||||
/// </summary>
|
||||
protected TImpl RootObject
|
||||
{
|
||||
get { return _rootObject; }
|
||||
}
|
||||
|
||||
public bool IsLoaded
|
||||
{
|
||||
get { return _rootObject != null; }
|
||||
}
|
||||
|
||||
[Conditional("ENABLE_LOGGING")]
|
||||
private void Log(string msg, Object target)
|
||||
{
|
||||
//#if ENABLE_LOGGING
|
||||
Debug.Log(msg, target);
|
||||
//#endif
|
||||
}
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
StartCoroutine(LoadCoroutine());
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
if (IsLoaded)
|
||||
{
|
||||
Destroy(_rootObject.gameObject);
|
||||
}
|
||||
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
protected virtual void OnLoaded() {}
|
||||
|
||||
private IEnumerator LoadCoroutine()
|
||||
{
|
||||
if (_rootObject != null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
SRServiceManager.LoadingCount++;
|
||||
#if UNITY_4_6 || UNITY_4_7 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
|
||||
if (Application.loadedLevelName == SceneName)
|
||||
#else
|
||||
if (UnityEngine.SceneManagement.SceneManager.GetSceneByName(SceneName).isLoaded)
|
||||
#endif
|
||||
{
|
||||
Log("[Service] Already in service scene {0}. Searching for root object...".Fmt(SceneName), this);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("[Service] Loading scene ({0})".Fmt(SceneName), this);
|
||||
|
||||
#if UNITY_PRO_LICENSE || UNITY_5 || UNITY_5_3_OR_NEWER
|
||||
#if UNITY_4_6 || UNITY_4_7 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
|
||||
yield return Application.LoadLevelAdditiveAsync(SceneName);
|
||||
#else
|
||||
yield return UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(SceneName, UnityEngine.SceneManagement.LoadSceneMode.Additive);
|
||||
#endif
|
||||
#else
|
||||
Application.LoadLevelAdditive(SceneName);
|
||||
yield return new WaitForEndOfFrame();
|
||||
#endif
|
||||
|
||||
Log("[Service] Scene loaded. Searching for root object...", this);
|
||||
}
|
||||
|
||||
var go = GameObject.Find(SceneName);
|
||||
|
||||
if (go == null)
|
||||
{
|
||||
goto Error;
|
||||
}
|
||||
|
||||
var timpl = go.GetComponent<TImpl>();
|
||||
|
||||
if (timpl == null)
|
||||
{
|
||||
goto Error;
|
||||
}
|
||||
|
||||
_rootObject = timpl;
|
||||
_rootObject.transform.parent = CachedTransform;
|
||||
|
||||
DontDestroyOnLoad(go);
|
||||
|
||||
Debug.Log("[Service] Loading {0} complete. (Scene: {1})".Fmt(GetType().Name, SceneName), this);
|
||||
SRServiceManager.LoadingCount--;
|
||||
|
||||
OnLoaded();
|
||||
|
||||
yield break;
|
||||
|
||||
Error:
|
||||
|
||||
SRServiceManager.LoadingCount--;
|
||||
Debug.LogError("[Service] Root object ({0}) not found".Fmt(SceneName), this);
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff0dcbb555990d24e9e3055e77395656
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
17
JNFrame2/Assets/Plugins/SRF/Scripts/Service/SRServiceBase.cs
Normal file
17
JNFrame2/Assets/Plugins/SRF/Scripts/Service/SRServiceBase.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace SRF.Service
|
||||
{
|
||||
public abstract class SRServiceBase<T> : SRMonoBehaviourEx where T : class
|
||||
{
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
SRServiceManager.RegisterService<T>(this);
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
SRServiceManager.UnRegisterService<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4f48d5ad0a809349bd5e46160a824d3
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
530
JNFrame2/Assets/Plugins/SRF/Scripts/Service/SRServiceManager.cs
Normal file
530
JNFrame2/Assets/Plugins/SRF/Scripts/Service/SRServiceManager.cs
Normal file
@@ -0,0 +1,530 @@
|
||||
// Disable unreachable code warning caused by DEBUG
|
||||
#pragma warning disable 0162
|
||||
|
||||
namespace SRF.Service
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Components;
|
||||
using Helpers;
|
||||
using Internal;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
[AddComponentMenu(ComponentMenuPaths.SRServiceManager)]
|
||||
public class SRServiceManager : SRAutoSingleton<SRServiceManager>
|
||||
{
|
||||
#if SRDEBUG
|
||||
public const bool EnableLogging = true;
|
||||
#else
|
||||
public const bool EnableLogging = false;
|
||||
#endif
|
||||
|
||||
#if UNITY_EDITOR && ((!UNITY_2017 && !UNITY_2018 && !UNITY_2019) || UNITY_2019_3_OR_NEWER)
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||
public static void RuntimeInitialize()
|
||||
{
|
||||
// To handle entering play mode without a domain reload, need to reset the state of the service manager.
|
||||
_hasQuit = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Register the assembly that contains type <typeparamref name="TType"/> with the service manager.
|
||||
/// </summary>
|
||||
/// <typeparam name="TType"></typeparam>
|
||||
public static void RegisterAssembly<TType>()
|
||||
{
|
||||
#if NETFX_CORE
|
||||
var assembly = typeof(TType).GetTypeInfo().Assembly;
|
||||
#else
|
||||
var assembly = typeof(TType).Assembly;
|
||||
#endif
|
||||
|
||||
if (_assemblies.Contains(assembly))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_assemblies.Add(assembly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is there a service loading?
|
||||
/// </summary>
|
||||
public static bool IsLoading
|
||||
{
|
||||
get { return LoadingCount > 0; }
|
||||
}
|
||||
|
||||
public static int LoadingCount = 0;
|
||||
|
||||
public static T GetService<T>() where T : class
|
||||
{
|
||||
var s = GetServiceInternal(typeof(T)) as T;
|
||||
|
||||
if (s == null && (!_hasQuit || EnableLogging))
|
||||
{
|
||||
Debug.LogWarning("Service {0} not found. (HasQuit: {1})".Fmt(typeof(T).Name, _hasQuit));
|
||||
}
|
||||
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public static object GetService(Type t)
|
||||
{
|
||||
var s = GetServiceInternal(t);
|
||||
|
||||
if (s == null && (!_hasQuit || EnableLogging))
|
||||
{
|
||||
Debug.LogWarning("Service {0} not found. (HasQuit: {1})".Fmt(t.Name, _hasQuit));
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private static object GetServiceInternal(Type t)
|
||||
{
|
||||
if (_hasQuit || !Application.isPlaying)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var services = Instance._services;
|
||||
|
||||
for (var i = 0; i < services.Count; i++)
|
||||
{
|
||||
var s = services[i];
|
||||
|
||||
if (t.IsAssignableFrom(s.Type))
|
||||
{
|
||||
if (s.Object == null)
|
||||
{
|
||||
UnRegisterService(t);
|
||||
break;
|
||||
}
|
||||
|
||||
return s.Object;
|
||||
}
|
||||
}
|
||||
|
||||
return Instance.AutoCreateService(t);
|
||||
}
|
||||
|
||||
public static bool HasService<T>() where T : class
|
||||
{
|
||||
return HasService(typeof(T));
|
||||
}
|
||||
|
||||
public static bool HasService(Type t)
|
||||
{
|
||||
if (_hasQuit || !Application.isPlaying)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var services = Instance._services;
|
||||
|
||||
for (var i = 0; i < services.Count; i++)
|
||||
{
|
||||
var s = services[i];
|
||||
|
||||
if (t.IsAssignableFrom(s.Type))
|
||||
{
|
||||
return s.Object != null;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void RegisterService<T>(object service) where T : class
|
||||
{
|
||||
RegisterService(typeof(T), service);
|
||||
}
|
||||
|
||||
private static void RegisterService(Type t, object service)
|
||||
{
|
||||
if (_hasQuit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasService(t))
|
||||
{
|
||||
if (GetServiceInternal(t) == service)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Exception("Service already registered for type " + t.Name);
|
||||
}
|
||||
|
||||
UnRegisterService(t);
|
||||
|
||||
if (!t.IsInstanceOfType(service))
|
||||
{
|
||||
throw new ArgumentException("service {0} must be assignable from type {1}".Fmt(service.GetType(), t));
|
||||
}
|
||||
|
||||
Instance._services.Add(new Service {
|
||||
Object = service,
|
||||
Type = t
|
||||
});
|
||||
}
|
||||
|
||||
public static void UnRegisterService<T>() where T : class
|
||||
{
|
||||
UnRegisterService(typeof(T));
|
||||
}
|
||||
|
||||
private static void UnRegisterService(Type t)
|
||||
{
|
||||
if (_hasQuit || !HasInstance)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasService(t))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var services = Instance._services;
|
||||
|
||||
for (var i = services.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var s = services[i];
|
||||
|
||||
if (s.Type == t)
|
||||
{
|
||||
services.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class Service
|
||||
{
|
||||
public object Object;
|
||||
public Type Type;
|
||||
}
|
||||
|
||||
private class ServiceStub
|
||||
{
|
||||
public Func<object> Constructor;
|
||||
public Type InterfaceType;
|
||||
public Func<Type> Selector;
|
||||
public Type Type;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var s = InterfaceType.Name + " (";
|
||||
|
||||
if (Type != null)
|
||||
{
|
||||
s += "Type: " + Type;
|
||||
}
|
||||
else if (Selector != null)
|
||||
{
|
||||
s += "Selector: " + Selector;
|
||||
}
|
||||
else if (Constructor != null)
|
||||
{
|
||||
s += "Constructor: " + Constructor;
|
||||
}
|
||||
|
||||
s += ")";
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly List<Assembly> _assemblies = new List<Assembly>(2);
|
||||
|
||||
private readonly SRList<Service> _services = new SRList<Service>();
|
||||
|
||||
private List<ServiceStub> _serviceStubs;
|
||||
|
||||
private static bool _hasQuit;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
_hasQuit = false;
|
||||
base.Awake();
|
||||
DontDestroyOnLoad(CachedGameObject);
|
||||
|
||||
CachedGameObject.hideFlags = HideFlags.NotEditable;
|
||||
}
|
||||
|
||||
protected void UpdateStubs()
|
||||
{
|
||||
if (_serviceStubs != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RegisterAssembly<SRServiceManager>();
|
||||
|
||||
_serviceStubs = new List<ServiceStub>();
|
||||
|
||||
var types = new List<Type>();
|
||||
|
||||
foreach (var assembly in _assemblies)
|
||||
{
|
||||
try
|
||||
{
|
||||
#if NETFX_CORE
|
||||
types.AddRange(assembly.Types);
|
||||
#else
|
||||
types.AddRange(assembly.GetTypes());
|
||||
#endif
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("[SRServiceManager] Error loading assembly {0}".Fmt(assembly.FullName), this);
|
||||
Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
ScanType(type);
|
||||
}
|
||||
|
||||
if (EnableLogging)
|
||||
{
|
||||
var serviceStrings =
|
||||
_serviceStubs.Select(p => " {0}".Fmt(p)).ToArray();
|
||||
|
||||
Debug.Log("[SRServiceManager] Services Discovered: {0} \n {1}".Fmt(serviceStrings.Length,
|
||||
string.Join("\n ", serviceStrings)));
|
||||
}
|
||||
}
|
||||
|
||||
protected object AutoCreateService(Type t)
|
||||
{
|
||||
UpdateStubs();
|
||||
|
||||
foreach (var stub in _serviceStubs)
|
||||
{
|
||||
if (stub.InterfaceType != t)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
object service = null;
|
||||
|
||||
if (stub.Constructor != null)
|
||||
{
|
||||
service = stub.Constructor();
|
||||
}
|
||||
else
|
||||
{
|
||||
var serviceType = stub.Type;
|
||||
|
||||
if (serviceType == null)
|
||||
{
|
||||
serviceType = stub.Selector();
|
||||
}
|
||||
|
||||
service = DefaultServiceConstructor(t, serviceType);
|
||||
}
|
||||
|
||||
if (!HasService(t))
|
||||
{
|
||||
RegisterService(t, service);
|
||||
}
|
||||
|
||||
if (EnableLogging)
|
||||
{
|
||||
Debug.Log("[SRServiceManager] Auto-created service: {0} ({1})".Fmt(stub.Type, stub.InterfaceType),
|
||||
service as Object);
|
||||
}
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void OnApplicationQuit()
|
||||
{
|
||||
_hasQuit = true;
|
||||
_assemblies.Clear();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
protected void OnDisable()
|
||||
{
|
||||
if (EnableLogging)
|
||||
{
|
||||
Debug.Log("[SRServiceManager] Cleaning up services");
|
||||
}
|
||||
|
||||
// Script recompile is likely in progress - clear up everything.
|
||||
foreach (Service s in _services)
|
||||
{
|
||||
IDisposable disposable = s.Object as IDisposable;
|
||||
if (disposable != null)
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
|
||||
Behaviour behaviour = s.Object as Behaviour;
|
||||
if (behaviour != null)
|
||||
{
|
||||
DestroyImmediate(behaviour.gameObject);
|
||||
} else if (s.Object is Object)
|
||||
{
|
||||
DestroyImmediate(s.Object as Object);
|
||||
}
|
||||
}
|
||||
|
||||
_services.Clear(clean: true);
|
||||
}
|
||||
#endif
|
||||
|
||||
private static object DefaultServiceConstructor(Type serviceIntType, Type implType)
|
||||
{
|
||||
// If mono-behaviour based, create a gameobject for this service
|
||||
if (typeof(MonoBehaviour).IsAssignableFrom(implType))
|
||||
{
|
||||
var go = new GameObject("_S_" + serviceIntType.Name);
|
||||
return go.AddComponent(implType);
|
||||
}
|
||||
|
||||
// If ScriptableObject based, create an instance
|
||||
if (typeof(ScriptableObject).IsAssignableFrom(implType))
|
||||
{
|
||||
var obj = ScriptableObject.CreateInstance(implType);
|
||||
return obj;
|
||||
}
|
||||
|
||||
// If just a standard C# object, just create an instance
|
||||
return Activator.CreateInstance(implType);
|
||||
}
|
||||
|
||||
#region Type Scanning
|
||||
|
||||
private void ScanType(Type type)
|
||||
{
|
||||
var attribute = SRReflection.GetAttribute<ServiceAttribute>(type);
|
||||
|
||||
if (attribute != null)
|
||||
{
|
||||
_serviceStubs.Add(new ServiceStub {
|
||||
Type = type,
|
||||
InterfaceType = attribute.ServiceType
|
||||
});
|
||||
}
|
||||
|
||||
ScanTypeForConstructors(type, _serviceStubs);
|
||||
ScanTypeForSelectors(type, _serviceStubs);
|
||||
}
|
||||
|
||||
private static void ScanTypeForSelectors(Type t, List<ServiceStub> stubs)
|
||||
{
|
||||
var methods = GetStaticMethods(t);
|
||||
|
||||
foreach (var method in methods)
|
||||
{
|
||||
var attrib = SRReflection.GetAttribute<ServiceSelectorAttribute>(method);
|
||||
|
||||
if (attrib == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (method.ReturnType != typeof(Type))
|
||||
{
|
||||
Debug.LogError("ServiceSelector must have return type of Type ({0}.{1}())".Fmt(t.Name, method.Name));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (method.GetParameters().Length > 0)
|
||||
{
|
||||
Debug.LogError("ServiceSelector must have no parameters ({0}.{1}())".Fmt(t.Name, method.Name));
|
||||
continue;
|
||||
}
|
||||
|
||||
var stub = stubs.FirstOrDefault(p => p.InterfaceType == attrib.ServiceType);
|
||||
|
||||
if (stub == null)
|
||||
{
|
||||
stub = new ServiceStub {
|
||||
InterfaceType = attrib.ServiceType
|
||||
};
|
||||
|
||||
stubs.Add(stub);
|
||||
}
|
||||
|
||||
#if NETFX_CORE
|
||||
stub.Selector = (Func<Type>)method.CreateDelegate(typeof(Func<Type>));
|
||||
#else
|
||||
stub.Selector = (Func<Type>)Delegate.CreateDelegate(typeof(Func<Type>), method);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private static void ScanTypeForConstructors(Type t, List<ServiceStub> stubs)
|
||||
{
|
||||
var methods = GetStaticMethods(t);
|
||||
|
||||
foreach (var method in methods)
|
||||
{
|
||||
var attrib = SRReflection.GetAttribute<ServiceConstructorAttribute>(method);
|
||||
|
||||
if (attrib == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (method.ReturnType != attrib.ServiceType)
|
||||
{
|
||||
Debug.LogError("ServiceConstructor must have return type of {2} ({0}.{1}())".Fmt(t.Name, method.Name,
|
||||
attrib.ServiceType));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (method.GetParameters().Length > 0)
|
||||
{
|
||||
Debug.LogError("ServiceConstructor must have no parameters ({0}.{1}())".Fmt(t.Name, method.Name));
|
||||
continue;
|
||||
}
|
||||
|
||||
var stub = stubs.FirstOrDefault(p => p.InterfaceType == attrib.ServiceType);
|
||||
|
||||
if (stub == null)
|
||||
{
|
||||
stub = new ServiceStub {
|
||||
InterfaceType = attrib.ServiceType
|
||||
};
|
||||
|
||||
stubs.Add(stub);
|
||||
}
|
||||
|
||||
var m = method;
|
||||
stub.Constructor = () => m.Invoke(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Reflection
|
||||
|
||||
private static MethodInfo[] GetStaticMethods(Type t)
|
||||
{
|
||||
#if !NETFX_CORE
|
||||
return t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
#else
|
||||
return t.GetTypeInfo().DeclaredMethods.Where(p => p.IsStatic).ToArray();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83920a42d6e0f814bacbc701ae8636a5
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 16100
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
5
JNFrame2/Assets/Plugins/SRF/Scripts/UI.meta
Normal file
5
JNFrame2/Assets/Plugins/SRF/Scripts/UI.meta
Normal file
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed6eb48a67380fe40a3864e012ce762d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
145
JNFrame2/Assets/Plugins/SRF/Scripts/UI/ContentFitText.cs
Normal file
145
JNFrame2/Assets/Plugins/SRF/Scripts/UI/ContentFitText.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
namespace SRF.UI
|
||||
{
|
||||
using Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[RequireComponent(typeof (RectTransform))]
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu(ComponentMenuPaths.ContentFitText)]
|
||||
public class ContentFitText : UIBehaviour, ILayoutElement
|
||||
{
|
||||
public SRText CopySource;
|
||||
public Vector2 Padding;
|
||||
|
||||
public float minWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CopySource == null)
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return LayoutUtility.GetMinWidth(CopySource.rectTransform) + Padding.x;
|
||||
}
|
||||
}
|
||||
|
||||
public float preferredWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CopySource == null)
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return LayoutUtility.GetPreferredWidth(CopySource.rectTransform) + Padding.x;
|
||||
}
|
||||
}
|
||||
|
||||
public float flexibleWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CopySource == null)
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return LayoutUtility.GetFlexibleWidth(CopySource.rectTransform);
|
||||
}
|
||||
}
|
||||
|
||||
public float minHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CopySource == null)
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return LayoutUtility.GetFlexibleHeight(CopySource.rectTransform) + Padding.y;
|
||||
}
|
||||
}
|
||||
|
||||
public float preferredHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CopySource == null)
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return LayoutUtility.GetPreferredHeight(CopySource.rectTransform) + Padding.y;
|
||||
}
|
||||
}
|
||||
|
||||
public float flexibleHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CopySource == null)
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return LayoutUtility.GetFlexibleHeight(CopySource.rectTransform);
|
||||
}
|
||||
}
|
||||
|
||||
public int layoutPriority
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
|
||||
public void CalculateLayoutInputHorizontal()
|
||||
{
|
||||
CopySource.CalculateLayoutInputHorizontal();
|
||||
}
|
||||
|
||||
public void CalculateLayoutInputVertical()
|
||||
{
|
||||
CopySource.CalculateLayoutInputVertical();
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
SetDirty();
|
||||
CopySource.LayoutDirty += CopySourceOnLayoutDirty;
|
||||
}
|
||||
|
||||
private void CopySourceOnLayoutDirty(SRText srText)
|
||||
{
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
protected override void OnTransformParentChanged()
|
||||
{
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
CopySource.LayoutDirty -= CopySourceOnLayoutDirty;
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
protected override void OnDidApplyAnimationProperties()
|
||||
{
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
protected override void OnBeforeTransformParentChanged()
|
||||
{
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
protected void SetDirty()
|
||||
{
|
||||
if (!IsActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dced79525dbfa2b44b8d52b2cca6d745
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
95
JNFrame2/Assets/Plugins/SRF/Scripts/UI/CopyLayoutElement.cs
Normal file
95
JNFrame2/Assets/Plugins/SRF/Scripts/UI/CopyLayoutElement.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
namespace SRF.UI
|
||||
{
|
||||
using Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Copies the preferred size of another layout element (useful for a parent object basing its sizing from a child
|
||||
/// element).
|
||||
/// This does have very quirky behaviour, though.
|
||||
/// TODO: Write custom editor for this to match layout element editor
|
||||
/// </summary>
|
||||
[RequireComponent(typeof (RectTransform))]
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu(ComponentMenuPaths.CopyLayoutElement)]
|
||||
public class CopyLayoutElement : UIBehaviour, ILayoutElement
|
||||
{
|
||||
public bool CopyMinHeight;
|
||||
public bool CopyMinWidth;
|
||||
public bool CopyPreferredHeight;
|
||||
public bool CopyPreferredWidth;
|
||||
public RectTransform CopySource;
|
||||
public float PaddingMinHeight;
|
||||
public float PaddingMinWidth;
|
||||
public float PaddingPreferredHeight;
|
||||
public float PaddingPreferredWidth;
|
||||
|
||||
public float preferredWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!CopyPreferredWidth || CopySource == null || !IsActive())
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return LayoutUtility.GetPreferredWidth(CopySource) + PaddingPreferredWidth;
|
||||
}
|
||||
}
|
||||
|
||||
public float preferredHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!CopyPreferredHeight || CopySource == null || !IsActive())
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return LayoutUtility.GetPreferredHeight(CopySource) + PaddingPreferredHeight;
|
||||
}
|
||||
}
|
||||
|
||||
public float minWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!CopyMinWidth || CopySource == null || !IsActive())
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return LayoutUtility.GetMinWidth(CopySource) + PaddingMinWidth;
|
||||
}
|
||||
}
|
||||
|
||||
public float minHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!CopyMinHeight || CopySource == null || !IsActive())
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return LayoutUtility.GetMinHeight(CopySource) + PaddingMinHeight;
|
||||
}
|
||||
}
|
||||
|
||||
public int layoutPriority
|
||||
{
|
||||
get { return 2; }
|
||||
}
|
||||
|
||||
public float flexibleHeight
|
||||
{
|
||||
get { return -1; }
|
||||
}
|
||||
|
||||
public float flexibleWidth
|
||||
{
|
||||
get { return -1; }
|
||||
}
|
||||
|
||||
public void CalculateLayoutInputHorizontal() {}
|
||||
public void CalculateLayoutInputVertical() {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 525a40520606ceb469b7494cb8ddef87
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
50
JNFrame2/Assets/Plugins/SRF/Scripts/UI/CopyPreferredSize.cs
Normal file
50
JNFrame2/Assets/Plugins/SRF/Scripts/UI/CopyPreferredSize.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
namespace SRF.UI
|
||||
{
|
||||
using Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Copies the preferred size of another layout element (useful for a parent object basing its sizing from a child
|
||||
/// element).
|
||||
/// This does have very quirky behaviour, though.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof (RectTransform))]
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu(ComponentMenuPaths.CopyPreferredSize)]
|
||||
public class CopyPreferredSize : LayoutElement
|
||||
{
|
||||
public RectTransform CopySource;
|
||||
public float PaddingHeight;
|
||||
public float PaddingWidth;
|
||||
|
||||
public override float preferredWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CopySource == null || !IsActive())
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return LayoutUtility.GetPreferredWidth(CopySource) + PaddingWidth;
|
||||
}
|
||||
}
|
||||
|
||||
public override float preferredHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CopySource == null || !IsActive())
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return LayoutUtility.GetPreferredHeight(CopySource) + PaddingHeight;
|
||||
}
|
||||
}
|
||||
|
||||
public override int layoutPriority
|
||||
{
|
||||
get { return 2; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32609112f4257a740aa4b920a8556d24
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
107
JNFrame2/Assets/Plugins/SRF/Scripts/UI/CopyPreferredSizes.cs
Normal file
107
JNFrame2/Assets/Plugins/SRF/Scripts/UI/CopyPreferredSizes.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
|
||||
namespace SRF.UI
|
||||
{
|
||||
using Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Copies the preferred size of another layout element (useful for a parent object basing its sizing from a child
|
||||
/// element).
|
||||
/// This does have very quirky behaviour, though.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu(ComponentMenuPaths.CopyPreferredSizes)]
|
||||
public class CopyPreferredSizes : LayoutElement
|
||||
{
|
||||
public enum Operations
|
||||
{
|
||||
Max,
|
||||
Min
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class CopySource
|
||||
{
|
||||
public RectTransform Rect;
|
||||
|
||||
public float PaddingHeight;
|
||||
public float PaddingWidth;
|
||||
}
|
||||
|
||||
public CopySource[] CopySources;
|
||||
public Operations Operation;
|
||||
|
||||
|
||||
public override float preferredWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CopySources == null || CopySources.Length == 0 || !IsActive())
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
|
||||
float current = Operation == Operations.Max ? float.MinValue : float.MaxValue;
|
||||
|
||||
for (var i = 0; i < CopySources.Length; i++)
|
||||
{
|
||||
if (CopySources[i].Rect == null)
|
||||
continue;
|
||||
|
||||
float width = LayoutUtility.GetPreferredWidth(CopySources[i].Rect) + CopySources[i].PaddingWidth;
|
||||
if (Operation == Operations.Max && width > current)
|
||||
current = width;
|
||||
else if (Operation == Operations.Min && width < current)
|
||||
current = width;
|
||||
}
|
||||
|
||||
// ReSharper disable CompareOfFloatsByEqualityOperator
|
||||
if (Operation == Operations.Max && current == float.MinValue) return -1;
|
||||
if (Operation == Operations.Min && current == float.MaxValue) return -1;
|
||||
// ReSharper restore CompareOfFloatsByEqualityOperator
|
||||
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
||||
public override float preferredHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CopySources == null || CopySources.Length == 0 || !IsActive())
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
|
||||
float current = Operation == Operations.Max ? float.MinValue : float.MaxValue;
|
||||
|
||||
for (var i = 0; i < CopySources.Length; i++)
|
||||
{
|
||||
if (CopySources[i].Rect == null)
|
||||
continue;
|
||||
|
||||
float height = LayoutUtility.GetPreferredHeight(CopySources[i].Rect) + CopySources[i].PaddingHeight;
|
||||
if (Operation == Operations.Max && height > current)
|
||||
current = height;
|
||||
else if (Operation == Operations.Min && height < current)
|
||||
current = height;
|
||||
}
|
||||
|
||||
// ReSharper disable CompareOfFloatsByEqualityOperator
|
||||
if (Operation == Operations.Max && current == float.MinValue) return -1;
|
||||
if (Operation == Operations.Min && current == float.MaxValue) return -1;
|
||||
// ReSharper restore CompareOfFloatsByEqualityOperator
|
||||
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
||||
public override int layoutPriority
|
||||
{
|
||||
get { return 2; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5c292f06a2fb3644aac9698b40bd348
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,76 @@
|
||||
namespace SRF.UI
|
||||
{
|
||||
using Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Copies the preferred size of another layout element (useful for a parent object basing its sizing from a child
|
||||
/// element).
|
||||
/// This does have very quirky behaviour, though.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu(ComponentMenuPaths.CopySizeIntoLayoutElement)]
|
||||
public class CopySizeIntoLayoutElement : LayoutElement
|
||||
{
|
||||
public RectTransform CopySource;
|
||||
public float PaddingHeight;
|
||||
public float PaddingWidth;
|
||||
|
||||
public bool SetPreferredSize = false;
|
||||
public bool SetMinimumSize = false;
|
||||
|
||||
public override float preferredWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!SetPreferredSize || CopySource == null || !IsActive())
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return CopySource.rect.width + PaddingWidth;
|
||||
}
|
||||
}
|
||||
|
||||
public override float preferredHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!SetPreferredSize || CopySource == null || !IsActive())
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return CopySource.rect.height + PaddingHeight;
|
||||
}
|
||||
}
|
||||
public override float minWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!SetMinimumSize || CopySource == null || !IsActive())
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return CopySource.rect.width + PaddingWidth;
|
||||
}
|
||||
}
|
||||
|
||||
public override float minHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!SetMinimumSize || CopySource == null || !IsActive())
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
return CopySource.rect.height + PaddingHeight;
|
||||
}
|
||||
}
|
||||
|
||||
public override int layoutPriority
|
||||
{
|
||||
get { return 2; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65f264d1c98f61c4f9143ddeb0e74ff5
|
||||
timeCreated: 1476961746
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
190
JNFrame2/Assets/Plugins/SRF/Scripts/UI/DragHandle.cs
Normal file
190
JNFrame2/Assets/Plugins/SRF/Scripts/UI/DragHandle.cs
Normal file
@@ -0,0 +1,190 @@
|
||||
namespace SRF.UI
|
||||
{
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class DragHandle : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
|
||||
{
|
||||
private CanvasScaler _canvasScaler;
|
||||
private float _delta;
|
||||
private float _startValue;
|
||||
public RectTransform.Axis Axis = RectTransform.Axis.Horizontal;
|
||||
public bool Invert = false;
|
||||
public float MaxSize = -1;
|
||||
public LayoutElement TargetLayoutElement;
|
||||
public RectTransform TargetRectTransform;
|
||||
|
||||
private float Mult
|
||||
{
|
||||
get { return Invert ? -1 : 1; }
|
||||
}
|
||||
|
||||
public void OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
if (!Verify())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug.Log("OnBeginDrag");
|
||||
|
||||
_startValue = GetCurrentValue();
|
||||
_delta = 0;
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
if (!Verify())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug.Log("OnDrag");
|
||||
|
||||
var delta = 0f;
|
||||
|
||||
if (Axis == RectTransform.Axis.Horizontal)
|
||||
{
|
||||
delta += eventData.delta.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta += eventData.delta.y;
|
||||
}
|
||||
|
||||
if (_canvasScaler != null)
|
||||
{
|
||||
delta /= _canvasScaler.scaleFactor;
|
||||
}
|
||||
|
||||
delta *= Mult;
|
||||
_delta += delta;
|
||||
|
||||
SetCurrentValue(Mathf.Clamp(_startValue + _delta, GetMinSize(), GetMaxSize()));
|
||||
}
|
||||
|
||||
public void OnEndDrag(PointerEventData eventData)
|
||||
{
|
||||
if (!Verify())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug.Log("OnEndDrag");
|
||||
|
||||
SetCurrentValue(Mathf.Max(_startValue + _delta, GetMinSize()));
|
||||
_delta = 0;
|
||||
CommitCurrentValue();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Verify();
|
||||
_canvasScaler = GetComponentInParent<CanvasScaler>();
|
||||
}
|
||||
|
||||
private bool Verify()
|
||||
{
|
||||
if (TargetLayoutElement == null && TargetRectTransform == null)
|
||||
{
|
||||
Debug.LogWarning(
|
||||
"DragHandle: TargetLayoutElement and TargetRectTransform are both null. Disabling behaviour.");
|
||||
enabled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private float GetCurrentValue()
|
||||
{
|
||||
if (TargetLayoutElement != null)
|
||||
{
|
||||
return Axis == RectTransform.Axis.Horizontal
|
||||
? TargetLayoutElement.preferredWidth
|
||||
: TargetLayoutElement.preferredHeight;
|
||||
}
|
||||
|
||||
if (TargetRectTransform != null)
|
||||
{
|
||||
return Axis == RectTransform.Axis.Horizontal
|
||||
? TargetRectTransform.sizeDelta.x
|
||||
: TargetRectTransform.sizeDelta.y;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
private void SetCurrentValue(float value)
|
||||
{
|
||||
if (TargetLayoutElement != null)
|
||||
{
|
||||
if (Axis == RectTransform.Axis.Horizontal)
|
||||
{
|
||||
TargetLayoutElement.preferredWidth = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
TargetLayoutElement.preferredHeight = value;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (TargetRectTransform != null)
|
||||
{
|
||||
var d = TargetRectTransform.sizeDelta;
|
||||
|
||||
if (Axis == RectTransform.Axis.Horizontal)
|
||||
{
|
||||
d.x = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
d.y = value;
|
||||
}
|
||||
|
||||
TargetRectTransform.sizeDelta = d;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
private void CommitCurrentValue()
|
||||
{
|
||||
if (TargetLayoutElement != null)
|
||||
{
|
||||
if (Axis == RectTransform.Axis.Horizontal)
|
||||
{
|
||||
TargetLayoutElement.preferredWidth = ((RectTransform) TargetLayoutElement.transform).sizeDelta.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
TargetLayoutElement.preferredHeight = ((RectTransform) TargetLayoutElement.transform).sizeDelta.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float GetMinSize()
|
||||
{
|
||||
if (TargetLayoutElement == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return Axis == RectTransform.Axis.Horizontal ? TargetLayoutElement.minWidth : TargetLayoutElement.minHeight;
|
||||
}
|
||||
|
||||
private float GetMaxSize()
|
||||
{
|
||||
if (MaxSize > 0)
|
||||
{
|
||||
return MaxSize;
|
||||
}
|
||||
return float.MaxValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8faed27c04557e24e8aecd35f2b4d9d3
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
5
JNFrame2/Assets/Plugins/SRF/Scripts/UI/Editor.meta
Normal file
5
JNFrame2/Assets/Plugins/SRF/Scripts/UI/Editor.meta
Normal file
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fee397aaceb8d684a94ce2bae9b71aa1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@@ -0,0 +1,39 @@
|
||||
namespace SRF.UI.Editor
|
||||
{
|
||||
/*[CustomEditor(typeof(CopyLayoutElement))]
|
||||
[CanEditMultipleObjects]
|
||||
public class CopyLayoutElementEditor : UnityEditor.Editor
|
||||
{
|
||||
|
||||
private SerializedProperty _copySourceProperty;
|
||||
|
||||
private SerializedProperty _paddingWidthProperty;
|
||||
private SerializedProperty _paddingHeightProperty;
|
||||
|
||||
protected void OnEnable()
|
||||
{
|
||||
|
||||
_paddingWidthProperty = serializedObject.FindProperty("PaddingWidth");
|
||||
_paddingHeightProperty = serializedObject.FindProperty("PaddingHeight");
|
||||
_copySourceProperty = serializedObject.FindProperty("CopySource");
|
||||
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
|
||||
//base.OnInspectorGUI();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.PropertyField(_copySourceProperty);
|
||||
EditorGUILayout.PropertyField(_paddingWidthProperty);
|
||||
EditorGUILayout.PropertyField(_paddingHeightProperty);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
}
|
||||
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44df26ca5be5b5c468b5090cbe3df8ab
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,34 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace SRF.UI.Editor
|
||||
{
|
||||
[CustomEditor(typeof (CopyPreferredSize))]
|
||||
[CanEditMultipleObjects]
|
||||
public class CopyPreferredSizeEditor : UnityEditor.Editor
|
||||
{
|
||||
private SerializedProperty _copySourceProperty;
|
||||
private SerializedProperty _paddingHeightProperty;
|
||||
private SerializedProperty _paddingWidthProperty;
|
||||
|
||||
protected void OnEnable()
|
||||
{
|
||||
_paddingWidthProperty = serializedObject.FindProperty("PaddingWidth");
|
||||
_paddingHeightProperty = serializedObject.FindProperty("PaddingHeight");
|
||||
_copySourceProperty = serializedObject.FindProperty("CopySource");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
//base.OnInspectorGUI();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.PropertyField(_copySourceProperty);
|
||||
EditorGUILayout.PropertyField(_paddingWidthProperty);
|
||||
EditorGUILayout.PropertyField(_paddingHeightProperty);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
serializedObject.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 776c60ba14d0d0242968c3258a3ba16c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,31 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace SRF.UI.Editor
|
||||
{
|
||||
[CustomEditor(typeof(CopyPreferredSizes))]
|
||||
[CanEditMultipleObjects]
|
||||
public class CopyPreferredSizesEditor : UnityEditor.Editor
|
||||
{
|
||||
private SerializedProperty _copySourcesProperty;
|
||||
private SerializedProperty _operationProperty;
|
||||
|
||||
protected void OnEnable()
|
||||
{
|
||||
_copySourcesProperty = serializedObject.FindProperty("CopySources");
|
||||
_operationProperty = serializedObject.FindProperty("Operation");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
//base.OnInspectorGUI();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.PropertyField(_operationProperty);
|
||||
EditorGUILayout.PropertyField(_copySourcesProperty);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
serializedObject.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 393fb435a5c8c8043a1cbc34b977e315
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
using UnityEditor;
|
||||
using UnityEditor.UI;
|
||||
|
||||
namespace SRF.UI.Editor
|
||||
{
|
||||
[CustomEditor(typeof (LongPressButton), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class LongPressButtonEditor : ButtonEditor
|
||||
{
|
||||
private SerializedProperty _onLongPressProperty;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
_onLongPressProperty = serializedObject.FindProperty("_onLongPress");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
serializedObject.Update();
|
||||
EditorGUILayout.PropertyField(_onLongPressProperty);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d57f229ac662764aa4508a0d42ddede
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,32 @@
|
||||
using UnityEditor;
|
||||
using UnityEditor.UI;
|
||||
|
||||
namespace SRF.UI.Editor
|
||||
{
|
||||
[CustomEditor(typeof (SRNumberButton))]
|
||||
[CanEditMultipleObjects]
|
||||
public class SRNumberButtonEditor : ButtonEditor
|
||||
{
|
||||
private SerializedProperty _amountProperty;
|
||||
private SerializedProperty _targetFieldProperty;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
_targetFieldProperty = serializedObject.FindProperty("TargetField");
|
||||
_amountProperty = serializedObject.FindProperty("Amount");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
serializedObject.Update();
|
||||
EditorGUILayout.PropertyField(_targetFieldProperty);
|
||||
EditorGUILayout.PropertyField(_amountProperty);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d1845f798a1b5a47af337e37e463641
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "StompyRobot.SRF.Editor",
|
||||
"references": [
|
||||
"StompyRobot.SRF"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 714123ebf07616740963b992cf10f84c
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,105 @@
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SRF.UI.Editor
|
||||
{
|
||||
[CustomEditor(typeof (StyleComponent))]
|
||||
[CanEditMultipleObjects]
|
||||
public class StyleComponentEditor : UnityEditor.Editor
|
||||
{
|
||||
private SerializedProperty _styleKeyProperty;
|
||||
|
||||
protected void OnEnable()
|
||||
{
|
||||
_styleKeyProperty = serializedObject.FindProperty("_styleKey");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
var styleComponent = serializedObject.targetObject as StyleComponent;
|
||||
|
||||
if (styleComponent == null)
|
||||
{
|
||||
Debug.LogWarning("Target is null, expected StyleComponent");
|
||||
return;
|
||||
}
|
||||
|
||||
var styleRoot = styleComponent.GetComponentInParent<StyleRoot>();
|
||||
|
||||
if (styleRoot == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("There must be a StyleRoot component above this object in the hierarchy.",
|
||||
MessageType.Error,
|
||||
true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var styleSheet = styleRoot.StyleSheet;
|
||||
|
||||
if (styleSheet == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Style Root has no stylesheet set.", MessageType.Warning);
|
||||
|
||||
EditorGUILayout.Popup("Key", 0,
|
||||
new[] {string.IsNullOrEmpty(styleComponent.StyleKey) ? "--" : styleComponent.StyleKey});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var options = styleRoot.StyleSheet.GetStyleKeys(true).ToList();
|
||||
|
||||
var index = _styleKeyProperty.hasMultipleDifferentValues
|
||||
? 0
|
||||
: options.IndexOf(_styleKeyProperty.stringValue) + 1;
|
||||
|
||||
options.Insert(0, "--");
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
GUI.enabled = _styleKeyProperty.editable;
|
||||
var newIndex = EditorGUILayout.Popup("Key", index, options.ToArray());
|
||||
GUI.enabled = true;
|
||||
|
||||
if (newIndex != index)
|
||||
{
|
||||
_styleKeyProperty.stringValue = "";
|
||||
_styleKeyProperty.stringValue = newIndex == 0 ? "" : options[newIndex];
|
||||
}
|
||||
|
||||
if (serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
foreach (var o in serializedObject.targetObjects)
|
||||
{
|
||||
var c = o as StyleComponent;
|
||||
c.Refresh(true);
|
||||
}
|
||||
|
||||
_styleKeyProperty.serializedObject.Update();
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
if (GUILayout.Button("Open StyleSheet"))
|
||||
{
|
||||
Selection.activeObject = styleRoot.StyleSheet;
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
if (GUILayout.Button("Select StyleRoot"))
|
||||
{
|
||||
Selection.activeGameObject = styleRoot.gameObject;
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffea2a0fd78a7484f88b5b877c0d6659
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@@ -0,0 +1,178 @@
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SRF.UI.Editor
|
||||
{
|
||||
[CustomEditor(typeof (StyleSheet))]
|
||||
public class StyleSheetEditor : UnityEditor.Editor
|
||||
{
|
||||
public const float ColourColumnWidth = 40f;
|
||||
public const float OverrideColumnWidth = 20f;
|
||||
private string _newKeyField = "";
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
var styleSheet = target as StyleSheet;
|
||||
|
||||
if (styleSheet == null)
|
||||
{
|
||||
Debug.LogWarning("Expected target to be StyleSheer", target);
|
||||
return;
|
||||
}
|
||||
|
||||
var parentStyleSheet = styleSheet.Parent;
|
||||
|
||||
styleSheet.Parent =
|
||||
EditorGUILayout.ObjectField("Parent", styleSheet.Parent, typeof (StyleSheet), false) as StyleSheet;
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
EditorGUILayout.BeginVertical();
|
||||
|
||||
// Draw table header
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
GUILayout.Space(OverrideColumnWidth);
|
||||
GUILayout.Label("Name");
|
||||
GUILayout.Label("Img", GUILayout.Width(ColourColumnWidth));
|
||||
GUILayout.Label("Norm.", GUILayout.Width(ColourColumnWidth));
|
||||
GUILayout.Label("Hov.", GUILayout.Width(ColourColumnWidth));
|
||||
GUILayout.Label("Actv.", GUILayout.Width(ColourColumnWidth));
|
||||
GUILayout.Label("Dsbld.", GUILayout.Width(ColourColumnWidth));
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
var keys = styleSheet.GetStyleKeys(false);
|
||||
|
||||
if (parentStyleSheet != null)
|
||||
{
|
||||
keys = keys.Union(parentStyleSheet.GetStyleKeys());
|
||||
}
|
||||
|
||||
// Draw rows
|
||||
foreach (var key in keys)
|
||||
{
|
||||
// Style from the current stylesheet
|
||||
var style = styleSheet.GetStyle(key, false);
|
||||
|
||||
// Style from the parent stylesheet
|
||||
Style parentStyle = null;
|
||||
|
||||
if (parentStyleSheet != null)
|
||||
{
|
||||
parentStyle = parentStyleSheet.GetStyle(key, true);
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
var canEdit = style != null;
|
||||
|
||||
// If there is a parent stylesheet, and the parent contains this key
|
||||
if (parentStyleSheet != null && parentStyle != null)
|
||||
{
|
||||
var overrideParent = GUILayout.Toggle(style != null, "", GUILayout.Width(OverrideColumnWidth));
|
||||
|
||||
if (overrideParent && style == null)
|
||||
{
|
||||
// Copy the style to the current stylesheet
|
||||
Undo.RecordObject(styleSheet, "Override Style");
|
||||
styleSheet.AddStyle(key);
|
||||
style = styleSheet.GetStyle(key, false);
|
||||
style.CopyFrom(parentStyle);
|
||||
EditorUtility.SetDirty(styleSheet);
|
||||
canEdit = true;
|
||||
}
|
||||
else if (!overrideParent && style != null)
|
||||
{
|
||||
Undo.RecordObject(styleSheet, "Delete Style");
|
||||
styleSheet.DeleteStyle(key);
|
||||
style = null;
|
||||
EditorUtility.SetDirty(styleSheet);
|
||||
canEdit = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise display a delete button
|
||||
|
||||
if (GUILayout.Button("X", GUILayout.Width(OverrideColumnWidth)))
|
||||
{
|
||||
Undo.RecordObject(styleSheet, "Delete Style");
|
||||
styleSheet.DeleteStyle(key);
|
||||
EditorUtility.SetDirty(styleSheet);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
GUI.enabled = canEdit;
|
||||
|
||||
GUILayout.Label(key);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
var img =
|
||||
EditorGUILayout.ObjectField(style != null ? style.Image : parentStyle.Image, typeof (Sprite), false,
|
||||
GUILayout.Width(ColourColumnWidth)) as Sprite;
|
||||
|
||||
var normalColor = EditorGUILayout.ColorField(
|
||||
style != null ? style.NormalColor : parentStyle.NormalColor,
|
||||
GUILayout.Width(ColourColumnWidth));
|
||||
var hoverColor = EditorGUILayout.ColorField(style != null ? style.HoverColor : parentStyle.HoverColor,
|
||||
GUILayout.Width(ColourColumnWidth));
|
||||
var activeColor = EditorGUILayout.ColorField(
|
||||
style != null ? style.ActiveColor : parentStyle.ActiveColor,
|
||||
GUILayout.Width(ColourColumnWidth));
|
||||
var disabledColor =
|
||||
EditorGUILayout.ColorField(style != null ? style.DisabledColor : parentStyle.DisabledColor,
|
||||
GUILayout.Width(ColourColumnWidth));
|
||||
|
||||
if (EditorGUI.EndChangeCheck() && canEdit)
|
||||
{
|
||||
Undo.RecordObject(styleSheet, "Update Style");
|
||||
|
||||
style.Image = img;
|
||||
style.NormalColor = normalColor;
|
||||
style.HoverColor = hoverColor;
|
||||
style.ActiveColor = activeColor;
|
||||
style.DisabledColor = disabledColor;
|
||||
|
||||
EditorUtility.SetDirty(styleSheet);
|
||||
}
|
||||
|
||||
GUI.enabled = true;
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
GUILayout.Label("New Style");
|
||||
|
||||
_newKeyField = EditorGUILayout.TextField(_newKeyField);
|
||||
|
||||
GUI.enabled = !string.IsNullOrEmpty(_newKeyField) && styleSheet.GetStyle(_newKeyField) == null;
|
||||
|
||||
if (GUILayout.Button("Add"))
|
||||
{
|
||||
Undo.RecordObject(styleSheet, "Add Style");
|
||||
styleSheet.AddStyle(_newKeyField);
|
||||
EditorUtility.SetDirty(styleSheet);
|
||||
|
||||
_newKeyField = "";
|
||||
}
|
||||
|
||||
GUI.enabled = true;
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7cc490d54f84d704f90e31d72e293018
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
71
JNFrame2/Assets/Plugins/SRF/Scripts/UI/FlashGraphic.cs
Normal file
71
JNFrame2/Assets/Plugins/SRF/Scripts/UI/FlashGraphic.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
namespace SRF.UI
|
||||
{
|
||||
using Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Instantly sets colour to FlashColor on pointer down, then fades back to DefaultColour once pointer is released.
|
||||
/// </summary>
|
||||
[AddComponentMenu(ComponentMenuPaths.FlashGraphic)]
|
||||
[ExecuteInEditMode]
|
||||
public class FlashGraphic : UIBehaviour, IPointerDownHandler, IPointerUpHandler
|
||||
{
|
||||
public float DecayTime = 0.15f;
|
||||
public Color DefaultColor = new Color(1, 1, 1, 0);
|
||||
public Color FlashColor = Color.white;
|
||||
public Graphic Target;
|
||||
|
||||
private bool _isHoldingUntilNextPress;
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
Target.CrossFadeColor(FlashColor, 0f, true, true);
|
||||
_isHoldingUntilNextPress = false;
|
||||
}
|
||||
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
if (!_isHoldingUntilNextPress)
|
||||
{
|
||||
Target.CrossFadeColor(DefaultColor, DecayTime, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
|
||||
if (!_isHoldingUntilNextPress)
|
||||
{
|
||||
Target.CrossFadeColor(DefaultColor, 0f, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected void Update()
|
||||
{
|
||||
|
||||
if (!Application.isPlaying && Target != null)
|
||||
{
|
||||
Target.CrossFadeColor(DefaultColor, 0, true, true);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
public void Flash()
|
||||
{
|
||||
Target.CrossFadeColor(FlashColor, 0f, true, true);
|
||||
Target.CrossFadeColor(DefaultColor, DecayTime, true, true);
|
||||
_isHoldingUntilNextPress = false;
|
||||
}
|
||||
|
||||
public void FlashAndHoldUntilNextPress()
|
||||
{
|
||||
Target.CrossFadeColor(FlashColor, 0f, true, true);
|
||||
_isHoldingUntilNextPress = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95878e800ddd366418edfb56a22f9d56
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
48
JNFrame2/Assets/Plugins/SRF/Scripts/UI/InheritColour.cs
Normal file
48
JNFrame2/Assets/Plugins/SRF/Scripts/UI/InheritColour.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
namespace SRF.UI
|
||||
{
|
||||
using Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[RequireComponent(typeof (Graphic))]
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu(ComponentMenuPaths.InheritColour)]
|
||||
public class InheritColour : SRMonoBehaviour
|
||||
{
|
||||
private Graphic _graphic;
|
||||
public Graphic From;
|
||||
|
||||
private Graphic Graphic
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_graphic == null)
|
||||
{
|
||||
_graphic = GetComponent<Graphic>();
|
||||
}
|
||||
|
||||
return _graphic;
|
||||
}
|
||||
}
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
if (From == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Graphic.color = From.canvasRenderer.GetColor();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ed84aa42fb48c9458d3942c1d059055
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
5
JNFrame2/Assets/Plugins/SRF/Scripts/UI/Layout.meta
Normal file
5
JNFrame2/Assets/Plugins/SRF/Scripts/UI/Layout.meta
Normal file
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e77c380334ccc0d438d07473a296a1cc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
304
JNFrame2/Assets/Plugins/SRF/Scripts/UI/Layout/FlowLayoutGroup.cs
Normal file
304
JNFrame2/Assets/Plugins/SRF/Scripts/UI/Layout/FlowLayoutGroup.cs
Normal file
@@ -0,0 +1,304 @@
|
||||
namespace SRF.UI.Layout
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Layout Group controller that arranges children in rows, fitting as many on a line until total width exceeds parent
|
||||
/// bounds
|
||||
/// </summary>
|
||||
[AddComponentMenu(ComponentMenuPaths.FlowLayoutGroup)]
|
||||
public class FlowLayoutGroup : LayoutGroup
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the rects that will make up the current row being processed
|
||||
/// </summary>
|
||||
private readonly IList<RectTransform> _rowList = new List<RectTransform>();
|
||||
|
||||
private float _layoutHeight;
|
||||
public bool ChildForceExpandHeight = false;
|
||||
public bool ChildForceExpandWidth = false;
|
||||
public float Spacing = 0f;
|
||||
|
||||
protected bool IsCenterAlign
|
||||
{
|
||||
get
|
||||
{
|
||||
return childAlignment == TextAnchor.LowerCenter || childAlignment == TextAnchor.MiddleCenter ||
|
||||
childAlignment == TextAnchor.UpperCenter;
|
||||
}
|
||||
}
|
||||
|
||||
protected bool IsRightAlign
|
||||
{
|
||||
get
|
||||
{
|
||||
return childAlignment == TextAnchor.LowerRight || childAlignment == TextAnchor.MiddleRight ||
|
||||
childAlignment == TextAnchor.UpperRight;
|
||||
}
|
||||
}
|
||||
|
||||
protected bool IsMiddleAlign
|
||||
{
|
||||
get
|
||||
{
|
||||
return childAlignment == TextAnchor.MiddleLeft || childAlignment == TextAnchor.MiddleRight ||
|
||||
childAlignment == TextAnchor.MiddleCenter;
|
||||
}
|
||||
}
|
||||
|
||||
protected bool IsLowerAlign
|
||||
{
|
||||
get
|
||||
{
|
||||
return childAlignment == TextAnchor.LowerLeft || childAlignment == TextAnchor.LowerRight ||
|
||||
childAlignment == TextAnchor.LowerCenter;
|
||||
}
|
||||
}
|
||||
|
||||
public override void CalculateLayoutInputHorizontal()
|
||||
{
|
||||
base.CalculateLayoutInputHorizontal();
|
||||
|
||||
var minWidth = GetGreatestMinimumChildWidth() + padding.left + padding.right;
|
||||
|
||||
SetLayoutInputForAxis(minWidth, -1, -1, 0);
|
||||
}
|
||||
|
||||
public override void SetLayoutHorizontal()
|
||||
{
|
||||
SetLayout(rectTransform.rect.width, 0, false);
|
||||
}
|
||||
|
||||
public override void SetLayoutVertical()
|
||||
{
|
||||
SetLayout(rectTransform.rect.width, 1, false);
|
||||
}
|
||||
|
||||
public override void CalculateLayoutInputVertical()
|
||||
{
|
||||
_layoutHeight = SetLayout(rectTransform.rect.width, 1, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Main layout method
|
||||
/// </summary>
|
||||
/// <param name="width">Width to calculate the layout with</param>
|
||||
/// <param name="axis">0 for horizontal axis, 1 for vertical</param>
|
||||
/// <param name="layoutInput">If true, sets the layout input for the axis. If false, sets child position for axis</param>
|
||||
public float SetLayout(float width, int axis, bool layoutInput)
|
||||
{
|
||||
var groupHeight = rectTransform.rect.height;
|
||||
|
||||
// Width that is available after padding is subtracted
|
||||
var workingWidth = rectTransform.rect.width - padding.left - padding.right;
|
||||
|
||||
// Accumulates the total height of the rows, including spacing and padding.
|
||||
var yOffset = IsLowerAlign ? padding.bottom : (float)padding.top;
|
||||
|
||||
var currentRowWidth = 0f;
|
||||
var currentRowHeight = 0f;
|
||||
|
||||
for (var i = 0; i < rectChildren.Count; i++)
|
||||
{
|
||||
// LowerAlign works from back to front
|
||||
var index = IsLowerAlign ? rectChildren.Count - 1 - i : i;
|
||||
|
||||
var child = rectChildren[index];
|
||||
|
||||
var childWidth = LayoutUtility.GetPreferredSize(child, 0);
|
||||
var childHeight = LayoutUtility.GetPreferredSize(child, 1);
|
||||
|
||||
// Max child width is layout group with - padding
|
||||
childWidth = Mathf.Min(childWidth, workingWidth);
|
||||
|
||||
// Apply spacing if not the first element in a row
|
||||
if (_rowList.Count > 0)
|
||||
{
|
||||
currentRowWidth += Spacing;
|
||||
}
|
||||
|
||||
// If adding this element would exceed the bounds of the row,
|
||||
// go to a new line after processing the current row
|
||||
if (currentRowWidth + childWidth > workingWidth)
|
||||
{
|
||||
// Undo spacing addition if we're moving to a new line (Spacing is not applied on edges)
|
||||
currentRowWidth -= Spacing;
|
||||
|
||||
// Process current row elements positioning
|
||||
if (!layoutInput)
|
||||
{
|
||||
var h = CalculateRowVerticalOffset(groupHeight, yOffset, currentRowHeight);
|
||||
LayoutRow(_rowList, currentRowWidth, currentRowHeight, workingWidth, padding.left, h, axis);
|
||||
}
|
||||
|
||||
// Clear existing row
|
||||
_rowList.Clear();
|
||||
|
||||
// Add the current row height to total height accumulator, and reset to 0 for the next row
|
||||
yOffset += currentRowHeight;
|
||||
yOffset += Spacing;
|
||||
|
||||
currentRowHeight = 0;
|
||||
currentRowWidth = 0;
|
||||
}
|
||||
|
||||
currentRowWidth += childWidth;
|
||||
_rowList.Add(child);
|
||||
|
||||
// We need the largest element height to determine the starting position of the next line
|
||||
if (childHeight > currentRowHeight)
|
||||
{
|
||||
currentRowHeight = childHeight;
|
||||
}
|
||||
}
|
||||
|
||||
if (!layoutInput)
|
||||
{
|
||||
var h = CalculateRowVerticalOffset(groupHeight, yOffset, currentRowHeight);
|
||||
|
||||
// Layout the final row
|
||||
LayoutRow(_rowList, currentRowWidth, currentRowHeight, workingWidth, padding.left, h, axis);
|
||||
}
|
||||
|
||||
_rowList.Clear();
|
||||
|
||||
// Add the last rows height to the height accumulator
|
||||
yOffset += currentRowHeight;
|
||||
yOffset += IsLowerAlign ? padding.top : padding.bottom;
|
||||
|
||||
if (layoutInput)
|
||||
{
|
||||
if (axis == 1)
|
||||
{
|
||||
SetLayoutInputForAxis(yOffset, yOffset, -1, axis);
|
||||
}
|
||||
}
|
||||
|
||||
return yOffset;
|
||||
}
|
||||
|
||||
private float CalculateRowVerticalOffset(float groupHeight, float yOffset, float currentRowHeight)
|
||||
{
|
||||
float h;
|
||||
|
||||
if (IsLowerAlign)
|
||||
{
|
||||
h = groupHeight - yOffset - currentRowHeight;
|
||||
}
|
||||
else if (IsMiddleAlign)
|
||||
{
|
||||
h = groupHeight * 0.5f - _layoutHeight * 0.5f + yOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = yOffset;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
protected void LayoutRow(IList<RectTransform> contents, float rowWidth, float rowHeight, float maxWidth,
|
||||
float xOffset, float yOffset, int axis)
|
||||
{
|
||||
var xPos = xOffset;
|
||||
|
||||
if (!ChildForceExpandWidth && IsCenterAlign)
|
||||
{
|
||||
xPos += (maxWidth - rowWidth) * 0.5f;
|
||||
}
|
||||
else if (!ChildForceExpandWidth && IsRightAlign)
|
||||
{
|
||||
xPos += (maxWidth - rowWidth);
|
||||
}
|
||||
|
||||
var extraWidth = 0f;
|
||||
|
||||
if (ChildForceExpandWidth)
|
||||
{
|
||||
var flexibleChildCount = 0;
|
||||
|
||||
for (var i = 0; i < _rowList.Count; i++)
|
||||
{
|
||||
if (LayoutUtility.GetFlexibleWidth(_rowList[i]) > 0f)
|
||||
{
|
||||
flexibleChildCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (flexibleChildCount > 0)
|
||||
{
|
||||
extraWidth = (maxWidth - rowWidth) / flexibleChildCount;
|
||||
}
|
||||
}
|
||||
|
||||
for (var j = 0; j < _rowList.Count; j++)
|
||||
{
|
||||
var index = IsLowerAlign ? _rowList.Count - 1 - j : j;
|
||||
|
||||
var rowChild = _rowList[index];
|
||||
|
||||
var rowChildWidth = LayoutUtility.GetPreferredSize(rowChild, 0);
|
||||
|
||||
if (LayoutUtility.GetFlexibleWidth(rowChild) > 0f)
|
||||
{
|
||||
rowChildWidth += extraWidth;
|
||||
}
|
||||
|
||||
var rowChildHeight = LayoutUtility.GetPreferredSize(rowChild, 1);
|
||||
|
||||
if (ChildForceExpandHeight)
|
||||
{
|
||||
rowChildHeight = rowHeight;
|
||||
}
|
||||
|
||||
rowChildWidth = Mathf.Min(rowChildWidth, maxWidth);
|
||||
|
||||
var yPos = yOffset;
|
||||
|
||||
if (IsMiddleAlign)
|
||||
{
|
||||
yPos += (rowHeight - rowChildHeight) * 0.5f;
|
||||
}
|
||||
else if (IsLowerAlign)
|
||||
{
|
||||
yPos += (rowHeight - rowChildHeight);
|
||||
}
|
||||
|
||||
if (axis == 0)
|
||||
{
|
||||
#if UNITY_2019_1
|
||||
SetChildAlongAxis(rowChild, 0, 1f, xPos, rowChildWidth);
|
||||
#else
|
||||
SetChildAlongAxis(rowChild, 0, xPos, rowChildWidth);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if UNITY_2019_1
|
||||
SetChildAlongAxis(rowChild, 1, 1f, yPos, rowChildHeight);
|
||||
#else
|
||||
SetChildAlongAxis(rowChild, 1, yPos, rowChildHeight);
|
||||
#endif
|
||||
}
|
||||
|
||||
xPos += rowChildWidth + Spacing;
|
||||
}
|
||||
}
|
||||
|
||||
public float GetGreatestMinimumChildWidth()
|
||||
{
|
||||
var max = 0f;
|
||||
|
||||
for (var i = 0; i < rectChildren.Count; i++)
|
||||
{
|
||||
var w = LayoutUtility.GetMinWidth(rectChildren[i]);
|
||||
|
||||
max = Mathf.Max(w, max);
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3a5149e46522d84cb8079537220a929
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user