Insanely huge initial commit

This commit is contained in:
2026-02-21 17:04:05 -08:00
parent 9cdd36191a
commit 613d75914a
22525 changed files with 4035207 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// Array helpers
/// </summary>
public class MMArray : MonoBehaviour
{
/// <summary>
/// Rounds an int to the closest int in an array (array has to be sorted)
/// </summary>
/// <param name="value"></param>
/// <param name="array"></param>
/// <returns></returns>
public static int RoundIntToArray(int value, int[] array)
{
int min = 0;
if (array[min] >= value) return array[min];
int max = array.Length - 1;
if (array[max] <= value) return array[max];
while (max - min > 1)
{
int mid = (max + min) / 2;
if (array[mid] == value)
{
return array[mid];
}
else if (array[mid] < value)
{
min = mid;
}
else
{
max = mid;
}
}
if (array[max] - value <= value - array[min])
{
return array[max];
}
else
{
return array[min];
}
}
/// <summary>
/// Rounds a float to the closest float in an array (array has to be sorted)
/// </summary>
/// <param name="value"></param>
/// <param name="array"></param>
/// <returns></returns>
public static float RoundFloatToArray(float value, float[] array)
{
int min = 0;
if (array[min] >= value) return array[min];
int max = array.Length - 1;
if (array[max] <= value) return array[max];
while (max - min > 1)
{
int mid = (max + min) / 2;
if (array[mid] == value)
{
return array[mid];
}
else if (array[mid] < value)
{
min = mid;
}
else
{
max = mid;
}
}
if (array[max] - value <= value - array[min])
{
return array[max];
}
else
{
return array[min];
}
}
}
}

View File

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

View File

