Editor stuff

This commit is contained in:
Starpelly
2022-01-05 19:11:33 -05:00
parent 775fd7e580
commit 576b0d8482
458 changed files with 37611 additions and 15 deletions

View File

@ -0,0 +1,350 @@
/**
This class demonstrates the code discussed in these two articles:
http://devmag.org.za/2011/04/05/bzier-curves-a-tutorial/
http://devmag.org.za/2011/06/23/bzier-path-algorithms/
Use this code as you wish, at your own risk. If it blows up
your computer, makes a plane crash, or otherwise cause damage,
injury, or death, it is not my fault.
@author Herman Tulleken, dev.mag.org.za
*/
using System.Collections.Generic;
namespace UnityEngine.UI.Extensions
{
/**
Class for representing a Bezier path, and methods for getting suitable points to
draw the curve with line segments.
*/
public class BezierPath
{
public int SegmentsPerCurve = 10;
public float MINIMUM_SQR_DISTANCE = 0.01f;
// This corresponds to about 172 degrees, 8 degrees from a straight line
public float DIVISION_THRESHOLD = -0.99f;
private List<Vector2> controlPoints;
private int curveCount; //how many bezier curves in this path?
/**
Constructs a new empty Bezier curve. Use one of these methods
to add points: SetControlPoints, Interpolate, SamplePoints.
*/
public BezierPath()
{
controlPoints = new List<Vector2>();
}
/**
Sets the control points of this Bezier path.
Points 0-3 forms the first Bezier curve, points
3-6 forms the second curve, etc.
*/
public void SetControlPoints(List<Vector2> newControlPoints)
{
controlPoints.Clear();
controlPoints.AddRange(newControlPoints);
curveCount = (controlPoints.Count - 1) / 3;
}
public void SetControlPoints(Vector2[] newControlPoints)
{
controlPoints.Clear();
controlPoints.AddRange(newControlPoints);
curveCount = (controlPoints.Count - 1) / 3;
}
/**
Returns the control points for this Bezier curve.
*/
public List<Vector2> GetControlPoints()
{
return controlPoints;
}
/**
Calculates a Bezier interpolated path for the given points.
*/
public void Interpolate(List<Vector2> segmentPoints, float scale)
{
controlPoints.Clear();
if (segmentPoints.Count < 2)
{
return;
}
for (int i = 0; i < segmentPoints.Count; i++)
{
if (i == 0) // is first
{
Vector2 p1 = segmentPoints[i];
Vector2 p2 = segmentPoints[i + 1];
Vector2 tangent = (p2 - p1);
Vector2 q1 = p1 + scale * tangent;
controlPoints.Add(p1);
controlPoints.Add(q1);
}
else if (i == segmentPoints.Count - 1) //last
{
Vector2 p0 = segmentPoints[i - 1];
Vector2 p1 = segmentPoints[i];
Vector2 tangent = (p1 - p0);
Vector2 q0 = p1 - scale * tangent;
controlPoints.Add(q0);
controlPoints.Add(p1);
}
else
{
Vector2 p0 = segmentPoints[i - 1];
Vector2 p1 = segmentPoints[i];
Vector2 p2 = segmentPoints[i + 1];
Vector2 tangent = (p2 - p0).normalized;
Vector2 q0 = p1 - scale * tangent * (p1 - p0).magnitude;
Vector2 q1 = p1 + scale * tangent * (p2 - p1).magnitude;
controlPoints.Add(q0);
controlPoints.Add(p1);
controlPoints.Add(q1);
}
}
curveCount = (controlPoints.Count - 1) / 3;
}
/**
Sample the given points as a Bezier path.
*/
public void SamplePoints(List<Vector2> sourcePoints, float minSqrDistance, float maxSqrDistance, float scale)
{
if (sourcePoints.Count < 2)
{
return;
}
Stack<Vector2> samplePoints = new Stack<Vector2>();
samplePoints.Push(sourcePoints[0]);
Vector2 potentialSamplePoint = sourcePoints[1];
int i = 2;
for (i = 2; i < sourcePoints.Count; i++)
{
if (
((potentialSamplePoint - sourcePoints[i]).sqrMagnitude > minSqrDistance) &&
((samplePoints.Peek() - sourcePoints[i]).sqrMagnitude > maxSqrDistance))
{
samplePoints.Push(potentialSamplePoint);
}
potentialSamplePoint = sourcePoints[i];
}
//now handle last bit of curve
Vector2 p1 = samplePoints.Pop(); //last sample point
Vector2 p0 = samplePoints.Peek(); //second last sample point
Vector2 tangent = (p0 - potentialSamplePoint).normalized;
float d2 = (potentialSamplePoint - p1).magnitude;
float d1 = (p1 - p0).magnitude;
p1 = p1 + tangent * ((d1 - d2) / 2);
samplePoints.Push(p1);
samplePoints.Push(potentialSamplePoint);
Interpolate(new List<Vector2>(samplePoints), scale);
}
/**
Calculates a point on the path.
@param curveIndex The index of the curve that the point is on. For example,
the second curve (index 1) is the curve with control points 3, 4, 5, and 6.
@param t The parameter indicating where on the curve the point is. 0 corresponds
to the "left" point, 1 corresponds to the "right" end point.
*/
public Vector2 CalculateBezierPoint(int curveIndex, float t)
{
int nodeIndex = curveIndex * 3;
Vector2 p0 = controlPoints[nodeIndex];
Vector2 p1 = controlPoints[nodeIndex + 1];
Vector2 p2 = controlPoints[nodeIndex + 2];
Vector2 p3 = controlPoints[nodeIndex + 3];
return CalculateBezierPoint(t, p0, p1, p2, p3);
}
/**
Gets the drawing points. This implementation simply calculates a certain number
of points per curve.
*/
public List<Vector2> GetDrawingPoints0()
{
List<Vector2> drawingPoints = new List<Vector2>();
for (int curveIndex = 0; curveIndex < curveCount; curveIndex++)
{
if (curveIndex == 0) //Only do this for the first end point.
//When i != 0, this coincides with the
//end point of the previous segment,
{
drawingPoints.Add(CalculateBezierPoint(curveIndex, 0));
}
for (int j = 1; j <= SegmentsPerCurve; j++)
{
float t = j / (float)SegmentsPerCurve;
drawingPoints.Add(CalculateBezierPoint(curveIndex, t));
}
}
return drawingPoints;
}
/**
Gets the drawing points. This implementation simply calculates a certain number
of points per curve.
This is a slightly different implementation from the one above.
*/
public List<Vector2> GetDrawingPoints1()
{
List<Vector2> drawingPoints = new List<Vector2>();
for (int i = 0; i < controlPoints.Count - 3; i += 3)
{
Vector2 p0 = controlPoints[i];
Vector2 p1 = controlPoints[i + 1];
Vector2 p2 = controlPoints[i + 2];
Vector2 p3 = controlPoints[i + 3];
if (i == 0) //only do this for the first end point. When i != 0, this coincides with the end point of the previous segment,
{
drawingPoints.Add(CalculateBezierPoint(0, p0, p1, p2, p3));
}
for (int j = 1; j <= SegmentsPerCurve; j++)
{
float t = j / (float)SegmentsPerCurve;
drawingPoints.Add(CalculateBezierPoint(t, p0, p1, p2, p3));
}
}
return drawingPoints;
}
/**
This gets the drawing points of a bezier curve, using recursive division,
which results in less points for the same accuracy as the above implementation.
*/
public List<Vector2> GetDrawingPoints2()
{
List<Vector2> drawingPoints = new List<Vector2>();
for (int curveIndex = 0; curveIndex < curveCount; curveIndex++)
{
List<Vector2> bezierCurveDrawingPoints = FindDrawingPoints(curveIndex);
if (curveIndex != 0)
{
//remove the fist point, as it coincides with the last point of the previous Bezier curve.
bezierCurveDrawingPoints.RemoveAt(0);
}
drawingPoints.AddRange(bezierCurveDrawingPoints);
}
return drawingPoints;
}
List<Vector2> FindDrawingPoints(int curveIndex)
{
List<Vector2> pointList = new List<Vector2>();
Vector2 left = CalculateBezierPoint(curveIndex, 0);
Vector2 right = CalculateBezierPoint(curveIndex, 1);
pointList.Add(left);
pointList.Add(right);
FindDrawingPoints(curveIndex, 0, 1, pointList, 1);
return pointList;
}
/**
@returns the number of points added.
*/
int FindDrawingPoints(int curveIndex, float t0, float t1,
List<Vector2> pointList, int insertionIndex)
{
Vector2 left = CalculateBezierPoint(curveIndex, t0);
Vector2 right = CalculateBezierPoint(curveIndex, t1);
if ((left - right).sqrMagnitude < MINIMUM_SQR_DISTANCE)
{
return 0;
}
float tMid = (t0 + t1) / 2;
Vector2 mid = CalculateBezierPoint(curveIndex, tMid);
Vector2 leftDirection = (left - mid).normalized;
Vector2 rightDirection = (right - mid).normalized;
if (Vector2.Dot(leftDirection, rightDirection) > DIVISION_THRESHOLD || Mathf.Abs(tMid - 0.5f) < 0.0001f)
{
int pointsAddedCount = 0;
pointsAddedCount += FindDrawingPoints(curveIndex, t0, tMid, pointList, insertionIndex);
pointList.Insert(insertionIndex + pointsAddedCount, mid);
pointsAddedCount++;
pointsAddedCount += FindDrawingPoints(curveIndex, tMid, t1, pointList, insertionIndex + pointsAddedCount);
return pointsAddedCount;
}
return 0;
}
/**
Calculates a point on the Bezier curve represented with the four control points given.
*/
private Vector2 CalculateBezierPoint(float t, Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3)
{
float u = 1 - t;
float tt = t * t;
float uu = u * u;
float uuu = uu * u;
float ttt = tt * t;
Vector2 p = uuu * p0; //first term
p += 3 * uu * t * p1; //second term
p += 3 * u * tt * p2; //third term
p += ttt * p3; //fourth term
return p;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 89b61e0416e1256469165fca78d5ed21
timeCreated: 1463598733
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,25 @@
Sourced from Unity forums - [LZF compression and decompression for Unity](http://forum.unity3d.com/threads/lzf-compression-and-decompression-for-unity.152579/)
#Description#
The LZF Compression component is a useful extension to Unity to be able to compress data for sending over a network or for more efficient saving.
This was provided via Unity forum guru [mrbroshkin](http://forum.unity3d.com/members/mrbroshkin.124231/) based of [Agent_007](http://forum.unity3d.com/members/agent_007.78088/) initial conversion work.
#What's included#
The library is complete and has even been patched a few times already through the forum thread, so I took the most stable version without issues. (issus were reported on other versions, so I didn't take them)
There are some Unit Tests included in the following file:
>Assets\unity-ui-extensions\Scripts\Editor\CompressionTests.cs
These details some sample use cases and also provide a good way to test that the compression/decompression works as expected.
To run these Unit Tests In Unity 5.3, open the following editor window from the menu to see the tests and run them.
>Window\Editor Tests Runner
(For earlier versions of Unity, you will need to install the "Unity Test Tools" asset from the store and follow the instructions from there.)
#Contribute#
Feel free to submit patches (if required) back to the project to increase the scope and enjoy
#Notes#
When encoding data to byte array's for compression, it's best to use the Unicode character set to avoid issue. Some other encodings don't work as well with this lib. Example details found in the UnitTests.
Part of the reason I added this library, since it's not really UI, is to support the Serialisation component. Both together provide a useful solution for packing data to save or send over a network.

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 125e21ede8cf31746b15797b86e6a479
timeCreated: 1464945707
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,340 @@
//
// http://forum.unity3d.com/threads/lzf-compression-and-decompression-for-unity.152579/
//
/*
* Improved version to C# LibLZF Port:
* Copyright (c) 2010 Roman Atachiants <kelindar@gmail.com>
*
* Original CLZF Port:
* Copyright (c) 2005 Oren J. Maurice <oymaurice@hazorea.org.il>
*
* Original LibLZF Library Algorithm:
* Copyright (c) 2000-2008 Marc Alexander Lehmann <schmorp@schmorp.de>
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License version 2 (the "GPL"), in which case the
* provisions of the GPL are applicable instead of the above. If you wish to
* allow the use of your version of this file only under the terms of the
* GPL and not to allow others to use your version of this file under the
* BSD license, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the GPL. If
* you do not delete the provisions above, a recipient may use your version
* of this file under either the BSD or the GPL.
*/
/* Benchmark with Alice29 Canterbury Corpus
---------------------------------------
(Compression) Original CLZF C#
Raw = 152089, Compressed = 101092
8292,4743 ms.
---------------------------------------
(Compression) My LZF C#
Raw = 152089, Compressed = 101092
33,0019 ms.
---------------------------------------
(Compression) Zlib using SharpZipLib
Raw = 152089, Compressed = 54388
8389,4799 ms.
---------------------------------------
(Compression) QuickLZ C#
Raw = 152089, Compressed = 83494
80,0046 ms.
---------------------------------------
(Decompression) Original CLZF C#
Decompressed = 152089
16,0009 ms.
---------------------------------------
(Decompression) My LZF C#
Decompressed = 152089
15,0009 ms.
---------------------------------------
(Decompression) Zlib using SharpZipLib
Decompressed = 152089
3577,2046 ms.
---------------------------------------
(Decompression) QuickLZ C#
Decompressed = 152089
21,0012 ms.
*/
using System;
namespace UnityEngine.UI.Extensions
{
/// <summary>
/// Improved C# LZF Compressor, a very small data compression library. The compression algorithm is extremely fast.
/// Note for strings, ensure you only use Unicode else special characters may get corrupted.
public static class CLZF2
{
private static readonly uint HLOG = 14;
private static readonly uint HSIZE = (1 << 14);
private static readonly uint MAX_LIT = (1 << 5);
private static readonly uint MAX_OFF = (1 << 13);
private static readonly uint MAX_REF = ((1 << 8) + (1 << 3));
/// <summary>
/// Hashtable, that can be allocated only once
/// </summary>
private static readonly long[] HashTable = new long[HSIZE];
// Compresses inputBytes
public static byte[] Compress(byte[] inputBytes)
{
// Starting guess, increase it later if needed
int outputByteCountGuess = inputBytes.Length * 2;
byte[] tempBuffer = new byte[outputByteCountGuess];
int byteCount = lzf_compress(inputBytes, ref tempBuffer);
// If byteCount is 0, then increase buffer and try again
while (byteCount == 0)
{
outputByteCountGuess *= 2;
tempBuffer = new byte[outputByteCountGuess];
byteCount = lzf_compress(inputBytes, ref tempBuffer);
}
byte[] outputBytes = new byte[byteCount];
Buffer.BlockCopy(tempBuffer, 0, outputBytes, 0, byteCount);
return outputBytes;
}
// Decompress outputBytes
public static byte[] Decompress(byte[] inputBytes)
{
// Starting guess, increase it later if needed
int outputByteCountGuess = inputBytes.Length * 2;
byte[] tempBuffer = new byte[outputByteCountGuess];
int byteCount = lzf_decompress(inputBytes, ref tempBuffer);
// If byteCount is 0, then increase buffer and try again
while (byteCount == 0)
{
outputByteCountGuess *= 2;
tempBuffer = new byte[outputByteCountGuess];
byteCount = lzf_decompress(inputBytes, ref tempBuffer);
}
byte[] outputBytes = new byte[byteCount];
Buffer.BlockCopy(tempBuffer, 0, outputBytes, 0, byteCount);
return outputBytes;
}
/// <summary>
/// Compresses the data using LibLZF algorithm
/// </summary>
/// <param name="input">Reference to the data to compress</param>
/// <param name="output">Reference to a buffer which will contain the compressed data</param>
/// <returns>The size of the compressed archive in the output buffer</returns>
public static int lzf_compress(byte[] input, ref byte[] output)
{
int inputLength = input.Length;
int outputLength = output.Length;
Array.Clear(HashTable, 0, (int)HSIZE);
long hslot;
uint iidx = 0;
uint oidx = 0;
long reference;
uint hval = (uint)(((input[iidx]) << 8) | input[iidx + 1]); // FRST(in_data, iidx);
long off;
int lit = 0;
for (;;)
{
if (iidx < inputLength - 2)
{
hval = (hval << 8) | input[iidx + 2];
hslot = ((hval ^ (hval << 5)) >> (int)(((3 * 8 - HLOG)) - hval * 5) & (HSIZE - 1));
reference = HashTable[hslot];
HashTable[hslot] = (long)iidx;
if ((off = iidx - reference - 1) < MAX_OFF
&& iidx + 4 < inputLength
&& reference > 0
&& input[reference + 0] == input[iidx + 0]
&& input[reference + 1] == input[iidx + 1]
&& input[reference + 2] == input[iidx + 2]
)
{
/* match found at *reference++ */
uint len = 2;
uint maxlen = (uint)inputLength - iidx - len;
maxlen = maxlen > MAX_REF ? MAX_REF : maxlen;
if (oidx + lit + 1 + 3 >= outputLength)
return 0;
do
len++;
while (len < maxlen && input[reference + len] == input[iidx + len]);
if (lit != 0)
{
output[oidx++] = (byte)(lit - 1);
lit = -lit;
do
output[oidx++] = input[iidx + lit];
while ((++lit) != 0);
}
len -= 2;
iidx++;
if (len < 7)
{
output[oidx++] = (byte)((off >> 8) + (len << 5));
}
else
{
output[oidx++] = (byte)((off >> 8) + (7 << 5));
output[oidx++] = (byte)(len - 7);
}
output[oidx++] = (byte)off;
iidx += len - 1;
hval = (uint)(((input[iidx]) << 8) | input[iidx + 1]);
hval = (hval << 8) | input[iidx + 2];
HashTable[((hval ^ (hval << 5)) >> (int)(((3 * 8 - HLOG)) - hval * 5) & (HSIZE - 1))] = iidx;
iidx++;
hval = (hval << 8) | input[iidx + 2];
HashTable[((hval ^ (hval << 5)) >> (int)(((3 * 8 - HLOG)) - hval * 5) & (HSIZE - 1))] = iidx;
iidx++;
continue;
}
}
else if (iidx == inputLength)
break;
/* one more literal byte we must copy */
lit++;
iidx++;
if (lit == MAX_LIT)
{
if (oidx + 1 + MAX_LIT >= outputLength)
return 0;
output[oidx++] = (byte)(MAX_LIT - 1);
lit = -lit;
do
output[oidx++] = input[iidx + lit];
while ((++lit) != 0);
}
}
if (lit != 0)
{
if (oidx + lit + 1 >= outputLength)
return 0;
output[oidx++] = (byte)(lit - 1);
lit = -lit;
do
output[oidx++] = input[iidx + lit];
while ((++lit) != 0);
}
return (int)oidx;
}
/// <summary>
/// Decompresses the data using LibLZF algorithm
/// </summary>
/// <param name="input">Reference to the data to decompress</param>
/// <param name="output">Reference to a buffer which will contain the decompressed data</param>
/// <returns>Returns decompressed size</returns>
public static int lzf_decompress(byte[] input, ref byte[] output)
{
int inputLength = input.Length;
int outputLength = output.Length;
uint iidx = 0;
uint oidx = 0;
do
{
uint ctrl = input[iidx++];
if (ctrl < (1 << 5)) /* literal run */
{
ctrl++;
if (oidx + ctrl > outputLength)
{
//SET_ERRNO (E2BIG);
return 0;
}
do
output[oidx++] = input[iidx++];
while ((--ctrl) != 0);
}
else /* back reference */
{
uint len = ctrl >> 5;
int reference = (int)(oidx - ((ctrl & 0x1f) << 8) - 1);
if (len == 7)
len += input[iidx++];
reference -= input[iidx++];
if (oidx + len + 2 > outputLength)
{
//SET_ERRNO (E2BIG);
return 0;
}
if (reference < 0)
{
//SET_ERRNO (EINVAL);
return 0;
}
output[oidx++] = output[reference++];
output[oidx++] = output[reference++];
do
output[oidx++] = output[reference++];
while ((--len) != 0);
}
}
while (iidx < inputLength);
return (int)oidx;
}
}
}

View File

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

View File

@ -0,0 +1,233 @@
/// Credit Farfarer
/// Sourced from - https://gist.github.com/Farfarer/a765cd07920d48a8713a0c1924db6d70
/// Updated for UI / 2D - SimonDarksideJ
using System;
using System.Collections.Generic;
namespace UnityEngine.UI.Extensions
{
[System.Serializable]
public class CableCurve
{
[SerializeField]
Vector2 m_start;
[SerializeField]
Vector2 m_end;
[SerializeField]
float m_slack;
[SerializeField]
int m_steps;
[SerializeField]
bool m_regen;
static Vector2[] emptyCurve = new Vector2[] { new Vector2(0.0f, 0.0f), new Vector2(0.0f, 0.0f) };
[SerializeField]
Vector2[] points;
public bool regenPoints
{
get { return m_regen; }
set
{
m_regen = value;
}
}
public Vector2 start
{
get { return m_start; }
set
{
if (value != m_start)
m_regen = true;
m_start = value;
}
}
public Vector2 end
{
get { return m_end; }
set
{
if (value != m_end)
m_regen = true;
m_end = value;
}
}
public float slack
{
get { return m_slack; }
set
{
if (value != m_slack)
m_regen = true;
m_slack = Mathf.Max(0.0f, value);
}
}
public int steps
{
get { return m_steps; }
set
{
if (value != m_steps)
m_regen = true;
m_steps = Mathf.Max(2, value);
}
}
public Vector2 midPoint
{
get
{
Vector2 mid = Vector2.zero;
if (m_steps == 2)
{
return (points[0] + points[1]) * 0.5f;
}
else if (m_steps > 2)
{
int m = m_steps / 2;
if ((m_steps % 2) == 0)
{
mid = (points[m] + points[m + 1]) * 0.5f;
}
else
{
mid = points[m];
}
}
return mid;
}
}
public CableCurve()
{
points = emptyCurve;
m_start = Vector2.up;
m_end = Vector2.up + Vector2.right;
m_slack = 0.5f;
m_steps = 20;
m_regen = true;
}
public CableCurve(Vector2[] inputPoints)
{
points = inputPoints;
m_start = inputPoints[0];
m_end = inputPoints[1];
m_slack = 0.5f;
m_steps = 20;
m_regen = true;
}
public CableCurve(List<Vector2> inputPoints)
{
points = inputPoints.ToArray();
m_start = inputPoints[0];
m_end = inputPoints[1];
m_slack = 0.5f;
m_steps = 20;
m_regen = true;
}
public CableCurve(CableCurve v)
{
points = v.Points();
m_start = v.start;
m_end = v.end;
m_slack = v.slack;
m_steps = v.steps;
m_regen = v.regenPoints;
}
public Vector2[] Points()
{
if (!m_regen)
return points;
if (m_steps < 2)
return emptyCurve;
float lineDist = Vector2.Distance(m_end, m_start);
float lineDistH = Vector2.Distance(new Vector2(m_end.x, m_start.y), m_start);
float l = lineDist + Mathf.Max(0.0001f, m_slack);
float r = 0.0f;
float s = m_start.y;
float u = lineDistH;
float v = end.y;
if ((u - r) == 0.0f)
return emptyCurve;
float ztarget = Mathf.Sqrt(Mathf.Pow(l, 2.0f) - Mathf.Pow(v - s, 2.0f)) / (u - r);
int loops = 30;
int iterationCount = 0;
int maxIterations = loops * 10; // For safety.
bool found = false;
float z = 0.0f;
float ztest = 0.0f;
float zstep = 100.0f;
float ztesttarget = 0.0f;
for (int i = 0; i < loops; i++)
{
for (int j = 0; j < 10; j++)
{
iterationCount++;
ztest = z + zstep;
ztesttarget = (float)Math.Sinh(ztest) / ztest;
if (float.IsInfinity(ztesttarget))
continue;
if (ztesttarget == ztarget)
{
found = true;
z = ztest;
break;
}
else if (ztesttarget > ztarget)
{
break;
}
else
{
z = ztest;
}
if (iterationCount > maxIterations)
{
found = true;
break;
}
}
if (found)
break;
zstep *= 0.1f;
}
float a = (u - r) / 2.0f / z;
float p = (r + u - a * Mathf.Log((l + v - s) / (l - v + s))) / 2.0f;
float q = (v + s - l * (float)Math.Cosh(z) / (float)Math.Sinh(z)) / 2.0f;
points = new Vector2[m_steps];
float stepsf = m_steps - 1;
float stepf;
for (int i = 0; i < m_steps; i++)
{
stepf = i / stepsf;
Vector2 pos = Vector2.zero;
pos.x = Mathf.Lerp(start.x, end.x, stepf);
pos.y = a * (float)Math.Cosh(((stepf * lineDistH) - p) / a) + q;
points[i] = pos;
}
m_regen = false;
return points;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2444f085ab49ff24b888b175f46b55c7
timeCreated: 1501871616
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,82 @@
/// Credit Board To Bits Games
/// Original Sourced from - https://www.youtube.com/watch?v=Or3fA-UjnwU
/// Updated and modified for UI Extensions to be more generic
namespace UnityEngine.UI.Extensions
{
public class Circle
{
[SerializeField]
private float xAxis;
[SerializeField]
private float yAxis;
[SerializeField]
private int steps;
public float X
{
get { return xAxis; }
set { xAxis = value; }
}
public float Y
{
get { return yAxis; }
set { yAxis = value; }
}
public int Steps
{
get { return steps; }
set { steps = value; }
}
public Circle(float radius)
{
this.xAxis = radius;
this.yAxis = radius;
this.steps = 1;
}
public Circle(float radius, int steps)
{
this.xAxis = radius;
this.yAxis = radius;
this.steps = steps;
}
public Circle(float xAxis, float yAxis)
{
this.xAxis = xAxis;
this.yAxis = yAxis;
this.steps = 10;
}
public Circle(float xAxis, float yAxis, int steps)
{
this.xAxis = xAxis;
this.yAxis = yAxis;
this.steps = steps;
}
public Vector2 Evaluate(float t)
{
float increments = 360f / steps;
float angle = Mathf.Deg2Rad * increments * t;
float x = Mathf.Sin(angle) * xAxis;
float y = Mathf.Cos(angle) * yAxis;
return new Vector2(x, y);
}
public void Evaluate(float t, out Vector2 eval)
{
float increments = 360f / steps;
float angle = Mathf.Deg2Rad * increments * t;
eval.x = Mathf.Sin(angle) * xAxis;
eval.y = Mathf.Cos(angle) * yAxis;
}
}
}

View File

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

View File

@ -0,0 +1,31 @@
/// Credit FireOApache
/// sourced from: http://answers.unity3d.com/questions/1149417/ui-button-onclick-sensitivity-for-high-dpi-devices.html#answer-1197307
/*USAGE:
Simply place the script on the EventSystem in the scene to correct the drag thresholds*/
using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions
{
[RequireComponent(typeof(EventSystem))]
[AddComponentMenu("UI/Extensions/DragCorrector")]
public class DragCorrector : MonoBehaviour
{
public int baseTH = 6;
public int basePPI = 210;
public int dragTH = 0;
void Start()
{
dragTH = baseTH * (int)Screen.dpi / basePPI;
EventSystem es = GetComponent<EventSystem>();
if (es)
{
es.pixelDragThreshold = dragTH;
}
}
}
}

View File

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

View File

@ -0,0 +1,269 @@
using System;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.Serialization;
namespace UnityEngine.UI
{
/// <summary>
/// Simple toggle -- something that has an 'on' and 'off' states: checkbox, toggle button, radio button, etc.
/// </summary>
[AddComponentMenu("UI/Extensions/Extensions Toggle", 31)]
[RequireComponent(typeof(RectTransform))]
public class ExtensionsToggle : Selectable, IPointerClickHandler, ISubmitHandler, ICanvasElement
{
/// <summary>
/// Variable to identify this script, change the datatype if needed to fit your use case
/// </summary>
public string UniqueID;
public enum ToggleTransition
{
None,
Fade
}
[Serializable]
public class ToggleEvent : UnityEvent<bool>
{ }
[Serializable]
public class ToggleEventObject : UnityEvent<ExtensionsToggle>
{ }
/// <summary>
/// Transition type.
/// </summary>
public ToggleTransition toggleTransition = ToggleTransition.Fade;
/// <summary>
/// Graphic the toggle should be working with.
/// </summary>
public Graphic graphic;
// group that this toggle can belong to
[SerializeField]
private ExtensionsToggleGroup m_Group;
public ExtensionsToggleGroup Group
{
get { return m_Group; }
set
{
m_Group = value;
#if UNITY_EDITOR
if (Application.isPlaying)
#endif
{
SetToggleGroup(m_Group, true);
PlayEffect(true);
}
}
}
/// <summary>
/// Allow for delegate-based subscriptions for faster events than 'eventReceiver', and allowing for multiple receivers.
/// </summary>
[Tooltip("Use this event if you only need the bool state of the toggle that was changed")]
public ToggleEvent onValueChanged = new ToggleEvent();
/// <summary>
/// Allow for delegate-based subscriptions for faster events than 'eventReceiver', and allowing for multiple receivers.
/// </summary>
[Tooltip("Use this event if you need access to the toggle that was changed")]
public ToggleEventObject onToggleChanged = new ToggleEventObject();
// Whether the toggle is on
[FormerlySerializedAs("m_IsActive")]
[Tooltip("Is the toggle currently on or off?")]
[SerializeField]
private bool m_IsOn;
protected ExtensionsToggle()
{ }
#if UNITY_EDITOR
protected override void OnValidate()
{
base.OnValidate();
Set(m_IsOn, false);
PlayEffect(toggleTransition == ToggleTransition.None);
#if UNITY_2018_3_OR_NEWER
if (!Application.isPlaying)
#else
var prefabType = UnityEditor.PrefabUtility.GetPrefabType(this);
if (prefabType != UnityEditor.PrefabType.Prefab && !Application.isPlaying)
#endif
{
CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this);
}
}
#endif // if UNITY_EDITOR
public virtual void Rebuild(CanvasUpdate executing)
{
#if UNITY_EDITOR
if (executing == CanvasUpdate.Prelayout)
{
onValueChanged.Invoke(m_IsOn);
onToggleChanged.Invoke(this);
}
#endif
}
public virtual void LayoutComplete()
{ }
public virtual void GraphicUpdateComplete()
{ }
protected override void OnEnable()
{
base.OnEnable();
SetToggleGroup(m_Group, false);
PlayEffect(true);
}
protected override void OnDisable()
{
SetToggleGroup(null, false);
base.OnDisable();
}
protected override void OnDidApplyAnimationProperties()
{
// Check if isOn has been changed by the animation.
// Unfortunately there is no way to check if we don't have a graphic.
if (graphic != null)
{
bool oldValue = !Mathf.Approximately(graphic.canvasRenderer.GetColor().a, 0);
if (m_IsOn != oldValue)
{
m_IsOn = oldValue;
Set(!oldValue);
}
}
base.OnDidApplyAnimationProperties();
}
private void SetToggleGroup(ExtensionsToggleGroup newGroup, bool setMemberValue)
{
ExtensionsToggleGroup oldGroup = m_Group;
// Sometimes IsActive returns false in OnDisable so don't check for it.
// Rather remove the toggle too often than too little.
if (m_Group != null)
m_Group.UnregisterToggle(this);
// At runtime the group variable should be set but not when calling this method from OnEnable or OnDisable.
// That's why we use the setMemberValue parameter.
if (setMemberValue)
m_Group = newGroup;
// Only register to the new group if this Toggle is active.
if (m_Group != null && IsActive())
m_Group.RegisterToggle(this);
// If we are in a new group, and this toggle is on, notify group.
// Note: Don't refer to m_Group here as it's not guaranteed to have been set.
if (newGroup != null && newGroup != oldGroup && IsOn && IsActive())
m_Group.NotifyToggleOn(this);
}
/// <summary>
/// Whether the toggle is currently active.
/// </summary>
public bool IsOn
{
get { return m_IsOn; }
set
{
Set(value);
}
}
void Set(bool value)
{
Set(value, true);
}
void Set(bool value, bool sendCallback)
{
if (m_IsOn == value)
return;
// if we are in a group and set to true, do group logic
m_IsOn = value;
if (m_Group != null && IsActive())
{
if (m_IsOn || (!m_Group.AnyTogglesOn() && !m_Group.AllowSwitchOff))
{
m_IsOn = true;
m_Group.NotifyToggleOn(this);
}
}
// Always send event when toggle is clicked, even if value didn't change
// due to already active toggle in a toggle group being clicked.
// Controls like Dropdown rely on this.
// It's up to the user to ignore a selection being set to the same value it already was, if desired.
PlayEffect(toggleTransition == ToggleTransition.None);
if (sendCallback)
{
onValueChanged.Invoke(m_IsOn);
onToggleChanged.Invoke(this);
}
}
/// <summary>
/// Play the appropriate effect.
/// </summary>
private void PlayEffect(bool instant)
{
if (graphic == null)
return;
#if UNITY_EDITOR
if (!Application.isPlaying)
graphic.canvasRenderer.SetAlpha(m_IsOn ? 1f : 0f);
else
#endif
graphic.CrossFadeAlpha(m_IsOn ? 1f : 0f, instant ? 0f : 0.1f, true);
}
/// <summary>
/// Assume the correct visual state.
/// </summary>
protected override void Start()
{
PlayEffect(true);
}
private void InternalToggle()
{
if (!IsActive() || !IsInteractable())
return;
IsOn = !IsOn;
}
/// <summary>
/// React to clicks.
/// </summary>
public virtual void OnPointerClick(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left)
return;
InternalToggle();
}
public virtual void OnSubmit(BaseEventData eventData)
{
InternalToggle();
}
}
}

View File

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

View File

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Events;
using UnityEngine.EventSystems;
namespace UnityEngine.UI
{
[AddComponentMenu("UI/Extensions/Extensions Toggle Group")]
[DisallowMultipleComponent]
public class ExtensionsToggleGroup : UIBehaviour
{
[SerializeField]
private bool m_AllowSwitchOff = false;
public bool AllowSwitchOff { get { return m_AllowSwitchOff; } set { m_AllowSwitchOff = value; } }
private List<ExtensionsToggle> m_Toggles = new List<ExtensionsToggle>();
[Serializable]
public class ToggleGroupEvent : UnityEvent<bool>
{ }
public ToggleGroupEvent onToggleGroupChanged = new ToggleGroupEvent();
public ToggleGroupEvent onToggleGroupToggleChanged = new ToggleGroupEvent();
public ExtensionsToggle SelectedToggle { get; private set; }
protected ExtensionsToggleGroup()
{ }
private void ValidateToggleIsInGroup(ExtensionsToggle toggle)
{
if (toggle == null || !m_Toggles.Contains(toggle))
throw new ArgumentException(string.Format("Toggle {0} is not part of ToggleGroup {1}", new object[] { toggle, this }));
}
public void NotifyToggleOn(ExtensionsToggle toggle)
{
ValidateToggleIsInGroup(toggle);
// disable all toggles in the group
for (var i = 0; i < m_Toggles.Count; i++)
{
if (m_Toggles[i] == toggle)
{
SelectedToggle = toggle;
continue;
}
m_Toggles[i].IsOn = false;
}
onToggleGroupChanged.Invoke(AnyTogglesOn());
}
public void UnregisterToggle(ExtensionsToggle toggle)
{
if (m_Toggles.Contains(toggle))
{
m_Toggles.Remove(toggle);
toggle.onValueChanged.RemoveListener(NotifyToggleChanged);
}
}
private void NotifyToggleChanged(bool isOn)
{
onToggleGroupToggleChanged.Invoke(isOn);
}
public void RegisterToggle(ExtensionsToggle toggle)
{
if (!m_Toggles.Contains(toggle))
{
m_Toggles.Add(toggle);
toggle.onValueChanged.AddListener(NotifyToggleChanged);
}
}
public bool AnyTogglesOn()
{
return m_Toggles.Find(x => x.IsOn) != null;
}
public IEnumerable<ExtensionsToggle> ActiveToggles()
{
return m_Toggles.Where(x => x.IsOn);
}
public void SetAllTogglesOff()
{
bool oldAllowSwitchOff = m_AllowSwitchOff;
m_AllowSwitchOff = true;
for (var i = 0; i < m_Toggles.Count; i++)
m_Toggles[i].IsOn = false;
m_AllowSwitchOff = oldAllowSwitchOff;
}
public void HasTheGroupToggle(bool value)
{
Debug.Log("Testing, the group has toggled [" + value + "]");
}
public void HasAToggleFlipped(bool value)
{
Debug.Log("Testing, a toggle has toggled [" + value + "]");
}
}
}

View File

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

View File

@ -0,0 +1,33 @@
using System;
namespace UnityEngine.UI.Extensions
{
public static class ExtentionMethods
{
public static T GetOrAddComponent<T>(this GameObject child) where T : Component
{
T result = child.GetComponent<T>();
if (result == null)
{
result = child.AddComponent<T>();
}
return result;
}
public static bool IsPrefab(this GameObject gameObject)
{
if (gameObject == null)
{
throw new ArgumentNullException(nameof(gameObject));
}
return
!gameObject.scene.IsValid() &&
!gameObject.scene.isLoaded &&
gameObject.GetInstanceID() >= 0 &&
// I noticed that ones with IDs under 0 were objects I didn't recognize
!gameObject.hideFlags.HasFlag(HideFlags.HideInHierarchy);
// I don't care about GameObjects *inside* prefabs, just the overall prefab.
}
}
}

View File

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

View File

@ -0,0 +1,42 @@
/// Credit Vicente Russo
/// Sourced from - https://bitbucket.org/SimonDarksideJ/unity-ui-extensions/issues/23/returnkeytriggersbutton
using UnityEngine.Events;
namespace UnityEngine.UI.Extensions
{
/// <summary>
/// Usage: Add this component to the input and add the function to execute to the EnterSubmit event of this script
/// </summary>
[RequireComponent(typeof(InputField))]
[AddComponentMenu("UI/Extensions/Input Field Submit")]
public class InputFieldEnterSubmit : MonoBehaviour
{
[System.Serializable]
public class EnterSubmitEvent : UnityEvent<string>
{
}
public EnterSubmitEvent EnterSubmit;
public bool defocusInput = true;
private InputField _input;
void Awake()
{
_input = GetComponent<InputField>();
_input.onEndEdit.AddListener(OnEndEdit);
}
public void OnEndEdit(string txt)
{
if (!UIExtensionsInputManager.GetKeyDown(KeyCode.Return) && !UIExtensionsInputManager.GetKeyDown(KeyCode.KeypadEnter))
return;
EnterSubmit.Invoke(txt);
if (defocusInput)
{
UnityEngine.EventSystems.EventSystem.current.SetSelectedGameObject(null);
}
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bfc77d7b04a86f845b59fb0979e8ec53
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,21 @@
/// Credit Slipp Douglas Thompson
/// Sourced from - https://gist.github.com/capnslipp/349c18283f2fea316369
namespace UnityEngine.UI.Extensions
{
/// A concrete subclass of the Unity UI `Graphic` class that just skips drawing.
/// Useful for providing a raycast target without actually drawing anything.
[AddComponentMenu("Layout/Extensions/NonDrawingGraphic")]
public class NonDrawingGraphic : MaskableGraphic
{
public override void SetMaterialDirty() { return; }
public override void SetVerticesDirty() { return; }
/// Probably not necessary since the chain of calls `Rebuild()`->`UpdateGeometry()`->`DoMeshGeneration()`->`OnPopulateMesh()` won't happen; so here really just as a fail-safe.
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
return;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 51db53697a53f7a479b8570674dae649
timeCreated: 1483541456
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,28 @@
/// Credit FireOApache
/// sourced from: http://answers.unity3d.com/questions/1149417/ui-button-onclick-sensitivity-for-high-dpi-devices.html#answer-1197307
/*USAGE:
Simply place the script on A Text control in the scene to display the current PPI / DPI of the screen*/
namespace UnityEngine.UI.Extensions
{
[RequireComponent(typeof(Text))]
[AddComponentMenu("UI/Extensions/PPIViewer")]
public class PPIViewer : MonoBehaviour
{
private Text label;
void Awake()
{
label = GetComponent<Text>();
}
void Start()
{
if (label != null)
{
label.text = "PPI: " + Screen.dpi.ToString();
}
}
}
}

View File

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

View File

@ -0,0 +1,139 @@
using System.Collections.Generic;
/// Credit Brogan King (@BroganKing)
/// Original Sourced from - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/158/pagination-script
using System.Linq;
namespace UnityEngine.UI.Extensions
{
[AddComponentMenu("UI/Extensions/Pagination Manager")]
public class PaginationManager : ToggleGroup
{
private List<Toggle> m_PaginationChildren;
[SerializeField]
private ScrollSnapBase scrollSnap = null;
private bool isAClick;
public int CurrentPage
{
get { return scrollSnap.CurrentPage; }
}
protected PaginationManager()
{ }
// Use this for initialization
protected override void Start()
{
base.Start();
if (scrollSnap == null)
{
Debug.LogError("A ScrollSnap script must be attached");
return;
}
// do not want the scroll snap pagination
if (scrollSnap.Pagination)
scrollSnap.Pagination = null;
// set scroll snap listeners
scrollSnap.OnSelectionPageChangedEvent.AddListener(SetToggleGraphics);
scrollSnap.OnSelectionChangeEndEvent.AddListener(OnPageChangeEnd);
ResetPaginationChildren();
}
/// <summary>
/// Remake the internal list of child toggles (m_PaginationChildren).
/// Used after adding/removing a toggle.
/// </summary>
public void ResetPaginationChildren()
{
// add selectables to list
m_PaginationChildren = GetComponentsInChildren<Toggle>().ToList<Toggle>();
for (int i = 0; i < m_PaginationChildren.Count; i++)
{
m_PaginationChildren[i].onValueChanged.AddListener(ToggleClick);
m_PaginationChildren[i].group = this;
m_PaginationChildren[i].isOn = false;
}
// set toggles on start
SetToggleGraphics(CurrentPage);
// warn user that they have uneven amount of pagination toggles to page count
if (m_PaginationChildren.Count != scrollSnap._scroll_rect.content.childCount)
Debug.LogWarning("Uneven pagination icon to page count");
}
/// <summary>
/// Calling from other scripts if you need to change screens programmatically
/// </summary>
/// <param name="pageNo"></param>
public void GoToScreen(int pageNo)
{
scrollSnap.GoToScreen(pageNo, true);
}
/// <summary>
/// Calls GoToScreen() based on the index of toggle that was pressed
/// </summary>
/// <param name="target"></param>
private void ToggleClick(Toggle target)
{
if (!target.isOn)
{
isAClick = true;
GoToScreen(m_PaginationChildren.IndexOf(target));
}
}
private void ToggleClick(bool toggle)
{
if (toggle)
{
for (int i = 0; i < m_PaginationChildren.Count; i++)
{
if (m_PaginationChildren[i].isOn && !scrollSnap._suspendEvents)
{
GoToScreen(i);
break;
}
}
}
}
/// <summary>
/// Calls GoToScreen() based on the index of toggle that was pressed
/// </summary>
/// <param name="target"></param>
private void ToggleClick(int target)
{
isAClick = true;
GoToScreen(target);
}
private void SetToggleGraphics(int pageNo)
{
if (!isAClick)
{
m_PaginationChildren[pageNo].isOn = true;
//for (int i = 0; i < m_PaginationChildren.Count; i++)
//{
// m_PaginationChildren[i].isOn = pageNo == i ? true : false;
//}
}
}
private void OnPageChangeEnd(int pageNo)
{
isAClick = false;
}
}
}

View File

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

View File

@ -0,0 +1,7 @@
/// Credit tanoshimi
/// Sourced from - https://forum.unity3d.com/threads/read-only-fields.68976/
namespace UnityEngine.UI.Extensions
{
public class ReadOnlyAttribute : PropertyAttribute { }
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 244394c76ae0d484d83567b74f4332cd
timeCreated: 1498392707
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,36 @@
/// Credit Melang
/// Sourced from - http://forum.unity3d.com/members/melang.593409/
/// Updated SimonDarksideJ - reworked to 4.6.1 standards
using UnityEngine.EventSystems;
namespace UnityEngine.UI
{
[RequireComponent(typeof(InputField))]
[AddComponentMenu("UI/Extensions/Return Key Trigger")]
public class ReturnKeyTriggersButton : MonoBehaviour, ISubmitHandler
{
private EventSystem _system;
public Button button;
private bool highlight = true;
public float highlightDuration = 0.2f;
void Start()
{
_system = EventSystem.current;
}
void RemoveHighlight()
{
button.OnPointerExit(new PointerEventData(_system));
}
public void OnSubmit(BaseEventData eventData)
{
if (highlight) button.OnPointerEnter(new PointerEventData(_system));
button.OnPointerClick(new PointerEventData(_system));
if (highlight) Invoke("RemoveHighlight", highlightDuration);
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f08f1bd2c562a474c99ff9d746d3c99b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,149 @@
/// Credit srinivas sunil
/// sourced from: https://bitbucket.org/SimonDarksideJ/unity-ui-extensions/pull-requests/21/develop_53/diff
/// Updated by Hiep Eldest : https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/300/scrollconflictmanager-not-working-if
using UnityEngine.EventSystems;
/// <summary>
/// This is the most efficient way to handle scroll conflicts when there are multiple scroll rects, this is useful when there is a vertical scrollrect in/on a horizontal scrollrect or vice versa
/// Attach the script to the rect scroll and assign other rectscroll in the inspector (one is vertical and other is horizontal) gathered and modified from unity answers(delta snipper)
/// </summary>
namespace UnityEngine.UI.Extensions
{
[RequireComponent(typeof(ScrollRect))]
[AddComponentMenu("UI/Extensions/Scrollrect Conflict Manager")]
public class ScrollConflictManager : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
{
[Tooltip("The parent ScrollRect control hosting this ScrollSnap")]
public ScrollRect ParentScrollRect;
[Tooltip("The parent ScrollSnap control hosting this Scroll Snap.\nIf left empty, it will use the ScrollSnap of the ParentScrollRect")]
private ScrollSnapBase ParentScrollSnap;
private ScrollRect _myScrollRect;
private IBeginDragHandler[] _beginDragHandlers;
private IEndDragHandler[] _endDragHandlers;
private IDragHandler[] _dragHandlers;
//This tracks if the other one should be scrolling instead of the current one.
private bool scrollOther;
//This tracks whether the other one should scroll horizontally or vertically.
private bool scrollOtherHorizontally;
void Awake()
{
if (ParentScrollRect)
{
InitialiseConflictManager();
}
}
private void InitialiseConflictManager()
{
//Get the current scroll rect so we can disable it if the other one is scrolling
_myScrollRect = this.GetComponent<ScrollRect>();
//If the current scroll Rect has the vertical checked then the other one will be scrolling horizontally.
scrollOtherHorizontally = _myScrollRect.vertical;
//Check some attributes to let the user know if this wont work as expected
if (scrollOtherHorizontally)
{
if (_myScrollRect.horizontal)
Debug.LogError("You have added the SecondScrollRect to a scroll view that already has both directions selected");
if (!ParentScrollRect.horizontal)
Debug.LogError("The other scroll rect does not support scrolling horizontally");
}
else if (!ParentScrollRect.vertical)
{
Debug.LogError("The other scroll rect does not support scrolling vertically");
}
if (ParentScrollRect && !ParentScrollSnap)
{
ParentScrollSnap = ParentScrollRect.GetComponent<ScrollSnapBase>();
}
}
void Start()
{
if (ParentScrollRect)
{
AssignScrollRectHandlers();
}
}
private void AssignScrollRectHandlers()
{
_beginDragHandlers = ParentScrollRect.GetComponents<IBeginDragHandler>();
_dragHandlers = ParentScrollRect.GetComponents<IDragHandler>();
_endDragHandlers = ParentScrollRect.GetComponents<IEndDragHandler>();
}
public void SetParentScrollRect(ScrollRect parentScrollRect)
{
ParentScrollRect = parentScrollRect;
InitialiseConflictManager();
AssignScrollRectHandlers();
}
#region DragHandler
public void OnBeginDrag(PointerEventData eventData)
{
//Get the absolute values of the x and y differences so we can see which one is bigger and scroll the other scroll rect accordingly
float horizontal = Mathf.Abs(eventData.position.x - eventData.pressPosition.x);
float vertical = Mathf.Abs(eventData.position.y - eventData.pressPosition.y);
if (scrollOtherHorizontally)
{
if (horizontal > vertical)
{
scrollOther = true;
//disable the current scroll rect so it does not move.
_myScrollRect.enabled = false;
for (int i = 0, length = _beginDragHandlers.Length; i < length; i++)
{
_beginDragHandlers[i].OnBeginDrag(eventData);
if(ParentScrollSnap) ParentScrollSnap.OnBeginDrag(eventData);
}
}
}
else if (vertical > horizontal)
{
scrollOther = true;
//disable the current scroll rect so it does not move.
_myScrollRect.enabled = false;
for (int i = 0, length = _beginDragHandlers.Length; i < length; i++)
{
_beginDragHandlers[i].OnBeginDrag(eventData);
if (ParentScrollSnap) ParentScrollSnap.OnBeginDrag(eventData);
}
}
}
public void OnEndDrag(PointerEventData eventData)
{
if (scrollOther)
{
_myScrollRect.enabled = true;
scrollOther = false;
for (int i = 0, length = _endDragHandlers.Length; i < length; i++)
{
_endDragHandlers[i].OnEndDrag(eventData);
if (ParentScrollSnap) ParentScrollSnap.OnEndDrag(eventData);
}
}
}
public void OnDrag(PointerEventData eventData)
{
if (scrollOther)
{
for (int i = 0, length = _endDragHandlers.Length; i < length; i++)
{
_dragHandlers[i].OnDrag(eventData);
if (ParentScrollSnap) ParentScrollSnap.OnDrag(eventData);
}
}
}
#endregion DragHandler
}
}

View File

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

View File

@ -0,0 +1,109 @@
/// Credit CaptainSchnittchen
/// Credit TouchPad (OnScroll function) update - GamesRUs
/// sourced from: http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-2011648
/*USAGE:
Simply place the script on the ScrollRect that contains the selectable children we'll be scrolling to
and drag'n'drop the RectTransform of the options "container" that we'll be scrolling.*/
using System;
using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions
{
[AddComponentMenu("UI/Extensions/ScrollRectEx")]
public class ScrollRectEx : ScrollRect
{
private bool routeToParent = false;
/// <summary>
/// Do action for all parents
/// </summary>
private void DoForParents<T>(Action<T> action) where T : IEventSystemHandler
{
Transform parent = transform.parent;
while (parent != null)
{
foreach (var component in parent.GetComponents<Component>())
{
if (component is T)
action((T)(IEventSystemHandler)component);
}
parent = parent.parent;
}
}
/// <summary>
/// Always route initialize potential drag event to parents
/// </summary>
public override void OnInitializePotentialDrag(PointerEventData eventData)
{
DoForParents<IInitializePotentialDragHandler>((parent) => { parent.OnInitializePotentialDrag(eventData); });
base.OnInitializePotentialDrag(eventData);
}
/// <summary>
/// Drag event
/// </summary>
public override void OnDrag(UnityEngine.EventSystems.PointerEventData eventData)
{
if (routeToParent)
DoForParents<IDragHandler>((parent) => { parent.OnDrag(eventData); });
else
base.OnDrag(eventData);
}
/// <summary>
/// Begin drag event
/// </summary>
public override void OnBeginDrag(UnityEngine.EventSystems.PointerEventData eventData)
{
if (!horizontal && Math.Abs(eventData.delta.x) > Math.Abs(eventData.delta.y))
routeToParent = true;
else if (!vertical && Math.Abs(eventData.delta.x) < Math.Abs(eventData.delta.y))
routeToParent = true;
else
routeToParent = false;
if (routeToParent)
DoForParents<IBeginDragHandler>((parent) => { parent.OnBeginDrag(eventData); });
else
base.OnBeginDrag(eventData);
}
/// <summary>
/// End drag event
/// </summary>
public override void OnEndDrag(UnityEngine.EventSystems.PointerEventData eventData)
{
if (routeToParent)
DoForParents<IEndDragHandler>((parent) => { parent.OnEndDrag(eventData); });
else
base.OnEndDrag(eventData);
routeToParent = false;
}
public override void OnScroll(PointerEventData eventData)
{
if (!horizontal && Math.Abs(eventData.scrollDelta.x) > Math.Abs(eventData.scrollDelta.y))
{
routeToParent = true;
}
else if (!vertical && Math.Abs(eventData.scrollDelta.x) < Math.Abs(eventData.scrollDelta.y))
{
routeToParent = true;
}
else
{
routeToParent = false;
}
if (routeToParent)
DoForParents<IScrollHandler>((parent) => {
parent.OnScroll(eventData);
});
else
base.OnScroll(eventData);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5a7b69ea2282ad240824a4bce7a65a46
timeCreated: 1440844492
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,17 @@
/// Credit Feaver1968
/// Sourced from - http://forum.unity3d.com/threads/scroll-to-the-bottom-of-a-scrollrect-in-code.310919/
namespace UnityEngine.UI.Extensions
{
public static class ScrollRectExtensions
{
public static void ScrollToTop(this ScrollRect scrollRect)
{
scrollRect.normalizedPosition = new Vector2(0, 1);
}
public static void ScrollToBottom(this ScrollRect scrollRect)
{
scrollRect.normalizedPosition = new Vector2(0, 0);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9abaa5d90896b4d4a937574b6b3878ab
timeCreated: 1440845965
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,34 @@
/// Credit Martin Sharkbomb
/// Sourced from - http://www.sharkbombs.com/2015/08/26/unity-ui-scrollrect-tools/
namespace UnityEngine.UI.Extensions
{
[RequireComponent(typeof(ScrollRect))]
[AddComponentMenu("UI/Extensions/ScrollRectLinker")]
public class ScrollRectLinker : MonoBehaviour
{
public bool clamp = true;
[SerializeField]
ScrollRect controllingScrollRect = null;
ScrollRect scrollRect = null;
void Awake()
{
scrollRect = GetComponent<ScrollRect>();
if (controllingScrollRect != null)
controllingScrollRect.onValueChanged.AddListener(MirrorPos);
}
void MirrorPos(Vector2 scrollPos)
{
if (clamp)
scrollRect.normalizedPosition = new Vector2(Mathf.Clamp01(scrollPos.x), Mathf.Clamp01(scrollPos.y));
else
scrollRect.normalizedPosition = scrollPos;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4f1f9a7e297738d47b8c6286a737406f
timeCreated: 1440840782
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,141 @@
/// Credit Martin Sharkbomb
/// Sourced from - http://www.sharkbombs.com/2015/08/26/unity-ui-scrollrect-tools/
using System.Collections;
using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions
{
[RequireComponent(typeof(ScrollRect))]
[AddComponentMenu("UI/Extensions/ScrollRectTweener")]
public class ScrollRectTweener : MonoBehaviour, IDragHandler
{
ScrollRect scrollRect;
Vector2 startPos;
Vector2 targetPos;
bool wasHorizontal;
bool wasVertical;
public float moveSpeed = 5000f;
public bool disableDragWhileTweening = false;
void Awake()
{
scrollRect = GetComponent<ScrollRect>();
wasHorizontal = scrollRect.horizontal;
wasVertical = scrollRect.vertical;
}
public void ScrollHorizontal(float normalizedX)
{
Scroll(new Vector2(normalizedX, scrollRect.verticalNormalizedPosition));
}
public void ScrollHorizontal(float normalizedX, float duration)
{
Scroll(new Vector2(normalizedX, scrollRect.verticalNormalizedPosition), duration);
}
public void ScrollVertical(float normalizedY)
{
Scroll(new Vector2(scrollRect.horizontalNormalizedPosition, normalizedY));
}
public void ScrollVertical(float normalizedY, float duration)
{
Scroll(new Vector2(scrollRect.horizontalNormalizedPosition, normalizedY), duration);
}
public void Scroll(Vector2 normalizedPos)
{
Scroll(normalizedPos, GetScrollDuration(normalizedPos));
}
float GetScrollDuration(Vector2 normalizedPos)
{
Vector2 currentPos = GetCurrentPos();
return Vector2.Distance(DeNormalize(currentPos), DeNormalize(normalizedPos)) / moveSpeed;
}
Vector2 DeNormalize(Vector2 normalizedPos)
{
return new Vector2(normalizedPos.x * scrollRect.content.rect.width, normalizedPos.y * scrollRect.content.rect.height);
}
Vector2 GetCurrentPos()
{
return new Vector2(scrollRect.horizontalNormalizedPosition, scrollRect.verticalNormalizedPosition);
}
public void Scroll(Vector2 normalizedPos, float duration)
{
startPos = GetCurrentPos();
targetPos = normalizedPos;
if (disableDragWhileTweening)
LockScrollability();
StopAllCoroutines();
StartCoroutine(DoMove(duration));
}
IEnumerator DoMove(float duration)
{
// Abort if movement would be too short
if (duration < 0.05f)
yield break;
Vector2 posOffset = targetPos - startPos;
float currentTime = 0f;
while (currentTime < duration)
{
currentTime += Time.deltaTime;
scrollRect.normalizedPosition = EaseVector(currentTime, startPos, posOffset, duration);
yield return null;
}
scrollRect.normalizedPosition = targetPos;
if (disableDragWhileTweening)
RestoreScrollability();
}
public Vector2 EaseVector(float currentTime, Vector2 startValue, Vector2 changeInValue, float duration)
{
return new Vector2(
changeInValue.x * Mathf.Sin(currentTime / duration * (Mathf.PI / 2)) + startValue.x,
changeInValue.y * Mathf.Sin(currentTime / duration * (Mathf.PI / 2)) + startValue.y
);
}
public void OnDrag(PointerEventData eventData)
{
if (!disableDragWhileTweening)
StopScroll();
}
void StopScroll()
{
StopAllCoroutines();
if (disableDragWhileTweening)
RestoreScrollability();
}
void LockScrollability()
{
scrollRect.horizontal = false;
scrollRect.vertical = false;
}
void RestoreScrollability()
{
scrollRect.horizontal = wasHorizontal;
scrollRect.vertical = wasVertical;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 37838caa3fcff7f46a5e1418b35173c2
timeCreated: 1440840781
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,93 @@
///Credit Tomek S
///Sourced from - https://pastebin.com/NXYu37jC
using System.Collections;
using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions
{
[AddComponentMenu("UI/Extensions/Selectable Scalar")]
[RequireComponent(typeof(Button))]
public class SelectableScaler : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
public AnimationCurve animCurve;
[Tooltip("Animation speed multiplier")]
public float speed = 1;
private Vector3 initScale;
public Transform target;
Selectable selectable;
public Selectable Target
{
get
{
if (selectable == null)
selectable = GetComponent<Selectable>();
return selectable;
}
}
// Use this for initialization
void Awake()
{
if (target == null)
target = transform;
initScale = target.localScale;
}
void OnEnable()
{
target.localScale = initScale;
}
public void OnPointerDown(PointerEventData eventData)
{
if (Target != null && !Target.interactable)
return;
StopCoroutine("ScaleOUT");
StartCoroutine("ScaleIN");
}
public void OnPointerUp(PointerEventData eventData)
{
if (Target != null && !Target.interactable)
return;
StopCoroutine("ScaleIN");
StartCoroutine("ScaleOUT");
}
IEnumerator ScaleIN()
{
if (animCurve.keys.Length > 0)
{
target.localScale = initScale;
float t = 0;
float maxT = animCurve.keys[animCurve.length - 1].time;
while (t < maxT)
{
t += speed * Time.unscaledDeltaTime;
target.localScale = Vector3.one * animCurve.Evaluate(t);
yield return null;
}
}
}
IEnumerator ScaleOUT()
{
if (animCurve.keys.Length > 0)
{
//target.localScale = initScale;
float t = 0;
float maxT = animCurve.keys[animCurve.length - 1].time;
while (t < maxT)
{
t += speed * Time.unscaledDeltaTime;
target.localScale = Vector3.one * animCurve.Evaluate(maxT - t);
yield return null;
}
transform.localScale = initScale;
}
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 65fce2c84ce1eff4383c094d715a7e1b
timeCreated: 1492258094
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,36 @@
/// <summary>
/// Tool script taken from the UI source as it's set to Internal for some reason. So to use in the extensions project it is needed here also.
/// </summary>
///
namespace UnityEngine.UI.Extensions
{
internal static class SetPropertyUtility
{
public static bool SetColor(ref Color currentValue, Color newValue)
{
if (currentValue.r == newValue.r && currentValue.g == newValue.g && currentValue.b == newValue.b && currentValue.a == newValue.a)
return false;
currentValue = newValue;
return true;
}
public static bool SetStruct<T>(ref T currentValue, T newValue) where T: struct
{
if (currentValue.Equals(newValue))
return false;
currentValue = newValue;
return true;
}
public static bool SetClass<T>(ref T currentValue, T newValue) where T: class
{
if ((currentValue == null && newValue == null) || (currentValue != null && currentValue.Equals(newValue)))
return false;
currentValue = newValue;
return true;
}
}
}

View File

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

View File

@ -0,0 +1,27 @@
/// Credit SimonDarksideJ
using System.Collections.Generic;
namespace UnityEngine.UI.Extensions
{
public static class ShaderLibrary
{
public static Dictionary<string, Shader> shaderInstances = new Dictionary<string, Shader>();
public static Shader[] preLoadedShaders;
public static Shader GetShaderInstance(string shaderName)
{
if (shaderInstances.ContainsKey(shaderName))
{
return shaderInstances[shaderName];
}
var newInstance = Shader.Find(shaderName);
if (newInstance != null)
{
shaderInstances.Add(shaderName, newInstance);
}
return newInstance;
}
}
}

View File

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

View File

@ -0,0 +1,14 @@
using UnityEngine;
public class TestCompression : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 585e75d4a56389b4690b3506f37751bc
timeCreated: 1464883584
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,65 @@
/// Credit Simon (simonDarksideJ) Jackson
/// Sourced from - My head
namespace UnityEngine.UI.Extensions
{
public static class UIExtensionMethods
{
public static Canvas GetParentCanvas(this RectTransform rt)
{
RectTransform parent = rt;
Canvas parentCanvas = rt.GetComponent<Canvas>();
int SearchIndex = 0;
while (parentCanvas == null || SearchIndex > 50)
{
parentCanvas = rt.GetComponentInParent<Canvas>();
if (parentCanvas == null)
{
parent = parent.parent.GetComponent<RectTransform>();
SearchIndex++;
}
}
return parentCanvas;
}
public static Vector2 TransformInputBasedOnCanvasType(this Vector2 input, Canvas canvas)
{
if (canvas.renderMode == RenderMode.ScreenSpaceOverlay)
{
return canvas.GetEventCamera().ScreenToWorldPoint(input);
}
else
{
return input;
}
}
public static Vector3 TransformInputBasedOnCanvasType(this Vector2 input, RectTransform rt)
{
var canvas = rt.GetParentCanvas();
if (input == Vector2.zero || canvas.renderMode == RenderMode.ScreenSpaceOverlay)
{
return input;
}
else
{
// Needs work :S
Vector2 movePos;
RectTransformUtility.ScreenPointToLocalPointInRectangle(
rt,
input, canvas.GetEventCamera(),
out movePos);
Vector3 output = canvas.transform.TransformPoint(movePos);
return output;
}
}
public static Camera GetEventCamera(this Canvas input)
{
return input.worldCamera == null ? Camera.main : input.worldCamera;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 08fd87e2db0639a4caf7a053f227a470
timeCreated: 1498086098
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,296 @@
/// Credit SimonDarksideJ
/// Sourced from: https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/348/menu-manager-does-not-work-with-the-new
#if UNITY_2019_1_OR_NEWER && !ENABLE_LEGACY_INPUT_MANAGER
#define NEW_INPUT_SYSTEM
#endif
using System;
using System.Collections.Generic;
#if NEW_INPUT_SYSTEM
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
#endif
namespace UnityEngine.UI.Extensions
{
public static class UIExtensionsInputManager
{
#if NEW_INPUT_SYSTEM
private static bool[] mouseButtons = new bool[3] { false, false, false };
private static Dictionary<KeyCode, bool> keys = new Dictionary<KeyCode, bool>();
private static Dictionary<String, bool> buttons = new Dictionary<String, bool>();
#endif
public static bool GetMouseButton(int button)
{
#if NEW_INPUT_SYSTEM
if (Mouse.current == null)
{
return false;
}
return Mouse.current.leftButton.isPressed;
#else
return Input.GetMouseButton(button);
#endif
}
public static bool GetMouseButtonDown(int button)
{
#if NEW_INPUT_SYSTEM
if (Mouse.current == null)
{
return false;
}
if (Mouse.current.leftButton.isPressed)
{
if (!mouseButtons[button])
{
mouseButtons[button] = true;
return true;
}
}
return false;
#else
return Input.GetMouseButtonDown(button);
#endif
}
public static bool GetMouseButtonUp(int button)
{
#if NEW_INPUT_SYSTEM
if (Mouse.current == null)
{
return false;
}
if (mouseButtons[button] && !Mouse.current.leftButton.isPressed)
{
mouseButtons[button] = false;
return true;
}
return false;
#else
return Input.GetMouseButtonUp(button);
#endif
}
public static bool GetButton(string input)
{
#if NEW_INPUT_SYSTEM
ButtonControl buttonPressed = GetButtonControlFromString(input);
if (!buttons.ContainsKey(input))
{
buttons.Add(input, false);
}
return buttonPressed != null ? buttonPressed.isPressed : false;
#else
return Input.GetButton(input);
#endif
}
#if NEW_INPUT_SYSTEM
private static ButtonControl GetButtonControlFromString(string input)
{
if (Gamepad.current == null)
{
return null;
}
switch (input)
{
case "Submit":
return Gamepad.current.aButton;
case "Cancel":
return Gamepad.current.bButton;
default:
return null;
}
}
#endif
public static bool GetButtonDown(string input)
{
#if NEW_INPUT_SYSTEM
ButtonControl buttonPressed = GetButtonControlFromString(input);
if (buttonPressed.isPressed)
{
if (!buttons.ContainsKey(input))
{
buttons.Add(input, false);
}
if (!buttons[input])
{
buttons[input] = true;
return true;
}
}
else
{
buttons[input] = false;
}
return false;
#else
return Input.GetButtonDown(input);
#endif
}
public static bool GetButtonUp(string input)
{
#if NEW_INPUT_SYSTEM
ButtonControl buttonPressed = GetButtonControlFromString(input);
if (buttons[input] && !buttonPressed.isPressed)
{
buttons[input] = false;
return true;
}
return false;
#else
return Input.GetButtonUp(input);
#endif
}
public static bool GetKey(KeyCode key)
{
#if NEW_INPUT_SYSTEM
KeyControl keyPressed = GetKeyControlFromKeyCode(key);
if (!keys.ContainsKey(key))
{
keys.Add(key, false);
}
return keyPressed != null ? keyPressed.isPressed : false;
#else
return Input.GetKey(key);
#endif
}
#if NEW_INPUT_SYSTEM
private static KeyControl GetKeyControlFromKeyCode(KeyCode key)
{
if (Keyboard.current == null)
{
return null;
}
switch (key)
{
case KeyCode.Escape:
return Keyboard.current.escapeKey;
case KeyCode.KeypadEnter:
return Keyboard.current.numpadEnterKey;
case KeyCode.UpArrow:
return Keyboard.current.upArrowKey;
case KeyCode.DownArrow:
return Keyboard.current.downArrowKey;
case KeyCode.RightArrow:
return Keyboard.current.rightArrowKey;
case KeyCode.LeftArrow:
return Keyboard.current.leftArrowKey;
case KeyCode.LeftShift:
return Keyboard.current.leftShiftKey;
case KeyCode.Tab:
return Keyboard.current.tabKey;
default:
return null;
}
}
#endif
public static bool GetKeyDown(KeyCode key)
{
#if NEW_INPUT_SYSTEM
KeyControl keyPressed = GetKeyControlFromKeyCode(key);
if (keyPressed.isPressed)
{
if (!keys.ContainsKey(key))
{
keys.Add(key, false);
}
if (!keys[key])
{
keys[key] = true;
return true;
}
}
else
{
keys[key] = false;
}
return false;
#else
return Input.GetKeyDown(key);
#endif
}
public static bool GetKeyUp(KeyCode key)
{
#if NEW_INPUT_SYSTEM
KeyControl keyPressed = GetKeyControlFromKeyCode(key);
if (keys[key] && !keyPressed.isPressed)
{
keys[key] = false;
return true;
}
return false;
#else
return Input.GetKeyUp(key);
#endif
}
public static float GetAxisRaw(string axis)
{
#if NEW_INPUT_SYSTEM
if (Gamepad.current == null)
{
return 0f;
}
switch (axis)
{
case "Horizontal":
return Gamepad.current.leftStick.x.ReadValue();
case "Vertical":
return Gamepad.current.leftStick.y.ReadValue();
}
return 0f;
#else
return Input.GetAxisRaw(axis);
#endif
}
public static Vector3 MousePosition
{
get
{
#if NEW_INPUT_SYSTEM
return Mouse.current.position.ReadValue();
#else
return Input.mousePosition;
#endif
}
}
public static Vector3 MouseScrollDelta
{
get
{
#if NEW_INPUT_SYSTEM
return Mouse.current.position.ReadValue();
#else
return Input.mouseScrollDelta;
#endif
}
}
}
}

View File

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

View File

@ -0,0 +1,119 @@
/// Credit SimonDarksideJ
/// Sourced from - Issue Proposal #153
using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions
{
[AddComponentMenu("UI/Extensions/UI Highlightable Extension")]
[RequireComponent(typeof(RectTransform), typeof(Graphic))]
public class UIHighlightable : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
{
private Graphic m_Graphic;
private bool m_Highlighted;
private bool m_Pressed;
[System.Serializable]
public class InteractableChangedEvent : Events.UnityEvent<bool> { }
[SerializeField][Tooltip("Can this panel be interacted with or is it disabled? (does not affect child components)")]
private bool m_Interactable = true;
[SerializeField][Tooltip("Does the panel remain in the pressed state when clicked? (default false)")]
private bool m_ClickToHold;
public bool Interactable
{
get { return m_Interactable; }
set
{
m_Interactable = value;
HighlightInteractable(m_Graphic);
OnInteractableChanged.Invoke(m_Interactable);
}
}
public bool ClickToHold
{
get { return m_ClickToHold; }
set { m_ClickToHold = value; }
}
[Tooltip("The default color for the panel")]
public Color NormalColor = Color.grey;
[Tooltip("The color for the panel when a mouse is over it or it is in focus")]
public Color HighlightedColor = Color.yellow;
[Tooltip("The color for the panel when it is clicked/held")]
public Color PressedColor = Color.green;
[Tooltip("The color for the panel when it is not interactable (see Interactable)")]
public Color DisabledColor = Color.gray;
[Tooltip("Event for when the panel is enabled / disabled, to enable disabling / enabling of child or other gameobjects")]
public InteractableChangedEvent OnInteractableChanged;
void Awake()
{
m_Graphic = GetComponent<Graphic>();
}
public void OnPointerEnter(PointerEventData eventData)
{
if (Interactable && !m_Pressed)
{
m_Highlighted = true;
m_Graphic.color = HighlightedColor;
}
}
public void OnPointerExit(PointerEventData eventData)
{
if (Interactable && !m_Pressed)
{
m_Highlighted = false;
m_Graphic.color = NormalColor;
}
}
public void OnPointerDown(PointerEventData eventData)
{
if (Interactable)
{
m_Graphic.color = PressedColor;
if (ClickToHold)
{
m_Pressed = !m_Pressed;
}
}
}
public void OnPointerUp(PointerEventData eventData)
{
if(!m_Pressed) HighlightInteractable(m_Graphic);
}
private void HighlightInteractable(Graphic graphic)
{
if (m_Interactable)
{
if (m_Highlighted)
{
graphic.color = HighlightedColor;
}
else
{
graphic.color = NormalColor;
}
}
else
{
graphic.color = DisabledColor;
}
}
#if UNITY_EDITOR
private void OnValidate()
{
HighlightInteractable(GetComponent<Graphic>());
}
#endif
}
}

View File

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

View File

@ -0,0 +1,86 @@
/// Credit Alastair Aitchison
/// Sourced from - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/123/uilinerenderer-issues-with-specifying
namespace UnityEngine.UI.Extensions
{
[AddComponentMenu("UI/Extensions/UI Line Connector")]
[RequireComponent(typeof(UILineRenderer))]
[ExecuteInEditMode]
public class UILineConnector : MonoBehaviour
{
// The elements between which line segments should be drawn
public RectTransform[] transforms;
private Vector3[] previousPositions;
private RectTransform canvas;
private RectTransform rt;
private UILineRenderer lr;
private void Awake()
{
canvas = GetComponentInParent<RectTransform>().GetParentCanvas().GetComponent<RectTransform>();
rt = GetComponent<RectTransform>();
lr = GetComponent<UILineRenderer>();
}
// Update is called once per frame
void Update()
{
if (transforms == null || transforms.Length < 1)
{
return;
}
//Performance check to only redraw when the child transforms move
if (previousPositions != null && previousPositions.Length == transforms.Length)
{
bool updateLine = false;
for (int i = 0; i < transforms.Length; i++)
{
if (!updateLine && previousPositions[i] != transforms[i].position)
{
updateLine = true;
}
}
if (!updateLine) return;
}
// Get the pivot points
Vector2 thisPivot = rt.pivot;
Vector2 canvasPivot = canvas.pivot;
// Set up some arrays of coordinates in various reference systems
Vector3[] worldSpaces = new Vector3[transforms.Length];
Vector3[] canvasSpaces = new Vector3[transforms.Length];
Vector2[] points = new Vector2[transforms.Length];
// First, convert the pivot to worldspace
for (int i = 0; i < transforms.Length; i++)
{
worldSpaces[i] = transforms[i].TransformPoint(thisPivot);
}
// Then, convert to canvas space
for (int i = 0; i < transforms.Length; i++)
{
canvasSpaces[i] = canvas.InverseTransformPoint(worldSpaces[i]);
}
// Calculate delta from the canvas pivot point
for (int i = 0; i < transforms.Length; i++)
{
points[i] = new Vector2(canvasSpaces[i].x, canvasSpaces[i].y);
}
// And assign the converted points to the line renderer
lr.Points = points;
lr.RelativeSize = false;
lr.drivenExternally = true;
previousPositions = new Vector3[transforms.Length];
for (int i = 0; i < transforms.Length; i++)
{
previousPositions[i] = transforms[i].position;
}
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8b52ee3a4491f3742bb35fa3eec798d3
timeCreated: 1498085244
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,303 @@
/// Credit zero3growlithe
/// sourced from: http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-2011648
/*USAGE:
Simply place the script on the ScrollRect that contains the selectable children you will be scrolling
*/
using System;
using System.Collections;
using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions
{
[RequireComponent(typeof(ScrollRect))]
[AddComponentMenu("UI/Extensions/UIScrollToSelection")]
public class UIScrollToSelection : MonoBehaviour
{
#region MEMBERS
[Header("[ References ]")]
[SerializeField, Tooltip("View (boundaries/mask) rect transform. Used to check if automatic scroll to selection is required.")]
private RectTransform viewportRectTransform;
[SerializeField, Tooltip("Scroll rect used to reach selected element.")]
private ScrollRect targetScrollRect;
[Header("[ Scrolling ]")]
[SerializeField, Tooltip("Allow automatic scrolling only on these axes.")]
private Axis scrollAxes = Axis.ANY;
[SerializeField, Tooltip("MOVE_TOWARDS: stiff movement, LERP: smoothed out movement")]
private ScrollMethod usedScrollMethod = ScrollMethod.MOVE_TOWARDS;
[SerializeField]
private float scrollSpeed = 50;
[Space(5)]
[SerializeField, Tooltip("Scroll speed used when element to select is out of \"JumpOffsetThreshold\" range")]
private float endOfListJumpScrollSpeed = 150;
[SerializeField, Range(0, 1), Tooltip("If next element to scroll to is located over this screen percentage, use \"EndOfListJumpScrollSpeed\" to reach this element faster.")]
private float jumpOffsetThreshold = 1;
[Header("[ Input ]")]
[SerializeField]
private MouseButton cancelScrollMouseButtons = MouseButton.ANY;
[SerializeField]
private KeyCode[] cancelScrollKeys = new KeyCode[0];
// INTERNAL - MEMBERS ONLY
private Vector3[] viewRectCorners = new Vector3[4];
private Vector3[] selectedElementCorners = new Vector3[4];
#endregion
#region PROPERTIES
// REFERENCES
public RectTransform ViewRectTransform
{
get { return viewportRectTransform; }
set { viewportRectTransform = value; }
}
public ScrollRect TargetScrollRect
{
get { return targetScrollRect; }
set { targetScrollRect = value; }
}
// SCROLLING
public Axis ScrollAxes => scrollAxes;
public ScrollMethod UsedScrollMethod => usedScrollMethod;
public float ScrollSpeed => scrollSpeed;
public float EndOfListJumpScrollSpeed => endOfListJumpScrollSpeed;
public float JumpOffsetThreshold => jumpOffsetThreshold;
// INPUT
public MouseButton CancelScrollMouseButtons => cancelScrollMouseButtons;
public KeyCode[] CancelScrollKeys => cancelScrollKeys;
// VARIABLES
private RectTransform scrollRectContentTransform;
private GameObject lastCheckedSelection;
// COROUTINES
private Coroutine animationCoroutine;
#endregion
#region FUNCTIONS
protected void Awake()
{
ValidateReferences();
}
protected void LateUpdate()
{
TryToScrollToSelection();
}
protected void Reset()
{
TargetScrollRect = gameObject.GetComponentInParent<ScrollRect>() ?? gameObject.GetComponentInChildren<ScrollRect>();
ViewRectTransform = gameObject.GetComponent<RectTransform>();
}
private void ValidateReferences()
{
if (!targetScrollRect)
{
targetScrollRect = GetComponent<ScrollRect>();
}
if (!targetScrollRect)
{
Debug.LogError("[UIScrollToSelection] No ScrollRect found. Either attach this script to a ScrollRect or assign on in the 'Target Scroll Rect' property");
gameObject.SetActive(false);
return;
}
if (ViewRectTransform == null)
{
ViewRectTransform = TargetScrollRect.GetComponent<RectTransform>();
}
if (TargetScrollRect != null)
{
scrollRectContentTransform = TargetScrollRect.content;
}
if (EventSystem.current == null)
{
Debug.LogError("[UIScrollToSelection] Unity UI EventSystem not found. It is required to check current selected object.");
gameObject.SetActive(false);
return;
}
}
private void TryToScrollToSelection()
{
// update references if selection changed
GameObject selection = EventSystem.current.currentSelectedGameObject;
if (selection == null || selection.activeInHierarchy == false || selection == lastCheckedSelection ||
selection.transform.IsChildOf(transform) == false)
{
return;
}
RectTransform selectionRect = selection.GetComponent<RectTransform>();
ViewRectTransform.GetWorldCorners(viewRectCorners);
selectionRect.GetWorldCorners(selectedElementCorners);
ScrollToSelection(selection);
lastCheckedSelection = selection;
}
private void ScrollToSelection(GameObject selection)
{
// initial check if we can scroll at all
if (selection == null)
{
return;
}
// this is just to make names shorter a bit
Vector3[] corners = viewRectCorners;
Vector3[] selectionCorners = selectedElementCorners;
// calculate scroll offset
Vector2 offsetToSelection = Vector2.zero;
offsetToSelection.x =
(selectionCorners[0].x < corners[0].x ? selectionCorners[0].x - corners[0].x : 0) +
(selectionCorners[2].x > corners[2].x ? selectionCorners[2].x - corners[2].x : 0);
offsetToSelection.y =
(selectionCorners[0].y < corners[0].y ? selectionCorners[0].y - corners[0].y : 0) +
(selectionCorners[1].y > corners[1].y ? selectionCorners[1].y - corners[1].y : 0);
// calculate final scroll speed
float finalScrollSpeed = ScrollSpeed;
if (Math.Abs(offsetToSelection.x) / Screen.width >= JumpOffsetThreshold || Math.Abs(offsetToSelection.y) / Screen.height >= JumpOffsetThreshold)
{
finalScrollSpeed = EndOfListJumpScrollSpeed;
}
// initiate animation coroutine
Vector2 targetPosition = (Vector2)scrollRectContentTransform.localPosition - offsetToSelection;
if (animationCoroutine != null)
{
StopCoroutine(animationCoroutine);
}
animationCoroutine = StartCoroutine(ScrollToPosition(targetPosition, finalScrollSpeed));
}
private IEnumerator ScrollToPosition(Vector2 targetPosition, float speed)
{
Vector3 startPosition = scrollRectContentTransform.localPosition;
// cancel movement on axes not specified in ScrollAxes mask
targetPosition.x = ((ScrollAxes | Axis.HORIZONTAL) == ScrollAxes) ? targetPosition.x : startPosition.x;
targetPosition.y = ((ScrollAxes | Axis.VERTICAL) == ScrollAxes) ? targetPosition.y : startPosition.y;
// move to target position
Vector2 currentPosition2D = startPosition;
float horizontalSpeed = (Screen.width / Screen.dpi) * speed;
float verticalSpeed = (Screen.height / Screen.dpi) * speed;
while (currentPosition2D != targetPosition && CheckIfScrollInterrupted() == false)
{
currentPosition2D.x = MoveTowardsValue(currentPosition2D.x, targetPosition.x, horizontalSpeed, UsedScrollMethod);
currentPosition2D.y = MoveTowardsValue(currentPosition2D.y, targetPosition.y, verticalSpeed, UsedScrollMethod);
scrollRectContentTransform.localPosition = currentPosition2D;
yield return null;
}
scrollRectContentTransform.localPosition = currentPosition2D;
}
private bool CheckIfScrollInterrupted()
{
bool mouseButtonClicked = false;
// check mouse buttons
switch (CancelScrollMouseButtons)
{
case MouseButton.LEFT:
mouseButtonClicked |= Input.GetMouseButtonDown(0);
break;
case MouseButton.RIGHT:
mouseButtonClicked |= Input.GetMouseButtonDown(1);
break;
case MouseButton.MIDDLE:
mouseButtonClicked |= Input.GetMouseButtonDown(2);
break;
}
if (mouseButtonClicked == true)
{
return true;
}
// check keyboard buttons
for (int i = 0; i < CancelScrollKeys.Length; i++)
{
if (Input.GetKeyDown(CancelScrollKeys[i]) == true)
{
return true;
}
}
return false;
}
private float MoveTowardsValue(float from, float to, float delta, ScrollMethod method)
{
switch (method)
{
case ScrollMethod.MOVE_TOWARDS:
return Mathf.MoveTowards(from, to, delta * Time.unscaledDeltaTime);
case ScrollMethod.LERP:
return Mathf.Lerp(from, to, delta * Time.unscaledDeltaTime);
default:
return from;
}
}
#endregion
#region CLASS_ENUMS
[Flags]
public enum Axis
{
NONE = 0x00000000,
HORIZONTAL = 0x00000001,
VERTICAL = 0x00000010,
ANY = 0x00000011
}
[Flags]
public enum MouseButton
{
NONE = 0x00000000,
LEFT = 0x00000001,
RIGHT = 0x00000010,
MIDDLE = 0x00000100,
ANY = 0x00000111
}
public enum ScrollMethod
{
MOVE_TOWARDS,
LERP
}
#endregion
}
}

View File

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

View File

@ -0,0 +1,123 @@
/// Credit zero3growlithe
/// sourced from: http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-2011648
/// Update by xesenix - based on UIScrollToSelection centers on selected element in scrollrect which can move in XY
/// you can restrict movement by locking axis on ScrollRect component
/*USAGE:
Simply place the script on the ScrollRect that contains the selectable children we'll be scrolling to
and drag'n'drop the RectTransform of the options "container" that we'll be scrolling.*/
using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions
{
[AddComponentMenu("UI/Extensions/UI ScrollTo Selection XY")]
[RequireComponent(typeof(ScrollRect))]
public class UIScrollToSelectionXY : MonoBehaviour
{
#region Variables
// settings
public float scrollSpeed = 10f;
[SerializeField]
private RectTransform layoutListGroup = null;
// temporary variables
private RectTransform targetScrollObject;
private bool scrollToSelection = true;
// references
private RectTransform scrollWindow = null;
private ScrollRect targetScrollRect = null;
#endregion
// Use this for initialization
private void Start()
{
targetScrollRect = GetComponent<ScrollRect>();
scrollWindow = targetScrollRect.GetComponent<RectTransform>();
}
// Update is called once per frame
private void Update()
{
ScrollRectToLevelSelection();
}
private void ScrollRectToLevelSelection()
{
// FIX: if you do not do that here events can have null value
var events = EventSystem.current;
// check main references
bool referencesAreIncorrect =
(targetScrollRect == null || layoutListGroup == null || scrollWindow == null);
if (referencesAreIncorrect == true)
{
return;
}
// get calculation references
RectTransform selection = events.currentSelectedGameObject != null ?
events.currentSelectedGameObject.GetComponent<RectTransform>() :
null;
if (selection != targetScrollObject)
{
scrollToSelection = true;
}
// check if scrolling is possible
bool isScrollDirectionUnknown = (selection == null || scrollToSelection == false);
if (isScrollDirectionUnknown == true || selection.transform.parent != layoutListGroup.transform)
{
return;
}
bool finishedX = false, finishedY = false;
if (targetScrollRect.vertical)
{
// move the current scroll rect to correct position
float selectionPos = -selection.anchoredPosition.y;
float listPixelAnchor = layoutListGroup.anchoredPosition.y;
// get the element offset value depending on the cursor move direction
float offlimitsValue = 0;
offlimitsValue = listPixelAnchor - selectionPos;
// move the target scroll rect
targetScrollRect.verticalNormalizedPosition += (offlimitsValue / layoutListGroup.sizeDelta.y) * Time.deltaTime * scrollSpeed;
finishedY = Mathf.Abs(offlimitsValue) < 2f;
}
if (targetScrollRect.horizontal)
{
// move the current scroll rect to correct position
float selectionPos = -selection.anchoredPosition.x;
float listPixelAnchor = layoutListGroup.anchoredPosition.x;
// get the element offset value depending on the cursor move direction
float offlimitsValue = 0;
offlimitsValue = listPixelAnchor - selectionPos;
// move the target scroll rect
targetScrollRect.horizontalNormalizedPosition += (offlimitsValue / layoutListGroup.sizeDelta.x) * Time.deltaTime * scrollSpeed;
finishedX = Mathf.Abs(offlimitsValue) < 2f;
}
// check if we reached our destination
if (finishedX && finishedY) {
scrollToSelection = false;
}
// save last object we were "heading to" to prevent blocking
targetScrollObject = selection;
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6580683838fcc12479150dd5e76e6b2e
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,119 @@
/// Credit AriathTheWise, Sfyne
/// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-1796783
/// Additional disabled - https://bitbucket.org/SimonDarksideJ/unity-ui-extensions/issues/47/uiselectableextension-_pressed-bug
/// Extended to include a HELD state that continually fires while the button is held down.
/// Refactored so it can be added to any button and expose the events in the editor.
using UnityEngine.Events;
using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions
{
/// <summary>
/// UIButton
/// </summary>
[AddComponentMenu("UI/Extensions/UI Selectable Extension")]
[RequireComponent(typeof(Selectable))]
public class UISelectableExtension : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
#region Sub-Classes
[System.Serializable]
public class UIButtonEvent : UnityEvent<PointerEventData.InputButton> { }
#endregion
#region Events
[Tooltip("Event that fires when a button is initially pressed down")]
public UIButtonEvent OnButtonPress;
[Tooltip("Event that fires when a button is released")]
public UIButtonEvent OnButtonRelease;
[Tooltip("Event that continually fires while a button is held down")]
public UIButtonEvent OnButtonHeld;
#endregion
private bool _pressed;
private PointerEventData _heldEventData;
void IPointerDownHandler.OnPointerDown(PointerEventData eventData)
{
//Can't set the state as it's too locked down.
//DoStateTransition(SelectionState.Pressed, false);
if (OnButtonPress != null)
{
OnButtonPress.Invoke(eventData.button);
}
_pressed = true;
_heldEventData = eventData;
}
void IPointerUpHandler.OnPointerUp(PointerEventData eventData)
{
//DoStateTransition(SelectionState.Normal, false);
if (OnButtonRelease != null)
{
OnButtonRelease.Invoke(eventData.button);
}
_pressed = false;
_heldEventData = null;
}
void Update()
{
if (!_pressed)
return;
if (OnButtonHeld != null)
{
OnButtonHeld.Invoke(_heldEventData.button);
}
}
/// <summary>
/// Test method to verify a control has been clicked
/// </summary>
public void TestClicked()
{
#if DEBUG || UNITY_EDITOR
Debug.Log("Control Clicked");
#endif
}
/// <summary>
/// Test method to verify a control is pressed
/// </summary>
public void TestPressed()
{
#if DEBUG || UNITY_EDITOR
Debug.Log("Control Pressed");
#endif
}
/// <summary>
/// est method to verify if a control is released
/// </summary>
public void TestReleased()
{
#if DEBUG || UNITY_EDITOR
Debug.Log("Control Released");
#endif
}
/// <summary>
/// est method to verify if a control is being held
/// </summary>
public void TestHold()
{
#if DEBUG || UNITY_EDITOR
Debug.Log("Control Held");
#endif
}
//Fixed UISelectableExtension inactive bug (if gameObject becomes inactive while button is held down it never goes back to _pressed = false)
void OnDisable()
{
_pressed = false;
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6bb501adc62c7394fae41ae7a6032eb3
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,218 @@
/// Credit Tomasz Schelenz
/// Sourced from - https://bitbucket.org/SimonDarksideJ/unity-ui-extensions/issues/81/infinite-scrollrect
/// Demo - https://www.youtube.com/watch?v=uVTV7Udx78k - configures automatically. - works in both vertical and horizontal (but not both at the same time) - drag and drop - can be initialized by code (in case you populate your scrollview content from code)
/// Updated by Febo Zodiaco - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/349/magnticinfinitescroll
using System.Collections.Generic;
namespace UnityEngine.UI.Extensions
{
/// <summary>
/// Infinite scroll view with automatic configuration
///
/// Fields
/// - InitByUSer - in case your scrollrect is populated from code, you can explicitly Initialize the infinite scroll after your scroll is ready
/// by calling Init() method
///
/// Notes
/// - does not work in both vertical and horizontal orientation at the same time.
/// - in order to work it disables layout components and size fitter if present(automatically)
///
/// </summary>
[AddComponentMenu("UI/Extensions/UI Infinite Scroll")]
public class UI_InfiniteScroll : MonoBehaviour
{
//if true user will need to call Init() method manually (in case the contend of the scrollview is generated from code or requires special initialization)
[Tooltip("If false, will Init automatically, otherwise you need to call Init() method")]
public bool InitByUser = false;
protected ScrollRect _scrollRect;
private ContentSizeFitter _contentSizeFitter;
private VerticalLayoutGroup _verticalLayoutGroup;
private HorizontalLayoutGroup _horizontalLayoutGroup;
private GridLayoutGroup _gridLayoutGroup;
protected bool _isVertical = false;
protected bool _isHorizontal = false;
private float _disableMarginX = 0;
private float _disableMarginY = 0;
private bool _hasDisabledGridComponents = false;
protected List<RectTransform> items = new List<RectTransform>();
private Vector2 _newAnchoredPosition = Vector2.zero;
//TO DISABLE FLICKERING OBJECT WHEN SCROLL VIEW IS IDLE IN BETWEEN OBJECTS
private float _threshold = 100f;
private int _itemCount = 0;
private float _recordOffsetX = 0;
private float _recordOffsetY = 0;
protected virtual void Awake()
{
if (!InitByUser)
Init();
}
public virtual void SetNewItems(ref List<Transform> newItems)
{
if (_scrollRect != null)
{
if (_scrollRect.content == null && newItems == null)
{
return;
}
if (items != null)
{
items.Clear();
}
for (int i = _scrollRect.content.childCount - 1; i >= 0; i--)
{
Transform child = _scrollRect.content.GetChild(i);
child.SetParent(null);
GameObject.DestroyImmediate(child.gameObject);
}
foreach (Transform newItem in newItems)
{
newItem.SetParent(_scrollRect.content);
}
SetItems();
}
}
private void SetItems()
{
for (int i = 0; i < _scrollRect.content.childCount; i++)
{
items.Add(_scrollRect.content.GetChild(i).GetComponent<RectTransform>());
}
_itemCount = _scrollRect.content.childCount;
}
public void Init()
{
if (GetComponent<ScrollRect>() != null)
{
_scrollRect = GetComponent<ScrollRect>();
_scrollRect.onValueChanged.AddListener(OnScroll);
_scrollRect.movementType = ScrollRect.MovementType.Unrestricted;
if (_scrollRect.content.GetComponent<VerticalLayoutGroup>() != null)
{
_verticalLayoutGroup = _scrollRect.content.GetComponent<VerticalLayoutGroup>();
}
if (_scrollRect.content.GetComponent<HorizontalLayoutGroup>() != null)
{
_horizontalLayoutGroup = _scrollRect.content.GetComponent<HorizontalLayoutGroup>();
}
if (_scrollRect.content.GetComponent<GridLayoutGroup>() != null)
{
_gridLayoutGroup = _scrollRect.content.GetComponent<GridLayoutGroup>();
}
if (_scrollRect.content.GetComponent<ContentSizeFitter>() != null)
{
_contentSizeFitter = _scrollRect.content.GetComponent<ContentSizeFitter>();
}
_isHorizontal = _scrollRect.horizontal;
_isVertical = _scrollRect.vertical;
if (_isHorizontal && _isVertical)
{
Debug.LogError("UI_InfiniteScroll doesn't support scrolling in both directions, please choose one direction (horizontal or vertical)");
}
SetItems();
}
else
{
Debug.LogError("UI_InfiniteScroll => No ScrollRect component found");
}
}
void DisableGridComponents()
{
if (_isVertical)
{
_recordOffsetY = items[1].GetComponent<RectTransform>().anchoredPosition.y - items[0].GetComponent<RectTransform>().anchoredPosition.y;
if (_recordOffsetY < 0)
{
_recordOffsetY *= -1;
}
_disableMarginY = _recordOffsetY * _itemCount / 2;
}
if (_isHorizontal)
{
_recordOffsetX = items[1].GetComponent<RectTransform>().anchoredPosition.x - items[0].GetComponent<RectTransform>().anchoredPosition.x;
if (_recordOffsetX < 0)
{
_recordOffsetX *= -1;
}
_disableMarginX = _recordOffsetX * _itemCount / 2;
}
if (_verticalLayoutGroup)
{
_verticalLayoutGroup.enabled = false;
}
if (_horizontalLayoutGroup)
{
_horizontalLayoutGroup.enabled = false;
}
if (_contentSizeFitter)
{
_contentSizeFitter.enabled = false;
}
if (_gridLayoutGroup)
{
_gridLayoutGroup.enabled = false;
}
_hasDisabledGridComponents = true;
}
public void OnScroll(Vector2 pos)
{
if (!_hasDisabledGridComponents)
DisableGridComponents();
for (int i = 0; i < items.Count; i++)
{
if (_isHorizontal)
{
if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).x > _disableMarginX + _threshold)
{
_newAnchoredPosition = items[i].anchoredPosition;
_newAnchoredPosition.x -= _itemCount * _recordOffsetX;
items[i].anchoredPosition = _newAnchoredPosition;
_scrollRect.content.GetChild(_itemCount - 1).transform.SetAsFirstSibling();
}
else if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).x < -_disableMarginX)
{
_newAnchoredPosition = items[i].anchoredPosition;
_newAnchoredPosition.x += _itemCount * _recordOffsetX;
items[i].anchoredPosition = _newAnchoredPosition;
_scrollRect.content.GetChild(0).transform.SetAsLastSibling();
}
}
if (_isVertical)
{
if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).y > _disableMarginY + _threshold)
{
_newAnchoredPosition = items[i].anchoredPosition;
_newAnchoredPosition.y -= _itemCount * _recordOffsetY;
items[i].anchoredPosition = _newAnchoredPosition;
_scrollRect.content.GetChild(_itemCount - 1).transform.SetAsFirstSibling();
}
else if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).y < -_disableMarginY)
{
_newAnchoredPosition = items[i].anchoredPosition;
_newAnchoredPosition.y += _itemCount * _recordOffsetY;
items[i].anchoredPosition = _newAnchoredPosition;
_scrollRect.content.GetChild(0).transform.SetAsLastSibling();
}
}
}
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 61fe0f6272fa94d4eb3dafc6aecd50ff
timeCreated: 1467462282
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,200 @@
/// Credit Febo Zodiaco
/// Sourced from - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/349/magnticinfinitescroll
///
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions
{
[AddComponentMenu("UI/Extensions/UI Magnetic Infinite Scroll")]
[RequireComponent(typeof(ScrollRect))]
public class UI_MagneticInfiniteScroll : UI_InfiniteScroll, IDragHandler, IEndDragHandler, IScrollHandler
{
public event Action<GameObject> OnNewSelect;
[Tooltip("The pointer to the pivot, the visual element for centering objects.")]
[SerializeField]
private RectTransform pivot = null;
[Tooltip("The maximum speed that allows you to activate the magnet to center on the pivot")]
[SerializeField]
private float maxSpeedForMagnetic = 10f;
[SerializeField]
[Tooltip("The index of the object which must be initially centered")]
private int indexStart = 0;
[SerializeField]
[Tooltip("The time to decelerate and aim to the pivot")]
private float timeForDeceleration = 0.05f;
private float _pastPositionMouseSpeed;
private float _initMovementDirection = 0;
private float _pastPosition = 0;
private float _currentSpeed = 0.0f;
private float _stopValue = 0.0f;
private readonly float _waitForContentSet = 0.1f;
private float _currentTime = 0;
private int _nearestIndex = 0;
private bool _useMagnetic = true;
private bool _isStopping = false;
private bool _isMovement = false;
public List<RectTransform> Items { get; }
protected override void Awake()
{
base.Awake();
StartCoroutine(SetInitContent());
}
private void Update()
{
if (_scrollRect == null || !_scrollRect.content || !pivot || !_useMagnetic || !_isMovement || items == null)
{
return;
}
float currentPosition = GetRightAxis(_scrollRect.content.anchoredPosition);
_currentSpeed = Mathf.Abs(currentPosition - _pastPosition);
_pastPosition = currentPosition;
if (Mathf.Abs(_currentSpeed) > maxSpeedForMagnetic)
{
return;
}
if (_isStopping)
{
Vector2 anchoredPosition = _scrollRect.content.anchoredPosition;
_currentTime += Time.deltaTime;
float valueLerp = _currentTime / timeForDeceleration;
float newPosition = Mathf.Lerp(GetRightAxis(anchoredPosition), _stopValue, valueLerp);
_scrollRect.content.anchoredPosition = _isVertical ? new Vector2(anchoredPosition.x, newPosition) :
new Vector2(newPosition, anchoredPosition.y);
if (newPosition == GetRightAxis(anchoredPosition) && _nearestIndex > 0 && _nearestIndex < items.Count)
{
_isStopping = false;
_isMovement = false;
var item = items[_nearestIndex];
if (item != null && OnNewSelect != null)
{
OnNewSelect.Invoke(item.gameObject);
}
}
}
else
{
float distance = Mathf.Infinity * (-_initMovementDirection);
for (int i = 0; i < items.Count; i++)
{
var item = items[i];
if (item == null)
{
continue;
}
var aux = GetRightAxis(item.position) - GetRightAxis(pivot.position);
if ((_initMovementDirection <= 0 && aux < distance && aux > 0) ||
(_initMovementDirection > 0 && aux > distance && aux < 0))
{
distance = aux;
_nearestIndex = i;
}
}
_isStopping = true;
_stopValue = GetAnchoredPositionForPivot(_nearestIndex);
_scrollRect.StopMovement();
}
}
public override void SetNewItems(ref List<Transform> newItems)
{
foreach (var element in newItems)
{
RectTransform rectTransform = element.GetComponent<RectTransform>();
if (rectTransform && pivot)
{
rectTransform.sizeDelta = pivot.sizeDelta;
}
}
base.SetNewItems(ref newItems);
}
public void SetContentInPivot(int index)
{
float newPos = GetAnchoredPositionForPivot(index);
Vector2 anchoredPosition = _scrollRect.content.anchoredPosition;
if (_scrollRect.content)
{
_scrollRect.content.anchoredPosition = _isVertical ? new Vector2(anchoredPosition.x, newPos) :
new Vector2(newPos, anchoredPosition.y);
_pastPosition = GetRightAxis(_scrollRect.content.anchoredPosition);
}
}
private IEnumerator SetInitContent()
{
yield return new WaitForSeconds(_waitForContentSet);
SetContentInPivot(indexStart);
}
private float GetAnchoredPositionForPivot(int index)
{
if (!pivot || items == null || items.Count < 0)
{
return 0f;
}
index = Mathf.Clamp(index, 0, items.Count - 1);
float posItem = GetRightAxis(items[index].anchoredPosition);
float posPivot = GetRightAxis(pivot.anchoredPosition);
return posPivot - posItem;
}
private void FinishPrepareMovement()
{
_isMovement = true;
_useMagnetic = true;
_isStopping = false;
_currentTime = 0;
}
private float GetRightAxis(Vector2 vector)
{
return _isVertical ? vector.y : vector.x;
}
public void OnDrag(PointerEventData eventData)
{
float currentPosition = GetRightAxis(UIExtensionsInputManager.MousePosition);
_initMovementDirection = Mathf.Sign(currentPosition - _pastPositionMouseSpeed);
_pastPositionMouseSpeed = currentPosition;
_useMagnetic = false;
_isStopping = false;
}
public void OnEndDrag(PointerEventData eventData)
{
FinishPrepareMovement();
}
public void OnScroll(PointerEventData eventData)
{
_initMovementDirection = -UIExtensionsInputManager.MouseScrollDelta.y;
FinishPrepareMovement();
}
}
}

View File

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

View File

@ -0,0 +1,200 @@
/// Credit Tomasz Schelenz
/// Sourced from - https://bitbucket.org/SimonDarksideJ/unity-ui-extensions/issues/82/scrollrectocclusion
/// Demo - https://youtu.be/uVTV7Udx78k?t=39s ScrollRectOcclusion - disables the objects outside of the scrollrect viewport. Useful for scrolls with lots of content, reduces geometry and drawcalls (if content is not batched) In some cases it might create a bit of spikes, especially if you have lots of UI.Text objects in the childs. In that case consider to Add CanvasGroup to your childs and instead of calling setActive on game object change CanvasGroup.alpha value. At 0 it is not being rendered hence will also optimize the performance.
using System.Collections.Generic;
namespace UnityEngine.UI.Extensions
{
/// <summary>
/// ScrollRectOcclusion - disables the objects outside of the scrollrect viewport.
/// Useful for scrolls with lots of content, reduces geometry and drawcalls (if content is not batched)
///
/// Fields
/// - InitByUSer - in case your scrollrect is populated from code, you can explicitly Initialize the infinite scroll after your scroll is ready
/// by calling Init() method
///
/// Notes
/// - In some cases it might create a bit of spikes, especially if you have lots of UI.Text objects in the child's. In that case consider to Add
/// CanvasGroup to your child's and instead of calling setActive on game object change CanvasGroup.alpha value. At 0 it is not being rendered hence will
/// also optimize the performance.
/// - works for both vertical and horizontal scrolls, even at the same time (grid layout)
/// - in order to work it disables layout components and size fitter if present (automatically)
/// </summary>
[AddComponentMenu("UI/Extensions/UI Scrollrect Occlusion")]
public class UI_ScrollRectOcclusion : MonoBehaviour
{
//if true user will need to call Init() method manually (in case the contend of the scrollview is generated from code or requires special initialization)
public bool InitByUser = false;
private bool _initialised = false;
private ScrollRect _scrollRect;
private ContentSizeFitter _contentSizeFitter;
private VerticalLayoutGroup _verticalLayoutGroup;
private HorizontalLayoutGroup _horizontalLayoutGroup;
private GridLayoutGroup _gridLayoutGroup;
private bool _isVertical = false;
private bool _isHorizontal = false;
private float _disableMarginX = 0;
private float _disableMarginY = 0;
private bool _hasDisabledGridComponents = false;
private List<RectTransform> _items = new List<RectTransform>();
private bool _reset = false;
void Awake()
{
if (InitByUser)
return;
Init();
}
public void Init()
{
if (_initialised)
{
Debug.LogError("Control already initialized\nYou have to enable the InitByUser setting on the control in order to use Init() when running");
return;
}
if (GetComponent<ScrollRect>() != null)
{
_initialised = true;
_scrollRect = GetComponent<ScrollRect>();
_scrollRect.onValueChanged.AddListener(OnScroll);
_isHorizontal = _scrollRect.horizontal;
_isVertical = _scrollRect.vertical;
for (int i = 0; i < _scrollRect.content.childCount; i++)
{
_items.Add(_scrollRect.content.GetChild(i).GetComponent<RectTransform>());
}
if (_scrollRect.content.GetComponent<VerticalLayoutGroup>() != null)
{
_verticalLayoutGroup = _scrollRect.content.GetComponent<VerticalLayoutGroup>();
}
if (_scrollRect.content.GetComponent<HorizontalLayoutGroup>() != null)
{
_horizontalLayoutGroup = _scrollRect.content.GetComponent<HorizontalLayoutGroup>();
}
if (_scrollRect.content.GetComponent<GridLayoutGroup>() != null)
{
_gridLayoutGroup = _scrollRect.content.GetComponent<GridLayoutGroup>();
}
if (_scrollRect.content.GetComponent<ContentSizeFitter>() != null)
{
_contentSizeFitter = _scrollRect.content.GetComponent<ContentSizeFitter>();
}
}
else
{
Debug.LogError("UI_ScrollRectOcclusion => No ScrollRect component found");
}
}
void ToggleGridComponents(bool toggle)
{
if (_isVertical)
_disableMarginY = _scrollRect.GetComponent<RectTransform>().rect.height / 2 + _items[0].sizeDelta.y;
if (_isHorizontal)
_disableMarginX = _scrollRect.GetComponent<RectTransform>().rect.width / 2 + _items[0].sizeDelta.x;
if (_verticalLayoutGroup)
{
_verticalLayoutGroup.enabled = toggle;
}
if (_horizontalLayoutGroup)
{
_horizontalLayoutGroup.enabled = toggle;
}
if (_contentSizeFitter)
{
_contentSizeFitter.enabled = toggle;
}
if (_gridLayoutGroup)
{
_gridLayoutGroup.enabled = toggle;
}
_hasDisabledGridComponents = !toggle;
}
public void OnScroll(Vector2 pos)
{
if (_reset)
{
return;
}
if (!_hasDisabledGridComponents)
{
ToggleGridComponents(false);
}
for (int i = 0; i < _items.Count; i++)
{
if (_isVertical && _isHorizontal)
{
if (_scrollRect.transform.InverseTransformPoint(_items[i].position).y < -_disableMarginY || _scrollRect.transform.InverseTransformPoint(_items[i].position).y > _disableMarginY
|| _scrollRect.transform.InverseTransformPoint(_items[i].position).x < -_disableMarginX || _scrollRect.transform.InverseTransformPoint(_items[i].position).x > _disableMarginX)
{
_items[i].gameObject.SetActive(false);
}
else
{
_items[i].gameObject.SetActive(true);
}
}
else
{
if (_isVertical)
{
if (_scrollRect.transform.InverseTransformPoint(_items[i].position).y < -_disableMarginY || _scrollRect.transform.InverseTransformPoint(_items[i].position).y > _disableMarginY)
{
_items[i].gameObject.SetActive(false);
}
else
{
_items[i].gameObject.SetActive(true);
}
}
if (_isHorizontal)
{
if (_scrollRect.transform.InverseTransformPoint(_items[i].position).x < -_disableMarginX || _scrollRect.transform.InverseTransformPoint(_items[i].position).x > _disableMarginX)
{
_items[i].gameObject.SetActive(false);
}
else
{
_items[i].gameObject.SetActive(true);
}
}
}
}
}
public void SetDirty()
{
_reset = true;
}
private void LateUpdate()
{
if (_reset)
{
_reset = false;
_items.Clear();
for (int i = 0; i < _scrollRect.content.childCount; i++)
{
_items.Add(_scrollRect.content.GetChild(i).GetComponent<RectTransform>());
_items[i].gameObject.SetActive(true);
}
ToggleGridComponents(true);
}
}
}
}

View File

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

View File

@ -0,0 +1,104 @@
/// Credit Tomasz Schelenz
/// Sourced from - https://bitbucket.org/SimonDarksideJ/unity-ui-extensions/issues/83/ui_tweenscale
/// Demo - https://youtu.be/uVTV7Udx78k?t=1m33s Dynamic scaling of text or image (including button) based on curves. works on scrollrect scale so you can pretty much use it for any ui type.
/// Notes In some cases it can create spikes due to redrawing on change, it is recommended to use it on simple objects in separated canvases to avoid redrawing full canvas.
using System.Collections;
namespace UnityEngine.UI.Extensions
{
/// <summary>
/// Dynamic scaling of text or image (including button) based on curves
///
/// Fields
/// - animCurve - animation curve for scale (if isUniform set to false, will apply only to X scale)
/// - speed - animation speed
/// - isLoop - animation will play infinitely (in order to make it work set your animation curve to loop)
/// - playAtAwake - starts automatically with script becoming active. Otherwise you need to call Play() method.
/// - isUniform - if false animCurve will modify object X scale and animCurveY - Y scale.
///
///
/// Notes
/// - If you want to stop the animation call the ResetTween() method.
/// - In some cases it can create spikes due to redrawing on change, it is recommended to use it on simple objects in separated canvases to
/// avoid redrawing full canvas.
/// - If you want to scale object only in 1 axis select non unifor and use linear curve from 1 to 1 to lock the scale.
///
/// </summary>
[AddComponentMenu("UI/Extensions/UI Tween Scale")]
public class UI_TweenScale : MonoBehaviour
{
//ANIMATION FOR X AND Y, OR X IF isUniform set to false
public AnimationCurve animCurve;
[Tooltip("Animation speed multiplier")]
public float speed = 1;
[Tooltip("If true animation will loop, for best effect set animation curve to loop on start and end point")]
public bool isLoop = false;
//IF TRUE ANIMATION STARTS AUTOMATICALLY
[Tooltip("If true animation will start automatically, otherwise you need to call Play() method to start the animation")]
public bool playAtAwake = false;
[Space(10)]
//if true both x and y axis will be using animCurve;
[Header("Non uniform scale")]
[Tooltip("If true component will scale by the same amount in X and Y axis, otherwise use animCurve for X scale and animCurveY for Y scale")]
public bool isUniform = true;
//IF isUniform set to false use this for Y axis
public AnimationCurve animCurveY;
private Vector3 initScale;
private Transform myTransform;
void Awake()
{
myTransform = GetComponent<Transform>();
initScale = myTransform.localScale;
if (playAtAwake)
{
Play();
}
}
public void Play()
{
StartCoroutine("Tween");
}
Vector3 newScale = Vector3.one;
IEnumerator Tween()
{
myTransform.localScale = initScale;
float t = 0;
float maxT = animCurve.keys[animCurve.length - 1].time;
while (t < maxT || isLoop)
{
t += speed * Time.deltaTime;
if (!isUniform)
{
newScale.x = 1 * animCurve.Evaluate(t);
newScale.y = 1 * animCurveY.Evaluate(t);
myTransform.localScale = newScale;
}
else
{
myTransform.localScale = Vector3.one * animCurve.Evaluate(t);
}
yield return null;
}
}
public void ResetTween()
{
StopCoroutine("Tween");
myTransform.localScale = initScale;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 61bf9d6fa29ed164e8a1df46e0d40835
timeCreated: 1467462200
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,24 @@
/// Credit Izitmee
/// Sourced from - http://forum.unity3d.com/threads/find-anchoredposition-of-a-recttransform-relative-to-another-recttransform.330560/#post-2300992
/// Updated by Brave Michael - http://forum.unity3d.com/threads/find-anchoredposition-of-a-recttransform-relative-to-another-recttransform.330560/#post-2300992
namespace UnityEngine.UI.Extensions
{
public static class RectTransformExtension
{
/// <summary>
/// Converts the anchoredPosition of the first RectTransform to the second RectTransform,
/// taking into consideration offset, anchors and pivot, and returns the new anchoredPosition
/// </summary>
public static Vector2 switchToRectTransform(this RectTransform from, RectTransform to)
{
Vector2 localPoint;
Vector2 fromPivotDerivedOffset = new Vector2(from.rect.width * from.pivot.x + from.rect.xMin, from.rect.height * from.pivot.y + from.rect.yMin);
Vector2 screenP = RectTransformUtility.WorldToScreenPoint(null, from.position);
screenP += fromPivotDerivedOffset;
RectTransformUtility.ScreenPointToLocalPointInRectangle(to, screenP, null, out localPoint);
Vector2 pivotDerivedOffset = new Vector2(to.rect.width * to.pivot.x + to.rect.xMin, to.rect.height * to.pivot.y + to.rect.yMin);
return to.anchoredPosition + localPoint - pivotDerivedOffset;
}
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 977482c1b88728145ba612c0fdec3b92
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData: