上传YomovSDK

This commit is contained in:
Sora丶kong
2026-03-03 03:15:46 +08:00
parent 9096da7e6c
commit eb97f31065
6477 changed files with 1932208 additions and 3 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aea01893c4a887048868eaa5b37c656a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,72 @@
fileFormatVersion: 2
guid: 1907658b89c1bbe42a0063df40b7ca24
labels:
- RoslynAnalyzer
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints:
- UNITY_2020_3_OR_NEWER
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 620557a5e202e644cb322b8fcc9422ea
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Abdelfattah-Radwan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 93ef12b9e040fa8429d9ef686212ed4e
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,2 @@
Git URL:
https://github.com/Abdelfattah-Radwan/FishNet.CodeAnalysis

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 835336ee0aec7ef41a1cfda40886f443
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a72c0fe8d07e9fd49911db527eddbc39
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cd9a0ca39fab66c448fdc3e25da9d482
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
{
"name": "GameKit.Dependencies"
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 36bccdedfe0feeb4daf43bef9e43b65b
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c8ce00cde8ada214fb582a92539f14b9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b43a8f6c3cc189c40ae6b248e76e2788
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c197d238762d66b41927449d5c48b3f4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 428419a625f80f6438c5b74beb2ac763
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bce51828adfc9b540b10914a9ec82c31
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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:

View File

@@ -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:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e3c02d1d5545ae54687d1a313ebb2fd6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 102b5a2337dae434f989eee1a6a1c571
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a8361a4f779768242840a9c994392e20
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1266c8c8d104aeb4faf3f1daaee87479
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 203e832301eed08499198358cfd13e7d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 53002e457d153bf49aad4b2b28d4353c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 54eb82a57a65e8548b57f5ca2a62bb76
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,96 @@
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>
/// <typeparam name="T"></typeparam>
/// <param name=""></param>
/// <param name="value"></param>
public static void AddUnique<T>(this List<T> list, object value)
{
if (!list.Contains((T)value))
list.Add((T)value);
}
/// <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;
}
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 1b93eae9ff81b3e4b892128ca4b392ed
timeCreated: 1530140103
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 602eeac4b016b174f90ae5e85254ac86
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c0e7937b287d3d24d807a115c1a3a464
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9d31d19bc39eb6041bad18d8eb68ed68
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a3a909760282d284591c20c873f20837
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: dd42f76391fc1254f82767dbf1a4bc8b
timeCreated: 1525378031
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

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

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: e6c66aec505f9254491b2b126a2d4745
timeCreated: 1522959833
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 4ab517aa5c3b6e34ca20461339adda04
timeCreated: 1526172456
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 17013b2a21298c14ea4808251346a38a
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3a54dd369b7206e4f9e7716a42e53454
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: c673118198f5c4b41986d52762828363
timeCreated: 1527268448
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 1c18e15e44d21a94d8919f4b6b125a1f
timeCreated: 1522349045
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e330113395c59ca4dba5de001e010f08
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 27a618c551d5fdb4ca70bf07e1905580
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 18a583dc22a9a0f4cabec0c4a0219c6e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,252 @@
using System;
using System.Collections.Generic;
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>
/// Holds cached Lists of value types.
/// </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.
/// </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();
CollectionCaches<T>.Store(value, count);
}
/// <summary>
/// Stores a collection.
/// </summary>
/// <param name="value">Value to store.</param>
public static void Store(List<T> value)
{
foreach (T item in value)
item.ResetState();
CollectionCaches<T>.Store(value);
}
/// <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();
CollectionCaches<T>.Store(value);
}
}
/// <summary>
/// Holds cached diposable types.
/// </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.
/// </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>
/// Holds cached Lists of value types.
/// </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.
/// </summary>
/// <param name="value">Value to store.</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.
/// </summary>
/// <param name="value">Value to store.</param>
public static void Store(List<T> value)
{
value.Clear();
_listCache.Push(value);
}
/// <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>
/// Holds cached types.
/// </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 a value to the stack.
/// </summary>
/// <param name="value"></param>
public static void Store(T value)
{
_stack.Push(value);
}
}
#endregion
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3cb13274f7491a941b6e89a767905f56
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,68 @@

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)
{
//If instance isn't null.
if (DDOL.Instance != null)
results.AddRange(DDOL.Instance.gameObject.GetComponentsInChildren<T>(includeInactive));
}
return results;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4fa6d28a28dbf6b4295602abad3de328
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5f3d973dcfa06554998575e8eef0938a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 02a9084f4f788cd4293cdff56a49b5dd
timeCreated: 1522043602
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: b396f2be4de550a4e92b552650311600
timeCreated: 1525378031
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ba23540de73f58b458e7d7a200f3bb30
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a29cd7621a70a044bb205cc8cfd96b3c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6aa7bd78c33474948b74e3c7a1d97454
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f04cb37e5f34ee749b8be696cb9c6ba3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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() { }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1baacd2a6a8a0e94b897c6b7176c7000
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f1fcd998728ace94ea809c34ad0d09e8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2169e34ec7dd63a4e99b5cc89fd0e966
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cbc5b08db621303449f60b59f56eac92
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d60e355b6d09be14487df1ed91e901b2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2fee1d5cad375e84eaab6a4cd1d6e915
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 22d4118a529704b49858d02b956dc48d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c4b4655d59b39584faed638f43d4d287
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5764e627642cf5643a3f4518d450840e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
using UnityEngine;
namespace GameKit.Utilities.Types
{
public class DDOL : MonoBehaviour
{
#region Public.
/// <summary>
/// Singleton instance of this class.
/// </summary>
public static DDOL Instance { get; private set; }
#endregion
private void Awake()
{
FirstInitialize();
}
/// <summary>
/// Initializes this script for use. Should only be completed once.
/// </summary>
private void FirstInitialize()
{
if (Instance != null && Instance != this)
{
Debug.LogError("Multiple DDOL scripts found. There should be only one.");
return;
}
else
{
Instance = this;
gameObject.name = "FirstGearGames DDOL";
DontDestroyOnLoad(gameObject);
}
}
/// <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();
DDOL ddol = obj.AddComponent<DDOL>();
return ddol;
}
//Already made.
else
{
return Instance;
}
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 4e0b25628cfd4f241a22a7c0ee2b932f
timeCreated: 1528404670
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More