@@ -0,0 +1,396 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace MoreMountains.Tools
{
/// <summary>
/// Color helpers
/// </summary>
public static class MMColors
{
// via https://gist.github.com/LotteMakesStuff/f7ce43f11e545a151b95b5e87f76304c
// NOTE: The follwing color names come from the CSS3 specification, Section 4.3 Extended Color Keywords
// http://www.w3.org/TR/css3-color/#svg-color
public static readonly Color ReunoYellow = new Color32(255, 196, 0, 255);
public static readonly Color BestRed = new Color32(255, 24, 0, 255);
public static readonly Color AliceBlue = new Color32(240, 248, 255, 255);
public static readonly Color AntiqueWhite = new Color32(250, 235, 215, 255);
public static readonly Color Aqua = new Color32(0, 255, 255, 255);
public static readonly Color Aquamarine = new Color32(127, 255, 212, 255);
public static readonly Color Azure = new Color32(240, 255, 255, 255);
public static readonly Color Beige = new Color32(245, 245, 220, 255);
public static readonly Color Bisque = new Color32(255, 228, 196, 255);
public static readonly Color Black = new Color32(0, 0, 0, 255);
public static readonly Color BlanchedAlmond = new Color32(255, 235, 205, 255);
public static readonly Color Blue = new Color32(0, 0, 255, 255);
public static readonly Color BlueViolet = new Color32(138, 43, 226, 255);
public static readonly Color Brown = new Color32(165, 42, 42, 255);
public static readonly Color Burlywood = new Color32(222, 184, 135, 255);
public static readonly Color CadetBlue = new Color32(95, 158, 160, 255);
public static readonly Color Chartreuse = new Color32(127, 255, 0, 255);
public static readonly Color Chocolate = new Color32(210, 105, 30, 255);
public static readonly Color Coral = new Color32(255, 127, 80, 255);
public static readonly Color CornflowerBlue = new Color32(100, 149, 237, 255);
public static readonly Color Cornsilk = new Color32(255, 248, 220, 255);
public static readonly Color Crimson = new Color32(220, 20, 60, 255);
public static readonly Color Cyan = new Color32(0, 255, 255, 255);
public static readonly Color DarkBlue = new Color32(0, 0, 139, 255);
public static readonly Color DarkCyan = new Color32(0, 139, 139, 255);
public static readonly Color DarkGoldenrod = new Color32(184, 134, 11, 255);
public static readonly Color DarkGray = new Color32(169, 169, 169, 255);
public static readonly Color DarkGreen = new Color32(0, 100, 0, 255);
public static readonly Color DarkKhaki = new Color32(189, 183, 107, 255);
public static readonly Color DarkMagenta = new Color32(139, 0, 139, 255);
public static readonly Color DarkOliveGreen = new Color32(85, 107, 47, 255);
public static readonly Color DarkOrange = new Color32(255, 140, 0, 255);
public static readonly Color DarkOrchid = new Color32(153, 50, 204, 255);
public static readonly Color DarkRed = new Color32(139, 0, 0, 255);
public static readonly Color DarkSalmon = new Color32(233, 150, 122, 255);
public static readonly Color DarkSeaGreen = new Color32(143, 188, 143, 255);
public static readonly Color DarkSlateBlue = new Color32(72, 61, 139, 255);
public static readonly Color DarkSlateGray = new Color32(47, 79, 79, 255);
public static readonly Color DarkTurquoise = new Color32(0, 206, 209, 255);
public static readonly Color DarkViolet = new Color32(148, 0, 211, 255);
public static readonly Color DeepPink = new Color32(255, 20, 147, 255);
public static readonly Color DeepSkyBlue = new Color32(0, 191, 255, 255);
public static readonly Color DimGray = new Color32(105, 105, 105, 255);
public static readonly Color DodgerBlue = new Color32(30, 144, 255, 255);
public static readonly Color FireBrick = new Color32(178, 34, 34, 255);
public static readonly Color FloralWhite = new Color32(255, 250, 240, 255);
public static readonly Color ForestGreen = new Color32(34, 139, 34, 255);
public static readonly Color Fuchsia = new Color32(255, 0, 255, 255);
public static readonly Color Gainsboro = new Color32(220, 220, 220, 255);
public static readonly Color GhostWhite = new Color32(248, 248, 255, 255);
public static readonly Color Gold = new Color32(255, 215, 0, 255);
public static readonly Color Goldenrod = new Color32(218, 165, 32, 255);
public static readonly Color Gray = new Color32(128, 128, 128, 255);
public static readonly Color Green = new Color32(0, 128, 0, 255);
public static readonly Color GreenYellow = new Color32(173, 255, 47, 255);
public static readonly Color Honeydew = new Color32(240, 255, 240, 255);
public static readonly Color HotPink = new Color32(255, 105, 180, 255);
public static readonly Color IndianRed = new Color32(205, 92, 92, 255);
public static readonly Color Indigo = new Color32(75, 0, 130, 255);
public static readonly Color Ivory = new Color32(255, 255, 240, 255);
public static readonly Color Khaki = new Color32(240, 230, 140, 255);
public static readonly Color Lavender = new Color32(230, 230, 250, 255);
public static readonly Color Lavenderblush = new Color32(255, 240, 245, 255);
public static readonly Color LawnGreen = new Color32(124, 252, 0, 255);
public static readonly Color LemonChiffon = new Color32(255, 250, 205, 255);
public static readonly Color LightBlue = new Color32(173, 216, 230, 255);
public static readonly Color LightCoral = new Color32(240, 128, 128, 255);
public static readonly Color LightCyan = new Color32(224, 255, 255, 255);
public static readonly Color LightGoldenodYellow = new Color32(250, 250, 210, 255);
public static readonly Color LightGray = new Color32(211, 211, 211, 255);
public static readonly Color LightGreen = new Color32(144, 238, 144, 255);
public static readonly Color LightPink = new Color32(255, 182, 193, 255);
public static readonly Color LightSalmon = new Color32(255, 160, 122, 255);
public static readonly Color LightSeaGreen = new Color32(32, 178, 170, 255);
public static readonly Color LightSkyBlue = new Color32(135, 206, 250, 255);
public static readonly Color LightSlateGray = new Color32(119, 136, 153, 255);
public static readonly Color LightSteelBlue = new Color32(176, 196, 222, 255);
public static readonly Color LightYellow = new Color32(255, 255, 224, 255);
public static readonly Color Lime = new Color32(0, 255, 0, 255);
public static readonly Color LimeGreen = new Color32(50, 205, 50, 255);
public static readonly Color Linen = new Color32(250, 240, 230, 255);
public static readonly Color Magenta = new Color32(255, 0, 255, 255);
public static readonly Color Maroon = new Color32(128, 0, 0, 255);
public static readonly Color MediumAquamarine = new Color32(102, 205, 170, 255);
public static readonly Color MediumBlue = new Color32(0, 0, 205, 255);
public static readonly Color MediumOrchid = new Color32(186, 85, 211, 255);
public static readonly Color MediumPurple = new Color32(147, 112, 219, 255);
public static readonly Color MediumSeaGreen = new Color32(60, 179, 113, 255);
public static readonly Color MediumSlateBlue = new Color32(123, 104, 238, 255);
public static readonly Color MediumSpringGreen = new Color32(0, 250, 154, 255);
public static readonly Color MediumTurquoise = new Color32(72, 209, 204, 255);
public static readonly Color MediumVioletRed = new Color32(199, 21, 133, 255);
public static readonly Color MidnightBlue = new Color32(25, 25, 112, 255);
public static readonly Color Mintcream = new Color32(245, 255, 250, 255);
public static readonly Color MistyRose = new Color32(255, 228, 225, 255);
public static readonly Color Moccasin = new Color32(255, 228, 181, 255);
public static readonly Color NavajoWhite = new Color32(255, 222, 173, 255);
public static readonly Color Navy = new Color32(0, 0, 128, 255);
public static readonly Color OldLace = new Color32(253, 245, 230, 255);
public static readonly Color Olive = new Color32(128, 128, 0, 255);
public static readonly Color Olivedrab = new Color32(107, 142, 35, 255);
public static readonly Color Orange = new Color32(255, 165, 0, 255);
public static readonly Color Orangered = new Color32(255, 69, 0, 255);
public static readonly Color Orchid = new Color32(218, 112, 214, 255);
public static readonly Color PaleGoldenrod = new Color32(238, 232, 170, 255);
public static readonly Color PaleGreen = new Color32(152, 251, 152, 255);
public static readonly Color PaleTurquoise = new Color32(175, 238, 238, 255);
public static readonly Color PaleVioletred = new Color32(219, 112, 147, 255);
public static readonly Color PapayaWhip = new Color32(255, 239, 213, 255);
public static readonly Color PeachPuff = new Color32(255, 218, 185, 255);
public static readonly Color Peru = new Color32(205, 133, 63, 255);
public static readonly Color Pink = new Color32(255, 192, 203, 255);
public static readonly Color Plum = new Color32(221, 160, 221, 255);
public static readonly Color PowderBlue = new Color32(176, 224, 230, 255);
public static readonly Color Purple = new Color32(128, 0, 128, 255);
public static readonly Color Red = new Color32(255, 0, 0, 255);
public static readonly Color RosyBrown = new Color32(188, 143, 143, 255);
public static readonly Color RoyalBlue = new Color32(65, 105, 225, 255);
public static readonly Color SaddleBrown = new Color32(139, 69, 19, 255);
public static readonly Color Salmon = new Color32(250, 128, 114, 255);
public static readonly Color SandyBrown = new Color32(244, 164, 96, 255);
public static readonly Color SeaGreen = new Color32(46, 139, 87, 255);
public static readonly Color Seashell = new Color32(255, 245, 238, 255);
public static readonly Color Sienna = new Color32(160, 82, 45, 255);
public static readonly Color Silver = new Color32(192, 192, 192, 255);
public static readonly Color SkyBlue = new Color32(135, 206, 235, 255);
public static readonly Color SlateBlue = new Color32(106, 90, 205, 255);
public static readonly Color SlateGray = new Color32(112, 128, 144, 255);
public static readonly Color Snow = new Color32(255, 250, 250, 255);
public static readonly Color SpringGreen = new Color32(0, 255, 127, 255);
public static readonly Color SteelBlue = new Color32(70, 130, 180, 255);
public static readonly Color Tan = new Color32(210, 180, 140, 255);
public static readonly Color Teal = new Color32(0, 128, 128, 255);
public static readonly Color Thistle = new Color32(216, 191, 216, 255);
public static readonly Color Tomato = new Color32(255, 99, 71, 255);
public static readonly Color Turquoise = new Color32(64, 224, 208, 255);
public static readonly Color Violet = new Color32(238, 130, 238, 255);
public static readonly Color Wheat = new Color32(245, 222, 179, 255);
public static readonly Color White = new Color32(255, 255, 255, 255);
public static readonly Color WhiteSmoke = new Color32(245, 245, 245, 255);
public static readonly Color Yellow = new Color32(255, 255, 0, 255);
public static readonly Color YellowGreen = new Color32(154, 205, 50, 255);
public static Dictionary<int, Color> ColorDictionary;
public static Color RandomColor()
{
int random = Random.Range(0, 140);
return GetColorAt(random);
}
public static Color GetColorAt(int index)
{
if (ColorDictionary == null)
{
InitializeDictionary();
}
if (index < ColorDictionary.Count)
{
return ColorDictionary[index];
}
else
{
return Color.white;
}
}
public static void InitializeDictionary()
{
ColorDictionary = new Dictionary<int, Color>
{
{ 0, AliceBlue },
{ 1, AntiqueWhite },
{ 2, Aqua },
{ 3, Aquamarine },
{ 4, Azure },
{ 5, Beige },
{ 6, Bisque },
{ 7, Black },
{ 8, BlanchedAlmond },
{ 9, Blue },
{ 10, BlueViolet },
{ 11, Brown },
{ 12, Burlywood },
{ 13, CadetBlue },
{ 14, Chartreuse },
{ 15, Chocolate },
{ 16, Coral },
{ 17, CornflowerBlue },
{ 18, Cornsilk },
{ 19, Crimson },
{ 20, Cyan },
{ 21, DarkBlue },
{ 22, DarkCyan },
{ 23, DarkGoldenrod },
{ 24, DarkGray },
{ 25, DarkGreen },
{ 26, DarkKhaki },
{ 27, DarkMagenta },
{ 28, DarkOliveGreen },
{ 29, DarkOrange },
{ 30, DarkOrchid },
{ 31, DarkRed },
{ 32, DarkSalmon },
{ 33, DarkSeaGreen },
{ 34, DarkSlateBlue },
{ 35, DarkSlateGray },
{ 36, DarkTurquoise },
{ 37, DarkViolet },
{ 38, DeepPink },
{ 39, DeepSkyBlue },
{ 40, DimGray },
{ 41, DodgerBlue },
{ 42, FireBrick },
{ 43, FloralWhite },
{ 44, ForestGreen },
{ 45, Fuchsia },
{ 46, Gainsboro },
{ 47, GhostWhite },
{ 48, Gold },
{ 49, Goldenrod },
{ 50, Gray },
{ 51, Green },
{ 52, GreenYellow },
{ 53, Honeydew },
{ 54, HotPink },
{ 55, IndianRed },
{ 56, Indigo },
{ 57, Ivory },
{ 58, Khaki },
{ 59, Lavender },
{ 60, Lavenderblush },
{ 61, LawnGreen },
{ 62, LemonChiffon },
{ 63, LightBlue },
{ 64, LightCoral },
{ 65, LightCyan },
{ 66, LightGoldenodYellow },
{ 67, LightGray },
{ 68, LightGreen },
{ 69, LightPink },
{ 70, LightSalmon },
{ 71, LightSeaGreen },
{ 72, LightSkyBlue },
{ 73, LightSlateGray },
{ 74, LightSteelBlue },
{ 75, LightYellow },
{ 76, Lime },
{ 77, LimeGreen },
{ 78, Linen },
{ 79, Magenta },
{ 80, Maroon },
{ 81, MediumAquamarine },
{ 82, MediumBlue },
{ 83, MediumOrchid },
{ 84, MediumPurple },
{ 85, MediumSeaGreen },
{ 86, MediumSlateBlue },
{ 87, MediumSpringGreen },
{ 88, MediumTurquoise },
{ 89, MediumVioletRed },
{ 90, MidnightBlue },
{ 91, Mintcream },
{ 92, MistyRose },
{ 93, Moccasin },
{ 94, NavajoWhite },
{ 95, Navy },
{ 96, OldLace },
{ 97, Olive },
{ 98, Olivedrab },
{ 99, Orange },
{ 100, Orangered },
{ 101, Orchid },
{ 102, PaleGoldenrod },
{ 103, PaleGreen },
{ 104, PaleTurquoise },
{ 105, PaleVioletred },
{ 106, PapayaWhip },
{ 107, PeachPuff },
{ 108, Peru },
{ 109, Pink },
{ 110, Plum },
{ 111, PowderBlue },
{ 112, Purple },
{ 113, Red },
{ 114, RosyBrown },
{ 115, RoyalBlue },
{ 116, SaddleBrown },
{ 117, Salmon },
{ 118, SandyBrown },
{ 119, SeaGreen },
{ 120, Seashell },
{ 121, Sienna },
{ 122, Silver },
{ 123, SkyBlue },
{ 124, SlateBlue },
{ 125, SlateGray },
{ 126, Snow },
{ 127, SpringGreen },
{ 128, SteelBlue },
{ 129, Tan },
{ 130, Teal },
{ 131, Thistle },
{ 132, Tomato },
{ 133, Turquoise },
{ 134, Violet },
{ 135, Wheat },
{ 136, White },
{ 137, WhiteSmoke },
{ 138, Yellow },
{ 139, YellowGreen },
{ 140, ReunoYellow },
{ 141, BestRed }
};
}
/// <summary>
/// Returns a random color between the two min/max specified
/// </summary>
/// <param name="color"></param>
/// <param name="min"></param>
/// <param name="max"></param>
/// <returns></returns>
public static Color MMRandomColor(this Color color, Color min, Color max)
{
Color c = new Color()
{
r = UnityEngine.Random.Range(min.r, max.r),
g = UnityEngine.Random.Range(min.g, max.g),
b = UnityEngine.Random.Range(min.b, max.b),
a = UnityEngine.Random.Range(min.a, max.a)
};
return c;
}
/// <summary>
/// Tint : Uses HSV color conversions, keeps the original values, multiplies alpha
/// Multiply : The whole color, including alpha, is multiplied over the original
/// Replace : completely replaces the original with the target color
/// ReplaceKeepAlpha : color is replaced but the original alpha channel is ignored
/// Add : target color gets added (including its alpha)
/// </summary>
public enum ColoringMode { Tint, Multiply, Replace, ReplaceKeepAlpha, Add }
public static Color MMColorize(this Color originalColor, Color targetColor, ColoringMode coloringMode, float lerpAmount = 1.0f)
{
Color resultColor = Color.white;
switch (coloringMode)
{
case ColoringMode.Tint:
{
float s_h, s_s, s_v, t_h, t_s, t_v;
Color.RGBToHSV(originalColor, out s_h, out s_s, out s_v);
Color.RGBToHSV(targetColor, out t_h, out t_s, out t_v);
resultColor = Color.HSVToRGB(t_h, t_s, s_v * t_v);
resultColor.a = originalColor.a * targetColor.a;
}
break;
case ColoringMode.Multiply:
resultColor = originalColor * targetColor;
break;
case ColoringMode.Replace:
resultColor = targetColor;
break;
case ColoringMode.ReplaceKeepAlpha:
resultColor = targetColor;
resultColor.a = originalColor.a;
break;
case ColoringMode.Add:
resultColor = originalColor + targetColor;
break;
default:
break;
}
return Color.Lerp(originalColor, resultColor, lerpAmount);
}
}
}

