Add StickGame Assets
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd9a0ca39fab66c448fdc3e25da9d482
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"name": "GameKit.Dependencies"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36bccdedfe0feeb4daf43bef9e43b65b
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c8ce00cde8ada214fb582a92539f14b9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b43a8f6c3cc189c40ae6b248e76e2788
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c197d238762d66b41927449d5c48b3f4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,488 @@
|
||||
#if UNITY_EDITOR
|
||||
// Project : UNITY FOLDOUT
|
||||
// Contacts : Pix - ask@pixeye.games
|
||||
// https://github.com/PixeyeHQ/InspectorFoldoutGroup
|
||||
// MIT license https://github.com/PixeyeHQ/InspectorFoldoutGroup/blob/master/LICENSE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
|
||||
namespace GameKit.Dependencies.Inspectors
|
||||
{
|
||||
[CustomEditor(typeof(Object), true, isFallback = true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class EditorOverride : Editor
|
||||
{
|
||||
|
||||
public override VisualElement CreateInspectorGUI()
|
||||
{
|
||||
return base.CreateInspectorGUI();
|
||||
}
|
||||
//===============================//
|
||||
// Members
|
||||
//===============================//
|
||||
|
||||
Dictionary<string, CacheFoldProp> cacheFolds = new Dictionary<string, CacheFoldProp>();
|
||||
List<SerializedProperty> props = new List<SerializedProperty>();
|
||||
List<MethodInfo> methods = new List<MethodInfo>();
|
||||
bool initialized;
|
||||
|
||||
|
||||
//===============================//
|
||||
// Logic
|
||||
//===============================//
|
||||
void OnEnable()
|
||||
{
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
//if (Application.wantsToQuit)
|
||||
//if (applicationIsQuitting) return;
|
||||
// if (Toolbox.isQuittingOrChangingScene()) return;
|
||||
if (target != null)
|
||||
foreach (var c in cacheFolds)
|
||||
{
|
||||
EditorPrefs.SetBool(string.Format($"{c.Value.atr.name}{c.Value.props[0].name}{target.GetInstanceID()}"), c.Value.expanded);
|
||||
c.Value.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override bool RequiresConstantRepaint()
|
||||
{
|
||||
return EditorFramework.needToRepaint;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
|
||||
Setup();
|
||||
|
||||
if (props.Count == 0)
|
||||
{
|
||||
DrawDefaultInspector();
|
||||
return;
|
||||
}
|
||||
|
||||
Header();
|
||||
Body();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
void Header()
|
||||
{
|
||||
using (new EditorGUI.DisabledScope("m_Script" == props[0].propertyPath))
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.PropertyField(props[0], true);
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
|
||||
void Body()
|
||||
{
|
||||
foreach (var pair in cacheFolds)
|
||||
{
|
||||
this.UseVerticalLayout(() => Foldout(pair.Value), StyleFramework.box);
|
||||
EditorGUI.indentLevel = 0;
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
for (var i = 1; i < props.Count; i++)
|
||||
{
|
||||
// if (props[i].isArray)
|
||||
// {
|
||||
// DrawPropertySortableArray(props[i]);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
EditorGUILayout.PropertyField(props[i], true);
|
||||
//}
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (methods == null) return;
|
||||
foreach (MethodInfo memberInfo in methods)
|
||||
{
|
||||
this.UseButton(memberInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void Foldout(CacheFoldProp cache)
|
||||
{
|
||||
cache.expanded = EditorGUILayout.Foldout(cache.expanded, cache.atr.name, true,
|
||||
StyleFramework.foldout);
|
||||
|
||||
if (cache.expanded)
|
||||
{
|
||||
EditorGUI.indentLevel = 1;
|
||||
|
||||
for (int i = 0; i < cache.props.Count; i++)
|
||||
{
|
||||
this.UseVerticalLayout(() => Child(i), StyleFramework.boxChild);
|
||||
}
|
||||
}
|
||||
|
||||
void Child(int i)
|
||||
{
|
||||
// if (cache.props[i].isArray)
|
||||
// {
|
||||
// DrawPropertySortableArray(cache.props[i]);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
EditorGUILayout.PropertyField(cache.props[i], new GUIContent(ObjectNames.NicifyVariableName(cache.props[i].name)), true);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
void Setup()
|
||||
{
|
||||
EditorFramework.currentEvent = Event.current;
|
||||
if (!initialized)
|
||||
{
|
||||
// SetupButtons();
|
||||
|
||||
List<FieldInfo> objectFields;
|
||||
GroupAttribute prevFold = default;
|
||||
|
||||
var length = EditorTypes.Get(target, out objectFields);
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
#region FOLDERS
|
||||
|
||||
var fold = Attribute.GetCustomAttribute(objectFields[i], typeof(GroupAttribute)) as GroupAttribute;
|
||||
CacheFoldProp c;
|
||||
if (fold == null)
|
||||
{
|
||||
if (prevFold != null && prevFold.foldEverything)
|
||||
{
|
||||
if (!cacheFolds.TryGetValue(prevFold.name, out c))
|
||||
{
|
||||
cacheFolds.Add(prevFold.name, new CacheFoldProp { atr = prevFold, types = new HashSet<string> { objectFields[i].Name } });
|
||||
}
|
||||
else
|
||||
{
|
||||
c.types.Add(objectFields[i].Name);
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
prevFold = fold;
|
||||
|
||||
if (!cacheFolds.TryGetValue(fold.name, out c))
|
||||
{
|
||||
var expanded = EditorPrefs.GetBool(string.Format($"{fold.name}{objectFields[i].Name}{target.GetInstanceID()}"), false);
|
||||
cacheFolds.Add(fold.name, new CacheFoldProp { atr = fold, types = new HashSet<string> { objectFields[i].Name }, expanded = expanded });
|
||||
}
|
||||
else c.types.Add(objectFields[i].Name);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
var property = serializedObject.GetIterator();
|
||||
var next = property.NextVisible(true);
|
||||
if (next)
|
||||
{
|
||||
do
|
||||
{
|
||||
HandleFoldProp(property);
|
||||
} while (property.NextVisible(false));
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
// void SetupButtons()
|
||||
// {
|
||||
// var members = GetButtonMembers(target);
|
||||
//
|
||||
// foreach (var memberInfo in members)
|
||||
// {
|
||||
// var method = memberInfo as MethodInfo;
|
||||
// if (method == null)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if (method.GetParameters().Length > 0)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if (methods == null) methods = new List<MethodInfo>();
|
||||
// methods.Add(method);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public void HandleFoldProp(SerializedProperty prop)
|
||||
{
|
||||
bool shouldBeFolded = false;
|
||||
|
||||
foreach (var pair in cacheFolds)
|
||||
{
|
||||
if (pair.Value.types.Contains(prop.name))
|
||||
{
|
||||
var pr = prop.Copy();
|
||||
shouldBeFolded = true;
|
||||
pair.Value.props.Add(pr);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldBeFolded == false)
|
||||
{
|
||||
var pr = prop.Copy();
|
||||
props.Add(pr);
|
||||
}
|
||||
}
|
||||
|
||||
// IEnumerable<MemberInfo> GetButtonMembers(object target)
|
||||
// {
|
||||
// return target.GetType()
|
||||
// .GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic)
|
||||
// .Where(CheckButtonAttribute);
|
||||
// }
|
||||
|
||||
// bool CheckButtonAttribute(MemberInfo memberInfo)
|
||||
// {
|
||||
// return Attribute.IsDefined(memberInfo, typeof(ButtonAttribute));
|
||||
// }
|
||||
|
||||
class CacheFoldProp
|
||||
{
|
||||
public HashSet<string> types = new HashSet<string>();
|
||||
public List<SerializedProperty> props = new List<SerializedProperty>();
|
||||
public GroupAttribute atr;
|
||||
public bool expanded;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
props.Clear();
|
||||
types.Clear();
|
||||
atr = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class EditorUIHelper
|
||||
{
|
||||
public static void UseVerticalLayout(this Editor e, Action action, GUIStyle style)
|
||||
{
|
||||
EditorGUILayout.BeginVertical(style);
|
||||
action();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
public static void UseButton(this Editor e, MethodInfo m)
|
||||
{
|
||||
if (GUILayout.Button(m.Name))
|
||||
{
|
||||
m.Invoke(e.target, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class StyleFramework
|
||||
{
|
||||
public static GUIStyle box;
|
||||
public static GUIStyle boxChild;
|
||||
public static GUIStyle foldout;
|
||||
public static GUIStyle button;
|
||||
public static GUIStyle text;
|
||||
|
||||
static StyleFramework()
|
||||
{
|
||||
bool pro = EditorGUIUtility.isProSkin;
|
||||
|
||||
|
||||
var uiTex_in = UnityEngine.Resources.Load<Texture2D>("IN foldout focus-6510");
|
||||
var uiTex_in_on = UnityEngine.Resources.Load<Texture2D>("IN foldout focus on-5718");
|
||||
|
||||
var c_on = pro ? Color.white : new Color(51 / 255f, 102 / 255f, 204 / 255f, 1);
|
||||
|
||||
button = new GUIStyle(EditorStyles.miniButton);
|
||||
button.font = Font.CreateDynamicFontFromOSFont(new[] { "Terminus (TTF) for Windows", "Calibri" }, 17);
|
||||
|
||||
text = new GUIStyle(EditorStyles.label);
|
||||
text.richText = true;
|
||||
text.contentOffset = new Vector2(0, 5);
|
||||
text.font = Font.CreateDynamicFontFromOSFont(new[] { "Terminus (TTF) for Windows", "Calibri" }, 14);
|
||||
|
||||
foldout = new GUIStyle(EditorStyles.foldout);
|
||||
|
||||
foldout.overflow = new RectOffset(-10, 0, 3, 0);
|
||||
foldout.padding = new RectOffset(25, 0, -3, 0);
|
||||
|
||||
foldout.active.textColor = c_on;
|
||||
foldout.active.background = uiTex_in;
|
||||
foldout.onActive.textColor = c_on;
|
||||
foldout.onActive.background = uiTex_in_on;
|
||||
|
||||
foldout.focused.textColor = c_on;
|
||||
foldout.focused.background = uiTex_in;
|
||||
foldout.onFocused.textColor = c_on;
|
||||
foldout.onFocused.background = uiTex_in_on;
|
||||
|
||||
foldout.hover.textColor = c_on;
|
||||
foldout.hover.background = uiTex_in;
|
||||
|
||||
foldout.onHover.textColor = c_on;
|
||||
foldout.onHover.background = uiTex_in_on;
|
||||
|
||||
box = new GUIStyle(GUI.skin.box);
|
||||
box.padding = new RectOffset(10, 0, 10, 0);
|
||||
|
||||
boxChild = new GUIStyle(GUI.skin.box);
|
||||
boxChild.active.textColor = c_on;
|
||||
boxChild.active.background = uiTex_in;
|
||||
boxChild.onActive.textColor = c_on;
|
||||
boxChild.onActive.background = uiTex_in_on;
|
||||
|
||||
boxChild.focused.textColor = c_on;
|
||||
boxChild.focused.background = uiTex_in;
|
||||
boxChild.onFocused.textColor = c_on;
|
||||
boxChild.onFocused.background = uiTex_in_on;
|
||||
|
||||
EditorStyles.foldout.active.textColor = c_on;
|
||||
EditorStyles.foldout.active.background = uiTex_in;
|
||||
EditorStyles.foldout.onActive.textColor = c_on;
|
||||
EditorStyles.foldout.onActive.background = uiTex_in_on;
|
||||
|
||||
EditorStyles.foldout.focused.textColor = c_on;
|
||||
EditorStyles.foldout.focused.background = uiTex_in;
|
||||
EditorStyles.foldout.onFocused.textColor = c_on;
|
||||
EditorStyles.foldout.onFocused.background = uiTex_in_on;
|
||||
|
||||
EditorStyles.foldout.hover.textColor = c_on;
|
||||
EditorStyles.foldout.hover.background = uiTex_in;
|
||||
|
||||
EditorStyles.foldout.onHover.textColor = c_on;
|
||||
EditorStyles.foldout.onHover.background = uiTex_in_on;
|
||||
}
|
||||
|
||||
public static string FirstLetterToUpperCase(this string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s))
|
||||
return string.Empty;
|
||||
|
||||
var a = s.ToCharArray();
|
||||
a[0] = char.ToUpper(a[0]);
|
||||
return new string(a);
|
||||
}
|
||||
|
||||
public static IList<Type> GetTypeTree(this Type t)
|
||||
{
|
||||
var types = new List<Type>();
|
||||
while (t.BaseType != null)
|
||||
{
|
||||
types.Add(t);
|
||||
t = t.BaseType;
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
}
|
||||
|
||||
static class EditorTypes
|
||||
{
|
||||
public static Dictionary<int, List<FieldInfo>> fields = new Dictionary<int, List<FieldInfo>>(FastComparable.Default);
|
||||
|
||||
public static int Get(Object target, out List<FieldInfo> objectFields)
|
||||
{
|
||||
var t = target.GetType();
|
||||
var hash = t.GetHashCode();
|
||||
|
||||
if (!fields.TryGetValue(hash, out objectFields))
|
||||
{
|
||||
var typeTree = t.GetTypeTree();
|
||||
objectFields = target.GetType()
|
||||
.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic)
|
||||
.OrderByDescending(x => typeTree.IndexOf(x.DeclaringType))
|
||||
.ToList();
|
||||
fields.Add(hash, objectFields);
|
||||
}
|
||||
|
||||
return objectFields.Count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class FastComparable : IEqualityComparer<int>
|
||||
{
|
||||
public static FastComparable Default = new FastComparable();
|
||||
|
||||
public bool Equals(int x, int y)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
public int GetHashCode(int obj)
|
||||
{
|
||||
return obj.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class EditorFramework
|
||||
{
|
||||
internal static bool needToRepaint;
|
||||
|
||||
internal static Event currentEvent;
|
||||
internal static float t;
|
||||
|
||||
static EditorFramework()
|
||||
{
|
||||
EditorApplication.update += Updating;
|
||||
}
|
||||
|
||||
|
||||
static void Updating()
|
||||
{
|
||||
CheckMouse();
|
||||
|
||||
if (needToRepaint)
|
||||
{
|
||||
t += Time.deltaTime;
|
||||
|
||||
if (t >= 0.3f)
|
||||
{
|
||||
t -= 0.3f;
|
||||
needToRepaint = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CheckMouse()
|
||||
{
|
||||
var ev = currentEvent;
|
||||
if (ev == null) return;
|
||||
|
||||
if (ev.type == EventType.MouseMove)
|
||||
needToRepaint = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 428419a625f80f6438c5b74beb2ac763
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bce51828adfc9b540b10914a9ec82c31
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,140 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07896d08487bbb049b494e9e216360ad
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 1
|
||||
swizzle: 50462976
|
||||
cookieLightType: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 3
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 3
|
||||
buildTarget: Server
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,140 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 795626f49ade9024a86e0c1a58aa004b
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 0
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 1
|
||||
swizzle: 50462976
|
||||
cookieLightType: 1
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 3
|
||||
buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
- serializedVersion: 3
|
||||
buildTarget: Server
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,25 @@
|
||||
// Project : UNITY FOLDOUT
|
||||
// Contacts : Pix - ask@pixeye.games
|
||||
// https://github.com/PixeyeHQ/InspectorFoldoutGroup
|
||||
// MIT license https://github.com/PixeyeHQ/InspectorFoldoutGroup/blob/master/LICENSE
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Dependencies.Inspectors
|
||||
{
|
||||
public class GroupAttribute : PropertyAttribute
|
||||
{
|
||||
public string name;
|
||||
public bool foldEverything;
|
||||
|
||||
/// <summary>Adds the property to the specified foldout group.</summary>
|
||||
/// <param name="name">Name of the foldout group.</param>
|
||||
/// <param name="foldEverything">Toggle to put all properties to the specified group</param>
|
||||
public GroupAttribute(string name, bool foldEverything = false)
|
||||
{
|
||||
this.foldEverything = foldEverything;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3c02d1d5545ae54687d1a313ebb2fd6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 102b5a2337dae434f989eee1a6a1c571
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8361a4f779768242840a9c994392e20
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,118 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Dependencies.Inspectors
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Based on: https://forum.unity.com/threads/draw-a-field-only-if-a-condition-is-met.448855/
|
||||
/// </summary>
|
||||
[CustomPropertyDrawer(typeof(ShowIfAttribute))]
|
||||
public class ShowIfPropertyDrawer : PropertyDrawer
|
||||
{
|
||||
#region Fields
|
||||
|
||||
// Reference to the attribute on the property.
|
||||
ShowIfAttribute drawIf;
|
||||
|
||||
// Field that is being compared.
|
||||
SerializedProperty comparedField;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
if (!ShowMe(property) && drawIf.disablingType == ShowIfAttribute.DisablingType.DontDraw)
|
||||
{
|
||||
return -EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (property.propertyType == SerializedPropertyType.Generic)
|
||||
{
|
||||
int numChildren = 0;
|
||||
float totalHeight = 0.0f;
|
||||
|
||||
IEnumerator children = property.GetEnumerator();
|
||||
HashSet<SerializedProperty> drawnprops = new HashSet<SerializedProperty>();
|
||||
|
||||
while (children.MoveNext())
|
||||
{
|
||||
SerializedProperty child = children.Current as SerializedProperty;
|
||||
if (drawnprops.Contains(child))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
drawnprops.Add(child);
|
||||
|
||||
GUIContent childLabel = new GUIContent(child.displayName);
|
||||
|
||||
totalHeight += EditorGUI.GetPropertyHeight(child, childLabel) + EditorGUIUtility.standardVerticalSpacing;
|
||||
numChildren++;
|
||||
}
|
||||
|
||||
// Remove extra space at end, (we only want spaces between items)
|
||||
totalHeight -= EditorGUIUtility.standardVerticalSpacing;
|
||||
|
||||
return totalHeight;
|
||||
}
|
||||
|
||||
return EditorGUI.GetPropertyHeight(property, label);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Errors default to showing the property.
|
||||
/// </summary>
|
||||
private bool ShowMe(SerializedProperty property)
|
||||
{
|
||||
drawIf = attribute as ShowIfAttribute;
|
||||
// Replace propertyname to the value from the parameter
|
||||
string path = property.propertyPath.Contains(".") ? System.IO.Path.ChangeExtension(property.propertyPath, drawIf.comparedPropertyName) : drawIf.comparedPropertyName;
|
||||
|
||||
comparedField = property.serializedObject.FindProperty(path);
|
||||
|
||||
if (comparedField == null)
|
||||
{
|
||||
Debug.LogError("Cannot find property with name: " + path);
|
||||
return true;
|
||||
}
|
||||
|
||||
// get the value & compare based on types
|
||||
switch (comparedField.type)
|
||||
{ // Possible extend cases to support your own type
|
||||
case "bool":
|
||||
return comparedField.boolValue.Equals(drawIf.comparedValue);
|
||||
case "Enum":
|
||||
return comparedField.enumValueIndex.Equals((int)drawIf.comparedValue);
|
||||
default:
|
||||
Debug.LogError("Error: " + comparedField.type + " is not supported of " + path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
// If the condition is met, simply draw the field.
|
||||
if (ShowMe(property))
|
||||
{
|
||||
EditorGUI.PropertyField(position, property);
|
||||
} //...check if the disabling type is read only. If it is, draw it disabled
|
||||
else if (drawIf.disablingType == ShowIfAttribute.DisablingType.ReadOnly)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
EditorGUI.PropertyField(position, property);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1266c8c8d104aeb4faf3f1daaee87479
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,45 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace GameKit.Dependencies.Inspectors
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Draws the field/property ONLY if the compared property compared by the comparison type with the value of comparedValue returns true.
|
||||
/// Based on: https://forum.unity.com/threads/draw-a-field-only-if-a-condition-is-met.448855/
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
|
||||
public class ShowIfAttribute : PropertyAttribute
|
||||
{
|
||||
#region Fields
|
||||
|
||||
public string comparedPropertyName { get; private set; }
|
||||
public object comparedValue { get; private set; }
|
||||
public DisablingType disablingType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Types of comperisons.
|
||||
/// </summary>
|
||||
public enum DisablingType
|
||||
{
|
||||
ReadOnly = 2,
|
||||
DontDraw = 3
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Only draws the field only if a condition is met. Supports enum and bools.
|
||||
/// </summary>
|
||||
/// <param name="comparedPropertyName">The name of the property that is being compared (case sensitive).</param>
|
||||
/// <param name="comparedValue">The value the property is being compared to.</param>
|
||||
/// <param name="disablingType">The type of disabling that should happen if the condition is NOT met. Defaulted to DisablingType.DontDraw.</param>
|
||||
public ShowIfAttribute(string comparedPropertyName, object comparedValue, DisablingType disablingType = DisablingType.DontDraw)
|
||||
{
|
||||
this.comparedPropertyName = comparedPropertyName;
|
||||
this.comparedValue = comparedValue;
|
||||
this.disablingType = disablingType;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 203e832301eed08499198358cfd13e7d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53002e457d153bf49aad4b2b28d4353c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,83 @@
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[InitializeOnLoad]
|
||||
#endif
|
||||
public static class ApplicationState
|
||||
{
|
||||
|
||||
#if !UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// True if application is quitting.
|
||||
/// </summary>
|
||||
private static bool _isQuitting;
|
||||
#endif
|
||||
static ApplicationState()
|
||||
{
|
||||
#if !UNITY_EDITOR
|
||||
_isQuitting = false;
|
||||
#endif
|
||||
Application.quitting -= Application_quitting;
|
||||
Application.quitting += Application_quitting;
|
||||
}
|
||||
|
||||
private static void Application_quitting()
|
||||
{
|
||||
#if !UNITY_EDITOR
|
||||
_isQuitting = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns if the application is quitting for editor or builds.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool IsQuitting()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPlaying)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
#else
|
||||
return _isQuitting;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if the application is playing for editor or builds.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool IsPlaying()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
return EditorApplication.isPlaying;
|
||||
#else
|
||||
return Application.isPlaying;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quits the application for editor or builds.
|
||||
/// </summary>
|
||||
public static void Quit()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorApplication.isPlaying = false;
|
||||
#else
|
||||
Application.Quit();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54eb82a57a65e8548b57f5ca2a62bb76
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,97 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
public static class Arrays
|
||||
{
|
||||
/// <summary>
|
||||
/// Randomizer used for shuffling.
|
||||
/// </summary>
|
||||
private static System.Random _random = new System.Random();
|
||||
|
||||
/// <summary>
|
||||
/// Adds an entry to a list if it does not exist already.
|
||||
/// </summary>
|
||||
/// <returns>True if the entry was added.</returns>
|
||||
public static bool AddUnique<T>(this List<T> list, T value)
|
||||
{
|
||||
bool contains = list.Contains((T)value);
|
||||
if (!contains)
|
||||
list.Add((T)value);
|
||||
|
||||
return !contains;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an object from a list through re-ordering. This breaks the order of the list for a faster remove.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static bool FastReferenceRemove<T>(this List<T> list, object value)
|
||||
{
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
if (object.ReferenceEquals(list[i], value))
|
||||
{
|
||||
FastIndexRemove(list, i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an index from a list through re-ordering. This breaks the order of the list for a faster remove.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="list"></param>
|
||||
/// <param name="index"></param>
|
||||
public static void FastIndexRemove<T>(this List<T> list, int index)
|
||||
{
|
||||
list[index] = list[list.Count - 1];
|
||||
list.RemoveAt(list.Count - 1);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Shuffles an array.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="array"></param>
|
||||
public static void Shuffle<T>(this T[] array)
|
||||
{
|
||||
int n = array.Length;
|
||||
for (int i = 0; i < (n - 1); i++)
|
||||
{
|
||||
int r = i + _random.Next(n - i);
|
||||
T t = array[r];
|
||||
array[r] = array[i];
|
||||
array[i] = t;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shuffles a list.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="lst"></param>
|
||||
public static void Shuffle<T>(this List<T> lst)
|
||||
{
|
||||
int n = lst.Count;
|
||||
for (int i = 0; i < (n - 1); i++)
|
||||
{
|
||||
int r = i + _random.Next(n - i);
|
||||
T t = lst[r];
|
||||
lst[r] = lst[i];
|
||||
lst[i] = t;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b93eae9ff81b3e4b892128ca4b392ed
|
||||
timeCreated: 1530140103
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
public static class Booleans
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a boolean to an integer, 1 for true 0 for false.
|
||||
/// </summary>
|
||||
public static int ToInt(this bool b)
|
||||
{
|
||||
return (b) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 602eeac4b016b174f90ae5e85254ac86
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,93 @@
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Ways a CanvasGroup can have it's blocking properties modified.
|
||||
/// </summary>
|
||||
public enum CanvasGroupBlockingType
|
||||
{
|
||||
Unchanged = 0,
|
||||
DoNotBlock = 1,
|
||||
Block = 2,
|
||||
}
|
||||
|
||||
public static class CanvaseGroups
|
||||
{
|
||||
|
||||
public static void SetBlockingType(this CanvasGroup group, CanvasGroupBlockingType blockingType)
|
||||
{
|
||||
if (blockingType == CanvasGroupBlockingType.Unchanged)
|
||||
return;
|
||||
|
||||
bool block = (blockingType == CanvasGroupBlockingType.Block);
|
||||
group.blocksRaycasts = block;
|
||||
group.interactable = block;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a CanvasGroup blocking type and alpha.
|
||||
/// </summary>
|
||||
/// <param name="blockingType">How to handle interactions.</param>
|
||||
/// <param name="alpha">Alpha for CanvasGroup.</param>
|
||||
public static void SetActive(this CanvasGroup group, CanvasGroupBlockingType blockingType, float alpha)
|
||||
{
|
||||
group.SetBlockingType(blockingType);
|
||||
group.alpha = alpha;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a canvasGroup active with specified alpha.
|
||||
/// </summary>
|
||||
public static void SetActive(this CanvasGroup group, float alpha)
|
||||
{
|
||||
group.SetActive(true, false);
|
||||
group.alpha = alpha;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a canvasGroup inactive with specified alpha.
|
||||
/// </summary>
|
||||
public static void SetInactive(this CanvasGroup group, float alpha)
|
||||
{
|
||||
group.SetActive(false, false);
|
||||
group.alpha = alpha;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a group active state by changing alpha and interaction toggles.
|
||||
/// </summary>
|
||||
public static void SetActive(this CanvasGroup group, bool active, bool setAlpha)
|
||||
{
|
||||
if (group == null)
|
||||
return;
|
||||
|
||||
if (setAlpha)
|
||||
{
|
||||
if (active)
|
||||
group.alpha = 1f;
|
||||
else
|
||||
group.alpha = 0f;
|
||||
}
|
||||
|
||||
group.interactable = active;
|
||||
group.blocksRaycasts = active;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a group active state by changing alpha and interaction toggles with a custom alpha.
|
||||
/// </summary>
|
||||
public static void SetActive(this CanvasGroup group, bool active, float alpha)
|
||||
{
|
||||
if (group == null)
|
||||
return;
|
||||
|
||||
group.alpha = alpha;
|
||||
|
||||
group.interactable = active;
|
||||
group.blocksRaycasts = active;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0e7937b287d3d24d807a115c1a3a464
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
public static class DictionaryFN
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Uses a hacky way to TryGetValue on a dictionary when using IL2CPP and on mobile.
|
||||
/// This is to support older devices that don't properly handle IL2CPP builds.
|
||||
/// </summary>
|
||||
public static bool TryGetValueIL2CPP<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key, out TValue value)
|
||||
{
|
||||
#if ENABLE_IL2CPP && UNITY_IOS || UNITY_ANDROID
|
||||
if (dict.ContainsKey(key))
|
||||
{
|
||||
value = dict[key];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return dict.TryGetValue(key, out value);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d31d19bc39eb6041bad18d8eb68ed68
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
102
phr/StickGame/Assets/FishNet/Plugins/GameKit/Utilities/Disks.cs
Normal file
102
phr/StickGame/Assets/FishNet/Plugins/GameKit/Utilities/Disks.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
public static class Disks
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Writes specified text to a file path.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="formatPath">True to format the path to the current platform.</param>
|
||||
public static void WriteToFile(string text, string path, bool formatPath = true)
|
||||
{
|
||||
//If to format the path for the platform.
|
||||
if (formatPath)
|
||||
path = FormatPlatformPath(path);
|
||||
|
||||
//Path came back or was passed in as an empty string.
|
||||
if (path == string.Empty)
|
||||
{
|
||||
Debug.LogError("Path cannot be null.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//Get directory path.
|
||||
string directory = Path.GetDirectoryName(path);
|
||||
//If directory doesn't exist try to create it.
|
||||
if (!Directory.Exists(directory))
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
//Try to write the file data.
|
||||
using (FileStream fs = new FileStream(path, FileMode.Create))
|
||||
{
|
||||
using (StreamWriter writer = new StreamWriter(fs))
|
||||
writer.Write(text);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"An error occured during a file write. Error: {ex.Message} {Environment.NewLine} File path: {path} {Environment.NewLine} Text: {text}");
|
||||
}
|
||||
|
||||
/* If within the editor then refresh the asset database so changes
|
||||
* reflect in the project folder. */
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.AssetDatabase.Refresh();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats a file path to the current platform.
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static string FormatPlatformPath(string path)
|
||||
{
|
||||
//No path specified.
|
||||
if (path == string.Empty)
|
||||
{
|
||||
Debug.LogError("Path cannot be empty.");
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
string convertedPath = string.Empty;
|
||||
|
||||
//Get the directories as an array.
|
||||
string[] directories = path.Split(Path.DirectorySeparatorChar);
|
||||
|
||||
//Go through each directory.
|
||||
for (int i = 0; i < directories.Length; i++)
|
||||
{
|
||||
/* If only one entry in array then the path
|
||||
* is in the root of the Resources folder. */
|
||||
if (directories.Length == 1)
|
||||
{
|
||||
//Append to converted path and break from the loop.
|
||||
convertedPath = directories[i];
|
||||
break;
|
||||
}
|
||||
//More than one entry, meaning there are sub paths.
|
||||
else
|
||||
{
|
||||
/* Set converted path to the current
|
||||
* convertedPath combined with the next directory. */
|
||||
convertedPath = Path.Combine(convertedPath, directories[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return convertedPath;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3a909760282d284591c20c873f20837
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
public enum EditorLayoutEnableType
|
||||
{
|
||||
Enabled = 0,
|
||||
Disabled = 1,
|
||||
DisabledWhilePlaying = 2
|
||||
}
|
||||
public static class Editing
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Adds a property field.
|
||||
/// </summary>
|
||||
public static void AddPropertyField(SerializedProperty sp, GUIContent guiContent, EditorLayoutEnableType enableType = EditorLayoutEnableType.Enabled, params GUILayoutOption[] options)
|
||||
{
|
||||
bool disable = DisableLayout(enableType);
|
||||
if (disable)
|
||||
GUI.enabled = false;
|
||||
|
||||
EditorGUILayout.PropertyField(sp, guiContent, options);
|
||||
|
||||
if (disable)
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an object field.
|
||||
/// </summary>
|
||||
public static void AddObjectField(string label, MonoScript ms, Type type, bool allowSceneObjects, EditorLayoutEnableType enableType = EditorLayoutEnableType.Enabled, params GUILayoutOption[] options)
|
||||
{
|
||||
bool disable = DisableLayout(enableType);
|
||||
if (disable)
|
||||
GUI.enabled = false;
|
||||
|
||||
EditorGUILayout.ObjectField("Script:", ms, type, allowSceneObjects, options);
|
||||
|
||||
if (disable)
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables GUI if playing.
|
||||
/// </summary>
|
||||
public static void DisableGUIIfPlaying()
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
GUI.enabled = false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Enables GUI if playing.
|
||||
/// </summary>
|
||||
public static void EnableGUIIfPlaying()
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if a layout field should be disabled.
|
||||
/// </summary>
|
||||
/// <param name="enableType"></param>
|
||||
/// <returns></returns>
|
||||
private static bool DisableLayout(EditorLayoutEnableType enableType)
|
||||
{
|
||||
return (enableType == EditorLayoutEnableType.Disabled || (enableType == EditorLayoutEnableType.DisabledWhilePlaying && Application.isPlaying));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd42f76391fc1254f82767dbf1a4bc8b
|
||||
timeCreated: 1525378031
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
130
phr/StickGame/Assets/FishNet/Plugins/GameKit/Utilities/Enums.cs
Normal file
130
phr/StickGame/Assets/FishNet/Plugins/GameKit/Utilities/Enums.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
|
||||
public static class Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// Determine an enum value from a given string. This can be an expensive function.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="text">Text of string.</param>
|
||||
/// <param name="defaultValue">Default value if enum couldn't be found.</param>
|
||||
/// <returns>Enum found or default value if no enum is found.</returns>
|
||||
public static T FromString<T>(string text, T defaultValue)
|
||||
{
|
||||
//If string is empty or null return default value.
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return defaultValue;
|
||||
//If enum isn't defined return default value.
|
||||
if (!Enum.IsDefined(typeof(T), (string)text))
|
||||
return defaultValue;
|
||||
//Return parsed value.
|
||||
return (T)Enum.Parse(typeof(T), text, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if whole(extended enum) has any of the part values.
|
||||
/// </summary>
|
||||
/// <param name="whole"></param>
|
||||
/// <param name="part">Values to check for within whole.</param>
|
||||
/// <returns>Returns true part is within whole.</returns>
|
||||
public static bool Contains(this Enum whole, Enum part)
|
||||
{
|
||||
//If not the same type of Enum return false.
|
||||
/* Commented out for performance. Designer
|
||||
* should know better than to compare two different
|
||||
* enums. */
|
||||
//if (!SameType(value, target))
|
||||
// return false;
|
||||
|
||||
/* Convert enum values to ulong. With so few
|
||||
* values a uint would be safe, but should
|
||||
* the options expand ulong is safer. */
|
||||
ulong wholeNum = Convert.ToUInt64(whole);
|
||||
ulong partNum = Convert.ToUInt64(part);
|
||||
|
||||
return ((wholeNum & partNum) != 0);
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns if part values contains any of whole(extended enum).
|
||||
/// </summary>
|
||||
/// <param name="whole"></param>
|
||||
/// <param name="part"></param>
|
||||
/// <returns>Returns true whole is within part.</returns>
|
||||
public static bool ReverseContains(this Enum whole, Enum part)
|
||||
{
|
||||
//If not the same type of Enum return false.
|
||||
/* Commented out for performance. Designer
|
||||
* should know better than to compare two different
|
||||
* enums. */
|
||||
//if (!SameType(value, target))
|
||||
// return false;
|
||||
|
||||
/* Convert enum values to ulong. With so few
|
||||
* values a uint would be safe, but should
|
||||
* the options expand ulong is safer. */
|
||||
ulong wholeNum = Convert.ToUInt64(whole);
|
||||
ulong partNum = Convert.ToUInt64(part);
|
||||
|
||||
return ((partNum & wholeNum) != 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if an enum equals a specified value.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="target"></param>
|
||||
/// <returns></returns>
|
||||
public static bool Equals(this Enum value, Enum target)
|
||||
{
|
||||
//If not the same type of Enum return false.
|
||||
/* Commented out for performance. Designer
|
||||
* should know better than to compare two different
|
||||
* enums. */
|
||||
//if (!SameType(value, target))
|
||||
// return false;
|
||||
|
||||
ulong valueNum = Convert.ToUInt64(value);
|
||||
ulong wholeNum = Convert.ToUInt64(target);
|
||||
|
||||
return (valueNum == wholeNum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if a is the same Enum as b.
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="target"></param>
|
||||
/// <returns></returns>
|
||||
public static bool SameType(Enum a, Enum b)
|
||||
{
|
||||
return (a.GetType() == b.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the highest numeric value for T.
|
||||
/// </summary>
|
||||
public static int GetHighestValue<T>()
|
||||
{
|
||||
Type enumType = typeof(T);
|
||||
/* Brute force enum values.
|
||||
* Linq Last/Max lookup throws for IL2CPP. */
|
||||
int highestValue = 0;
|
||||
Array pidValues = Enum.GetValues(enumType);
|
||||
foreach (T pid in pidValues)
|
||||
{
|
||||
object obj = Enum.Parse(enumType, pid.ToString());
|
||||
int value = Convert.ToInt32(obj);
|
||||
highestValue = Math.Max(highestValue, value);
|
||||
}
|
||||
|
||||
return highestValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6c66aec505f9254491b2b126a2d4745
|
||||
timeCreated: 1522959833
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
232
phr/StickGame/Assets/FishNet/Plugins/GameKit/Utilities/Floats.cs
Normal file
232
phr/StickGame/Assets/FishNet/Plugins/GameKit/Utilities/Floats.cs
Normal file
@@ -0,0 +1,232 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
public static class Floats
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to randomize float values.
|
||||
/// </summary>
|
||||
private static System.Random _random = new System.Random();
|
||||
|
||||
/// <summary>
|
||||
/// Sets a source float to value if equal to or greater than tolerance.
|
||||
/// </summary>
|
||||
/// <param name="source">Float to check against tolerance.</param>
|
||||
/// <param name="tolerance">Tolerance float must be equal to or greater than to change to value.</param>
|
||||
/// <param name="value">Value source is set to when breaking tolerance.</param>
|
||||
public static float SetIfOverTolerance(this float source, float tolerance, float value)
|
||||
{
|
||||
if (source >= tolerance)
|
||||
source = value;
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a source float to value if equal to or less than tolerance.
|
||||
/// </summary>
|
||||
/// <param name="source">Float to check against tolerance.</param>
|
||||
/// <param name="tolerance">Tolerance float must be equal to or less than to change to value.</param>
|
||||
/// <param name="value">Value source is set to when breaking tolerance.</param>
|
||||
public static float SetIfUnderTolerance(this float source, float tolerance, float value)
|
||||
{
|
||||
if (source <= tolerance)
|
||||
source = value;
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns how much time is left on an endTime. Returns -1 if no time is left.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static float TimeRemainingValue(this float endTime)
|
||||
{
|
||||
float remaining = endTime - Time.time;
|
||||
//None remaining.
|
||||
if (remaining < 0f)
|
||||
return -1f;
|
||||
|
||||
return (endTime - Time.time);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns how much time is left on an endTime. Returns -1 if no time is left.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static int TimeRemainingValue(this float endTime, bool useFloor = true)
|
||||
{
|
||||
float remaining = endTime - Time.time;
|
||||
//None remaining.
|
||||
if (remaining < 0f)
|
||||
return -1;
|
||||
|
||||
float result = (endTime - Time.time);
|
||||
return (useFloor) ? Mathf.FloorToInt(result) : Mathf.CeilToInt(result);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns time remaining as a string using hh:mm:ss.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="segments">Number of places to return. 1 is seconds, 2 is minutes, 3 is hours. If a placement does not exist it is replaced with 00.</param>
|
||||
/// <param name="emptyOnZero">True to return an empty string when value is 0 or less.</param>
|
||||
/// <returns></returns>
|
||||
public static string TimeRemainingText(this float value, byte segments, bool emptyOnZero = false)
|
||||
{
|
||||
if (emptyOnZero && value <= 0f)
|
||||
return string.Empty;
|
||||
|
||||
int timeRounded = Math.Max(Mathf.RoundToInt(value), 0);
|
||||
TimeSpan t = TimeSpan.FromSeconds(timeRounded);
|
||||
|
||||
int hours = Mathf.FloorToInt(t.Hours);
|
||||
int minutes = Mathf.FloorToInt(t.Minutes);
|
||||
int seconds = Mathf.FloorToInt(t.Seconds);
|
||||
|
||||
string timeText;
|
||||
if (segments == 1)
|
||||
{
|
||||
seconds += (minutes * 60);
|
||||
seconds += (hours * 3600);
|
||||
timeText = string.Format("{0:D2}", seconds);
|
||||
}
|
||||
else if (segments == 2)
|
||||
{
|
||||
minutes += (hours * 60);
|
||||
timeText = string.Format("{0:D2}:{1:D2}", minutes, seconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeText = string.Format("{0:D2}:{1:D2}:{2:D2}", hours, minutes, seconds);
|
||||
}
|
||||
|
||||
return timeText;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides a random inclusive int within a given range. Preferred over Unity's Random to eliminate confusion as Unity uses inclusive for floats max, and exclusive for int max.
|
||||
/// </summary>
|
||||
/// <param name="minimum">Inclusive minimum value.</param>
|
||||
/// <param name="maximum">Inclusive maximum value.</param>
|
||||
/// <returns></returns>
|
||||
public static float RandomInclusiveRange(float minimum, float maximum)
|
||||
{
|
||||
double min = Convert.ToDouble(minimum);
|
||||
double max = Convert.ToDouble(maximum);
|
||||
|
||||
double result = (_random.NextDouble() * (max - min)) + min;
|
||||
return Convert.ToSingle(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a random float between 0f and 1f.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static float Random01()
|
||||
{
|
||||
return RandomInclusiveRange(0f, 1f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if a target float is within variance of the source float.
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <param name="tolerance"></param>
|
||||
public static bool Near(this float a, float b, float tolerance = 0.01f)
|
||||
{
|
||||
return (Mathf.Abs(a - b) <= tolerance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamps a float and returns if the float required clamping.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="min"></param>
|
||||
/// <param name="max"></param>
|
||||
/// <param name="clamped"></param>
|
||||
/// <returns></returns>
|
||||
public static float Clamp(float value, float min, float max, ref bool clamped)
|
||||
{
|
||||
clamped = (value < min);
|
||||
if (clamped)
|
||||
return min;
|
||||
|
||||
clamped = (value > min);
|
||||
if (clamped)
|
||||
return max;
|
||||
|
||||
clamped = false;
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a float after being adjusted by the specified variance.
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="variance"></param>
|
||||
/// <returns></returns>
|
||||
public static float Variance(this float source, float variance)
|
||||
{
|
||||
float pickedVariance = RandomInclusiveRange(1f - variance, 1f + variance);
|
||||
return (source * pickedVariance);
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets a float value to result after being adjusted by the specified variance.
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="variance"></param>
|
||||
/// <returns></returns>
|
||||
public static void Variance(this float source, float variance, ref float result)
|
||||
{
|
||||
float pickedVariance = RandomInclusiveRange(1f - variance, 1f + variance);
|
||||
result = (source * pickedVariance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns negative-one, zero, or postive-one of a value instead of just negative-one or positive-one.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to sign.</param>
|
||||
/// <returns>Precise sign.</returns>
|
||||
public static float PreciseSign(float value)
|
||||
{
|
||||
if (value == 0f)
|
||||
return 0f;
|
||||
else
|
||||
return (Mathf.Sign(value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if a float is within a range.
|
||||
/// </summary>
|
||||
/// <param name="source">Value of float.</param>
|
||||
/// <param name="rangeMin">Minimum of range.</param>
|
||||
/// <param name="rangeMax">Maximum of range.</param>
|
||||
/// <returns></returns>
|
||||
public static bool InRange(this float source, float rangeMin, float rangeMax)
|
||||
{
|
||||
return (source >= rangeMin && source <= rangeMax);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Randomly flips a float value.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static float RandomlyFlip(this float value)
|
||||
{
|
||||
if (Ints.RandomInclusiveRange(0, 1) == 0)
|
||||
return value;
|
||||
else
|
||||
return (value *= -1f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ab517aa5c3b6e34ca20461339adda04
|
||||
timeCreated: 1526172456
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "GameKit.Utilities",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:6055be8ebefd69e48b49212b09b47b2f",
|
||||
"GUID:36bccdedfe0feeb4daf43bef9e43b65b"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.unity.textmeshpro",
|
||||
"expression": "",
|
||||
"define": "TEXTMESHPRO"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17013b2a21298c14ea4808251346a38a
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,85 @@
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
public static class Hashing
|
||||
{
|
||||
|
||||
private const uint FNV_offset_basis32 = 2166136261;
|
||||
private const uint FNV_prime32 = 16777619;
|
||||
private const ulong FNV_offset_basis64 = 14695981039346656037;
|
||||
private const ulong FNV_prime64 = 1099511628211;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// non cryptographic stable hash code,
|
||||
/// it will always return the same hash for the same
|
||||
/// string.
|
||||
///
|
||||
/// This is simply an implementation of FNV-1 32 bit xor folded to 16 bit
|
||||
/// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
/// <returns>The stable hash32.</returns>
|
||||
/// <param name="txt">Text.</param>
|
||||
public static ushort GetStableHashU16(this string txt)
|
||||
{
|
||||
uint hash32 = txt.GetStableHashU32();
|
||||
|
||||
return (ushort)((hash32 >> 16) ^ hash32);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// non cryptographic stable hash code,
|
||||
/// it will always return the same hash for the same
|
||||
/// string.
|
||||
///
|
||||
/// This is simply an implementation of FNV-1 32 bit
|
||||
/// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
/// <returns>The stable hash32.</returns>
|
||||
/// <param name="txt">Text.</param>
|
||||
public static uint GetStableHashU32(this string txt)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
uint hash = FNV_offset_basis32;
|
||||
for (int i = 0; i < txt.Length; i++)
|
||||
{
|
||||
uint ch = txt[i];
|
||||
hash = hash * FNV_prime32;
|
||||
hash = hash ^ ch;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// non cryptographic stable hash code,
|
||||
/// it will always return the same hash for the same
|
||||
/// string.
|
||||
///
|
||||
/// This is simply an implementation of FNV-1 64 bit
|
||||
/// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
/// </summary>
|
||||
/// <returns>The stable hash32.</returns>
|
||||
/// <param name="txt">Text.</param>
|
||||
public static ulong GetStableHashU64(this string txt)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
ulong hash = FNV_offset_basis64;
|
||||
for (int i = 0; i < txt.Length; i++)
|
||||
{
|
||||
ulong ch = txt[i];
|
||||
hash = hash * FNV_prime64;
|
||||
hash = hash ^ ch;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a54dd369b7206e4f9e7716a42e53454
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,91 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Various utility classes relating to floats.
|
||||
/// </summary>
|
||||
public static class Ints
|
||||
{
|
||||
private static System.Random _random = new System.Random();
|
||||
|
||||
/// <summary>
|
||||
/// Pads an index a specified value. Preferred over typical padding so that pad values used with skins can be easily found in the code.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="padding"></param>
|
||||
/// <returns></returns>
|
||||
public static string PadInt(int value, int padding)
|
||||
{
|
||||
return value.ToString().PadLeft(padding, '0');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides a random inclusive int within a given range. Preferred over Unity's Random to eliminate confusion as Unity uses inclusive for floats max, and exclusive for int max.
|
||||
/// </summary>
|
||||
/// <param name="minimum">Inclusive minimum value.</param>
|
||||
/// <param name="maximum">Inclusive maximum value.</param>
|
||||
/// <returns></returns>
|
||||
public static int RandomInclusiveRange(int minimum, int maximum)
|
||||
{
|
||||
return _random.Next(minimum, maximum + 1);
|
||||
}
|
||||
/// <summary>
|
||||
/// Provides a random exclusive int within a given range. Preferred over Unity's Random to eliminate confusion as Unity uses inclusive for floats max, and exclusive for int max.
|
||||
/// </summary>
|
||||
/// <param name="minimum">Inclusive minimum value.</param>
|
||||
/// <param name="maximum">Exclusive maximum value.</param>
|
||||
/// <returns></returns>
|
||||
public static int RandomExclusiveRange(int minimum, int maximum)
|
||||
{
|
||||
return _random.Next(minimum, maximum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a clamped int within a specified range.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to clamp.</param>
|
||||
/// <param name="minimum">Minimum value.</param>
|
||||
/// <param name="maximum">Maximum value.</param>
|
||||
/// <returns></returns>
|
||||
public static int Clamp(int value, int minimum, int maximum)
|
||||
{
|
||||
if (value < minimum)
|
||||
value = minimum;
|
||||
else if (value > maximum)
|
||||
value = maximum;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determins if all values passed in are the same.
|
||||
/// </summary>
|
||||
/// <param name="values">Values to check.</param>
|
||||
/// <returns>True if all values are the same.</returns>
|
||||
public static bool ValuesMatch(params int[] values)
|
||||
{
|
||||
if (values.Length == 0)
|
||||
{
|
||||
Debug.Log("Ints -> ValuesMatch -> values array is empty.");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Assign first value as element in first array.
|
||||
int firstValue = values[0];
|
||||
//Check all values.
|
||||
for (int i = 1; i < values.Length; i++)
|
||||
{
|
||||
//If any value doesn't match first value return false.
|
||||
if (firstValue != values[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
//If this far all values match.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c673118198f5c4b41986d52762828363
|
||||
timeCreated: 1527268448
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,45 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
public static class Layers
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a layer mask to a layer number.
|
||||
/// </summary>
|
||||
/// <param name="mask"></param>
|
||||
/// <returns></returns>
|
||||
public static int LayerMaskToLayerNumber(LayerMask mask)
|
||||
{
|
||||
return LayerValueToLayerNumber(mask.value);
|
||||
}
|
||||
/// <summary>
|
||||
/// Converts a layer value int to a layer int.
|
||||
/// </summary>
|
||||
/// <param name="bitmask"></param>
|
||||
/// <returns></returns>
|
||||
public static int LayerValueToLayerNumber(int bitmask)
|
||||
{
|
||||
int result = bitmask > 0 ? 0 : 31;
|
||||
while (bitmask > 1)
|
||||
{
|
||||
bitmask = bitmask >> 1;
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if a LayerMask contains a specified layer.
|
||||
/// </summary>
|
||||
/// <param name="layerMask">LayerMask to check for layer in.</param>
|
||||
/// <param name="layer">Layer to check within LayerMask.</param>
|
||||
/// <returns></returns>
|
||||
public static bool ContainsLayer(LayerMask layerMask, int layer)
|
||||
{
|
||||
return (layerMask == (layerMask | (1 << layer)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c18e15e44d21a94d8919f4b6b125a1f
|
||||
timeCreated: 1522349045
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
public static class LayoutGroups
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns how many entries can fit into a GridLayoutGroup
|
||||
/// </summary>
|
||||
public static int EntriesPerWidth(this GridLayoutGroup lg)
|
||||
{
|
||||
RectTransform rectTransform = lg.GetComponent<RectTransform>();
|
||||
return Mathf.CeilToInt(rectTransform.rect.width / lg.cellSize.x);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e330113395c59ca4dba5de001e010f08
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
public static class Materials
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the color or tint color property for a material.
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
/// <returns></returns>
|
||||
public static Color GetColor(this Material material)
|
||||
{
|
||||
if (material.HasProperty("_Color"))
|
||||
return material.color;
|
||||
else if (material.HasProperty("_TintColor"))
|
||||
return material.GetColor("_TintColor");
|
||||
|
||||
return Color.white;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the color or tint color property for a material.
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
public static void SetColor(this Material material, Color color)
|
||||
{
|
||||
if (material.HasProperty("_Color"))
|
||||
material.color = color;
|
||||
else if (material.HasProperty("_TintColor"))
|
||||
material.SetColor("_TintColor", color);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27a618c551d5fdb4ca70bf07e1905580
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
public static class Maths
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Returns a clamped SBytte.
|
||||
/// </summary>
|
||||
public static sbyte ClampSByte(long value, sbyte min, sbyte max)
|
||||
{
|
||||
if (value < min)
|
||||
return min;
|
||||
else if (value > max)
|
||||
return max;
|
||||
else
|
||||
return (sbyte)value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a clamped double.
|
||||
/// </summary>
|
||||
public static double ClampDouble(double value, double min, double max)
|
||||
{
|
||||
if (value < min)
|
||||
return min;
|
||||
else if (value > max)
|
||||
return max;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18a583dc22a9a0f4cabec0c4a0219c6e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,548 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Implement to use type with Caches.
|
||||
/// </summary>
|
||||
public interface IResettable
|
||||
{
|
||||
/// <summary>
|
||||
/// Resets values when being placed in a cache.
|
||||
/// </summary>
|
||||
void ResetState();
|
||||
/// <summary>
|
||||
/// Initializes values after being retrieved from a cache.
|
||||
/// </summary>
|
||||
void InitializeState();
|
||||
}
|
||||
|
||||
#region Resettable caches.
|
||||
/// <summary>
|
||||
/// Caches collections of multiple generics.
|
||||
/// </summary>
|
||||
public static class ResettableCollectionCaches<T1, T2> where T1 : IResettable where T2 : IResettable
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves a collection.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<T1, T2> RetrieveDictionary() => CollectionCaches<T1, T2>.RetrieveDictionary();
|
||||
|
||||
/// <summary>
|
||||
/// Stores a collection and sets the original reference to default.
|
||||
/// Method will not execute if value is null.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void StoreAndDefault(ref Dictionary<T1, T2> value)
|
||||
{
|
||||
if (value == null)
|
||||
return;
|
||||
Store(value);
|
||||
value = default;
|
||||
}
|
||||
/// <summary>
|
||||
/// Stores a collection.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
public static void Store(Dictionary<T1, T2> value)
|
||||
{
|
||||
foreach (KeyValuePair<T1, T2> kvp in value)
|
||||
{
|
||||
kvp.Key.ResetState();
|
||||
ObjectCaches<T1>.Store(kvp.Key);
|
||||
kvp.Value.ResetState();
|
||||
ObjectCaches<T2>.Store(kvp.Value);
|
||||
}
|
||||
value.Clear();
|
||||
CollectionCaches<T1, T2>.Store(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Caches collections of multiple generics.
|
||||
/// </summary>
|
||||
public static class ResettableT1CollectionCaches<T1, T2> where T1 : IResettable
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves a collection.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<T1, T2> RetrieveDictionary() => CollectionCaches<T1, T2>.RetrieveDictionary();
|
||||
|
||||
/// <summary>
|
||||
/// Stores a collection and sets the original reference to default.
|
||||
/// Method will not execute if value is null.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void StoreAndDefault(ref Dictionary<T1, T2> value)
|
||||
{
|
||||
if (value == null)
|
||||
return;
|
||||
Store(value);
|
||||
value = default;
|
||||
}
|
||||
/// <summary>
|
||||
/// Stores a collection.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
public static void Store(Dictionary<T1, T2> value)
|
||||
{
|
||||
foreach (T1 item in value.Keys)
|
||||
{
|
||||
item.ResetState();
|
||||
ObjectCaches<T1>.Store(item);
|
||||
}
|
||||
value.Clear();
|
||||
CollectionCaches<T1, T2>.Store(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Caches collections of multiple generics.
|
||||
/// </summary>
|
||||
public static class ResettableT2CollectionCaches<T1, T2> where T2 : IResettable
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves a collection.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<T1, T2> RetrieveDictionary() => CollectionCaches<T1, T2>.RetrieveDictionary();
|
||||
|
||||
/// <summary>
|
||||
/// Stores a collection and sets the original reference to default.
|
||||
/// Method will not execute if value is null.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void StoreAndDefault(ref Dictionary<T1, T2> value)
|
||||
{
|
||||
if (value == null)
|
||||
return;
|
||||
Store(value);
|
||||
value = default;
|
||||
}
|
||||
/// <summary>
|
||||
/// Stores a collection.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
public static void Store(Dictionary<T1, T2> value)
|
||||
{
|
||||
foreach (T2 item in value.Values)
|
||||
{
|
||||
item.ResetState();
|
||||
ObjectCaches<T2>.Store(item);
|
||||
}
|
||||
value.Clear();
|
||||
CollectionCaches<T1, T2>.Store(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Caches collections of a single generic.
|
||||
/// </summary>
|
||||
public static class ResettableCollectionCaches<T> where T : IResettable
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves a collection.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static T[] RetrieveArray() => CollectionCaches<T>.RetrieveArray();
|
||||
/// <summary>
|
||||
/// Retrieves a collection.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<T> RetrieveList() => CollectionCaches<T>.RetrieveList();
|
||||
/// <summary>
|
||||
/// Retrieves a collection.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static HashSet<T> RetrieveHashSet() => CollectionCaches<T>.RetrieveHashSet();
|
||||
|
||||
/// <summary>
|
||||
/// Stores a collection and sets the original reference to default.
|
||||
/// Method will not execute if value is null.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
/// <param name="count">Number of entries in the array from the beginning.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void StoreAndDefault(ref T[] value, int count)
|
||||
{
|
||||
if (value == null)
|
||||
return;
|
||||
Store(value, count);
|
||||
value = default;
|
||||
}
|
||||
/// <summary>
|
||||
/// Stores a collection.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
/// <param name="count">Number of entries in the array from the beginning.</param>
|
||||
public static void Store(T[] value, int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
value[i].ResetState();
|
||||
ObjectCaches<T>.Store(value[i]);
|
||||
}
|
||||
CollectionCaches<T>.Store(value, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores a collection and sets the original reference to default.
|
||||
/// Method will not execute if value is null.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void StoreAndDefault(ref List<T> value)
|
||||
{
|
||||
if (value == null)
|
||||
return;
|
||||
Store(value);
|
||||
value = default;
|
||||
}
|
||||
/// <summary>
|
||||
/// Stores a collection.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
public static void Store(List<T> value)
|
||||
{
|
||||
for (int i = 0; i < value.Count; i++)
|
||||
{
|
||||
value[i].ResetState();
|
||||
ObjectCaches<T>.Store(value[i]);
|
||||
}
|
||||
value.Clear();
|
||||
CollectionCaches<T>.Store(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores a collection and sets the original reference to default.
|
||||
/// Method will not execute if value is null.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void StoreAndDefault(ref HashSet<T> value)
|
||||
{
|
||||
if (value == null)
|
||||
return;
|
||||
Store(value);
|
||||
value = default;
|
||||
}
|
||||
/// <summary>
|
||||
/// Stores a collection.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
public static void Store(HashSet<T> value)
|
||||
{
|
||||
foreach (T item in value)
|
||||
{
|
||||
item.ResetState();
|
||||
ObjectCaches<T>.Store(item);
|
||||
}
|
||||
value.Clear();
|
||||
CollectionCaches<T>.Store(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Caches objects of a single generic.
|
||||
/// </summary>
|
||||
public static class ResettableObjectCaches<T> where T : IResettable
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves an instance of T.
|
||||
/// </summary>
|
||||
public static T Retrieve()
|
||||
{
|
||||
T result = ObjectCaches<T>.Retrieve();
|
||||
result.InitializeState();
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores an instance of T and sets the original reference to default.
|
||||
/// Method will not execute if value is null.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void StoreAndDefault(ref T value)
|
||||
{
|
||||
if (value == null)
|
||||
return;
|
||||
Store(value);
|
||||
value = default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores an instance of T.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
public static void Store(T value)
|
||||
{
|
||||
value.ResetState();
|
||||
ObjectCaches<T>.Store(value);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region NonResettable caches.
|
||||
/// <summary>
|
||||
/// Caches collections of multiple generics.
|
||||
/// </summary>
|
||||
public static class CollectionCaches<T1, T2>
|
||||
{
|
||||
/// <summary>
|
||||
/// Cache for dictionaries.
|
||||
/// </summary>
|
||||
private readonly static Stack<Dictionary<T1, T2>> _dictionaryCache = new Stack<Dictionary<T1, T2>>();
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a collection.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<T1, T2> RetrieveDictionary()
|
||||
{
|
||||
if (_dictionaryCache.Count == 0)
|
||||
return new Dictionary<T1, T2>();
|
||||
else
|
||||
return _dictionaryCache.Pop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores a collection and sets the original reference to default.
|
||||
/// Method will not execute if value is null.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void StoreAndDefault(ref Dictionary<T1, T2> value)
|
||||
{
|
||||
if (value == null)
|
||||
return;
|
||||
Store(value);
|
||||
value = default;
|
||||
}
|
||||
/// <summary>
|
||||
/// Stores a collection.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
public static void Store(Dictionary<T1, T2> value)
|
||||
{
|
||||
value.Clear();
|
||||
_dictionaryCache.Push(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Caches collections of a single generic.
|
||||
/// </summary>
|
||||
public static class CollectionCaches<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Cache for arrays.
|
||||
/// </summary>
|
||||
private readonly static Stack<T[]> _arrayCache = new Stack<T[]>();
|
||||
/// <summary>
|
||||
/// Cache for lists.
|
||||
/// </summary>
|
||||
private readonly static Stack<List<T>> _listCache = new Stack<List<T>>();
|
||||
/// <summary>
|
||||
/// Cache for hashset.
|
||||
/// </summary>
|
||||
private readonly static Stack<HashSet<T>> _hashsetCache = new Stack<HashSet<T>>();
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a collection.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static T[] RetrieveArray()
|
||||
{
|
||||
if (_arrayCache.Count == 0)
|
||||
return new T[0];
|
||||
else
|
||||
return _arrayCache.Pop();
|
||||
}
|
||||
/// <summary>
|
||||
/// Retrieves a collection.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<T> RetrieveList()
|
||||
{
|
||||
if (_listCache.Count == 0)
|
||||
return new List<T>();
|
||||
else
|
||||
return _listCache.Pop();
|
||||
}
|
||||
/// <summary>
|
||||
/// Retrieves a collection adding one entry.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<T> RetrieveList(T entry)
|
||||
{
|
||||
List<T> result;
|
||||
if (_listCache.Count == 0)
|
||||
result = new List<T>();
|
||||
else
|
||||
result = _listCache.Pop();
|
||||
|
||||
result.Add(entry);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a HashSet<T>.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static HashSet<T> RetrieveHashSet()
|
||||
{
|
||||
if (_hashsetCache.Count == 0)
|
||||
return new HashSet<T>();
|
||||
else
|
||||
return _hashsetCache.Pop();
|
||||
}
|
||||
/// <summary>
|
||||
/// Retrieves a collection adding one entry.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static HashSet<T> RetrieveHashSet(T entry)
|
||||
{
|
||||
HashSet<T> result;
|
||||
if (_hashsetCache.Count == 0)
|
||||
result = new HashSet<T>();
|
||||
else
|
||||
result = _hashsetCache.Pop();
|
||||
|
||||
result.Add(entry);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores a collection and sets the original reference to default.\
|
||||
/// Method will not execute if value is null.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
/// <param name="count">Number of entries in the array from the beginning.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void StoreAndDefault(ref T[] value, int count)
|
||||
{
|
||||
if (value == null)
|
||||
return;
|
||||
Store(value, count);
|
||||
value = default;
|
||||
}
|
||||
/// <summary>
|
||||
/// Stores a collection.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
/// <param name="count">Number of entries in the array from the beginning.</param>
|
||||
public static void Store(T[] value, int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
value[i] = default;
|
||||
|
||||
_arrayCache.Push(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores a collection and sets the original reference to default.
|
||||
/// Method will not execute if value is null.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void StoreAndDefault(ref List<T> value)
|
||||
{
|
||||
if (value == null)
|
||||
return;
|
||||
Store(value);
|
||||
value = default;
|
||||
}
|
||||
/// <summary>
|
||||
/// Stores a collection.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
public static void Store(List<T> value)
|
||||
{
|
||||
value.Clear();
|
||||
_listCache.Push(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores a collection and sets the original reference to default.
|
||||
/// Method will not execute if value is null.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void StoreAndDefault(ref HashSet<T> value)
|
||||
{
|
||||
if (value == null)
|
||||
return;
|
||||
Store(value);
|
||||
value = default;
|
||||
}
|
||||
/// <summary>
|
||||
/// Stores a collection.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
public static void Store(HashSet<T> value)
|
||||
{
|
||||
value.Clear();
|
||||
_hashsetCache.Push(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Caches objects of a single generic.
|
||||
/// </summary>
|
||||
public static class ObjectCaches<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Stack to use.
|
||||
/// </summary>
|
||||
private readonly static Stack<T> _stack = new Stack<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value from the stack or creates an instance when the stack is empty.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static T Retrieve()
|
||||
{
|
||||
if (_stack.Count == 0)
|
||||
return Activator.CreateInstance<T>();
|
||||
else
|
||||
return _stack.Pop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores an instance of T and sets the original reference to default.
|
||||
/// Method will not execute if value is null.
|
||||
/// </summary>
|
||||
/// <param name="value">Value to store.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void StoreAndDefault(ref T value)
|
||||
{
|
||||
if (value == null)
|
||||
return;
|
||||
Store(value);
|
||||
value = default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores a value to the stack.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public static void Store(T value)
|
||||
{
|
||||
_stack.Push(value);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3cb13274f7491a941b6e89a767905f56
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
|
||||
using GameKit.Utilities.Types;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
public static class Objects
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns if an object has been destroyed from memory.
|
||||
/// </summary>
|
||||
/// <param name="gameObject"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsDestroyed(this GameObject gameObject)
|
||||
{
|
||||
// UnityEngine overloads the == operator for the GameObject type
|
||||
// and returns null when the object has been destroyed, but
|
||||
// actually the object is still there but has not been cleaned up yet
|
||||
// if we test both we can determine if the object has been destroyed.
|
||||
return (gameObject == null && !ReferenceEquals(gameObject, null));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds all objects in the scene of type. This method is very expensive.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="requireSceneLoaded">True if the scene must be fully loaded before trying to seek objects.</param>
|
||||
/// <returns></returns>
|
||||
public static List<T> FindAllObjectsOfType<T>(bool activeSceneOnly = true, bool requireSceneLoaded = false, bool includeDDOL = true, bool includeInactive = true)
|
||||
{
|
||||
List<T> results = new List<T>();
|
||||
for (int i = 0; i < SceneManager.sceneCount; i++)
|
||||
{
|
||||
Scene scene = SceneManager.GetSceneAt(i);
|
||||
//If to include only current scene.
|
||||
if (activeSceneOnly)
|
||||
{
|
||||
if (SceneManager.GetActiveScene() != scene)
|
||||
continue;
|
||||
}
|
||||
//If the scene must be fully loaded to seek objects within.
|
||||
if (!scene.isLoaded && requireSceneLoaded)
|
||||
continue;
|
||||
|
||||
GameObject[] allGameObjects = scene.GetRootGameObjects();
|
||||
for (int j = 0; j < allGameObjects.Length; j++)
|
||||
{
|
||||
results.AddRange(allGameObjects[j].GetComponentsInChildren<T>(includeInactive));
|
||||
}
|
||||
}
|
||||
|
||||
//If to also include DDOL.
|
||||
if (includeDDOL)
|
||||
{
|
||||
GameObject ddolGo = DDOL.GetDDOL().gameObject;
|
||||
results.AddRange(ddolGo.GetComponentsInChildren<T>(includeInactive));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fa6d28a28dbf6b4295602abad3de328
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,109 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
public static class Particles
|
||||
{
|
||||
/// <summary>
|
||||
/// Issues stop on the specified particle systems.
|
||||
/// </summary>
|
||||
/// <param name="systems"></param>
|
||||
public static float StopParticleSystem(ParticleSystem[] systems, bool stopLoopingOnly)
|
||||
{
|
||||
return StopParticleSystem(systems, stopLoopingOnly, ParticleSystemStopBehavior.StopEmitting);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Issues stop on the specified particle systems while returning the time required to play out.
|
||||
/// </summary>
|
||||
/// <param name="systems"></param>
|
||||
public static float StopParticleSystem(ParticleSystem[] systems, ParticleSystemStopBehavior stopBehavior = ParticleSystemStopBehavior.StopEmitting)
|
||||
{
|
||||
return StopParticleSystem(systems, false, stopBehavior);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Issues stop on the specified particle systems while returning the time required to play out.
|
||||
/// </summary>
|
||||
/// <param name="systems"></param>
|
||||
public static float StopParticleSystem(ParticleSystem[] systems, bool stopLoopingOnly, ParticleSystemStopBehavior stopBehavior = ParticleSystemStopBehavior.StopEmitting)
|
||||
{
|
||||
if (systems == null)
|
||||
return 0f;
|
||||
|
||||
float playOutDuration = 0f;
|
||||
for (int i = 0; i < systems.Length; i++)
|
||||
playOutDuration = Mathf.Max(playOutDuration, StopParticleSystem(systems[i], stopLoopingOnly, stopBehavior));
|
||||
|
||||
return playOutDuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Issues stop on the specified particle systems.
|
||||
/// </summary>
|
||||
/// <param name="systems"></param>
|
||||
public static float StopParticleSystem(ParticleSystem system, bool stopLoopingOnly, bool stopChildren = false)
|
||||
{
|
||||
return StopParticleSystem(system, stopLoopingOnly, ParticleSystemStopBehavior.StopEmitting, stopChildren);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Issues stop on the specified particle systems while returning the time required to play out.
|
||||
/// </summary>
|
||||
/// <param name="systems"></param>
|
||||
public static float StopParticleSystem(ParticleSystem system, ParticleSystemStopBehavior stopBehavior = ParticleSystemStopBehavior.StopEmitting, bool stopChildren = false)
|
||||
{
|
||||
return StopParticleSystem(system, false, stopBehavior, stopChildren);
|
||||
}
|
||||
/// <summary>
|
||||
/// Issues stop on the specified particle system while returning the time required to play out.
|
||||
/// </summary>
|
||||
public static float StopParticleSystem(ParticleSystem system, bool stopLoopingOnly, ParticleSystemStopBehavior stopBehavior = ParticleSystemStopBehavior.StopEmitting, bool stopChildren = false)
|
||||
{
|
||||
if (system == null)
|
||||
return 0f;
|
||||
if (stopChildren)
|
||||
{
|
||||
ParticleSystem[] all = system.GetComponentsInChildren<ParticleSystem>();
|
||||
StopParticleSystem(all, stopLoopingOnly, stopBehavior);
|
||||
}
|
||||
|
||||
float playOutDuration = 0f;
|
||||
float timeLeft = system.main.duration - system.time;
|
||||
playOutDuration = Mathf.Max(playOutDuration, timeLeft);
|
||||
|
||||
if (stopLoopingOnly)
|
||||
{
|
||||
if (system.main.loop)
|
||||
system.Stop(false, stopBehavior);
|
||||
}
|
||||
else
|
||||
{
|
||||
system.Stop(false, stopBehavior);
|
||||
}
|
||||
|
||||
return playOutDuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the longest time required for all systems to stop.
|
||||
/// </summary>
|
||||
/// <param name="systems"></param>
|
||||
/// <returns></returns>
|
||||
public static float ReturnLongestCycle(ParticleSystem[] systems)
|
||||
{
|
||||
float longestPlayTime = 0f;
|
||||
for (int i = 0; i < systems.Length; i++)
|
||||
{
|
||||
float timeLeft = systems[i].main.duration - systems[i].time;
|
||||
longestPlayTime = Mathf.Max(longestPlayTime, timeLeft);
|
||||
}
|
||||
|
||||
return longestPlayTime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f3d973dcfa06554998575e8eef0938a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,55 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
public static class Quaternions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Returns how fast an object must rotate over duration to reach goal.
|
||||
/// </summary>
|
||||
/// <param name="goal">Quaternion to measure distance against.</param>
|
||||
/// <param name="duration">How long it should take to move to goal.</param>
|
||||
/// <param name="interval">A multiplier applied towards interval. Typically this is used for ticks passed.</param>
|
||||
/// <returns></returns>
|
||||
public static float GetRate(this Quaternion a, Quaternion goal, float duration, out float angle, uint interval = 1, float tolerance = 0f)
|
||||
{
|
||||
angle = a.Angle(goal, true);
|
||||
return angle / (duration * interval);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if two quaternions match.
|
||||
/// </summary>
|
||||
/// <param name="precise">True to use a custom implementation with no error tolerance. False to use Unity's implementation which may return a match even when not true due to error tolerance.</param>
|
||||
/// <returns></returns>
|
||||
public static bool Matches(this Quaternion a, Quaternion b, bool precise = false)
|
||||
{
|
||||
if (precise)
|
||||
return (a.w == b.w && a.x == b.x && a.y == b.y && a.z == b.z);
|
||||
else
|
||||
return (a == b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the angle between two quaterions.
|
||||
/// </summary>
|
||||
/// <param name="precise">True to use a custom implementation with no error tolerance. False to use Unity's implementation which may return 0f due to error tolerance, even while there is a difference.</param>
|
||||
/// <returns></returns>
|
||||
public static float Angle(this Quaternion a, Quaternion b, bool precise = false)
|
||||
{
|
||||
if (precise)
|
||||
{
|
||||
//This is run Unitys implementation without the error tolerance.
|
||||
float dot = (a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w);
|
||||
return (Mathf.Acos(Mathf.Min(Mathf.Abs(dot), 1f)) * 2f * 57.29578f);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Quaternion.Angle(a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02a9084f4f788cd4293cdff56a49b5dd
|
||||
timeCreated: 1522043602
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
|
||||
public static class Strings
|
||||
{
|
||||
/// <summary>
|
||||
/// Attachs or detaches an suffix to a string.
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="suffix"></param>
|
||||
/// <param name="addExtension"></param>
|
||||
public static string ReturnModifySuffix(string text, string suffix, bool addExtension)
|
||||
{
|
||||
/* Since saving to a json, add the .json extension if not present.
|
||||
* Length must be greater than 6 to contain a character and .json. */
|
||||
if (text.Length > (suffix.Length + 1))
|
||||
{
|
||||
//If to add the extension.
|
||||
if (addExtension)
|
||||
{
|
||||
//If doesn't contain the extension then add it on.
|
||||
if (!text.Substring(text.Length - suffix.Length).Contains(suffix, StringComparison.CurrentCultureIgnoreCase))
|
||||
return (text + suffix);
|
||||
//Already contains extension.
|
||||
else
|
||||
return text;
|
||||
}
|
||||
//Remove extension.
|
||||
else
|
||||
{
|
||||
//If contains extension.
|
||||
if (text.Substring(text.Length - suffix.Length).Contains(suffix, StringComparison.CurrentCultureIgnoreCase))
|
||||
return text.Substring(0, text.Length - (suffix.Length));
|
||||
//Doesn't contain extension.
|
||||
return text;
|
||||
}
|
||||
}
|
||||
//Text isn't long enough to manipulate.
|
||||
else
|
||||
{
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns if a string contains another string using StringComparison.
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <param name="contains"></param>
|
||||
/// <param name="comp"></param>
|
||||
/// <returns></returns>
|
||||
public static bool Contains(this string s, string contains, StringComparison comp)
|
||||
{
|
||||
int index = s.IndexOf(contains, comp);
|
||||
return (index >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b396f2be4de550a4e92b552650311600
|
||||
timeCreated: 1525378031
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,177 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities
|
||||
{
|
||||
|
||||
public static class Transforms
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a position for the rectTransform ensuring it's fully on the screen.
|
||||
/// </summary>
|
||||
/// <param name="desiredPosition">Preferred position for the rectTransform.</param>
|
||||
/// <param name="padding">How much padding the transform must be from the screen edges.</param>
|
||||
public static Vector3 GetOnScreenPosition(this RectTransform rectTransform, Vector3 desiredPosition, Vector2 padding)
|
||||
{
|
||||
Vector2 scale = new Vector2(rectTransform.localScale.x, rectTransform.localScale.y);
|
||||
//Value of which the tooltip would exceed screen bounds.
|
||||
//If there would be overshoot then adjust to be just on the edge of the overshooting side.
|
||||
float overshoot;
|
||||
|
||||
float halfWidthRequired = ((rectTransform.sizeDelta.x * scale.x) / 2f) + padding.x;
|
||||
overshoot = (Screen.width - (desiredPosition.x + halfWidthRequired));
|
||||
//If overshooting on the right.
|
||||
if (overshoot < 0f)
|
||||
desiredPosition.x += overshoot;
|
||||
overshoot = (desiredPosition.x - halfWidthRequired);
|
||||
//If overshooting on the left.
|
||||
if (overshoot < 0f)
|
||||
desiredPosition.x = halfWidthRequired;
|
||||
|
||||
float halfHeightRequired = ((rectTransform.sizeDelta.y * scale.y) / 2f) + padding.y;
|
||||
overshoot = (Screen.height - (desiredPosition.y + halfHeightRequired));
|
||||
//If overshooting on the right.
|
||||
if (overshoot < 0f)
|
||||
desiredPosition.y += overshoot;
|
||||
overshoot = (desiredPosition.y - halfHeightRequired);
|
||||
//If overshooting on the left.
|
||||
if (overshoot < 0f)
|
||||
desiredPosition.y = halfHeightRequired;
|
||||
|
||||
return desiredPosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a parent for src while maintaining position, rotation, and scale of src.
|
||||
/// </summary>
|
||||
/// <param name="parent">Transform to become a child of.</param>
|
||||
public static void SetParentAndKeepTransform(this Transform src, Transform parent)
|
||||
{
|
||||
Vector3 pos = src.position;
|
||||
Quaternion rot = src.rotation;
|
||||
Vector3 scale = src.localScale;
|
||||
|
||||
src.SetParent(parent);
|
||||
src.position = pos;
|
||||
src.rotation = rot;
|
||||
src.localScale = scale;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys all children under the specified transform.
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
public static void DestroyChildren(this Transform t, bool destroyImmediately = false)
|
||||
{
|
||||
foreach (Transform child in t)
|
||||
{
|
||||
if (destroyImmediately)
|
||||
MonoBehaviour.DestroyImmediate(child.gameObject);
|
||||
else
|
||||
MonoBehaviour.Destroy(child.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys all children of a type under the specified transform.
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
public static void DestroyChildren<T>(this Transform t, bool destroyImmediately = false) where T : MonoBehaviour
|
||||
{
|
||||
T[] children = t.GetComponentsInChildren<T>();
|
||||
foreach (T child in children)
|
||||
{
|
||||
if (destroyImmediately)
|
||||
MonoBehaviour.DestroyImmediate(child.gameObject);
|
||||
else
|
||||
MonoBehaviour.Destroy(child.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets components in children and optionally parent.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="results"></param>
|
||||
/// <param name="parent"></param>
|
||||
/// <param name="includeParent"></param>
|
||||
/// <param name="includeInactive"></param>
|
||||
public static void GetComponentsInChildren<T>(this Transform parent, List<T> results, bool includeParent = true, bool includeInactive = false) where T : Component
|
||||
{
|
||||
if (!includeParent)
|
||||
{
|
||||
List<T> current = GameKit.Utilities.CollectionCaches<T>.RetrieveList();
|
||||
for (int i = 0; i < parent.childCount; i++)
|
||||
{
|
||||
parent.GetChild(i).GetComponentsInChildren(includeInactive, current);
|
||||
results.AddRange(current);
|
||||
}
|
||||
GameKit.Utilities.CollectionCaches<T>.Store(current);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.GetComponentsInChildren(includeInactive, results);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the position of this transform.
|
||||
/// </summary>
|
||||
public static Vector3 GetPosition(this Transform t, bool localSpace)
|
||||
{
|
||||
return (localSpace) ? t.localPosition : t.position;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns the rotation of this transform.
|
||||
/// </summary>
|
||||
public static Quaternion GetRotation(this Transform t, bool localSpace)
|
||||
{
|
||||
return (localSpace) ? t.localRotation : t.rotation;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns the scale of this transform.
|
||||
/// </summary>
|
||||
public static Vector3 GetScale(this Transform t)
|
||||
{
|
||||
return t.localScale;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the position of this transform.
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <param name="localSpace"></param>
|
||||
public static void SetPosition(this Transform t, bool localSpace, Vector3 pos)
|
||||
{
|
||||
if (localSpace)
|
||||
t.localPosition = pos;
|
||||
else
|
||||
t.position = pos;
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets the position of this transform.
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <param name="localSpace"></param>
|
||||
public static void SetRotation(this Transform t, bool localSpace, Quaternion rot)
|
||||
{
|
||||
if (localSpace)
|
||||
t.localRotation = rot;
|
||||
else
|
||||
t.rotation = rot;
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets the position of this transform.
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <param name="localSpace"></param>
|
||||
public static void SetScale(this Transform t, Vector3 scale)
|
||||
{
|
||||
t.localScale = scale;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba23540de73f58b458e7d7a200f3bb30
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a29cd7621a70a044bb205cc8cfd96b3c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,236 @@
|
||||
using GameKit.Dependencies.Inspectors;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities.Types
|
||||
{
|
||||
|
||||
public class CanvasGroupFader : MonoBehaviour
|
||||
{
|
||||
#region Types.
|
||||
/// <summary>
|
||||
/// Current fade state or goal for this class.
|
||||
/// </summary>
|
||||
public enum FadeGoalType
|
||||
{
|
||||
Unset = 0,
|
||||
Hidden = 1,
|
||||
Visible = 2,
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public.
|
||||
/// <summary>
|
||||
/// Current goal for the fader.
|
||||
/// </summary>
|
||||
public FadeGoalType FadeGoal { get; private set; } = FadeGoalType.Unset;
|
||||
/// <summary>
|
||||
/// True if hidden or in the process of hiding.
|
||||
/// </summary>
|
||||
public bool IsHiding => (FadeGoal == FadeGoalType.Hidden);
|
||||
/// <summary>
|
||||
/// True if visible. Will be true long as the CanvasGroup has alpha. Also see IsHiding.
|
||||
/// </summary>
|
||||
public bool IsVisible => (CanvasGroup.alpha > 0f);
|
||||
#endregion
|
||||
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
/// CanvasGroup to fade in and out.
|
||||
/// </summary>
|
||||
[Tooltip("CanvasGroup to fade in and out.")]
|
||||
[SerializeField, Group("Components")]
|
||||
protected CanvasGroup CanvasGroup;
|
||||
/// <summary>
|
||||
/// True to update the CanvasGroup blocking settings when showing and hiding.
|
||||
/// </summary>
|
||||
[Tooltip("True to update the CanvasGroup blocking settings when showing and hiding.")]
|
||||
[SerializeField, Group("Effects")]
|
||||
protected bool UpdateCanvasBlocking = true;
|
||||
/// <summary>
|
||||
/// How long it should take to fade in the CanvasGroup.
|
||||
/// </summary>
|
||||
[SerializeField, Group("Effects")]
|
||||
protected float FadeInDuration = 0.1f;
|
||||
/// <summary>
|
||||
/// How long it should take to fade out the CanvasGroup.
|
||||
/// </summary>
|
||||
[SerializeField, Group("Effects")]
|
||||
protected float FadeOutDuration = 0.3f;
|
||||
#endregion
|
||||
|
||||
#region Private.
|
||||
/// <summary>
|
||||
/// True if a fade cycle has completed at least once.
|
||||
/// </summary>
|
||||
private bool _completedOnce;
|
||||
#endregion
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
FadeGoal = (CanvasGroup.alpha > 0f) ? FadeGoalType.Visible : FadeGoalType.Hidden;
|
||||
}
|
||||
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
if (FadeGoal == FadeGoalType.Visible)
|
||||
ShowImmediately();
|
||||
else
|
||||
HideImmediately();
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
Fade();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows CanvasGroup immediately.
|
||||
/// </summary>
|
||||
public virtual void ShowImmediately()
|
||||
{
|
||||
SetFadeGoal(true);
|
||||
CompleteFade(true);
|
||||
OnShow();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hides CanvasGroup immediately.
|
||||
/// </summary>
|
||||
public virtual void HideImmediately()
|
||||
{
|
||||
SetFadeGoal(false);
|
||||
CompleteFade(false);
|
||||
OnHide();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows CanvasGroup with a fade.
|
||||
/// </summary>
|
||||
public virtual void Show()
|
||||
{
|
||||
if (FadeInDuration <= 0f)
|
||||
{
|
||||
ShowImmediately();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFadeGoal(true);
|
||||
OnShow();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called after Show or ShowImmediate.
|
||||
/// </summary>
|
||||
protected virtual void OnShow() { }
|
||||
|
||||
/// <summary>
|
||||
/// Hides CanvasGroup with a fade.
|
||||
/// </summary>
|
||||
public virtual void Hide()
|
||||
{
|
||||
if (FadeOutDuration <= 0f)
|
||||
{
|
||||
HideImmediately();
|
||||
}
|
||||
else
|
||||
{
|
||||
//Immediately make unclickable so players cannot hit UI objects as it's fading out.
|
||||
SetCanvasGroupBlockingType(CanvasGroupBlockingType.Block);
|
||||
SetFadeGoal(false);
|
||||
OnHide();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called after Hide or HideImmediate.
|
||||
/// </summary>
|
||||
protected virtual void OnHide() { }
|
||||
|
||||
/// <summary>
|
||||
/// Sets showing and begins fading if required.
|
||||
/// </summary>
|
||||
/// <param name="fadeIn"></param>
|
||||
private void SetFadeGoal(bool fadeIn)
|
||||
{
|
||||
FadeGoal = (fadeIn) ? FadeGoalType.Visible : FadeGoalType.Hidden;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fades in or out over time.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private void Fade()
|
||||
{
|
||||
//Should not be possible.
|
||||
if (FadeGoal == FadeGoalType.Unset)
|
||||
{
|
||||
Debug.LogError($"{gameObject.name} has an unset FadeGoal. This should not be possible.");
|
||||
return;
|
||||
}
|
||||
|
||||
bool fadingIn = (FadeGoal == FadeGoalType.Visible);
|
||||
float duration;
|
||||
float targetAlpha;
|
||||
if (fadingIn)
|
||||
{
|
||||
targetAlpha = 1f;
|
||||
duration = FadeInDuration;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetAlpha = 0f;
|
||||
duration = FadeOutDuration;
|
||||
}
|
||||
|
||||
/* Already at goal and had completed an iteration at least once.
|
||||
* This is checked because even if at alpha we want to
|
||||
* complete the cycle if not done once so that all
|
||||
* local states and canvasgroup settings are proper. */
|
||||
if (_completedOnce && CanvasGroup.alpha == targetAlpha)
|
||||
return;
|
||||
|
||||
float rate = (1f / duration);
|
||||
CanvasGroup.alpha = Mathf.MoveTowards(CanvasGroup.alpha, targetAlpha, rate * Time.deltaTime);
|
||||
|
||||
//If complete.
|
||||
if (CanvasGroup.alpha == targetAlpha)
|
||||
CompleteFade(fadingIn);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the fade completes.
|
||||
/// </summary>
|
||||
protected virtual void CompleteFade(bool fadingIn)
|
||||
{
|
||||
CanvasGroupBlockingType blockingType;
|
||||
float alpha;
|
||||
if (fadingIn)
|
||||
{
|
||||
blockingType = CanvasGroupBlockingType.Block;
|
||||
alpha = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
blockingType = CanvasGroupBlockingType.DoNotBlock;
|
||||
alpha = 0f;
|
||||
}
|
||||
|
||||
SetCanvasGroupBlockingType(blockingType);
|
||||
CanvasGroup.alpha = alpha;
|
||||
_completedOnce = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the CanvasGroups interactable and bloacking state.
|
||||
/// </summary>
|
||||
protected virtual void SetCanvasGroupBlockingType(CanvasGroupBlockingType blockingType)
|
||||
{
|
||||
if (UpdateCanvasBlocking)
|
||||
CanvasGroup.SetBlockingType(blockingType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6aa7bd78c33474948b74e3c7a1d97454
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f04cb37e5f34ee749b8be696cb9c6ba3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,59 @@
|
||||
|
||||
namespace GameKit.Utilities.Types.CanvasContainers
|
||||
{
|
||||
public class ButtonData : IResettable
|
||||
{
|
||||
#region Public.
|
||||
/// <summary>
|
||||
/// Text to place on the button.
|
||||
/// </summary>
|
||||
public string Text { get; protected set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// When not null this will be called when action is taken.
|
||||
/// </summary>
|
||||
/// <param name="key">Optional key to associate with callback.</param>
|
||||
public delegate void PressedDelegate(string key);
|
||||
/// <summary>
|
||||
/// Optional key to include within the callback.
|
||||
/// </summary>
|
||||
public string Key { get; protected set; } = string.Empty;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Delegate to invoke when pressed.
|
||||
/// </summary>
|
||||
private PressedDelegate _delegate = null;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this for use.
|
||||
/// </summary>
|
||||
/// <param name="text">Text to display on the button.</param>
|
||||
/// <param name="callback">Callback when OnPressed is called.</param>
|
||||
/// <param name="key">Optional key to include within the callback.</param>
|
||||
public void Initialize(string text, PressedDelegate callback, string key = "")
|
||||
{
|
||||
Text = text;
|
||||
Key = key;
|
||||
_delegate = callback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called whewn the button for this data is pressed.
|
||||
/// </summary>
|
||||
public virtual void OnPressed()
|
||||
{
|
||||
_delegate?.Invoke(Key);
|
||||
}
|
||||
|
||||
public virtual void ResetState()
|
||||
{
|
||||
Text = string.Empty;
|
||||
_delegate = null;
|
||||
Key = string.Empty;
|
||||
}
|
||||
|
||||
public void InitializeState() { }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1baacd2a6a8a0e94b897c6b7176c7000
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,232 @@
|
||||
using GameKit.Dependencies.Inspectors;
|
||||
using System.Runtime.CompilerServices;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace GameKit.Utilities.Types.CanvasContainers
|
||||
{
|
||||
|
||||
public class FloatingContainer : CanvasGroupFader
|
||||
{
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
/// RectTransform to move.
|
||||
/// </summary>
|
||||
[Tooltip("RectTransform to move.")]
|
||||
[SerializeField, Group("Components")]
|
||||
protected RectTransform RectTransform;
|
||||
/// <summary>
|
||||
/// True to use edge avoidance.
|
||||
/// </summary>
|
||||
[Tooltip("True to use edge avoidance.")]
|
||||
[SerializeField, Group("Sizing")]
|
||||
protected bool UseEdgeAvoidance = true;
|
||||
/// <summary>
|
||||
/// How much to avoid screen edges when being moved.
|
||||
/// </summary>
|
||||
[Tooltip("How much to avoid screen edges when being moved.")]
|
||||
[SerializeField, Group("Sizing"), ShowIf(nameof(UseEdgeAvoidance), true)]
|
||||
protected Vector2 EdgeAvoidance;
|
||||
#endregion
|
||||
|
||||
#region Private.
|
||||
/// <summary>
|
||||
/// Desired position.
|
||||
/// </summary>
|
||||
private Vector3 _positionGoal;
|
||||
/// <summary>
|
||||
/// Desired rotation.
|
||||
/// </summary>
|
||||
private Quaternion _rotationGoal;
|
||||
/// <summary>
|
||||
/// Desired scale.
|
||||
/// </summary>
|
||||
private Vector3 _scaleGoal = Vector3.one;
|
||||
/// <summary>
|
||||
/// How much edge avoidance to use.
|
||||
/// </summary>
|
||||
private Vector2? _edgeAvoidance;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Attachs a gameObject as a child of this object and sets transform valus to default.
|
||||
/// </summary>
|
||||
/// <param name="go">GameObject to attach.</param>
|
||||
public void AttachGameObject(GameObject go)
|
||||
{
|
||||
if (go == null)
|
||||
return;
|
||||
|
||||
Transform goT = go.transform;
|
||||
goT.SetParent(transform);
|
||||
goT.localPosition = Vector3.zero;
|
||||
goT.localRotation = Quaternion.identity;
|
||||
goT.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the container.
|
||||
/// </summary>
|
||||
/// <param name="position">Position to use.</param>
|
||||
/// <param name="rotation">Rotation to use.</param>
|
||||
/// <param name="scale">Scale to use.</param>
|
||||
/// <param name="pivot">Pivot for rectTransform.</param>
|
||||
/// <param name="edgeAvoidanceOverride">How far to keep the RectTransform from the edge. If null serialized avoidance will be used.</param>
|
||||
public virtual void Show(Vector3 position, Quaternion rotation, Vector3 scale, Vector2 pivot, Vector2? edgeAvoidanceOverride = null)
|
||||
{
|
||||
UpdateEdgeAvoidance(edgeAvoidanceOverride, false);
|
||||
UpdatePivot(pivot, false);
|
||||
UpdatePositionRotationAndScale(position, rotation, scale);
|
||||
base.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the container.
|
||||
/// </summary>
|
||||
/// <param name="position">Position to use.</param>
|
||||
/// <param name="edgeAvoidanceOverride">How far to keep the RectTransform from the edge. If null serialized avoidance will be used.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual void Show(Vector3 position, Vector2? edgeAvoidanceOverride = null)
|
||||
{
|
||||
Show(position, Quaternion.identity, Vector3.one, RectTransform.pivot);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the container.
|
||||
/// </summary>
|
||||
/// <param name="position">Position to use.</param>
|
||||
/// <param name="rotation">Rotation to use.</param>
|
||||
/// <param name="edgeAvoidanceOverride">How far to keep the RectTransform from the edge. If null serialized avoidance will be used.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual void Show(Vector3 position, Quaternion rotation, Vector2? edgeAvoidanceOverride = null)
|
||||
{
|
||||
Show(position, rotation, Vector3.one, RectTransform.pivot);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the container.
|
||||
/// </summary>
|
||||
/// <param name="startingPoint">Transform to use for position, rotation, and scale.</param>
|
||||
/// <param name="edgeAvoidanceOverride">How far to keep the RectTransform from the edge. If null serialized avoidance will be used.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual void Show(Transform startingPoint, Vector2? edgeAvoidanceOverride = null)
|
||||
{
|
||||
if (startingPoint == null)
|
||||
{
|
||||
Debug.LogError($"A null Transform cannot be used as the starting point.");
|
||||
return;
|
||||
}
|
||||
|
||||
Show(startingPoint.position, startingPoint.rotation, startingPoint.localScale, RectTransform.pivot);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the rectTransform pivot.
|
||||
/// </summary>
|
||||
/// <param name="pivot">New pivot.</param>
|
||||
/// <param name="move">True to move the RectTransform after updating.</param>
|
||||
public virtual void UpdatePivot(Vector2 pivot, bool move = true)
|
||||
{
|
||||
RectTransform.pivot = pivot;
|
||||
if (move)
|
||||
Move();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates to a new position.
|
||||
/// </summary>
|
||||
/// <param name="position">Next position.</param>
|
||||
/// <param name="move">True to move towards new position.</param>
|
||||
public virtual void UpdatePosition(Vector3 position, bool move = true)
|
||||
{
|
||||
_positionGoal = position;
|
||||
if (move)
|
||||
Move();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates to a new rotation.
|
||||
/// </summary>
|
||||
/// <param name="rotation">Next rotation.</param>
|
||||
public virtual void UpdateRotation(Quaternion rotation, bool move = true)
|
||||
{
|
||||
_rotationGoal = rotation;
|
||||
if (move)
|
||||
Move();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates to a new scale.
|
||||
/// </summary>
|
||||
/// <param name="scale">Next scale.</param>
|
||||
/// <param name="move">True to move the RectTransform after updating.</param>
|
||||
public virtual void UpdateScale(Vector3 scale, bool move = true)
|
||||
{
|
||||
_scaleGoal = scale;
|
||||
if (move)
|
||||
Move();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates to a new position and rotation.
|
||||
/// </summary>
|
||||
/// <param name="position">Next position.</param>
|
||||
/// <param name="rotation">Next rotation.</param>
|
||||
/// <param name="move">True to move the RectTransform after updating.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual void UpdatePositionAndRotation(Vector3 position, Quaternion rotation, bool move = true)
|
||||
{
|
||||
UpdatePosition(position, false);
|
||||
UpdateRotation(rotation, false);
|
||||
if (move)
|
||||
Move();
|
||||
}
|
||||
/// <summary>
|
||||
/// Updates to a new position, rotation, and scale.
|
||||
/// </summary>
|
||||
/// <param name="position">Next position.</param>
|
||||
/// <param name="rotation">Next rotation.</param>
|
||||
/// <param name="scale">Next scale.</param>
|
||||
/// <param name="move">True to move the RectTransform after updating.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public virtual void UpdatePositionRotationAndScale(Vector3 position, Quaternion rotation, Vector3 scale, bool move = true)
|
||||
{
|
||||
UpdatePositionAndRotation(position, rotation, false);
|
||||
UpdateScale(scale, false);
|
||||
Move();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates how much edge avoidance to use. When null serialized values are used.
|
||||
/// </summary>
|
||||
/// <param name="edgeAvoidanceOverride">How far to keep the RectTransform from the edge. If null serialized avoidance will be used.</param>
|
||||
/// <param name="move">True to move the RectTransform after updating.</param>
|
||||
public virtual void UpdateEdgeAvoidance(Vector2? edgeAvoidanceOverride = null, bool move = true)
|
||||
{
|
||||
_edgeAvoidance = (edgeAvoidanceOverride.HasValue) ? edgeAvoidanceOverride.Value : EdgeAvoidance;
|
||||
if (move)
|
||||
Move();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves to configured goals.
|
||||
/// </summary>
|
||||
protected virtual void Move()
|
||||
{
|
||||
//Update scale first so edge avoidance takes it into consideration.
|
||||
RectTransform.localScale = _scaleGoal;
|
||||
|
||||
Vector2 position = _positionGoal;
|
||||
if (UseEdgeAvoidance)
|
||||
{
|
||||
Vector2 avoidance = (_edgeAvoidance.HasValue) ? _edgeAvoidance.Value : EdgeAvoidance;
|
||||
position = RectTransform.GetOnScreenPosition(_positionGoal, avoidance);
|
||||
}
|
||||
|
||||
RectTransform.SetPositionAndRotation(position, _rotationGoal);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1fcd998728ace94ea809c34ad0d09e8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,35 @@
|
||||
using GameKit.Dependencies.Inspectors;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace GameKit.Utilities.Types.CanvasContainers
|
||||
{
|
||||
|
||||
public class FloatingImage : FloatingContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// Renderer to apply sprite on.
|
||||
/// </summary>
|
||||
[Tooltip("Renderer to apply sprite on.")]
|
||||
[SerializeField, Group("Components")]
|
||||
protected Image Renderer;
|
||||
|
||||
/// <summary>
|
||||
/// Sets which sprite to use.
|
||||
/// </summary>
|
||||
/// <param name="sprite">Sprite to use.</param>
|
||||
/// <param name="sizeOverride">When has value the renderer will be set to this size. Otherwise, the size of the sprite will be used. This value assumes the sprite anchors are set to center.</param>
|
||||
public virtual void SetSprite(Sprite sprite, Vector3? sizeOverride)
|
||||
{
|
||||
Renderer.sprite = sprite;
|
||||
Vector3 size = (sizeOverride == null)
|
||||
? (sprite.bounds.size * sprite.pixelsPerUnit)
|
||||
: sizeOverride.Value;
|
||||
|
||||
Renderer.rectTransform.sizeDelta = size;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2169e34ec7dd63a4e99b5cc89fd0e966
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,45 @@
|
||||
using GameKit.Utilities.Types;
|
||||
using GameKit.Utilities.Types.CanvasContainers;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace GameKit.Utilities.Types.OptionMenuButtons
|
||||
{
|
||||
|
||||
public class FloatingOptions : CanvasGroupFader
|
||||
{
|
||||
#region Protected.
|
||||
/// <summary>
|
||||
/// Current buttons.
|
||||
/// </summary>
|
||||
protected List<ButtonData> Buttons = new List<ButtonData>();
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Adds buttons.
|
||||
/// </summary>
|
||||
/// <param name="clearExisting">True to clear existing buttons first.</param>
|
||||
/// <param name="buttonDatas">Buttons to add.</param>
|
||||
protected virtual void AddButtons(bool clearExisting, IEnumerable<ButtonData> buttonDatas)
|
||||
{
|
||||
if (clearExisting)
|
||||
RemoveButtons();
|
||||
foreach (ButtonData item in buttonDatas)
|
||||
Buttons.Add(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all buttons.
|
||||
/// </summary>
|
||||
protected virtual void RemoveButtons()
|
||||
{
|
||||
foreach (ButtonData item in Buttons)
|
||||
GameKit.Utilities.ResettableObjectCaches<ButtonData>.Store(item);
|
||||
Buttons.Clear();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cbc5b08db621303449f60b59f56eac92
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities.Types.CanvasContainers
|
||||
{
|
||||
public class ImageButtonData : ButtonData
|
||||
{
|
||||
#region Public.
|
||||
/// <summary>
|
||||
/// Image to display.
|
||||
/// </summary>
|
||||
public Sprite DisplayImage { get; protected set; } = null;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this for use.
|
||||
/// </summary>
|
||||
/// <param name="sprite">Image to use on the button.</param>
|
||||
/// <param name="text">Text to display on the button.</param>
|
||||
/// <param name="callback">Callback when OnPressed is called.</param>
|
||||
/// <param name="key">Optional key to include within the callback.</param>
|
||||
public void Initialize(Sprite sprite, string text, PressedDelegate callback, string key = "")
|
||||
{
|
||||
base.Initialize(text, callback, key);
|
||||
DisplayImage = sprite;
|
||||
}
|
||||
|
||||
public override void ResetState()
|
||||
{
|
||||
base.ResetState();
|
||||
DisplayImage = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d60e355b6d09be14487df1ed91e901b2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
#if TEXTMESHPRO
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace GameKit.Utilities.Types.CanvasContainers
|
||||
{
|
||||
|
||||
public class OptionMenuImageButton : OptionMenuButton
|
||||
{
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
/// Image component to show image on.
|
||||
/// </summary>
|
||||
[Tooltip("Image component to show image on.")]
|
||||
[SerializeField]
|
||||
private Image _image;
|
||||
#endregion
|
||||
|
||||
public virtual void Initialize(ImageButtonData buttonData)
|
||||
{
|
||||
base.Initialize(buttonData);
|
||||
_image.sprite = buttonData.DisplayImage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2fee1d5cad375e84eaab6a4cd1d6e915
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
#if TEXTMESHPRO
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace GameKit.Utilities.Types.CanvasContainers
|
||||
{
|
||||
|
||||
public class OptionMenuButton : MonoBehaviour
|
||||
{
|
||||
#region Public.
|
||||
/// <summary>
|
||||
/// ButtonData for this button.
|
||||
/// </summary>
|
||||
public ButtonData ButtonData { get; protected set; }
|
||||
#endregion
|
||||
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
/// Text component to show button text.
|
||||
/// </summary>
|
||||
[Tooltip("Text component to show button text.")]
|
||||
[SerializeField]
|
||||
private TextMeshProUGUI _text;
|
||||
#endregion
|
||||
|
||||
public virtual void Initialize(ButtonData buttonData)
|
||||
{
|
||||
ButtonData = buttonData;
|
||||
_text.text = buttonData.Text;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22d4118a529704b49858d02b956dc48d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,111 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities.Types
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Gameplay canvases register to this manager.
|
||||
/// </summary>
|
||||
public class RectTransformResizer : MonoBehaviour
|
||||
{
|
||||
#region Types.
|
||||
public class ResizeData : IResettable
|
||||
{
|
||||
public byte Remaining;
|
||||
public ResizeDelegate Delegate;
|
||||
|
||||
public ResizeData()
|
||||
{
|
||||
Remaining = 2;
|
||||
}
|
||||
|
||||
public void InitializeState() { }
|
||||
|
||||
public void ResetState()
|
||||
{
|
||||
Remaining = 2;
|
||||
Delegate = null;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public.
|
||||
/// <summary>
|
||||
/// Delegate for resizing RectTransforms.
|
||||
/// </summary>
|
||||
/// <param name="complete">True if the resize iterations are complete. Typically show your visuals when true.</param>
|
||||
public delegate void ResizeDelegate(bool complete);
|
||||
#endregion
|
||||
|
||||
#region Private.
|
||||
/// <summary>
|
||||
/// Elements to resize.
|
||||
/// </summary>
|
||||
private List<ResizeData> _resizeDatas = new List<ResizeData>();
|
||||
/// <summary>
|
||||
/// Singleton instance of this class.
|
||||
/// </summary>
|
||||
private static RectTransformResizer _instance;
|
||||
#endregion
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
foreach (ResizeData item in _resizeDatas)
|
||||
ResettableObjectCaches<ResizeData>.Store(item);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
Resize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls pending resizeDatas.
|
||||
/// </summary>
|
||||
private void Resize()
|
||||
{
|
||||
for (int i = 0; i < _resizeDatas.Count; i++)
|
||||
{
|
||||
_resizeDatas[i].Remaining--;
|
||||
bool complete = (_resizeDatas[i].Remaining == 0);
|
||||
_resizeDatas[i].Delegate?.Invoke(complete);
|
||||
if (complete)
|
||||
{
|
||||
ResettableObjectCaches<ResizeData>.Store(_resizeDatas[i]);
|
||||
_resizeDatas.RemoveAt(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Used to call a delegate twice, over two frames.
|
||||
/// This is an easy way to resize RectTransforms multiple times as they will often fail after the first resize due to Unity limitations.
|
||||
/// Note: this work-around may not be required for newer Unity versions.
|
||||
/// </summary>
|
||||
/// <param name="del">Delegate to invoke when resizing completes.</param>
|
||||
public static void Resize(ResizeDelegate del)
|
||||
{
|
||||
//Check to make a singleton instance.
|
||||
if (_instance == null)
|
||||
{
|
||||
GameObject go = new GameObject(typeof(RectTransformResizer).Name);
|
||||
_instance = go.AddComponent<RectTransformResizer>();
|
||||
DontDestroyOnLoad(go);
|
||||
}
|
||||
|
||||
_instance.Resize_Internal(del);
|
||||
}
|
||||
private void Resize_Internal(ResizeDelegate del)
|
||||
{
|
||||
ResizeData rd = ResettableObjectCaches<ResizeData>.Retrieve();
|
||||
rd.Delegate = del;
|
||||
_instance._resizeDatas.Add(rd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4b4655d59b39584faed638f43d4d287
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace GameKit.Utilities.Types.CanvasContainers
|
||||
{
|
||||
|
||||
public class ResizableContainer : FloatingContainer
|
||||
{
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
/// Minimum and maximum range for widwth and height of the RectTransform.
|
||||
/// </summary>
|
||||
[Tooltip("Minimum and maximum range for width and height of the RectTransform.")]
|
||||
//[Foldout("Sizing")]
|
||||
public FloatRange2D SizeLimits = new FloatRange2D()
|
||||
{
|
||||
X = new FloatRange(0f, 999999f),
|
||||
Y = new FloatRange(0f, 999999f)
|
||||
};
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Sets a size, and resizes if needed.
|
||||
/// Other transform values must be set separately using inherited methods.
|
||||
/// </summary>
|
||||
/// <param name="size">New size to use.</param>
|
||||
/// <param name="ignoreSizeLimits">True to ignore serialized Size limits.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetSizeAndShow(Vector2 size, bool ignoreSizeLimits = false)
|
||||
{
|
||||
ResizeAndShow(size, ignoreSizeLimits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resizes this canvas.
|
||||
/// </summary>
|
||||
protected virtual void ResizeAndShow(Vector2 desiredSize, bool ignoreSizeLimits)
|
||||
{
|
||||
float widthRequired = desiredSize.x;
|
||||
float heightRequired = desiredSize.y;
|
||||
//Clamp width and height.
|
||||
widthRequired = Mathf.Clamp(widthRequired, SizeLimits.X.Minimum, SizeLimits.X.Maximum);
|
||||
heightRequired = Mathf.Clamp(heightRequired, SizeLimits.Y.Minimum, SizeLimits.Y.Maximum);
|
||||
base.RectTransform.sizeDelta = new Vector2(widthRequired, heightRequired);
|
||||
base.Move();
|
||||
base.Show();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5764e627642cf5643a3f4518d450840e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities.Types
|
||||
{
|
||||
|
||||
|
||||
public class DDOL : MonoBehaviour
|
||||
{
|
||||
#region Public.
|
||||
/// <summary>
|
||||
/// Singleton instance of this class.
|
||||
/// </summary>
|
||||
[Obsolete("Use GetDDOL().")] //Remove on 2023/06/01.
|
||||
public static DDOL Instance => GetDDOL();
|
||||
/// <summary>
|
||||
/// Created instance of DDOL.
|
||||
/// </summary>
|
||||
private static DDOL _instance;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current DDOL or creates one if not yet created.
|
||||
/// </summary>
|
||||
public static DDOL GetDDOL()
|
||||
{
|
||||
//Not yet made.
|
||||
if (_instance == null)
|
||||
{
|
||||
GameObject obj = new GameObject();
|
||||
obj.name = "FirstGearGames DDOL";
|
||||
DDOL ddol = obj.AddComponent<DDOL>();
|
||||
DontDestroyOnLoad(ddol);
|
||||
_instance = ddol;
|
||||
return ddol;
|
||||
}
|
||||
//Already made.
|
||||
else
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e0b25628cfd4f241a22a7c0ee2b932f
|
||||
timeCreated: 1528404670
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a4e1653f734aa924a947707391413c6c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,51 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities.Types.Editing
|
||||
{
|
||||
/* Source https://forum.unity.com/threads/how-to-link-scenes-in-the-inspector.383140/ */
|
||||
|
||||
[CustomPropertyDrawer(typeof(SceneAttribute))]
|
||||
public class SceneDrawer : PropertyDrawer
|
||||
{
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
if (property.propertyType == SerializedPropertyType.String)
|
||||
{
|
||||
SceneAsset sceneObject = AssetDatabase.LoadAssetAtPath<SceneAsset>(property.stringValue);
|
||||
|
||||
if (sceneObject == null && !string.IsNullOrEmpty(property.stringValue))
|
||||
{
|
||||
// try to load it from the build settings for legacy compatibility
|
||||
sceneObject = GetBuildSettingsSceneObject(property.stringValue);
|
||||
}
|
||||
if (sceneObject == null && !string.IsNullOrEmpty(property.stringValue))
|
||||
{
|
||||
Debug.Log($"Could not find scene {property.stringValue} in {property.propertyPath}, assign the proper scenes in your NetworkManager");
|
||||
}
|
||||
SceneAsset scene = (SceneAsset)EditorGUI.ObjectField(position, label, sceneObject, typeof(SceneAsset), true);
|
||||
|
||||
property.stringValue = AssetDatabase.GetAssetPath(scene);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.LabelField(position, label.text, "Use [Scene] with strings.");
|
||||
}
|
||||
}
|
||||
|
||||
protected SceneAsset GetBuildSettingsSceneObject(string sceneName)
|
||||
{
|
||||
foreach (EditorBuildSettingsScene buildScene in EditorBuildSettings.scenes)
|
||||
{
|
||||
SceneAsset sceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(buildScene.path);
|
||||
if (sceneAsset != null && sceneAsset.name == sceneName)
|
||||
{
|
||||
return sceneAsset;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c144891e57ef5054d9b7e03b82c00cf2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,40 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities.Types
|
||||
{
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public struct FloatRange
|
||||
{
|
||||
public FloatRange(float minimum, float maximum)
|
||||
{
|
||||
Minimum = minimum;
|
||||
Maximum = maximum;
|
||||
}
|
||||
/// <summary>
|
||||
/// Minimum range.
|
||||
/// </summary>
|
||||
public float Minimum;
|
||||
/// <summary>
|
||||
/// Maximum range.
|
||||
/// </summary>
|
||||
public float Maximum;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a random value between Minimum and Maximum.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public float RandomInclusive()
|
||||
{
|
||||
return Floats.RandomInclusiveRange(Minimum, Maximum);
|
||||
}
|
||||
|
||||
public float Lerp(float percent)
|
||||
{
|
||||
return Mathf.Lerp(Minimum, Maximum, percent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35d4414338c0ab248a1b838402887ac0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,58 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameKit.Utilities.Types
|
||||
{
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
|
||||
public struct FloatRange2D
|
||||
{
|
||||
public FloatRange X;
|
||||
public FloatRange Y;
|
||||
|
||||
public FloatRange2D(FloatRange x, FloatRange y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
|
||||
public FloatRange2D(float xMin, float xMax, float yMin, float yMax)
|
||||
{
|
||||
X = new FloatRange(xMin, xMax);
|
||||
Y = new FloatRange(yMin, yMax);
|
||||
}
|
||||
|
||||
public Vector2 Clamp(Vector2 original)
|
||||
{
|
||||
return new Vector2(
|
||||
ClampX(original.x),
|
||||
ClampY(original.y)
|
||||
);
|
||||
}
|
||||
|
||||
public Vector3 Clamp(Vector3 original)
|
||||
{
|
||||
return new Vector3(
|
||||
ClampX(original.x),
|
||||
ClampY(original.y),
|
||||
original.z
|
||||
);
|
||||
}
|
||||
|
||||
public float ClampX(float original)
|
||||
{
|
||||
return Mathf.Clamp(original, X.Minimum, X.Maximum);
|
||||
}
|
||||
|
||||
public float ClampY(float original)
|
||||
{
|
||||
return Mathf.Clamp(original, Y.Minimum, Y.Maximum);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a2c6d65e69e9154b8f99096ed3096dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,55 @@
|
||||
namespace GameKit.Utilities.Types
|
||||
{
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public struct IntRange
|
||||
{
|
||||
public IntRange(int minimum, int maximum)
|
||||
{
|
||||
Minimum = minimum;
|
||||
Maximum = maximum;
|
||||
}
|
||||
/// <summary>
|
||||
/// Minimum range.
|
||||
/// </summary>
|
||||
public int Minimum;
|
||||
/// <summary>
|
||||
/// Maximum range.
|
||||
/// </summary>
|
||||
public int Maximum;
|
||||
|
||||
/// <summary>
|
||||
/// Returns an exclusive random value between Minimum and Maximum.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public float RandomExclusive()
|
||||
{
|
||||
return Ints.RandomExclusiveRange(Minimum, Maximum);
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns an inclusive random value between Minimum and Maximum.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public float RandomInclusive()
|
||||
{
|
||||
return Ints.RandomInclusiveRange(Minimum, Maximum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns value clamped within minimum and maximum.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public int Clamp(int value)
|
||||
{
|
||||
if (value < Minimum)
|
||||
return Minimum;
|
||||
if (value > Maximum)
|
||||
return Maximum;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16f03af589a154c47bcbcc3f82b710a6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05bf45e6c53189b428920bb4f1f4244d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user