View File

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

View File

@@ -0,0 +1,106 @@
using UnityEngine;
using System.Collections;
namespace MoreMountains.Tools
{
/// <summary>
/// This class displays an on-screen console for easier debugging
/// DO NOT ADD THIS CLASS AS A COMPONENT.
/// Instead, use the MMDebug.DebugOnScreen methods that will take care of everything
/// </summary>
public class MMConsole : MonoBehaviour
{
protected string _messageStack;
protected int _numberOfMessages=0;
protected bool _messageStackHasBeenDisplayed=false;
protected int _largestMessageLength=0;
protected int _marginTop = 10;
protected int _marginLeft = 10;
protected int _padding = 10;
protected int _fontSize = 10;
protected int _characterHeight = 16;
protected int _characterWidth = 6;
/// <summary>
/// Draws a box containing the current stack of messages on top of the screen.
/// </summary>
protected virtual void OnGUI()
{
// we define the style to use and the font size
GUIStyle style = GUI.skin.GetStyle ("label");
style.fontSize = _fontSize;
// we determine our box dimension based on the number of lines and the length of the longest line
int boxHeight = _numberOfMessages*_characterHeight;
int boxWidth = _largestMessageLength * _characterWidth;
// we draw a box and the message on top of it
GUI.Box (new Rect (_marginLeft,_marginTop,boxWidth+_padding*2,boxHeight+_padding*2), "");
GUI.Label(new Rect(_marginLeft+_padding, _marginTop+_padding, boxWidth, boxHeight), _messageStack);
// we set our flag to true, which will trigger the reset of the stack next time it's accessed
_messageStackHasBeenDisplayed=true;
}
/// <summary>
/// Sets the size of the font, and automatically deduces the character's height and width.
/// </summary>
/// <param name="fontSize">Font size.</param>
public virtual void SetFontSize(int fontSize)
{
_fontSize = fontSize;
_characterHeight = (int)Mathf.Round(1.6f * fontSize + 0.49f);
_characterWidth = (int)Mathf.Round(0.6f * fontSize + 0.49f);
}
/// <summary>
/// Sets the screen offset, from the top left corner
/// </summary>
/// <param name="top"></param>
/// <param name="left"></param>
public virtual void SetScreenOffset(int top = 10, int left = 10)
{
_marginTop = top;
_marginLeft = left;
}
/// <summary>
/// Replaces the content of the current message stack with the specified string
/// </summary>
/// <param name="newMessage">New message.</param>
public virtual void SetMessage(string newMessage)
{
_messageStack=newMessage;
_numberOfMessages=1;
}
/// <summary>
/// Adds the specified message to the message stack.
/// </summary>
/// <param name="newMessage">New message.</param>
public virtual void AddMessage(string newMessage)
{
// if the message stack has been displayed, we empty it and reset our counters
if (_messageStackHasBeenDisplayed)
{
_messageStack="";
_messageStackHasBeenDisplayed=false;
_numberOfMessages=0;
_largestMessageLength=0;
}
// we add the specified message to the stack
_messageStack += newMessage+"\n";
// if this new message is longer than our previous longer message, we store it (this will expand the box's width
if (newMessage.Length > _largestMessageLength)
{
_largestMessageLength = newMessage.Length;
}
// we increment our counter
_numberOfMessages++;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 878e38786f84b4cb2befd22693a97a33
timeCreated: 1455961502
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Tools
{
public static class MMCoroutine
{
/// <summary>
/// Waits for the specified amount of frames
/// use : yield return MMCoroutine.WaitFor(1);
/// </summary>
/// <param name="frameCount"></param>
/// <returns></returns>
public static IEnumerator WaitForFrames(int frameCount)
{
while (frameCount > 0)
{
frameCount--;
yield return null;
}
}
/// <summary>
/// Waits for the specified amount of seconds (using regular time)
/// use : yield return MMCoroutine.WaitFor(1f);
/// </summary>
/// <param name="seconds"></param>
/// <returns></returns>
public static IEnumerator WaitFor(float seconds)
{
for (float timer = 0f; timer < seconds; timer += Time.deltaTime)
{
yield return null;
}
}
/// <summary>
/// Waits for the specified amount of seconds (using unscaled time)
/// use : yield return MMCoroutine.WaitForUnscaled(1f);
/// </summary>
/// <param name="seconds"></param>
/// <returns></returns>
public static IEnumerator WaitForUnscaled(float seconds)
{
for (float timer = 0f; timer < seconds; timer += Time.unscaledDeltaTime)
{
yield return null;
}
}
}
}

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d584bb96f63ba3848ab128ed5686f2f7
timeCreated: 1455815182
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,128 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
namespace MoreMountains.Tools
{
/// <summary>
/// Fade helpers
/// </summary>
public static class MMFade
{
/// <summary>
/// Fades the specified image to the target opacity and duration.
/// </summary>
/// <param name="target">Target.</param>
/// <param name="opacity">Opacity.</param>
/// <param name="duration">Duration.</param>
public static IEnumerator FadeImage(Image target, float duration, Color color)
{
if (target==null)
yield break;
float alpha = target.color.a;
for (float t = 0.0f; t < 1.0f; t += Time.deltaTime / duration)
{
if (target==null)
yield break;
Color newColor = new Color(color.r, color.g, color.b, Mathf.SmoothStep(alpha,color.a,t));
target.color=newColor;
yield return null;
}
target.color=color;
}
/// <summary>
/// Fades the specified image to the target opacity and duration.
/// </summary>
/// <param name="target">Target.</param>
/// <param name="opacity">Opacity.</param>
/// <param name="duration">Duration.</param>
public static IEnumerator FadeText(Text target, float duration, Color color)
{
if (target==null)
yield break;
float alpha = target.color.a;
for (float t = 0.0f; t < 1.0f; t += Time.deltaTime / duration)
{
if (target==null)
yield break;
Color newColor = new Color(color.r, color.g, color.b, Mathf.SmoothStep(alpha,color.a,t));
target.color=newColor;
yield return null;
}
target.color=color;
}
/// <summary>
/// Fades the specified image to the target opacity and duration.
/// </summary>
/// <param name="target">Target.</param>
/// <param name="opacity">Opacity.</param>
/// <param name="duration">Duration.</param>
public static IEnumerator FadeSprite(SpriteRenderer target, float duration, Color color)
{
if (target==null)
yield break;
float alpha = target.material.color.a;
float t=0f;
while (t<1.0f)
{
if (target==null)
yield break;
Color newColor = new Color(color.r, color.g, color.b, Mathf.SmoothStep(alpha,color.a,t));
target.material.color=newColor;
t += Time.deltaTime / duration;
yield return null;
}
Color finalColor = new Color(color.r, color.g, color.b, Mathf.SmoothStep(alpha,color.a,t));
if (target != null)
{
target.material.color=finalColor;
}
}
public static IEnumerator FadeCanvasGroup(CanvasGroup target, float duration, float targetAlpha, bool unscaled = true)
{
if (target==null)
yield break;
float currentAlpha = target.alpha;
float t=0f;
while (t<1.0f)
{
if (target==null)
yield break;
float newAlpha = Mathf.SmoothStep(currentAlpha,targetAlpha,t);
target.alpha=newAlpha;
if (unscaled)
{
t += Time.unscaledDeltaTime / duration;
}
else
{
t += Time.deltaTime / duration;
}
yield return null;
}
target.alpha=targetAlpha;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c55f5c5831b7b344bb8ae4b4471d7253
timeCreated: 1455815269
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
using UnityEngine.EventSystems;
namespace MoreMountains.Tools
{
public static class MMGUI
{
/// <summary>
/// Sets the size of a rect transform to the specified one
/// </summary>
/// <param name="rectTransform"></param>
/// <param name="newSize"></param>
public static void SetSize(RectTransform rectTransform, Vector2 newSize)
{
Vector2 currSize = rectTransform.rect.size;
Vector2 sizeDiff = newSize - currSize;
rectTransform.offsetMin = rectTransform.offsetMin - new Vector2(sizeDiff.x * rectTransform.pivot.x, sizeDiff.y * rectTransform.pivot.y);
rectTransform.offsetMax = rectTransform.offsetMax + new Vector2(sizeDiff.x * (1.0f - rectTransform.pivot.x), sizeDiff.y * (1.0f - rectTransform.pivot.y));
}
/// <summary>
/// Returns true if the pointer or first touch is blocked by UI
/// </summary>
/// <returns></returns>
public static bool PointOrTouchBlockedByUI()
{
if (EventSystem.current.IsPointerOverGameObject())
{
return true;
}
if (Input.touchCount > 0 && Input.touches[0].phase == TouchPhase.Began )
{
if (EventSystem.current.IsPointerOverGameObject(Input.touches[0].fingerId))
{
return true;
}
}
return false;
}
/// <summary>
/// Creates a texture of the specified size and color
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="color"></param>
/// <returns></returns>
public static Texture2D MakeTex(int width, int height, Color color)
{
Color[] pixelColors = new Color[width * height];
for (int i = 0; i < pixelColors.Length; i++)
{
pixelColors[i] = color;
}
Texture2D newTexture = new Texture2D(width, height);
newTexture.SetPixels(pixelColors);
newTexture.Apply();
return newTexture;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 45ff1ad6fa9e7af4ead4e1db1ed52877
timeCreated: 1460813345
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,89 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// A helper class to handle geometry related operations
/// </summary>
public static class MMGeometry
{
// Based on https://answers.unity.com/questions/1019436/get-outeredge-vertices-c.html
public struct MMEdge
{
public int Vertice1;
public int Vertice2;
public int TriangleIndex;
public MMEdge(int aV1, int aV2, int aIndex)
{
Vertice1 = aV1;
Vertice2 = aV2;
TriangleIndex = aIndex;
}
}
public static List<MMEdge> GetEdges(int[] indices)
{
List<MMEdge> edgeList = new List<MMEdge>();
for (int i = 0; i < indices.Length; i += 3)
{
int vertice1 = indices[i];
int vertice2 = indices[i + 1];
int vertice3 = indices[i + 2];
edgeList.Add(new MMEdge(vertice1, vertice2, i));
edgeList.Add(new MMEdge(vertice2, vertice3, i));
edgeList.Add(new MMEdge(vertice3, vertice1, i));
}
return edgeList;
}
public static List<MMEdge> FindBoundary(this List<MMEdge> edges)
{
List<MMEdge> edgeList = new List<MMEdge>(edges);
for (int i = edgeList.Count - 1; i > 0; i--)
{
for (int n = i - 1; n >= 0; n--)
{
// if we find a shared edge we remove both
if (edgeList[i].Vertice1 == edgeList[n].Vertice2 && edgeList[i].Vertice2 == edgeList[n].Vertice1)
{
edgeList.RemoveAt(i);
edgeList.RemoveAt(n);
i--;
break;
}
}
}
return edgeList;
}
public static List<MMEdge> SortEdges(this List<MMEdge> edges)
{
List<MMEdge> edgeList = new List<MMEdge>(edges);
for (int i = 0; i < edgeList.Count - 2; i++)
{
MMEdge E = edgeList[i];
for (int n = i + 1; n < edgeList.Count; n++)
{
MMEdge a = edgeList[n];
if (E.Vertice2 == a.Vertice1)
{
if (n == i + 1)
{
// if they're already in order, we move on
break;
}
else
{
// otherwise we swap
edgeList[n] = edgeList[i + 1];
edgeList[i + 1] = a;
break;
}
}
}
}
return edgeList;
}
}
}

View File

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

View File

@@ -0,0 +1,39 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
using System.Reflection;
namespace MoreMountains.Tools
{
/// <summary>
/// Various helpers
/// </summary>
public static class MMHelpers
{
public static T CopyComponent<T>(T original, GameObject destination) where T : Component
{
System.Type type = original.GetType();
T dst = destination.GetComponent(type) as T;
if (!dst) dst = destination.AddComponent(type) as T;
FieldInfo[] fields = type.GetFields();
foreach (FieldInfo field in fields)
{
if (field.IsStatic) continue;
field.SetValue(dst, field.GetValue(original));
}
PropertyInfo[] props = type.GetProperties();
foreach (PropertyInfo prop in props)
{
if (!prop.CanWrite || !prop.CanWrite || prop.Name == "name")
{
continue;
}
prop.SetValue(dst, prop.GetValue(original, null), null);
}
return dst as T;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 61848ed5026b644829e2fcb4a2207848
timeCreated: 1456159535
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
using UnityEngine;
using System.Collections;
namespace MoreMountains.Tools
{
/// <summary>
/// Image helpers
/// </summary>
public class MMImage : MonoBehaviour
{
/// <summary>
/// Coroutine used to make the character's sprite flicker (when hurt for example).
/// </summary>
public static IEnumerator Flicker(Renderer renderer, Color initialColor, Color flickerColor, float flickerSpeed, float flickerDuration)
{
if (renderer==null)
{
yield break;
}
if (!renderer.material.HasProperty("_Color"))
{
yield break;
}
if (initialColor == flickerColor)
{
yield break;
}
float flickerStop = Time.time + flickerDuration;
while (Time.time<flickerStop)
{
renderer.material.color = flickerColor;
yield return MMCoroutine.WaitFor(flickerSpeed);
renderer.material.color = initialColor;
yield return MMCoroutine.WaitFor(flickerSpeed);
}
renderer.material.color = initialColor;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7e19dbc2273664c2d8ff6566055a994b
timeCreated: 1455877857
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,139 @@
using UnityEngine;
using System.Collections;
namespace MoreMountains.Tools
{
/// <summary>
/// Input helpers
/// </summary>
public class MMInput : MonoBehaviour
{
/// <summary>
/// All possible states for a button. Can be used in a state machine.
/// </summary>
public enum ButtonStates { Off, ButtonDown, ButtonPressed, ButtonUp }
public enum AxisTypes { Positive, Negative }
/// <summary>
/// Takes an axis and returns a ButtonState depending on whether the axis is pressed or not (useful for xbox triggers for example), and when you need to use an axis/trigger as a binary thing
/// </summary>
/// <returns>The axis as button.</returns>
/// <param name="axisName">Axis name.</param>
/// <param name="threshold">Threshold value below which the button is off or released.</param>
/// <param name="currentState">Current state of the axis.</param>
public static ButtonStates ProcessAxisAsButton (string axisName, float threshold, ButtonStates currentState, AxisTypes AxisType = AxisTypes.Positive)
{
float axisValue = Input.GetAxis (axisName);
ButtonStates returnState;
bool comparison = (AxisType == AxisTypes.Positive) ? (axisValue < threshold) : (axisValue > threshold);
if (comparison)
{
if (currentState == ButtonStates.ButtonPressed)
{
returnState = ButtonStates.ButtonUp;
}
else
{
returnState = ButtonStates.Off;
}
}
else
{
if (currentState == ButtonStates.Off)
{
returnState = ButtonStates.ButtonDown;
}
else
{
returnState = ButtonStates.ButtonPressed;
}
}
return returnState;
}
/// <summary>
/// IM button, short for InputManager button, a class used to handle button states, whether mobile or actual keys
/// </summary>
public class IMButton
{
/// a state machine used to store button states
public MMStateMachine<MMInput.ButtonStates> State {get;protected set;}
/// the unique ID of this button
public string ButtonID;
public delegate void ButtonDownMethodDelegate();
public delegate void ButtonPressedMethodDelegate();
public delegate void ButtonUpMethodDelegate();
public ButtonDownMethodDelegate ButtonDownMethod;
public ButtonPressedMethodDelegate ButtonPressedMethod;
public ButtonUpMethodDelegate ButtonUpMethod;
/// returns the time (in unscaled seconds) since the last time the button was pressed down
public float TimeSinceLastButtonDown { get { return Time.unscaledTime - _lastButtonDownAt; } }
/// returns the time (in unscaled seconds) since the last time the button was released
public float TimeSinceLastButtonUp { get { return Time.unscaledTime - _lastButtonUpAt; } }
/// returns true if this button was pressed down within the time (in unscaled seconds) passed in parameters
public bool ButtonDownRecently(float time) { return (Time.unscaledTime - TimeSinceLastButtonDown <= time); }
/// returns true if this button was released within the time (in unscaled seconds) passed in parameters
public bool ButtonUpRecently(float time) { return (Time.unscaledTime - TimeSinceLastButtonUp <= time); }
protected float _lastButtonDownAt;
protected float _lastButtonUpAt;
public IMButton(string playerID, string buttonID, ButtonDownMethodDelegate btnDown = null, ButtonPressedMethodDelegate btnPressed = null, ButtonUpMethodDelegate btnUp = null)
{
ButtonID = playerID + "_" + buttonID;
ButtonDownMethod = btnDown;
ButtonUpMethod = btnUp;
ButtonPressedMethod = btnPressed;
State = new MMStateMachine<MMInput.ButtonStates> (null, false);
State.ChangeState (MMInput.ButtonStates.Off);
}
public virtual void TriggerButtonDown()
{
_lastButtonDownAt = Time.unscaledTime;
if (ButtonDownMethod == null)
{
State.ChangeState(MMInput.ButtonStates.ButtonDown);
}
else
{
ButtonDownMethod();
}
}
public virtual void TriggerButtonPressed()
{
if (ButtonPressedMethod == null)
{
State.ChangeState(MMInput.ButtonStates.ButtonPressed);
}
else
{
ButtonPressedMethod();
}
}
public virtual void TriggerButtonUp()
{
_lastButtonUpAt = Time.unscaledTime;
if (ButtonUpMethod == null)
{
State.ChangeState(MMInput.ButtonStates.ButtonUp);
}
else
{
ButtonUpMethod();
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a0874b2291d387847be139a6824cc576
timeCreated: 1477174630
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
using UnityEngine;
using System.Collections;
namespace MoreMountains.Tools
{
public class MMLayers
{
public static bool LayerInLayerMask(int layer, LayerMask layerMask)
{
if(((1 << layer) & layerMask) != 0)
{
return true;
}
else
{
return false;
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 01d38a71c34274ee0b94de34ac7931c8
timeCreated: 1470777155
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,662 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
namespace MoreMountains.Tools
{
/// <summary>
/// Math helpers
/// </summary>
public static class MMMaths
{
/// <summary>
/// Internal method used to compute the spring velocity
/// </summary>
/// <param name="currentValue"></param>
/// <param name="targetValue"></param>
/// <param name="velocity"></param>
/// <param name="damping"></param>
/// <param name="frequency"></param>
/// <param name="speed"></param>
/// <param name="deltaTime"></param>
/// <returns></returns>
private static float SpringVelocity(float currentValue, float targetValue, float velocity, float damping, float frequency, float speed, float deltaTime)
{
frequency = frequency * 2f * Mathf.PI;
return velocity + (deltaTime * frequency * frequency * (targetValue - currentValue)) + (-2.0f * deltaTime * frequency * damping * velocity);
}
/// <summary>
/// Springs a float towards a target value
/// </summary>
/// <param name="currentValue">the current value to spring, passed as a ref</param>
/// <param name="targetValue">the target value we're aiming for</param>
/// <param name="velocity">a velocity value, passed as ref, used to compute the current speed of the springed value</param>
/// <param name="damping">the damping, between 0.01f and 1f, the higher the daming, the less springy it'll be</param>
/// <param name="frequency">the frequency, in Hz, so the amount of periods the spring should go over in 1 second</param>
/// <param name="speed">the speed (between 0 and 1) at which the spring should operate</param>
/// <param name="deltaTime">the delta time (usually Time.deltaTime or Time.unscaledDeltaTime)</param>
public static void Spring(ref float currentValue, float targetValue, ref float velocity, float damping, float frequency, float speed, float deltaTime)
{
float initialVelocity = velocity;
velocity = SpringVelocity(currentValue, targetValue, velocity, damping, frequency, speed, deltaTime);
velocity = MMMaths.Lerp(initialVelocity, velocity, speed, Time.deltaTime);
currentValue += deltaTime * velocity;
}
/// <summary>
/// Springs a Vector2 towards a target value
/// </summary>
/// <param name="currentValue">the current value to spring, passed as a ref</param>
/// <param name="targetValue">the target value we're aiming for</param>
/// <param name="velocity">a velocity value, passed as ref, used to compute the current speed of the springed value</param>
/// <param name="damping">the damping, between 0.01f and 1f, the higher the daming, the less springy it'll be</param>
/// <param name="frequency">the frequency, in Hz, so the amount of periods the spring should go over in 1 second</param>
/// <param name="speed">the speed (between 0 and 1) at which the spring should operate</param>
/// <param name="deltaTime">the delta time (usually Time.deltaTime or Time.unscaledDeltaTime)</param>
public static void Spring(ref Vector2 currentValue, Vector2 targetValue, ref Vector2 velocity, float damping, float frequency, float speed, float deltaTime)
{
Vector2 initialVelocity = velocity;
velocity.x = SpringVelocity(currentValue.x, targetValue.x, velocity.x, damping, frequency, speed, deltaTime);
velocity.y = SpringVelocity(currentValue.y, targetValue.y, velocity.y, damping, frequency, speed, deltaTime);
velocity.x = MMMaths.Lerp(initialVelocity.x, velocity.x, speed, Time.deltaTime);
velocity.y = MMMaths.Lerp(initialVelocity.y, velocity.y, speed, Time.deltaTime);
currentValue += deltaTime * velocity;
}
/// <summary>
/// Springs a Vector3 towards a target value
/// </summary>
/// <param name="currentValue">the current value to spring, passed as a ref</param>
/// <param name="targetValue">the target value we're aiming for</param>
/// <param name="velocity">a velocity value, passed as ref, used to compute the current speed of the springed value</param>
/// <param name="damping">the damping, between 0.01f and 1f, the higher the daming, the less springy it'll be</param>
/// <param name="frequency">the frequency, in Hz, so the amount of periods the spring should go over in 1 second</param>
/// <param name="speed">the speed (between 0 and 1) at which the spring should operate</param>
/// <param name="deltaTime">the delta time (usually Time.deltaTime or Time.unscaledDeltaTime)</param>
public static void Spring(ref Vector3 currentValue, Vector3 targetValue, ref Vector3 velocity, float damping, float frequency, float speed, float deltaTime)
{
Vector3 initialVelocity = velocity;
velocity.x = SpringVelocity(currentValue.x, targetValue.x, velocity.x, damping, frequency, speed, deltaTime);
velocity.y = SpringVelocity(currentValue.y, targetValue.y, velocity.y, damping, frequency, speed, deltaTime);
velocity.z = SpringVelocity(currentValue.z, targetValue.z, velocity.z, damping, frequency, speed, deltaTime);
velocity.x = MMMaths.Lerp(initialVelocity.x, velocity.x, speed, Time.deltaTime);
velocity.y = MMMaths.Lerp(initialVelocity.y, velocity.y, speed, Time.deltaTime);
velocity.z = MMMaths.Lerp(initialVelocity.z, velocity.z, speed, Time.deltaTime);
currentValue += deltaTime * velocity;
}
/// <summary>
/// Springs a Vector4 towards a target value
/// </summary>
/// <param name="currentValue">the current value to spring, passed as a ref</param>
/// <param name="targetValue">the target value we're aiming for</param>
/// <param name="velocity">a velocity value, passed as ref, used to compute the current speed of the springed value</param>
/// <param name="damping">the damping, between 0.01f and 1f, the higher the daming, the less springy it'll be</param>
/// <param name="frequency">the frequency, in Hz, so the amount of periods the spring should go over in 1 second</param>
/// <param name="speed">the speed (between 0 and 1) at which the spring should operate</param>
/// <param name="deltaTime">the delta time (usually Time.deltaTime or Time.unscaledDeltaTime)</param>
public static void Spring(ref Vector4 currentValue, Vector4 targetValue, ref Vector4 velocity, float damping, float frequency, float speed, float deltaTime)
{
Vector4 initialVelocity = velocity;
velocity.x = SpringVelocity(currentValue.x, targetValue.x, velocity.x, damping, frequency, speed, deltaTime);
velocity.y = SpringVelocity(currentValue.y, targetValue.y, velocity.y, damping, frequency, speed, deltaTime);
velocity.z = SpringVelocity(currentValue.z, targetValue.z, velocity.z, damping, frequency, speed, deltaTime);
velocity.w = SpringVelocity(currentValue.w, targetValue.w, velocity.w, damping, frequency, speed, deltaTime);
velocity.x = MMMaths.Lerp(initialVelocity.x, velocity.x, speed, Time.deltaTime);
velocity.y = MMMaths.Lerp(initialVelocity.y, velocity.y, speed, Time.deltaTime);
velocity.z = MMMaths.Lerp(initialVelocity.z, velocity.z, speed, Time.deltaTime);
velocity.w = MMMaths.Lerp(initialVelocity.w, velocity.w, speed, Time.deltaTime);
currentValue += deltaTime * velocity;
}
/// <summary>
/// internal method used to determine the lerp rate
/// </summary>
/// <param name="rate"></param>
/// <returns></returns>
private static float LerpRate(float rate, float deltaTime)
{
rate = Mathf.Clamp01(rate);
float invRate = - Mathf.Log(1.0f - rate, 2.0f) * 60f;
return Mathf.Pow(2.0f, -invRate * deltaTime);
}
/// <summary>
/// Lerps a float towards a target at the specified rate
/// </summary>
/// <param name="value"></param>
/// <param name="target"></param>
/// <param name="rate"></param>
/// <returns></returns>
public static float Lerp(float value, float target, float rate, float deltaTime)
{
if (deltaTime == 0f) { return value; }
return Mathf.Lerp(target, value, LerpRate(rate, deltaTime));
}
/// <summary>
/// Lerps a Vector2 towards a target at the specified rate
/// </summary>
/// <param name="value"></param>
/// <param name="target"></param>
/// <param name="rate"></param>
/// <returns></returns>
public static Vector2 Lerp(Vector2 value, Vector2 target, float rate, float deltaTime)
{
if (deltaTime == 0f) { return value; }
return Vector2.Lerp(target, value, LerpRate(rate, deltaTime));
}
/// <summary>
/// Lerps a Vector3 towards a target at the specified rate
/// </summary>
/// <param name="value"></param>
/// <param name="target"></param>
/// <param name="rate"></param>
/// <returns></returns>
public static Vector3 Lerp(Vector3 value, Vector3 target, float rate, float deltaTime)
{
if (deltaTime == 0f) { return value; }
return Vector3.Lerp(target, value, LerpRate(rate, deltaTime));
}
/// <summary>
/// Lerps a Vector4 towards a target at the specified rate
/// </summary>
/// <param name="value"></param>
/// <param name="target"></param>
/// <param name="rate"></param>
/// <returns></returns>
public static Vector4 Lerp(Vector4 value, Vector4 target, float rate, float deltaTime)
{
if (deltaTime == 0f) { return value; }
return Vector4.Lerp(target, value, LerpRate(rate, deltaTime));
}
/// <summary>
/// Lerps a Quaternion towards a target at the specified rate
/// </summary>
/// <param name="value"></param>
/// <param name="target"></param>
/// <param name="rate"></param>
/// <returns></returns>
public static Quaternion Lerp(Quaternion value, Quaternion target, float rate, float deltaTime)
{
if (deltaTime == 0f) { return value; }
return Quaternion.Lerp(target, value, LerpRate(rate, deltaTime));
}
/// <summary>
/// Lerps a Color towards a target at the specified rate
/// </summary>
/// <param name="value"></param>
/// <param name="target"></param>
/// <param name="rate"></param>
/// <returns></returns>
public static Color Lerp(Color value, Color target, float rate, float deltaTime)
{
if (deltaTime == 0f) { return value; }
return Color.Lerp(target, value, LerpRate(rate, deltaTime));
}
/// <summary>
/// Lerps a Color32 towards a target at the specified rate
/// </summary>
/// <param name="value"></param>
/// <param name="target"></param>
/// <param name="rate"></param>
/// <returns></returns>
public static Color32 Lerp(Color32 value, Color32 target, float rate, float deltaTime)
{
if (deltaTime == 0f) { return value; }
return Color32.Lerp(target, value, LerpRate(rate, deltaTime));
}
/// <summary>
/// Clamps a float between min and max, both bounds being optional and driven by clampMin and clampMax respectively
/// </summary>
/// <param name="value"></param>
/// <param name="min"></param>
/// <param name="max"></param>
/// <param name="clampMin"></param>
/// <param name="clampMax"></param>
/// <returns></returns>
public static float Clamp(float value, float min, float max, bool clampMin, bool clampMax)
{
float returnValue = value;
if (clampMin && (returnValue < min))
{
returnValue = min;
}
if (clampMax && (returnValue > max))
{
returnValue = max;
}
return returnValue;
}
/// <summary>
/// Rounds a float to the nearest half value : 1, 1.5, 2, 2.5 etc
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static float RoundToNearestHalf(float a)
{
return a = a - (a % 0.5f);
}
/// <summary>
///
/// </summary>
/// <param name="direction"></param>
/// <returns></returns>
public static Quaternion LookAt2D(Vector2 direction)
{
var angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
return Quaternion.AngleAxis(angle, Vector3.forward);
}
/// <summary>
/// Takes a Vector3 and turns it into a Vector2
/// </summary>
/// <returns>The vector2.</returns>
/// <param name="target">The Vector3 to turn into a Vector2.</param>
public static Vector2 Vector3ToVector2 (Vector3 target)
{
return new Vector2(target.x, target.y);
}
/// <summary>
/// Takes a Vector2 and turns it into a Vector3 with a null z value
/// </summary>
/// <returns>The vector3.</returns>
/// <param name="target">The Vector2 to turn into a Vector3.</param>
public static Vector3 Vector2ToVector3 (Vector2 target)
{
return new Vector3(target.x, target.y, 0);
}
/// <summary>
/// Takes a Vector2 and turns it into a Vector3 with the specified z value
/// </summary>
/// <returns>The vector3.</returns>
/// <param name="target">The Vector2 to turn into a Vector3.</param>
/// <param name="newZValue">New Z value.</param>
public static Vector3 Vector2ToVector3 (Vector2 target, float newZValue)
{
return new Vector3(target.x, target.y, newZValue);
}
/// <summary>
/// Rounds all components of a Vector3.
/// </summary>
/// <returns>The vector3.</returns>
/// <param name="vector">Vector.</param>
public static Vector3 RoundVector3 (Vector3 vector)
{
return new Vector3 (Mathf.Round (vector.x), Mathf.Round (vector.y), Mathf.Round (vector.z));
}
/// <summary>
/// Returns a random Vector2 from 2 defined Vector2.
/// </summary>
/// <returns>The random Vector2.</returns>
/// <param name="min">Minimum.</param>
/// <param name="max">Maximum.</param>
public static Vector2 RandomVector2(Vector2 minimum, Vector2 maximum)
{
return new Vector2(UnityEngine.Random.Range(minimum.x, maximum.x),
UnityEngine.Random.Range(minimum.y, maximum.y));
}
/// <summary>
/// Returns a random Vector3 from 2 defined Vector3.
/// </summary>
/// <returns>The random Vector3.</returns>
/// <param name="min">Minimum.</param>
/// <param name="max">Maximum.</param>
public static Vector3 RandomVector3(Vector3 minimum, Vector3 maximum)
{
return new Vector3(UnityEngine.Random.Range(minimum.x, maximum.x),
UnityEngine.Random.Range(minimum.y, maximum.y),
UnityEngine.Random.Range(minimum.z, maximum.z));
}
/// <summary>
/// Returns a random point on the circle of the specified radius
/// </summary>
/// <param name="circleRadius"></param>
/// <returns></returns>
public static Vector2 RandomPointOnCircle(float circleRadius)
{
return UnityEngine.Random.insideUnitCircle.normalized * circleRadius;
}
/// <summary>
/// Returns a random point on the sphere of the specified radius
/// </summary>
/// <param name="sphereRadius"></param>
/// <returns></returns>
public static Vector3 RandomPointOnSphere(float sphereRadius)
{
return UnityEngine.Random.onUnitSphere * sphereRadius;
}
/// <summary>
/// Rotates a point around the given pivot.
/// </summary>
/// <returns>The new point position.</returns>
/// <param name="point">The point to rotate.</param>
/// <param name="pivot">The pivot's position.</param>
/// <param name="angle">The angle we want to rotate our point.</param>
public static Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, float angle)
{
angle = angle*(Mathf.PI/180f);
float rotatedX = Mathf.Cos(angle) * (point.x - pivot.x) - Mathf.Sin(angle) * (point.y-pivot.y) + pivot.x;
float rotatedY = Mathf.Sin(angle) * (point.x - pivot.x) + Mathf.Cos(angle) * (point.y - pivot.y) + pivot.y;
return new Vector3(rotatedX,rotatedY,0);
}
/// <summary>
/// Rotates a point around the given pivot.
/// </summary>
/// <returns>The new point position.</returns>
/// <param name="point">The point to rotate.</param>
/// <param name="pivot">The pivot's position.</param>
/// <param name="angles">The angle as a Vector3.</param>
public static Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Vector3 angle)
{
// we get point direction from the point to the pivot
Vector3 direction = point - pivot;
// we rotate the direction
direction = Quaternion.Euler(angle) * direction;
// we determine the rotated point's position
point = direction + pivot;
return point;
}
/// <summary>
/// Rotates a point around the given pivot.
/// </summary>
/// <returns>The new point position.</returns>
/// <param name="point">The point to rotate.</param>
/// <param name="pivot">The pivot's position.</param>
/// <param name="angles">The angle as a Vector3.</param>
public static Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Quaternion quaternion)
{
// we get point direction from the point to the pivot
Vector3 direction = point - pivot;
// we rotate the direction
direction = quaternion * direction;
// we determine the rotated point's position
point = direction + pivot;
return point;
}
/// <summary>
/// Rotates a vector2 by the angle (in degrees) specified and returns it
/// </summary>
/// <returns>The rotated Vector2.</returns>
/// <param name="vector">The vector to rotate.</param>
/// <param name="angle">Degrees.</param>
public static Vector2 RotateVector2(Vector2 vector, float angle) {
if (angle == 0)
{
return vector;
}
float sinus = Mathf.Sin(angle * Mathf.Deg2Rad);
float cosinus = Mathf.Cos(angle * Mathf.Deg2Rad);
float oldX = vector.x;
float oldY = vector.y;
vector.x = (cosinus * oldX) - (sinus * oldY);
vector.y = (sinus * oldX) + (cosinus * oldY);
return vector;
}
/// <summary>
/// Computes and returns the angle between two vectors, on a 360° scale
/// </summary>
/// <returns>The <see cref="System.Single"/>.</returns>
/// <param name="vectorA">Vector a.</param>
/// <param name="vectorB">Vector b.</param>
public static float AngleBetween(Vector2 vectorA, Vector2 vectorB)
{
float angle = Vector2.Angle(vectorA, vectorB);
Vector3 cross = Vector3.Cross(vectorA, vectorB);
if (cross.z > 0)
{
angle = 360 - angle;
}
return angle;
}
/// <summary>
/// Computes and returns the direction between two vector3, used to check if a vector is pointing left or right of another one
/// </summary>
/// <returns>The <see cref="System.Single"/>.</returns>
/// <param name="vectorA">Vector a.</param>
/// <param name="vectorB">Vector b.</param>
public static float AngleDirection(Vector3 vectorA, Vector3 vectorB, Vector3 up)
{
Vector3 cross = Vector3.Cross(vectorA, vectorB);
float direction = Vector3.Dot(cross, up);
return direction;
}
/// <summary>
/// Returns the distance between a point and a line.
/// </summary>
/// <returns>The between point and line.</returns>
/// <param name="point">Point.</param>
/// <param name="lineStart">Line start.</param>
/// <param name="lineEnd">Line end.</param>
public static float DistanceBetweenPointAndLine(Vector3 point, Vector3 lineStart, Vector3 lineEnd)
{
return Vector3.Magnitude(ProjectPointOnLine(point, lineStart, lineEnd) - point);
}
/// <summary>
/// Projects a point on a line (perpendicularly) and returns the projected point.
/// </summary>
/// <returns>The point on line.</returns>
/// <param name="point">Point.</param>
/// <param name="lineStart">Line start.</param>
/// <param name="lineEnd">Line end.</param>
public static Vector3 ProjectPointOnLine(Vector3 point, Vector3 lineStart, Vector3 lineEnd)
{
Vector3 rhs = point - lineStart;
Vector3 vector2 = lineEnd - lineStart;
float magnitude = vector2.magnitude;
Vector3 lhs = vector2;
if (magnitude > 1E-06f)
{
lhs = (Vector3)(lhs / magnitude);
}
float num2 = Mathf.Clamp(Vector3.Dot(lhs, rhs), 0f, magnitude);
return (lineStart + ((Vector3)(lhs * num2)));
}
/// <summary>
/// Returns the sum of all the int passed in parameters
/// </summary>
/// <param name="thingsToAdd">Things to add.</param>
public static int Sum(params int[] thingsToAdd)
{
int result=0;
for (int i = 0; i < thingsToAdd.Length; i++)
{
result += thingsToAdd[i];
}
return result;
}
/// <summary>
/// Returns the result of rolling a dice of the specified number of sides
/// </summary>
/// <returns>The result of the dice roll.</returns>
/// <param name="numberOfSides">Number of sides of the dice.</param>
public static int RollADice(int numberOfSides)
{
return (UnityEngine.Random.Range(1,numberOfSides+1));
}
/// <summary>
/// Returns a random success based on X% of chance.
/// Example : I have 20% of chance to do X, Chance(20) > true, yay!
/// </summary>
/// <param name="percent">Percent of chance.</param>
public static bool Chance(int percent)
{
return (UnityEngine.Random.Range(0,100) <= percent);
}
/// <summary>
/// Moves from "from" to "to" by the specified amount and returns the corresponding value
/// </summary>
/// <param name="from">From.</param>
/// <param name="to">To.</param>
/// <param name="amount">Amount.</param>
public static float Approach(float from, float to, float amount)
{
if (from < to)
{
from += amount;
if (from > to)
{
return to;
}
}
else
{
from -= amount;
if (from < to)
{
return to;
}
}
return from;
}
/// <summary>
/// Remaps a value x in interval [A,B], to the proportional value in interval [C,D]
/// </summary>
/// <param name="x">The value to remap.</param>
/// <param name="A">the minimum bound of interval [A,B] that contains the x value</param>
/// <param name="B">the maximum bound of interval [A,B] that contains the x value</param>
/// <param name="C">the minimum bound of target interval [C,D]</param>
/// <param name="D">the maximum bound of target interval [C,D]</param>
public static float Remap(float x, float A, float B, float C, float D)
{
float remappedValue = C + (x-A)/(B-A) * (D - C);
return remappedValue;
}
/// <summary>
/// Clamps the angle in parameters between a minimum and maximum angle (all angles expressed in degrees)
/// </summary>
/// <param name="angle"></param>
/// <param name="minimumAngle"></param>
/// <param name="maximumAngle"></param>
/// <returns></returns>
public static float ClampAngle(float angle, float minimumAngle, float maximumAngle)
{
if (angle < -360)
{
angle += 360;
}
if (angle > 360)
{
angle -= 360;
}
return Mathf.Clamp(angle, minimumAngle, maximumAngle);
}
public static float RoundToDecimal(float value, int numberOfDecimals)
{
if (numberOfDecimals <= 0)
{
return Mathf.Round(value);
}
else
{
return Mathf.Round(value * 10f * numberOfDecimals) / (10f * numberOfDecimals);
}
}
/// <summary>
/// Rounds the value passed in parameters to the closest value in the parameter array
/// </summary>
/// <param name="value"></param>
/// <param name="possibleValues"></param>
/// <returns></returns>
public static float RoundToClosest(float value, float[] possibleValues, bool pickSmallestDistance = false)
{
if (possibleValues.Length == 0)
{
return 0f;
}
float closestValue = possibleValues[0];
foreach (float possibleValue in possibleValues)
{
float closestDistance = Mathf.Abs(closestValue - value);
float possibleDistance = Mathf.Abs(possibleValue - value);
if (closestDistance > possibleDistance)
{
closestValue = possibleValue;
}
else if (closestDistance == possibleDistance)
{
if ((pickSmallestDistance && closestValue > possibleValue) || (!pickSmallestDistance && closestValue < possibleValue))
{
closestValue = (value < 0) ? closestValue : possibleValue;
}
}
}
return closestValue;
}
/// <summary>
/// Returns a vector3 based on the angle in parameters
/// </summary>
/// <param name="angle"></param>
/// <returns></returns>
public static Vector3 DirectionFromAngle(float angle, float additionalAngle)
{
angle += additionalAngle;
Vector3 direction = Vector3.zero;
direction.x = Mathf.Sin(angle * Mathf.Deg2Rad);
direction.y = 0f;
direction.z = Mathf.Cos(angle * Mathf.Deg2Rad);
return direction;
}
/// <summary>
/// Returns a vector3 based on the angle in parameters
/// </summary>
/// <param name="angle"></param>
/// <returns></returns>
public static Vector3 DirectionFromAngle2D(float angle, float additionalAngle)
{
angle += additionalAngle;
Vector3 direction = Vector3.zero;
direction.x = Mathf.Cos(angle * Mathf.Deg2Rad);
direction.y = Mathf.Sin(angle * Mathf.Deg2Rad);
direction.z = 0f;
return direction;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: fc798aa25d3634ebbb996c8d60ace648
timeCreated: 1456158841
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,116 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
namespace MoreMountains.Tools
{
/// <summary>
/// Movement helpers
/// </summary>
public static class MMMovement
{
/// <summary>
/// Moves an object from point A to point B in a given time
/// </summary>
/// <param name="movingObject">Moving object.</param>
/// <param name="pointA">Point a.</param>
/// <param name="pointB">Point b.</param>
/// <param name="duration">Time.</param>
public static IEnumerator MoveFromTo(GameObject movingObject,Vector3 pointA, Vector3 pointB, float duration, AnimationCurve curve = null)
{
float journey = 0f;
Vector3 newPosition;
while (journey < duration)
{
float percent = Mathf.Clamp01(journey / duration);
newPosition = Vector3.Lerp(pointA, pointB, curve.Evaluate(percent));
movingObject.transform.position = newPosition;
journey += Time.deltaTime;
yield return null;
}
yield break;
}
public static IEnumerator AnimateScale(Transform targetTransform, Vector3 vector, float duration, AnimationCurve curveX, AnimationCurve curveY, AnimationCurve curveZ, float multiplier = 1f)
{
if (targetTransform == null)
{
yield break;
}
if ((curveX == null) || (curveY == null) || (curveZ == null))
{
yield break;
}
if (duration == 0f)
{
yield break;
}
float journey = 0f;
while (journey < duration)
{
float percent = Mathf.Clamp01(journey / duration);
vector.x = curveX.Evaluate(percent);
vector.y = curveY.Evaluate(percent);
vector.z = curveZ.Evaluate(percent);
targetTransform.localScale = multiplier * vector;
journey += Time.deltaTime;
yield return null;
}
yield return null;
}
public static IEnumerator AnimateRotation(Transform targetTransform,
Vector3 vector,
float duration,
AnimationCurve curveX,
AnimationCurve curveY,
AnimationCurve curveZ,
float multiplier)
{
if (targetTransform == null)
{
yield break;
}
if ((curveX == null) || (curveY == null) || (curveZ == null))
{
yield break;
}
if (duration == 0f)
{
yield break;
}
float journey = 0f;
while (journey < duration)
{
float percent = Mathf.Clamp01(journey / duration);
vector.x = curveX.Evaluate(percent) * multiplier;
vector.y = curveY.Evaluate(percent) * multiplier;
vector.z = curveZ.Evaluate(percent) * multiplier;
targetTransform.localEulerAngles = vector;
journey += Time.deltaTime;
yield return null;
}
yield return null;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 195cd029f2c828848a5f260fc5457f3e
timeCreated: 1456589453
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,69 @@
using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
namespace MoreMountains.Tools
{
/// <summary>
/// Scene management helpers
/// </summary>
public class MMScene
{
/// <summary>
/// Returns an array filled with all the currently loaded scenes
/// </summary>
/// <returns></returns>
public static Scene[] GetLoadedScenes()
{
int sceneCount = SceneManager.sceneCount;
List<Scene> loadedScenes = new List<Scene>(sceneCount);
// Scene[] loadedScenes = new Scene[sceneCount];
for (int i = 0; i < sceneCount; i++)
{
var scene = SceneManager.GetSceneAt(i);
if (scene.isLoaded)
{
loadedScenes.Add(scene);
}
else
{
Debug.LogWarning($"{scene.name} NOT LOADED");
}
}
return loadedScenes.ToArray();
}
/// <summary>
/// Returns a list of all the scenes present in the build
/// </summary>
/// <returns></returns>
public static List<string> GetScenesInBuild()
{
List<string> scenesInBuild = new List<string>();
for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
{
string scenePath = SceneUtility.GetScenePathByBuildIndex(i);
int lastSlash = scenePath.LastIndexOf("/", StringComparison.Ordinal);
scenesInBuild.Add(scenePath.Substring(lastSlash + 1, scenePath.LastIndexOf(".", StringComparison.Ordinal) - lastSlash - 1));
}
return scenesInBuild;
}
/// <summary>
/// Returns true if a scene by the specified name is present in the build
/// </summary>
/// <param name="sceneName"></param>
/// <returns></returns>
public static bool SceneInBuild(string sceneName)
{
return GetScenesInBuild().Contains(sceneName);
}
}
}

View File

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

View File

@@ -0,0 +1,80 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
using System.Collections.Generic;
namespace MoreMountains.Tools
{
/// <summary>
/// A class to use to get more controlled randomness, taking values out of the bag randomly, and never getting them again.
///
/// Usage :
///
/// var shuffleBag = new ShuffleBag(40);
/// for (int i = 0; i<40; i++)
/// {
/// newValue = something;
/// shuffleBag.Add(newValue, amount);
/// }
///
/// then :
/// float something = shuffleBag.Pick();
///
/// </summary>
public class MMShufflebag<T>
{
public int Capacity { get { return _contents.Capacity; } }
public int Size { get { return _contents.Count; } }
protected List<T> _contents;
protected T _currentItem;
protected int _currentIndex = -1;
/// <summary>
/// Initializes the shufflebag
/// </summary>
/// <param name="initialCapacity"></param>
public MMShufflebag(int initialCapacity)
{
_contents = new List<T>(initialCapacity);
}
/// <summary>
/// Adds the specified quantity of the item to the bag
/// </summary>
/// <param name="item"></param>
/// <param name="quantity"></param>
public virtual void Add(T item, int quantity)
{
for (int i = 0; i < quantity; i++)
{
_contents.Add(item);
}
_currentIndex = Size - 1;
}
/// <summary>
/// Returns a random item from the bag
/// </summary>
/// <returns></returns>
public T Pick()
{
if (_currentIndex < 1)
{
_currentIndex = Size - 1;
_currentItem = _contents[0];
return _currentItem;
}
int position = UnityEngine.Random.Range(0, _currentIndex);
_currentItem = _contents[position];
_contents[position] = _contents[_currentIndex];
_contents[_currentIndex] = _currentItem;
_currentIndex--;
return _currentItem;
}
}
}

View File

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

View File

@@ -0,0 +1,80 @@
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// String helpers
/// </summary>
public static class MMString
{
/// <summary>
/// Uppercases the first letter of the parameter string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string UppercaseFirst(string s)
{
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
return char.ToUpper(s[0]) + s.Substring(1);
}
/// <summary>
/// Returns the length of a rich text, excluding its tags
/// </summary>
/// <param name="richText"></param>
/// <returns></returns>
public static int RichTextLength(string richText)
{
int richTextLength = 0;
bool insideTag = false;
richText = richText.Replace("<br>", "-");
foreach (char character in richText)
{
if (character == '<')
{
insideTag = true;
continue;
}
else if (character == '>')
{
insideTag = false;
}
else if (!insideTag)
{
richTextLength++;
}
}
return richTextLength;
}
/// <summary>
/// Elegantly uppercases the first letter of every word in a string
/// </summary>
/// <param name="title"></param>
/// <returns></returns>
public static string ToTitleCase(this string title)
{
return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(title.ToLower());
}
/// <summary>
/// Removes extra spaces in a string
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string RemoveExtraSpaces(this string s)
{
return Regex.Replace(s, @"\s+", " ");
}
}
}

View File

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

View File

@@ -0,0 +1,92 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
using Random = System.Random;
namespace MoreMountains.Tools
{
/// <summary>
/// A collection of helper methods for interacting with Tilemaps
/// </summary>
public class MMTilemap : MonoBehaviour
{
/// <summary>
/// Returns a random world position on the specified tilemap/grid combo, filled or not based on the shouldBeFilled flag
/// </summary>
/// <param name="targetTilemap"></param>
/// <param name="grid"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="shouldBeFilled"></param>
/// <param name="maxIterations"></param>
/// <returns></returns>
public static Vector2 GetRandomPosition(Tilemap targetTilemap, Grid grid, int width, int height, bool shouldBeFilled = true, int maxIterations = 1000)
{
int iterationsCount = 0;
Vector3Int randomCoordinate = Vector3Int.zero;
while (iterationsCount < maxIterations)
{
randomCoordinate.x = UnityEngine.Random.Range(0, width);
randomCoordinate.y = UnityEngine.Random.Range(0, height);
randomCoordinate += MMTilemapGridRenderer.ComputeOffset(width-1, height-1);
bool hasTile = targetTilemap.HasTile(randomCoordinate);
if (hasTile == shouldBeFilled)
{
return targetTilemap.CellToWorld(randomCoordinate) + (grid.cellSize / 2);
}
iterationsCount++;
}
return Vector2.zero;
}
/// <summary>
/// Returns a random position on the ground floor of the grid
/// </summary>
/// <param name="targetTilemap"></param>
/// <param name="grid"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="startingHeight"></param>
/// <param name="xMin"></param>
/// <param name="xMax"></param>
/// <param name="shouldBeFilled"></param>
/// <param name="maxIterations"></param>
/// <returns></returns>
public static Vector2 GetRandomPositionOnGround(Tilemap targetTilemap, Grid grid, int width, int height, int startingHeight, int xMin, int xMax, bool shouldBeFilled = true, int maxIterations = 1000)
{
int iterationsCount = 0;
Vector3Int randomCoordinate = Vector3Int.zero;
while (iterationsCount < maxIterations)
{
randomCoordinate.x = UnityEngine.Random.Range(xMin, xMax);
randomCoordinate.y = startingHeight;
randomCoordinate += MMTilemapGridRenderer.ComputeOffset(width-1, height-1);
int counter = height;
while (counter > 0)
{
bool hasTile = targetTilemap.HasTile(randomCoordinate);
if (hasTile == shouldBeFilled)
{
randomCoordinate.y++;
return targetTilemap.CellToWorld(randomCoordinate) + (grid.cellSize / 2);
}
randomCoordinate.y--;
counter--;
}
iterationsCount++;
}
return Vector2.zero;
}
}
}

View File

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

View File

@@ -0,0 +1,94 @@
using UnityEngine;
using System.Collections;
using System;
namespace MoreMountains.Tools
{
/// <summary>
/// Time helpers
/// </summary>
public class MMTime : MonoBehaviour
{
/// <summary>
/// Turns a float (expressed in seconds) into a string displaying hours, minutes, seconds and hundredths optionnally
/// </summary>
/// <param name="t"></param>
/// <param name="displayHours"></param>
/// <param name="displayMinutes"></param>
/// <param name="displaySeconds"></param>
/// <param name="displayHundredths"></param>
/// <returns></returns>
public static string FloatToTimeString(float t, bool displayHours = false, bool displayMinutes = true, bool displaySeconds = true, bool displayMilliseconds = false)
{
int intTime = (int)t;
int hours = intTime / 3600;
int minutes = intTime / 60;
int seconds = intTime % 60;
int milliseconds = Mathf.FloorToInt((t * 1000)%1000);
if (displayHours && displayMinutes && displaySeconds && displayMilliseconds)
{
return string.Format("{0:00}:{1:00}:{2:00}.{3:D3}", hours, minutes, seconds, milliseconds);
}
if (!displayHours && displayMinutes && displaySeconds && displayMilliseconds)
{
return string.Format("{0:00}:{1:00}.{2:D3}", minutes, seconds, milliseconds);
}
if (!displayHours && !displayMinutes && displaySeconds && displayMilliseconds)
{
return string.Format("{0:D2}.{1:D3}", seconds, milliseconds);
}
if (!displayHours && !displayMinutes && displaySeconds && !displayMilliseconds)
{
return string.Format("{0:00}", seconds);
}
if (displayHours && displayMinutes && displaySeconds && !displayMilliseconds)
{
return string.Format("{0:00}:{1:00}:{2:00}", hours, minutes, seconds);
}
if (!displayHours && displayMinutes && displaySeconds && !displayMilliseconds)
{
return string.Format("{0:00}:{1:00}", minutes, seconds);
}
return null;
}
/// <summary>
/// Takes a hh:mm:ss:SSS string and turns it into a float value expressed in seconds
/// </summary>
/// <returns>a number of seconds.</returns>
/// <param name="timeInStringNotation">Time in string notation to decode.</param>
public static float TimeStringToFloat(string timeInStringNotation)
{
if (timeInStringNotation.Length!=12)
{
throw new Exception("The time in the TimeStringToFloat method must be specified using a hh:mm:ss:SSS syntax");
}
string[] timeStringArray = timeInStringNotation.Split(new string[] {":","."},StringSplitOptions.None);
float startTime=0f;
float result;
if (float.TryParse(timeStringArray[0], out result))
{
startTime += result*3600f;
}
if (float.TryParse(timeStringArray[1], out result))
{
startTime += result*60f;
}
if (float.TryParse(timeStringArray[2], out result))
{
startTime += result;
}
if (float.TryParse(timeStringArray[3], out result))
{
startTime += result/1000f;
}
return startTime;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 49af33803f6148b4dad64c35bf986275
timeCreated: 1455815764
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: