commit
28e50814d7
|
@ -0,0 +1,4 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a7b682f292cfba6438971b2bc7e90705
|
||||
DefaultImporter:
|
||||
userData:
|
|
@ -0,0 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9001b012db436b1438e03cdda2954484
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
|
@ -0,0 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 82ea50ac9a6ea8940a71f86ea8d13bf0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
|
@ -0,0 +1,41 @@
|
|||
///Credit ChoMPHi
|
||||
///Sourced from - http://forum.unity3d.com/threads/accordion-type-layout.271818/
|
||||
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(VerticalLayoutGroup), typeof(ContentSizeFitter), typeof(ToggleGroup))]
|
||||
[AddComponentMenu("UI/Extensions/Accordion/Accordion Group")]
|
||||
public class Accordion : MonoBehaviour
|
||||
{
|
||||
|
||||
public enum Transition
|
||||
{
|
||||
Instant,
|
||||
Tween
|
||||
}
|
||||
|
||||
[SerializeField] private Transition m_Transition = Transition.Instant;
|
||||
[SerializeField] private float m_TransitionDuration = 0.3f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the transition.
|
||||
/// </summary>
|
||||
/// <value>The transition.</value>
|
||||
public Transition transition
|
||||
{
|
||||
get { return this.m_Transition; }
|
||||
set { this.m_Transition = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the duration of the transition.
|
||||
/// </summary>
|
||||
/// <value>The duration of the transition.</value>
|
||||
public float transitionDuration
|
||||
{
|
||||
get { return this.m_TransitionDuration; }
|
||||
set { this.m_TransitionDuration = value; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4387cc9950f37044c92f9d144a2b1002
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,138 @@
|
|||
///Credit ChoMPHi
|
||||
///Sourced from - http://forum.unity3d.com/threads/accordion-type-layout.271818/
|
||||
|
||||
using System;
|
||||
using UnityEngine.UI.Extensions.Tweens;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(RectTransform), typeof(LayoutElement))]
|
||||
[AddComponentMenu("UI/Extensions/Accordion/Accordion Element")]
|
||||
public class AccordionElement : Toggle
|
||||
{
|
||||
|
||||
[SerializeField] private float m_MinHeight = 18f;
|
||||
|
||||
private Accordion m_Accordion;
|
||||
private RectTransform m_RectTransform;
|
||||
private LayoutElement m_LayoutElement;
|
||||
|
||||
[NonSerialized]
|
||||
private readonly TweenRunner<FloatTween> m_FloatTweenRunner;
|
||||
|
||||
protected AccordionElement()
|
||||
{
|
||||
if (this.m_FloatTweenRunner == null)
|
||||
this.m_FloatTweenRunner = new TweenRunner<FloatTween>();
|
||||
|
||||
this.m_FloatTweenRunner.Init(this);
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
base.transition = Transition.None;
|
||||
base.toggleTransition = ToggleTransition.None;
|
||||
this.m_Accordion = this.gameObject.GetComponentInParent<Accordion>();
|
||||
this.m_RectTransform = this.transform as RectTransform;
|
||||
this.m_LayoutElement = this.gameObject.GetComponent<LayoutElement>();
|
||||
this.onValueChanged.AddListener(OnValueChanged);
|
||||
}
|
||||
|
||||
protected override void OnValidate()
|
||||
{
|
||||
base.OnValidate();
|
||||
|
||||
if (this.group == null)
|
||||
{
|
||||
ToggleGroup tg = this.GetComponentInParent<ToggleGroup>();
|
||||
|
||||
if (tg != null)
|
||||
{
|
||||
this.group = tg;
|
||||
}
|
||||
}
|
||||
|
||||
LayoutElement le = this.gameObject.GetComponent<LayoutElement>();
|
||||
|
||||
if (le != null)
|
||||
{
|
||||
if (this.isOn)
|
||||
{
|
||||
le.preferredHeight = -1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
le.preferredHeight = this.m_MinHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnValueChanged(bool state)
|
||||
{
|
||||
if (this.m_LayoutElement == null)
|
||||
return;
|
||||
|
||||
Accordion.Transition transition = (this.m_Accordion != null) ? this.m_Accordion.transition : Accordion.Transition.Instant;
|
||||
|
||||
if (transition == Accordion.Transition.Instant)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
this.m_LayoutElement.preferredHeight = -1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_LayoutElement.preferredHeight = this.m_MinHeight;
|
||||
}
|
||||
}
|
||||
else if (transition == Accordion.Transition.Tween)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
this.StartTween(this.m_MinHeight, this.GetExpandedHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
this.StartTween(this.m_RectTransform.rect.height, this.m_MinHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected float GetExpandedHeight()
|
||||
{
|
||||
if (this.m_LayoutElement == null)
|
||||
return this.m_MinHeight;
|
||||
|
||||
float originalPrefH = this.m_LayoutElement.preferredHeight;
|
||||
this.m_LayoutElement.preferredHeight = -1f;
|
||||
float h = LayoutUtility.GetPreferredHeight(this.m_RectTransform);
|
||||
this.m_LayoutElement.preferredHeight = originalPrefH;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
protected void StartTween(float startFloat, float targetFloat)
|
||||
{
|
||||
float duration = (this.m_Accordion != null) ? this.m_Accordion.transitionDuration : 0.3f;
|
||||
|
||||
FloatTween info = new FloatTween
|
||||
{
|
||||
duration = duration,
|
||||
startFloat = startFloat,
|
||||
targetFloat = targetFloat
|
||||
};
|
||||
info.AddOnChangedCallback(SetHeight);
|
||||
info.ignoreTimeScale = true;
|
||||
this.m_FloatTweenRunner.StartTween(info);
|
||||
}
|
||||
|
||||
protected void SetHeight(float height)
|
||||
{
|
||||
if (this.m_LayoutElement == null)
|
||||
return;
|
||||
|
||||
this.m_LayoutElement.preferredHeight = height;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3c9d341c4bc7de548937508e6f837144
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dc2df01d18eb92b49b30e7403cce8313
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
|
@ -0,0 +1,23 @@
|
|||
///Credit ChoMPHi
|
||||
///Sourced from - http://forum.unity3d.com/threads/accordion-type-layout.271818/
|
||||
|
||||
using UnityEngine.UI.Extensions;
|
||||
|
||||
namespace UnityEditor.UI
|
||||
{
|
||||
[CustomEditor(typeof(AccordionElement), true)]
|
||||
public class AccordionElementEditor : ToggleEditor {
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
this.serializedObject.Update();
|
||||
EditorGUILayout.PropertyField(this.serializedObject.FindProperty("m_MinHeight"));
|
||||
this.serializedObject.ApplyModifiedProperties();
|
||||
|
||||
base.serializedObject.Update();
|
||||
EditorGUILayout.PropertyField(base.serializedObject.FindProperty("m_IsOn"));
|
||||
EditorGUILayout.PropertyField(base.serializedObject.FindProperty("m_Interactable"));
|
||||
base.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8882b502b0c65b24ba4623d6a383815b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b9115417252d4cd42a5e167bdc1c2d3b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
|
@ -0,0 +1,121 @@
|
|||
///Credit ChoMPHi
|
||||
///Sourced from - http://forum.unity3d.com/threads/accordion-type-layout.271818/
|
||||
|
||||
using System.Collections;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace UnityEngine.UI.Extensions.Tweens
|
||||
{
|
||||
public struct FloatTween : ITweenValue
|
||||
{
|
||||
public class FloatTweenCallback : UnityEvent<float> {}
|
||||
public class FloatFinishCallback : UnityEvent {}
|
||||
|
||||
private float m_StartFloat;
|
||||
private float m_TargetFloat;
|
||||
private float m_Duration;
|
||||
private bool m_IgnoreTimeScale;
|
||||
private FloatTweenCallback m_Target;
|
||||
private FloatFinishCallback m_Finish;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the starting float.
|
||||
/// </summary>
|
||||
/// <value>The start float.</value>
|
||||
public float startFloat
|
||||
{
|
||||
get { return m_StartFloat; }
|
||||
set { m_StartFloat = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target float.
|
||||
/// </summary>
|
||||
/// <value>The target float.</value>
|
||||
public float targetFloat
|
||||
{
|
||||
get { return m_TargetFloat; }
|
||||
set { m_TargetFloat = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the duration of the tween.
|
||||
/// </summary>
|
||||
/// <value>The duration.</value>
|
||||
public float duration
|
||||
{
|
||||
get { return m_Duration; }
|
||||
set { m_Duration = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="UnityEngine.UI.Tweens.ColorTween"/> should ignore time scale.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if ignore time scale; otherwise, <c>false</c>.</value>
|
||||
public bool ignoreTimeScale
|
||||
{
|
||||
get { return m_IgnoreTimeScale; }
|
||||
set { m_IgnoreTimeScale = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tweens the float based on percentage.
|
||||
/// </summary>
|
||||
/// <param name="floatPercentage">Float percentage.</param>
|
||||
public void TweenValue(float floatPercentage)
|
||||
{
|
||||
if (!ValidTarget())
|
||||
return;
|
||||
|
||||
m_Target.Invoke( Mathf.Lerp (m_StartFloat, m_TargetFloat, floatPercentage) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a on changed callback.
|
||||
/// </summary>
|
||||
/// <param name="callback">Callback.</param>
|
||||
public void AddOnChangedCallback(UnityAction<float> callback)
|
||||
{
|
||||
if (m_Target == null)
|
||||
m_Target = new FloatTweenCallback();
|
||||
|
||||
m_Target.AddListener(callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a on finish callback.
|
||||
/// </summary>
|
||||
/// <param name="callback">Callback.</param>
|
||||
public void AddOnFinishCallback(UnityAction callback)
|
||||
{
|
||||
if (m_Finish == null)
|
||||
m_Finish = new FloatFinishCallback();
|
||||
|
||||
m_Finish.AddListener(callback);
|
||||
}
|
||||
|
||||
public bool GetIgnoreTimescale()
|
||||
{
|
||||
return m_IgnoreTimeScale;
|
||||
}
|
||||
|
||||
public float GetDuration()
|
||||
{
|
||||
return m_Duration;
|
||||
}
|
||||
|
||||
public bool ValidTarget()
|
||||
{
|
||||
return m_Target != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the on finish callback.
|
||||
/// </summary>
|
||||
public void Finished()
|
||||
{
|
||||
if (m_Finish != null)
|
||||
m_Finish.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e28e1e9e18f7daa4db5d1ac279d6ce66
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,16 @@
|
|||
///Credit ChoMPHi
|
||||
///Sourced from - http://forum.unity3d.com/threads/accordion-type-layout.271818/
|
||||
|
||||
using System.Collections;
|
||||
|
||||
namespace UnityEngine.UI.Extensions.Tweens
|
||||
{
|
||||
internal interface ITweenValue
|
||||
{
|
||||
void TweenValue(float floatPercentage);
|
||||
bool ignoreTimeScale { get; }
|
||||
float duration { get; }
|
||||
bool ValidTarget();
|
||||
void Finished();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9edf9da4c14ad2843879a2331b00f738
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,63 @@
|
|||
///Credit ChoMPHi
|
||||
///Sourced from - http://forum.unity3d.com/threads/accordion-type-layout.271818/
|
||||
|
||||
using System.Collections;
|
||||
|
||||
namespace UnityEngine.UI.Extensions.Tweens
|
||||
{
|
||||
// Tween runner, executes the given tween.
|
||||
// The coroutine will live within the given
|
||||
// behaviour container.
|
||||
internal class TweenRunner<T> where T : struct, ITweenValue
|
||||
{
|
||||
protected MonoBehaviour m_CoroutineContainer;
|
||||
protected IEnumerator m_Tween;
|
||||
|
||||
// utility function for starting the tween
|
||||
private static IEnumerator Start(T tweenInfo)
|
||||
{
|
||||
if (!tweenInfo.ValidTarget())
|
||||
yield break;
|
||||
|
||||
float elapsedTime = 0.0f;
|
||||
while (elapsedTime < tweenInfo.duration)
|
||||
{
|
||||
elapsedTime += tweenInfo.ignoreTimeScale ? Time.unscaledDeltaTime : Time.deltaTime;
|
||||
var percentage = Mathf.Clamp01 (elapsedTime / tweenInfo.duration);
|
||||
tweenInfo.TweenValue (percentage);
|
||||
yield return null;
|
||||
}
|
||||
tweenInfo.TweenValue (1.0f);
|
||||
tweenInfo.Finished();
|
||||
}
|
||||
|
||||
public void Init(MonoBehaviour coroutineContainer)
|
||||
{
|
||||
m_CoroutineContainer = coroutineContainer;
|
||||
}
|
||||
|
||||
public void StartTween(T info)
|
||||
{
|
||||
if (m_CoroutineContainer == null)
|
||||
{
|
||||
Debug.LogWarning ("Coroutine container not configured... did you forget to call Init?");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Tween != null)
|
||||
{
|
||||
m_CoroutineContainer.StopCoroutine (m_Tween);
|
||||
m_Tween = null;
|
||||
}
|
||||
|
||||
if (!m_CoroutineContainer.gameObject.activeInHierarchy)
|
||||
{
|
||||
info.TweenValue(1.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
m_Tween = Start (info);
|
||||
m_CoroutineContainer.StartCoroutine (m_Tween);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d00ab96853b24074cb837ee70f07dddc
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,50 @@
|
|||
/// Credit Melang
|
||||
/// Sourced from - http://forum.unity3d.com/members/melang.593409/
|
||||
|
||||
using System.Collections.Generic;
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/BestFit Outline")]
|
||||
public class BestFitOutline : Shadow
|
||||
{
|
||||
//
|
||||
// Constructors
|
||||
//
|
||||
protected BestFitOutline ()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
public override void ModifyVertices (List<UIVertex> verts)
|
||||
{
|
||||
if (!this.IsActive ())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Text foundtext = GetComponent<Text>();
|
||||
|
||||
float best_fit_adjustment = 1f;
|
||||
|
||||
if (foundtext && foundtext.resizeTextForBestFit)
|
||||
{
|
||||
best_fit_adjustment = (float)foundtext.cachedTextGenerator.fontSizeUsedForBestFit / (foundtext.resizeTextMaxSize-1); //max size seems to be exclusive
|
||||
}
|
||||
|
||||
int start = 0;
|
||||
int count = verts.Count;
|
||||
base.ApplyShadow (verts, base.effectColor, start, verts.Count, base.effectDistance.x*best_fit_adjustment, base.effectDistance.y*best_fit_adjustment);
|
||||
start = count;
|
||||
count = verts.Count;
|
||||
base.ApplyShadow (verts, base.effectColor, start, verts.Count, base.effectDistance.x*best_fit_adjustment, -base.effectDistance.y*best_fit_adjustment);
|
||||
start = count;
|
||||
count = verts.Count;
|
||||
base.ApplyShadow (verts, base.effectColor, start, verts.Count, -base.effectDistance.x*best_fit_adjustment, base.effectDistance.y*best_fit_adjustment);
|
||||
start = count;
|
||||
count = verts.Count;
|
||||
base.ApplyShadow (verts, base.effectColor, start, verts.Count, -base.effectDistance.x*best_fit_adjustment, -base.effectDistance.y*best_fit_adjustment);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7b30dd83a12669d4f973ff5a79ca9842
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,116 @@
|
|||
/// Credit dakka
|
||||
/// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1752415
|
||||
/// Notes - Mod from Yilmaz Kiymaz's editor scripts presentation at Unite 2013
|
||||
/// Updated ddreaper - removed Linq use, not required.
|
||||
|
||||
using UnityEditor;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
public class CanvasGroupActivator : EditorWindow
|
||||
{
|
||||
[MenuItem("Window/UI/Extensions/Canvas Groups Activator")]
|
||||
public static void InitWindow()
|
||||
{
|
||||
EditorWindow.GetWindow<CanvasGroupActivator>();
|
||||
}
|
||||
|
||||
CanvasGroup[] canvasGroups;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
ObtainCanvasGroups();
|
||||
}
|
||||
|
||||
void OnFocus()
|
||||
{
|
||||
ObtainCanvasGroups();
|
||||
}
|
||||
|
||||
void ObtainCanvasGroups()
|
||||
{
|
||||
canvasGroups = GameObject.FindObjectsOfType<CanvasGroup>();
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
if (canvasGroups == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GUILayout.Space(10f);
|
||||
GUILayout.Label("Canvas Groups");
|
||||
|
||||
for (int i = 0; i < canvasGroups.Length; i++)
|
||||
{
|
||||
if (canvasGroups[i] == null) { continue; }
|
||||
|
||||
bool initialActive = false;
|
||||
if (canvasGroups[i].alpha == 1.0f)
|
||||
initialActive = true;
|
||||
|
||||
bool active = EditorGUILayout.Toggle(canvasGroups[i].name, initialActive);
|
||||
if (active != initialActive)
|
||||
{
|
||||
//If deactivated and initially active
|
||||
if (!active && initialActive)
|
||||
{
|
||||
//Deactivate this
|
||||
canvasGroups[i].alpha = 0f;
|
||||
canvasGroups[i].interactable = false;
|
||||
canvasGroups[i].blocksRaycasts = false;
|
||||
}
|
||||
//If activated and initially deactive
|
||||
else if (active && !initialActive)
|
||||
{
|
||||
//Deactivate all others and activate this
|
||||
HideAllGroups();
|
||||
|
||||
canvasGroups[i].alpha = 1.0f;
|
||||
canvasGroups[i].interactable = true;
|
||||
canvasGroups[i].blocksRaycasts = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.Space(5f);
|
||||
|
||||
if (GUILayout.Button("Show All"))
|
||||
{
|
||||
ShowAllGroups();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Hide All"))
|
||||
{
|
||||
HideAllGroups();
|
||||
}
|
||||
}
|
||||
|
||||
void ShowAllGroups()
|
||||
{
|
||||
foreach (var group in canvasGroups)
|
||||
{
|
||||
if (group != null)
|
||||
{
|
||||
group.alpha = 1.0f;
|
||||
group.interactable = true;
|
||||
group.blocksRaycasts = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HideAllGroups()
|
||||
{
|
||||
foreach (var group in canvasGroups)
|
||||
{
|
||||
if (group != null)
|
||||
{
|
||||
group.alpha = 0;
|
||||
group.interactable = false;
|
||||
group.blocksRaycasts = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f60a419e63d329f43ba1bf57e98b34bf
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 726a11b8d64fa0143b34f417f5453f80
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
|
@ -0,0 +1,13 @@
|
|||
///Credit perchik
|
||||
///Sourced from - http://forum.unity3d.com/threads/receive-onclick-event-and-pass-it-on-to-lower-ui-elements.293642/
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class ClickBtn : MonoBehaviour
|
||||
{
|
||||
public void Click()
|
||||
{
|
||||
Debug.Log("Clicked");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 33a5d65e2f7d10648af0fde6d2de99cc
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,625 @@
|
|||
///Credit perchik
|
||||
///Sourced from - http://forum.unity3d.com/threads/receive-onclick-event-and-pass-it-on-to-lower-ui-elements.293642/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[AddComponentMenu("UI/Extensions/ComboBox")]
|
||||
public class ComboBox : MonoBehaviour
|
||||
{
|
||||
#region declarations
|
||||
#region private members
|
||||
|
||||
private bool _isActive = false; //is the drop down panel active
|
||||
|
||||
private Button comboBtn;
|
||||
private Image comboBtnImg;
|
||||
private Text comboBtnText;
|
||||
|
||||
private Button overlayBtn;
|
||||
|
||||
private GridLayoutGroup itemLayout;
|
||||
|
||||
|
||||
private float _scrollbarWidth = 20.0f;
|
||||
|
||||
private int scrollOffset; //offset of the selected item
|
||||
|
||||
private int _itemsToDisplay = 4; //how many items to show in the dropdown panel
|
||||
|
||||
private bool _hideFirstItem = false; //lets us hide the prompt after something is chosen
|
||||
|
||||
private int _selectedIndex = 0;
|
||||
|
||||
private List<ComboBoxItem> _items; //conceptual items in the list
|
||||
|
||||
private bool _interactable = true;
|
||||
|
||||
private Canvas _canvas;
|
||||
|
||||
#region private rect transforms
|
||||
/// <remarks> All of these have to be properties so that the editor script can access them</remarks>
|
||||
|
||||
private RectTransform _overlay; //overlayRT is a screensized box to handle clicks *not* on the button. (although this might have to change with multiple things on the screen.
|
||||
private RectTransform overlayRT
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_overlay == null)
|
||||
{
|
||||
_overlay = rectTransform.FindChild("Overlay").GetComponent<RectTransform>();
|
||||
overlayBtn = _overlay.gameObject.GetComponent<Button>();
|
||||
}
|
||||
return _overlay;
|
||||
}
|
||||
set
|
||||
{
|
||||
_overlay = value;
|
||||
}
|
||||
}
|
||||
|
||||
private RectTransform _rectTransform;
|
||||
private RectTransform rectTransform
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_rectTransform == null)
|
||||
{
|
||||
_rectTransform = GetComponent<RectTransform>();
|
||||
}
|
||||
return _rectTransform;
|
||||
}
|
||||
set { _rectTransform = value; }
|
||||
}
|
||||
|
||||
private RectTransform _comboBtnRT;
|
||||
private RectTransform comboBtnRT
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_comboBtnRT == null)
|
||||
{
|
||||
_comboBtnRT = rectTransform.FindChild("ComboButton").GetComponent<RectTransform>();
|
||||
comboBtn = _comboBtnRT.GetComponent<Button>();
|
||||
comboBtnImg = _comboBtnRT.FindChild("Image").GetComponent<Image>();
|
||||
comboBtnText = _comboBtnRT.FindChild("Text").GetComponent<Text>();
|
||||
}
|
||||
return _comboBtnRT;
|
||||
}
|
||||
set
|
||||
{
|
||||
_comboBtnRT = value;
|
||||
}
|
||||
}
|
||||
|
||||
private GameObject _scrollPanel;
|
||||
private GameObject scrollPanel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_scrollPanel == null)
|
||||
_scrollPanel = overlayRT.FindChild("ScrollPanel").gameObject;
|
||||
return _scrollPanel;
|
||||
}
|
||||
set
|
||||
{
|
||||
_scrollPanel = value;
|
||||
}
|
||||
}
|
||||
|
||||
private RectTransform _scrollPanelRT;
|
||||
private RectTransform scrollPanelRT
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_scrollPanelRT == null)
|
||||
_scrollPanelRT = scrollPanel.GetComponent<RectTransform>();
|
||||
return _scrollPanelRT;
|
||||
}
|
||||
set
|
||||
{
|
||||
_scrollPanelRT = value;
|
||||
}
|
||||
}
|
||||
|
||||
private RectTransform _itemsRT;
|
||||
private RectTransform itemsRT
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_itemsRT == null)
|
||||
{
|
||||
_itemsRT = scrollPanelRT.Find("Items").GetComponent<RectTransform>();
|
||||
itemLayout = _itemsRT.gameObject.GetComponent<GridLayoutGroup>();
|
||||
}
|
||||
return _itemsRT;
|
||||
}
|
||||
set
|
||||
{
|
||||
_itemsRT = value;
|
||||
}
|
||||
}
|
||||
|
||||
private RectTransform _scrollbarRT;
|
||||
private RectTransform scrollbarRT
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_scrollbarRT == null)
|
||||
_scrollbarRT = scrollPanelRT.Find("Scrollbar").GetComponent<RectTransform>();
|
||||
return _scrollbarRT;
|
||||
}
|
||||
set
|
||||
{
|
||||
_scrollbarRT = value;
|
||||
}
|
||||
}
|
||||
|
||||
private RectTransform _slidingAreaRT;
|
||||
private RectTransform slidingAreaRT
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_slidingAreaRT == null)
|
||||
_slidingAreaRT = scrollbarRT.Find("SlidingArea").GetComponent<RectTransform>();
|
||||
return _slidingAreaRT;
|
||||
}
|
||||
set
|
||||
{
|
||||
_slidingAreaRT = value;
|
||||
}
|
||||
}
|
||||
|
||||
private RectTransform _scrollHandleRT;
|
||||
private RectTransform scrollHandleRT
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_scrollHandleRT == null)
|
||||
_scrollHandleRT = slidingAreaRT.Find("Handle").GetComponent<RectTransform>();
|
||||
return _scrollHandleRT;
|
||||
}
|
||||
set
|
||||
{
|
||||
_scrollHandleRT = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
#region public accessors
|
||||
|
||||
public string HeaderOption = "";
|
||||
public Color32 disabledTextColor = new Color32(174, 174, 174, 255);
|
||||
public bool Interactable
|
||||
{
|
||||
get
|
||||
{
|
||||
return _interactable;
|
||||
}
|
||||
set
|
||||
{
|
||||
_interactable = value;
|
||||
|
||||
comboBtn.interactable = _interactable;
|
||||
if (comboBtnImg.sprite != null)
|
||||
{
|
||||
comboBtnImg.color = _interactable ?
|
||||
comboBtn.colors.normalColor :
|
||||
comboBtn.colors.disabledColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
comboBtnImg.color = new Color(1, 1, 1, 0); //transparent
|
||||
}
|
||||
if (!Application.isPlaying)//stop it from messing up in the editor
|
||||
return;
|
||||
if (!_interactable && _isActive)
|
||||
ToggleComboBox(false);
|
||||
}
|
||||
}
|
||||
|
||||
public int SelectedIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selectedIndex;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_selectedIndex == value)
|
||||
return;
|
||||
if (value > -1 && value < Items.Count)
|
||||
{
|
||||
_selectedIndex = value;
|
||||
RefreshSelected();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<ComboBoxItem> Items
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_items == null)
|
||||
{
|
||||
_items = new List<ComboBoxItem>();
|
||||
}
|
||||
|
||||
return _items;
|
||||
}
|
||||
set
|
||||
{
|
||||
_items = value;
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HideFirstItem
|
||||
{
|
||||
get
|
||||
{
|
||||
return _hideFirstItem;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
scrollOffset--;
|
||||
else
|
||||
scrollOffset++;
|
||||
_hideFirstItem = value;
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public int ItemsToDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return _itemsToDisplay;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_itemsToDisplay == value)
|
||||
return;
|
||||
_itemsToDisplay = value;
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public System.Action<int> OnSelectionChanged;//fires when selection is changed.
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region public methods
|
||||
|
||||
/// <summary>
|
||||
/// Update the main button with the selected item's parameters
|
||||
/// </summary>
|
||||
public void RefreshSelected()
|
||||
{
|
||||
//get the selected item
|
||||
ComboBoxItem item = (SelectedIndex > -1 && SelectedIndex < Items.Count) ? Items[SelectedIndex] : null;
|
||||
if (item == null) return;
|
||||
|
||||
bool hasImage = (item.Image != null);
|
||||
comboBtnImg.sprite = hasImage ? item.Image : null;
|
||||
comboBtnImg.color = !hasImage ? new Color(1, 1, 1, 0)//transparent if there's no image.
|
||||
: !Interactable ? new Color(1, 1, 1, .5f) //semitransparent if the combobox is disabled
|
||||
: Color.white; //fully opaque if it has an image and the combobox is enabled
|
||||
UpdateComboBoxText(comboBtnRT, hasImage);
|
||||
comboBtnText.text = item.Caption;
|
||||
|
||||
comboBtn.onClick.RemoveAllListeners();
|
||||
comboBtn.onClick.AddListener(() =>
|
||||
{
|
||||
ToggleComboBox(true);
|
||||
});
|
||||
if (!Application.isPlaying) return; //if it was running in editor we stop here.
|
||||
|
||||
for (int i = 0; i < itemsRT.childCount; i++)
|
||||
{
|
||||
Image tempImg = itemsRT.GetChild(i).GetComponent<Image>();
|
||||
tempImg.color = (SelectedIndex == (i + (HideFirstItem ? 1 : 0))) ? comboBtn.colors.highlightedColor : comboBtn.colors.normalColor;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// what happens when an item in the list is selected
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
public void OnItemClicked(int index)
|
||||
{
|
||||
Debug.Log("item " + index + " was clicked");
|
||||
bool selectionChanged = (index != SelectedIndex);
|
||||
SelectedIndex = index;
|
||||
ToggleComboBox(true);
|
||||
if (selectionChanged && OnSelectionChanged != null) OnSelectionChanged(index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add items to the dropdown list. Accepts any object of type ComboBoxItem, String, or Image
|
||||
/// </summary>
|
||||
/// <param name="list"></param>
|
||||
public void AddItems(params object[] list)
|
||||
{
|
||||
List<ComboBoxItem> cbItems = new List<ComboBoxItem>();
|
||||
foreach (var obj in list)
|
||||
{
|
||||
if (obj is ComboBoxItem)
|
||||
{
|
||||
cbItems.Add((ComboBoxItem)obj);
|
||||
}
|
||||
else if (obj is string)
|
||||
{
|
||||
cbItems.Add(new ComboBoxItem(caption: (string)obj));
|
||||
}
|
||||
else if (obj is Sprite)
|
||||
{
|
||||
cbItems.Add(new ComboBoxItem(image: (Sprite)obj));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.Exception("Only ComboBoxItems, Strings, and Sprite types are allowed");
|
||||
}
|
||||
}
|
||||
Items.AddRange(cbItems);
|
||||
Items = Items.Distinct().ToList();//remove any duplicates
|
||||
|
||||
}
|
||||
|
||||
public void ClearItems()
|
||||
{
|
||||
Items.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redraw the graphics (in response to something changing)
|
||||
/// </summary>
|
||||
public void UpdateGraphics()
|
||||
{
|
||||
//center the handle in the scrollbar
|
||||
float scrollbarWidth = Items.Count - (HideFirstItem ? 1 : 0) > ItemsToDisplay ? _scrollbarWidth : 0.0f;
|
||||
scrollHandleRT.offsetMin = -scrollbarWidth / 2 * Vector2.one;
|
||||
scrollHandleRT.offsetMax = scrollbarWidth / 2 * Vector2.one;
|
||||
|
||||
if (rectTransform.sizeDelta != comboBtnRT.sizeDelta)
|
||||
{
|
||||
comboBtnRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, rectTransform.sizeDelta.x);
|
||||
comboBtnRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, rectTransform.sizeDelta.y);
|
||||
comboBtnText.rectTransform.offsetMax = new Vector2(4, 0);
|
||||
|
||||
scrollPanelRT.SetParent(transform, true);
|
||||
scrollPanelRT.anchoredPosition = new Vector2(0, -comboBtnRT.sizeDelta.y);
|
||||
|
||||
|
||||
//make hte overlay fill the whole screen
|
||||
overlayRT.SetParent(_canvas.transform, false);
|
||||
overlayRT.offsetMax = Vector2.zero;
|
||||
overlayRT.offsetMin = Vector2.zero;
|
||||
|
||||
//reattach to correct parents, maintining global position
|
||||
overlayRT.SetParent(transform, true);
|
||||
scrollPanelRT.SetParent(overlayRT, true);
|
||||
|
||||
scrollPanel.GetComponent<ScrollRect>().scrollSensitivity = comboBtnRT.sizeDelta.y;
|
||||
|
||||
UpdateComboBoxText(comboBtnRT, Items[SelectedIndex].Image != null);
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// toggle the drop down list
|
||||
/// </summary>
|
||||
/// <param name="directClick">whether it was toggled by directly clicking on </param>
|
||||
public void ToggleComboBox(bool directClick)
|
||||
{
|
||||
if (HeaderOption != "") HideFirstItem = true;
|
||||
_isActive = !_isActive;
|
||||
// Debug.Log("toggling combo box tp "+ _isActive);
|
||||
overlayRT.gameObject.SetActive(_isActive);
|
||||
if (_isActive)
|
||||
{
|
||||
transform.SetAsLastSibling();
|
||||
FixScrollOffset();
|
||||
}
|
||||
else if (directClick)
|
||||
{
|
||||
scrollOffset = Mathf.RoundToInt(_itemsRT.anchoredPosition.y / rectTransform.sizeDelta.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region private methods
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_canvas = GetComponentInParent<Canvas>();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the control
|
||||
/// </summary>
|
||||
private void Initialize()
|
||||
{
|
||||
overlayRT.gameObject.SetActive(false);
|
||||
overlayBtn.onClick.AddListener(() => { ToggleComboBox(false); });
|
||||
|
||||
if (HeaderOption != "") AddItems(HeaderOption);
|
||||
|
||||
//float dropdownHeight = comboBtnRT.sizeDelta.y * Mathf.Min(ItemsToDisplay, Items.Length - (HideFirstItem ? 1 : 0));
|
||||
|
||||
//scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
|
||||
//scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, comboBtnRT.sizeDelta.x);
|
||||
|
||||
ScrollRect scrollPanelScrollRect = scrollPanel.GetComponent<ScrollRect>();
|
||||
scrollPanelScrollRect.scrollSensitivity = comboBtnRT.sizeDelta.y;
|
||||
scrollPanelScrollRect.content = itemsRT;
|
||||
|
||||
itemLayout.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
|
||||
itemLayout.constraintCount = 1;
|
||||
|
||||
//float scrollbarWidth = Items.Length - (HideFirstItem ? 1 : 0) > _itemsToDisplay ? _scrollbarWidth : 0.0f;
|
||||
//itemsRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollPanelRT.sizeDelta.x - scrollbarWidth);
|
||||
|
||||
//itemLayout.cellSize = new Vector2(comboBtnRT.sizeDelta.x - scrollbarWidth, comboBtnRT.sizeDelta.y);
|
||||
//itemLayout.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
|
||||
//itemLayout.constraintCount = 1;
|
||||
|
||||
//scrollbarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
|
||||
//scrollbarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
|
||||
|
||||
//slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 0);
|
||||
//slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight - scrollbarRT.sizeDelta.x);
|
||||
|
||||
//scrollHandleRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
|
||||
//scrollHandleRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, scrollbarWidth);
|
||||
|
||||
Interactable = Interactable; //call the logic in the getter.
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Redraw the component, with realigning.
|
||||
/// </summary>
|
||||
public void Refresh()
|
||||
{
|
||||
// Debug.Log("Refreshing");
|
||||
|
||||
int itemsLength = Items.Count - (HideFirstItem ? 1 : 0);
|
||||
if (itemsLength < 1)
|
||||
return;
|
||||
|
||||
float dropdownHeight = comboBtnRT.sizeDelta.y * Mathf.Min(_itemsToDisplay, itemsLength);
|
||||
float scrollbarWidth = itemsLength > ItemsToDisplay ? _scrollbarWidth : 0.0f;
|
||||
|
||||
|
||||
scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
|
||||
scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, comboBtnRT.sizeDelta.x);
|
||||
|
||||
itemsRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollPanelRT.sizeDelta.x - scrollbarWidth);
|
||||
|
||||
itemLayout.cellSize = new Vector2(comboBtnRT.sizeDelta.x - scrollbarWidth, comboBtnRT.sizeDelta.y);
|
||||
|
||||
scrollbarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
|
||||
scrollbarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
|
||||
|
||||
slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 0);
|
||||
slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight - scrollbarRT.sizeDelta.x);
|
||||
|
||||
scrollHandleRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
|
||||
scrollHandleRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, scrollbarWidth);
|
||||
|
||||
for (int i = itemsRT.childCount - 1; i >= 0; i--)//delete in reverse to avoid having to re-allocate memory on each delete. (ie if I deleted child 0, everythign would get shifted forward in the array)
|
||||
{
|
||||
DestroyImmediate(itemsRT.GetChild(0).gameObject);
|
||||
}
|
||||
|
||||
for (int i = (HideFirstItem ? 1 : 0); i < Items.Count; i++) //for each element to be shown in the dropdown list
|
||||
{
|
||||
ComboBoxItem item = Items[i];
|
||||
item.OnUpdate = Refresh;
|
||||
|
||||
Transform itemTfm = Instantiate(comboBtnRT) as Transform;//copy the top level combo box
|
||||
itemTfm.name += " " + i;
|
||||
itemTfm.SetParent(itemsRT, false);
|
||||
itemTfm.GetComponent<Image>().sprite = null; //hide the original background image (so that the dropdown box shows)
|
||||
|
||||
Text itemText = itemTfm.Find("Text").GetComponent<Text>();
|
||||
itemText.text = item.Caption;
|
||||
if (item.IsDisabled) itemText.color = disabledTextColor;
|
||||
|
||||
Image itemImg = itemTfm.Find("Image").GetComponent<Image>();
|
||||
itemImg.sprite = item.Image;
|
||||
itemImg.color = (item.Image == null) ? new Color(1, 1, 1, 0)
|
||||
: item.IsDisabled ? new Color(1, 1, 1, .5f)
|
||||
: Color.white;
|
||||
Button itemBtn = itemTfm.GetComponent<Button>();
|
||||
itemBtn.interactable = !item.IsDisabled;
|
||||
|
||||
int indx = i;
|
||||
itemBtn.onClick.RemoveAllListeners();
|
||||
itemBtn.onClick.AddListener(() =>
|
||||
{
|
||||
OnItemClicked(indx);
|
||||
if (item.OnSelect != null) item.OnSelect();
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
RefreshSelected();
|
||||
UpdateComboBoxItems();
|
||||
UpdateGraphics();
|
||||
FixScrollOffset();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// adjusts all of the items in the dropdown list to account for any images
|
||||
/// </summary>
|
||||
private void UpdateComboBoxItems()
|
||||
{
|
||||
//decide if any item in the list has images
|
||||
bool includeImages = false;
|
||||
foreach (ComboBoxItem item in Items)
|
||||
{
|
||||
if (item.Image != null)
|
||||
{
|
||||
includeImages = true; break;
|
||||
}
|
||||
}
|
||||
|
||||
//either align all of the text 10 units from the side, or 8+image width.
|
||||
foreach (Transform child in itemsRT)
|
||||
{
|
||||
UpdateComboBoxText(child, includeImages);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void UpdateComboBoxText(Transform child, bool includeImages)
|
||||
{
|
||||
child.Find("Text").GetComponent<RectTransform>().offsetMin = Vector2.right * (includeImages ? comboBtnImg.rectTransform.rect.width + 8.0f : 10.0f);
|
||||
}
|
||||
|
||||
|
||||
private void FixScrollOffset()
|
||||
{
|
||||
int selectedIndex = SelectedIndex + (HideFirstItem ? 1 : 0);
|
||||
if (selectedIndex < scrollOffset)
|
||||
scrollOffset = selectedIndex;
|
||||
else
|
||||
if (selectedIndex > scrollOffset + ItemsToDisplay - 1)
|
||||
scrollOffset = selectedIndex - ItemsToDisplay + 1;
|
||||
|
||||
|
||||
int itemsCount = Items.Count - (HideFirstItem ? 1 : 0);
|
||||
if (scrollOffset > itemsCount - ItemsToDisplay)
|
||||
scrollOffset = itemsCount - ItemsToDisplay;
|
||||
if (scrollOffset < 0)
|
||||
scrollOffset = 0;
|
||||
|
||||
_itemsRT.anchoredPosition = new Vector2(0.0f, scrollOffset * rectTransform.sizeDelta.y);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cd26acd32e1be2747b9e5f3587b2b1d5
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,96 @@
|
|||
///Credit perchik
|
||||
///Sourced from - http://forum.unity3d.com/threads/receive-onclick-event-and-pass-it-on-to-lower-ui-elements.293642/
|
||||
|
||||
using System;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
public class ComboBoxItem
|
||||
{
|
||||
[SerializeField]
|
||||
private string _caption;
|
||||
/// <summary>
|
||||
/// Caption of the Item
|
||||
/// </summary>
|
||||
public string Caption
|
||||
{
|
||||
get
|
||||
{
|
||||
return _caption;
|
||||
}
|
||||
set
|
||||
{
|
||||
_caption = value;
|
||||
if (OnUpdate != null)
|
||||
OnUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private Sprite _image;
|
||||
/// <summary>
|
||||
/// Image component of the Item
|
||||
/// </summary>
|
||||
public Sprite Image
|
||||
{
|
||||
get
|
||||
{
|
||||
return _image;
|
||||
}
|
||||
set
|
||||
{
|
||||
_image = value;
|
||||
if (OnUpdate != null)
|
||||
OnUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool _isDisabled;
|
||||
/// <summary>
|
||||
/// Is the Item currently enabled?
|
||||
/// </summary>
|
||||
public bool IsDisabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isDisabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
_isDisabled = value;
|
||||
if (OnUpdate != null)
|
||||
OnUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Action OnSelect; //action to be called when this item is selected
|
||||
|
||||
internal Action OnUpdate; //action to be called when something changes.
|
||||
|
||||
///<remarks> Value exists so that an item can have a caption and a value, like in traditional windows forms. Ie. an item may be a student's name, and the value could be the student's ID number</remarks>
|
||||
private string _value;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for ComboBoxOptions
|
||||
/// </summary>
|
||||
/// <param name="caption">Caption for the item </param>
|
||||
/// <param name="val">Value of the item </param>
|
||||
/// <param name="image"></param>
|
||||
/// <param name="disabled">Should the item start disabled</param>
|
||||
/// <param name="onSelect">Action to be called when this item is selected</param>
|
||||
public ComboBoxItem(string caption = "", string val = "", Sprite image = null, bool disabled = false, Action onSelect = null)
|
||||
{
|
||||
_caption = caption;
|
||||
_image = image;
|
||||
_value = val;
|
||||
_isDisabled = disabled;
|
||||
OnSelect = onSelect;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 261044bc84e00294d9bcf19909da3aa2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0a683473734705f4a81f6a4dbff1cb93
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
Binary file not shown.
|
@ -0,0 +1,4 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e2a3ef238d1087247ac988b1c9552363
|
||||
NativeFormatImporter:
|
||||
userData:
|
|
@ -1,61 +1,63 @@
|
|||
//Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1777407
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
using System;
|
||||
|
||||
[RequireComponent(typeof(Text),typeof(RectTransform))]
|
||||
public class CurvedText : BaseVertexEffect
|
||||
{
|
||||
public AnimationCurve curveForText = AnimationCurve.Linear (0, 0, 1, 10);
|
||||
public float curveMultiplier = 1;
|
||||
private RectTransform rectTrans;
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate ()
|
||||
{
|
||||
base.OnValidate ();
|
||||
if (curveForText [0].time != 0) {
|
||||
var tmpRect = curveForText [0];
|
||||
tmpRect.time = 0;
|
||||
curveForText.MoveKey (0, tmpRect);
|
||||
}
|
||||
if (rectTrans == null)
|
||||
rectTrans = GetComponent<RectTransform> ();
|
||||
if (curveForText [curveForText.length - 1].time != rectTrans.rect.width)
|
||||
OnRectTransformDimensionsChange ();
|
||||
}
|
||||
#endif
|
||||
protected override void Awake ()
|
||||
{
|
||||
base.Awake ();
|
||||
rectTrans = GetComponent<RectTransform> ();
|
||||
OnRectTransformDimensionsChange ();
|
||||
}
|
||||
protected override void OnEnable ()
|
||||
{
|
||||
base.OnEnable ();
|
||||
rectTrans = GetComponent<RectTransform> ();
|
||||
OnRectTransformDimensionsChange ();
|
||||
}
|
||||
public override void ModifyVertices (System.Collections.Generic.List<UIVertex> verts)
|
||||
{
|
||||
if (!IsActive ())
|
||||
return;
|
||||
|
||||
for (int index = 0; index < verts.Count; index++) {
|
||||
var uiVertex = verts [index];
|
||||
//Debug.Log ();
|
||||
uiVertex.position.y += curveForText.Evaluate (rectTrans.rect.width * rectTrans.pivot.x + uiVertex.position.x) * curveMultiplier;
|
||||
verts [index] = uiVertex;
|
||||
}
|
||||
}
|
||||
protected override void OnRectTransformDimensionsChange ()
|
||||
{
|
||||
var tmpRect = curveForText [curveForText.length - 1];
|
||||
tmpRect.time = rectTrans.rect.width;
|
||||
curveForText.MoveKey (curveForText.length - 1, tmpRect);
|
||||
}
|
||||
}
|
||||
/// Credit Breyer
|
||||
/// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1777407
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(Text), typeof(RectTransform))]
|
||||
[AddComponentMenu("UI/Effects/Extensions/Curved Text")]
|
||||
public class CurvedText : BaseVertexEffect
|
||||
{
|
||||
public AnimationCurve curveForText = AnimationCurve.Linear(0, 0, 1, 10);
|
||||
public float curveMultiplier = 1;
|
||||
private RectTransform rectTrans;
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate()
|
||||
{
|
||||
base.OnValidate();
|
||||
if (curveForText[0].time != 0)
|
||||
{
|
||||
var tmpRect = curveForText[0];
|
||||
tmpRect.time = 0;
|
||||
curveForText.MoveKey(0, tmpRect);
|
||||
}
|
||||
if (rectTrans == null)
|
||||
rectTrans = GetComponent<RectTransform>();
|
||||
if (curveForText[curveForText.length - 1].time != rectTrans.rect.width)
|
||||
OnRectTransformDimensionsChange();
|
||||
}
|
||||
#endif
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
rectTrans = GetComponent<RectTransform>();
|
||||
OnRectTransformDimensionsChange();
|
||||
}
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
rectTrans = GetComponent<RectTransform>();
|
||||
OnRectTransformDimensionsChange();
|
||||
}
|
||||
public override void ModifyVertices(System.Collections.Generic.List<UIVertex> verts)
|
||||
{
|
||||
if (!IsActive())
|
||||
return;
|
||||
|
||||
for (int index = 0; index < verts.Count; index++)
|
||||
{
|
||||
var uiVertex = verts[index];
|
||||
//Debug.Log ();
|
||||
uiVertex.position.y += curveForText.Evaluate(rectTrans.rect.width * rectTrans.pivot.x + uiVertex.position.x) * curveMultiplier;
|
||||
verts[index] = uiVertex;
|
||||
}
|
||||
}
|
||||
protected override void OnRectTransformDimensionsChange()
|
||||
{
|
||||
var tmpRect = curveForText[curveForText.length - 1];
|
||||
tmpRect.time = rectTrans.rect.width;
|
||||
curveForText.MoveKey(curveForText.length - 1, tmpRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c38666cb4d43a304588cf0b7e5f86db6
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1db494b8b78295d4c8fedb2cf71f139b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
|
@ -0,0 +1,387 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.UI.Extensions;
|
||||
|
||||
namespace UnityEditor.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// This script adds the Extensions UI menu options to the Unity Editor.
|
||||
/// </summary>
|
||||
|
||||
static internal class ExtensionMenuOptions
|
||||
{
|
||||
#region Unity Builder section - Do not change unless UI Source (Editor\MenuOptions) changes
|
||||
#region Unity Builder properties - Do not change unless UI Source (Editor\MenuOptions) changes
|
||||
private const string kUILayerName = "UI";
|
||||
private const float kWidth = 160f;
|
||||
private const float kThickHeight = 30f;
|
||||
private const float kThinHeight = 20f;
|
||||
private const string kStandardSpritePath = "UI/Skin/UISprite.psd";
|
||||
private const string kBackgroundSpriteResourcePath = "UI/Skin/Background.psd";
|
||||
private const string kInputFieldBackgroundPath = "UI/Skin/InputFieldBackground.psd";
|
||||
private const string kKnobPath = "UI/Skin/Knob.psd";
|
||||
private const string kCheckmarkPath = "UI/Skin/Checkmark.psd";
|
||||
|
||||
private static Vector2 s_ThickGUIElementSize = new Vector2(kWidth, kThickHeight);
|
||||
//private static Vector2 s_ThinGUIElementSize = new Vector2(kWidth, kThinHeight);
|
||||
private static Vector2 s_ImageGUIElementSize = new Vector2(100f, 100f);
|
||||
private static Color s_DefaultSelectableColor = new Color(1f, 1f, 1f, 1f);
|
||||
#endregion
|
||||
#region Unity Builder methods - Do not change unless UI Source (Editor\MenuOptions) changes
|
||||
private static void SetPositionVisibleinSceneView(RectTransform canvasRTransform, RectTransform itemTransform)
|
||||
{
|
||||
// Find the best scene view
|
||||
SceneView sceneView = SceneView.lastActiveSceneView;
|
||||
if (sceneView == null && SceneView.sceneViews.Count > 0)
|
||||
sceneView = SceneView.sceneViews[0] as SceneView;
|
||||
|
||||
// Couldn't find a SceneView. Don't set position.
|
||||
if (sceneView == null || sceneView.camera == null)
|
||||
return;
|
||||
|
||||
// Create world space Plane from canvas position.
|
||||
Vector2 localPlanePosition;
|
||||
Camera camera = sceneView.camera;
|
||||
Vector3 position = Vector3.zero;
|
||||
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRTransform, new Vector2(camera.pixelWidth / 2, camera.pixelHeight / 2), camera, out localPlanePosition))
|
||||
{
|
||||
// Adjust for canvas pivot
|
||||
localPlanePosition.x = localPlanePosition.x + canvasRTransform.sizeDelta.x * canvasRTransform.pivot.x;
|
||||
localPlanePosition.y = localPlanePosition.y + canvasRTransform.sizeDelta.y * canvasRTransform.pivot.y;
|
||||
|
||||
localPlanePosition.x = Mathf.Clamp(localPlanePosition.x, 0, canvasRTransform.sizeDelta.x);
|
||||
localPlanePosition.y = Mathf.Clamp(localPlanePosition.y, 0, canvasRTransform.sizeDelta.y);
|
||||
|
||||
// Adjust for anchoring
|
||||
position.x = localPlanePosition.x - canvasRTransform.sizeDelta.x * itemTransform.anchorMin.x;
|
||||
position.y = localPlanePosition.y - canvasRTransform.sizeDelta.y * itemTransform.anchorMin.y;
|
||||
|
||||
Vector3 minLocalPosition;
|
||||
minLocalPosition.x = canvasRTransform.sizeDelta.x * (0 - canvasRTransform.pivot.x) + itemTransform.sizeDelta.x * itemTransform.pivot.x;
|
||||
minLocalPosition.y = canvasRTransform.sizeDelta.y * (0 - canvasRTransform.pivot.y) + itemTransform.sizeDelta.y * itemTransform.pivot.y;
|
||||
|
||||
Vector3 maxLocalPosition;
|
||||
maxLocalPosition.x = canvasRTransform.sizeDelta.x * (1 - canvasRTransform.pivot.x) - itemTransform.sizeDelta.x * itemTransform.pivot.x;
|
||||
maxLocalPosition.y = canvasRTransform.sizeDelta.y * (1 - canvasRTransform.pivot.y) - itemTransform.sizeDelta.y * itemTransform.pivot.y;
|
||||
|
||||
position.x = Mathf.Clamp(position.x, minLocalPosition.x, maxLocalPosition.x);
|
||||
position.y = Mathf.Clamp(position.y, minLocalPosition.y, maxLocalPosition.y);
|
||||
}
|
||||
|
||||
itemTransform.anchoredPosition = position;
|
||||
itemTransform.localRotation = Quaternion.identity;
|
||||
itemTransform.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
private static GameObject CreateUIElementRoot(string name, MenuCommand menuCommand, Vector2 size)
|
||||
{
|
||||
GameObject parent = menuCommand.context as GameObject;
|
||||
if (parent == null || parent.GetComponentInParent<Canvas>() == null)
|
||||
{
|
||||
parent = GetOrCreateCanvasGameObject();
|
||||
}
|
||||
GameObject child = new GameObject(name);
|
||||
|
||||
Undo.RegisterCreatedObjectUndo(child, "Create " + name);
|
||||
Undo.SetTransformParent(child.transform, parent.transform, "Parent " + child.name);
|
||||
GameObjectUtility.SetParentAndAlign(child, parent);
|
||||
|
||||
RectTransform rectTransform = child.AddComponent<RectTransform>();
|
||||
rectTransform.sizeDelta = size;
|
||||
if (parent != menuCommand.context) // not a context click, so center in sceneview
|
||||
{
|
||||
SetPositionVisibleinSceneView(parent.GetComponent<RectTransform>(), rectTransform);
|
||||
}
|
||||
Selection.activeGameObject = child;
|
||||
return child;
|
||||
}
|
||||
|
||||
static GameObject CreateUIObject(string name, GameObject parent)
|
||||
{
|
||||
GameObject go = new GameObject(name);
|
||||
go.AddComponent<RectTransform>();
|
||||
GameObjectUtility.SetParentAndAlign(go, parent);
|
||||
return go;
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/UI/Canvas", false, 2009)]
|
||||
static public void AddCanvas(MenuCommand menuCommand)
|
||||
{
|
||||
var go = CreateNewUI();
|
||||
GameObjectUtility.SetParentAndAlign(go, menuCommand.context as GameObject);
|
||||
if (go.transform.parent as RectTransform)
|
||||
{
|
||||
RectTransform rect = go.transform as RectTransform;
|
||||
rect.anchorMin = Vector2.zero;
|
||||
rect.anchorMax = Vector2.one;
|
||||
rect.anchoredPosition = Vector2.zero;
|
||||
rect.sizeDelta = Vector2.zero;
|
||||
}
|
||||
Selection.activeGameObject = go;
|
||||
}
|
||||
|
||||
static public GameObject CreateNewUI()
|
||||
{
|
||||
// Root for the UI
|
||||
var root = new GameObject("Canvas");
|
||||
root.layer = LayerMask.NameToLayer(kUILayerName);
|
||||
Canvas canvas = root.AddComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
root.AddComponent<CanvasScaler>();
|
||||
root.AddComponent<GraphicRaycaster>();
|
||||
Undo.RegisterCreatedObjectUndo(root, "Create " + root.name);
|
||||
|
||||
// if there is no event system add one...
|
||||
CreateEventSystem(false);
|
||||
return root;
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/UI/EventSystem", false, 2010)]
|
||||
public static void CreateEventSystem(MenuCommand menuCommand)
|
||||
{
|
||||
GameObject parent = menuCommand.context as GameObject;
|
||||
CreateEventSystem(true, parent);
|
||||
}
|
||||
|
||||
private static void CreateEventSystem(bool select)
|
||||
{
|
||||
CreateEventSystem(select, null);
|
||||
}
|
||||
|
||||
private static void CreateEventSystem(bool select, GameObject parent)
|
||||
{
|
||||
var esys = Object.FindObjectOfType<EventSystem>();
|
||||
if (esys == null)
|
||||
{
|
||||
var eventSystem = new GameObject("EventSystem");
|
||||
GameObjectUtility.SetParentAndAlign(eventSystem, parent);
|
||||
esys = eventSystem.AddComponent<EventSystem>();
|
||||
eventSystem.AddComponent<StandaloneInputModule>();
|
||||
eventSystem.AddComponent<TouchInputModule>();
|
||||
|
||||
Undo.RegisterCreatedObjectUndo(eventSystem, "Create " + eventSystem.name);
|
||||
}
|
||||
|
||||
if (select && esys != null)
|
||||
{
|
||||
Selection.activeGameObject = esys.gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function that returns a Canvas GameObject; preferably a parent of the selection, or other existing Canvas.
|
||||
static public GameObject GetOrCreateCanvasGameObject()
|
||||
{
|
||||
GameObject selectedGo = Selection.activeGameObject;
|
||||
|
||||
// Try to find a gameobject that is the selected GO or one if its parents.
|
||||
Canvas canvas = (selectedGo != null) ? selectedGo.GetComponentInParent<Canvas>() : null;
|
||||
if (canvas != null && canvas.gameObject.activeInHierarchy)
|
||||
return canvas.gameObject;
|
||||
|
||||
// No canvas in selection or its parents? Then use just any canvas..
|
||||
canvas = Object.FindObjectOfType(typeof(Canvas)) as Canvas;
|
||||
if (canvas != null && canvas.gameObject.activeInHierarchy)
|
||||
return canvas.gameObject;
|
||||
|
||||
// No canvas in the scene at all? Then create a new one.
|
||||
return ExtensionMenuOptions.CreateNewUI();
|
||||
}
|
||||
|
||||
private static void SetDefaultColorTransitionValues(Selectable slider)
|
||||
{
|
||||
ColorBlock colors = slider.colors;
|
||||
colors.highlightedColor = new Color(0.882f, 0.882f, 0.882f);
|
||||
colors.pressedColor = new Color(0.698f, 0.698f, 0.698f);
|
||||
colors.disabledColor = new Color(0.521f, 0.521f, 0.521f);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region UI Extensions "Create" Menu items
|
||||
|
||||
[MenuItem("GameObject/UI/Extensions/Horizontal Scroll Snap", false, 2000)]
|
||||
static public void AddHorizontalScrollSnap(MenuCommand menuCommand)
|
||||
{
|
||||
GameObject horizontalScrollSnapRoot = CreateUIElementRoot("Horizontal Scroll Snap", menuCommand, s_ThickGUIElementSize);
|
||||
|
||||
GameObject childContent = new GameObject("Content");
|
||||
GameObjectUtility.SetParentAndAlign(childContent, horizontalScrollSnapRoot);
|
||||
|
||||
GameObject childPage01 = new GameObject("Page_01");
|
||||
GameObjectUtility.SetParentAndAlign(childPage01, childContent);
|
||||
|
||||
GameObject childText = new GameObject("Text");
|
||||
GameObjectUtility.SetParentAndAlign(childText, childPage01);
|
||||
|
||||
// Set RectTransform to stretch
|
||||
RectTransform rectTransformScrollSnapRoot = horizontalScrollSnapRoot.GetComponent<RectTransform>();
|
||||
rectTransformScrollSnapRoot.anchorMin = new Vector2(0.5f, 0.5f);
|
||||
rectTransformScrollSnapRoot.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
rectTransformScrollSnapRoot.anchoredPosition = Vector2.zero;
|
||||
rectTransformScrollSnapRoot.sizeDelta = new Vector2(300f, 150f);
|
||||
|
||||
|
||||
Image image = horizontalScrollSnapRoot.AddComponent<Image>();
|
||||
image.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(kBackgroundSpriteResourcePath);
|
||||
image.type = Image.Type.Sliced;
|
||||
image.color = new Color(1f, 1f, 1f, 0.392f);
|
||||
|
||||
ScrollRect sr = horizontalScrollSnapRoot.AddComponent<ScrollRect>();
|
||||
sr.vertical = false;
|
||||
horizontalScrollSnapRoot.AddComponent<HorizontalScrollSnap>();
|
||||
|
||||
//Setup Content container
|
||||
RectTransform rectTransformContent = childContent.AddComponent<RectTransform>();
|
||||
rectTransformContent.anchorMin = Vector2.zero;
|
||||
rectTransformContent.anchorMax = new Vector2(1f, 1f);
|
||||
//rectTransformContent.anchoredPosition = Vector2.zero;
|
||||
rectTransformContent.sizeDelta = Vector2.zero;
|
||||
|
||||
sr.content = rectTransformContent;
|
||||
|
||||
//Setup 1st Child
|
||||
Image pageImage = childPage01.AddComponent<Image>();
|
||||
pageImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(kStandardSpritePath);
|
||||
pageImage.type = Image.Type.Sliced;
|
||||
pageImage.color = s_DefaultSelectableColor;
|
||||
|
||||
RectTransform rectTransformPage01 = childPage01.GetComponent<RectTransform>();
|
||||
rectTransformPage01.anchorMin = new Vector2(0f, 0.5f);
|
||||
rectTransformPage01.anchorMax = new Vector2(0f, 0.5f);
|
||||
//rectTransformPage01.anchoredPosition = Vector2.zero;
|
||||
//rectTransformPage01.sizeDelta = Vector2.zero;
|
||||
rectTransformPage01.pivot = new Vector2(0f, 0.5f);
|
||||
|
||||
//Setup Text on Page01
|
||||
Text text = childText.AddComponent<Text>();
|
||||
text.text = "Page_01";
|
||||
text.alignment = TextAnchor.MiddleCenter;
|
||||
text.color = new Color(0.196f, 0.196f, 0.196f);
|
||||
|
||||
//Setup Text 1st Child
|
||||
RectTransform rectTransformPage01Text = childText.GetComponent<RectTransform>();
|
||||
rectTransformPage01Text.anchorMin = new Vector2(0.5f, 0.5f);
|
||||
rectTransformPage01Text.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
//rectTransformPage01Text.anchoredPosition = Vector2.zero;
|
||||
//rectTransformPage01Text.sizeDelta = Vector2.zero;
|
||||
rectTransformPage01Text.pivot = new Vector2(0.5f, 0.5f);
|
||||
|
||||
|
||||
//Need to add example child components like in the Asset (SJ)
|
||||
|
||||
Selection.activeGameObject = horizontalScrollSnapRoot;
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/UI/Extensions/UI Button", false, 2001)]
|
||||
static public void AddUIButton(MenuCommand menuCommand)
|
||||
{
|
||||
GameObject uiButtonRoot = CreateUIElementRoot("UI Button", menuCommand, s_ThickGUIElementSize);
|
||||
GameObject childText = new GameObject("Text");
|
||||
GameObjectUtility.SetParentAndAlign(childText, uiButtonRoot);
|
||||
|
||||
Image image = uiButtonRoot.AddComponent<Image>();
|
||||
image.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(kStandardSpritePath);
|
||||
image.type = Image.Type.Sliced;
|
||||
image.color = s_DefaultSelectableColor;
|
||||
|
||||
UIButton bt = uiButtonRoot.AddComponent<UIButton>();
|
||||
SetDefaultColorTransitionValues(bt);
|
||||
|
||||
Text text = childText.AddComponent<Text>();
|
||||
text.text = "Button";
|
||||
text.alignment = TextAnchor.MiddleCenter;
|
||||
text.color = new Color(0.196f, 0.196f, 0.196f);
|
||||
|
||||
RectTransform textRectTransform = childText.GetComponent<RectTransform>();
|
||||
textRectTransform.anchorMin = Vector2.zero;
|
||||
textRectTransform.anchorMax = Vector2.one;
|
||||
textRectTransform.sizeDelta = Vector2.zero;
|
||||
|
||||
Selection.activeGameObject = uiButtonRoot;
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/UI/Extensions/UI Flippable", false, 2003)]
|
||||
static public void AddUIFlippableImage(MenuCommand menuCommand)
|
||||
{
|
||||
GameObject go = CreateUIElementRoot("UI Flippable", menuCommand, s_ImageGUIElementSize);
|
||||
go.AddComponent<Image>();
|
||||
go.AddComponent<UIFlippable>();
|
||||
Selection.activeGameObject = go;
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/UI/Extensions/UI Window Base", false, 2004)]
|
||||
static public void AddUIWindowBase(MenuCommand menuCommand)
|
||||
{
|
||||
GameObject go = CreateUIElementRoot("UI Window Base", menuCommand, s_ThickGUIElementSize);
|
||||
go.AddComponent<UIWindowBase>();
|
||||
go.AddComponent<Image>();
|
||||
Selection.activeGameObject = go;
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/UI/Extensions/Accordion/Accordion Group", false, 2002)]
|
||||
static public void AddAccordionGroup(MenuCommand menuCommand)
|
||||
{
|
||||
GameObject go = CreateUIElementRoot("Accordion Group", menuCommand, s_ThickGUIElementSize);
|
||||
go.AddComponent<VerticalLayoutGroup>();
|
||||
go.AddComponent<ContentSizeFitter>();
|
||||
go.AddComponent<ToggleGroup>();
|
||||
go.AddComponent<Accordion>();
|
||||
Selection.activeGameObject = go;
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/UI/Extensions/Accordion/Accordion Element", false, 2002)]
|
||||
static public void AddAccordionElement(MenuCommand menuCommand)
|
||||
{
|
||||
GameObject go = CreateUIElementRoot("Accordion Element", menuCommand, s_ThickGUIElementSize);
|
||||
go.AddComponent<LayoutElement>();
|
||||
go.AddComponent<AccordionElement>();
|
||||
Selection.activeGameObject = go;
|
||||
|
||||
}
|
||||
|
||||
//Awaiting updated control from autor - Use PreFab for now
|
||||
//[MenuItem("GameObject/UI/Extensions/ComboBox", false, 2002)]
|
||||
//static public void AddComboBox(MenuCommand menuCommand)
|
||||
//{
|
||||
// GameObject go = CreateUIElementRoot("ComboBox", menuCommand, s_ThickGUIElementSize);
|
||||
// go.AddComponent<ComboBox>();
|
||||
// Selection.activeGameObject = go;
|
||||
//}
|
||||
|
||||
[MenuItem("GameObject/UI/Extensions/Selection Box", false, 2009)]
|
||||
static public void AddSelectionBox(MenuCommand menuCommand)
|
||||
{
|
||||
var go = CreateNewUI();
|
||||
go.name = "Selection Box";
|
||||
GameObjectUtility.SetParentAndAlign(go, menuCommand.context as GameObject);
|
||||
RectTransform rect = go.transform as RectTransform;
|
||||
rect.anchorMin = Vector2.zero;
|
||||
rect.anchorMax = Vector2.one;
|
||||
rect.anchoredPosition = Vector2.zero;
|
||||
rect.sizeDelta = Vector2.zero;
|
||||
|
||||
Image image = go.AddComponent<Image>();
|
||||
image.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(kBackgroundSpriteResourcePath);
|
||||
image.type = Image.Type.Sliced;
|
||||
image.fillCenter = false;
|
||||
image.color = new Color(1f, 1f, 1f, 0.392f);
|
||||
|
||||
|
||||
SelectionBox selectableArea = go.AddComponent<SelectionBox>();
|
||||
selectableArea.selectionMask = rect;
|
||||
selectableArea.color = new Color(0.816f, 0.816f, 0.816f, 0.353f);
|
||||
|
||||
|
||||
GameObject childSelectableItem = new GameObject("Selectable");
|
||||
GameObjectUtility.SetParentAndAlign(childSelectableItem, go);
|
||||
childSelectableItem.AddComponent<Image>();
|
||||
childSelectableItem.AddComponent<ExampleSelectable>();
|
||||
|
||||
|
||||
Selection.activeGameObject = go;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3cac6d35505037446b512aea22d40688
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -1,94 +1,104 @@
|
|||
//Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1780095
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[AddComponentMenu("UI/Effects/Gradient")]
|
||||
public class Gradient : BaseVertexEffect
|
||||
{
|
||||
public GradientMode gradientMode = GradientMode.Global;
|
||||
public GradientDir gradientDir = GradientDir.Vertical;
|
||||
public bool overwriteAllColor = false;
|
||||
public Color vertex1 = Color.white;
|
||||
public Color vertex2 = Color.black;
|
||||
private Graphic targetGraphic;
|
||||
|
||||
protected override void Start ()
|
||||
{
|
||||
targetGraphic = GetComponent<Graphic> ();
|
||||
}
|
||||
|
||||
public override void ModifyVertices (List<UIVertex> vertexList)
|
||||
{
|
||||
if (!IsActive () || vertexList.Count == 0) {
|
||||
return;
|
||||
}
|
||||
int count = vertexList.Count;
|
||||
UIVertex uiVertex = vertexList [0];
|
||||
if (gradientMode == GradientMode.Global) {
|
||||
if (gradientDir == GradientDir.DiagonalLeftToRight || gradientDir == GradientDir.DiagonalRightToLeft) {
|
||||
#if UNITY_EDITOR
|
||||
Debug.LogWarning("Diagonal dir is not supported in Global mode");
|
||||
#endif
|
||||
gradientDir = GradientDir.Vertical;
|
||||
}
|
||||
float bottomY = gradientDir == GradientDir.Vertical ? vertexList [vertexList.Count - 1].position.y : vertexList [vertexList.Count - 1].position.x;
|
||||
float topY = gradientDir == GradientDir.Vertical ? vertexList [0].position.y : vertexList [0].position.x;
|
||||
|
||||
float uiElementHeight = topY - bottomY;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
uiVertex = vertexList [i];
|
||||
if (!overwriteAllColor && uiVertex.color != targetGraphic.color)
|
||||
continue;
|
||||
uiVertex.color *= Color.Lerp (vertex2, vertex1, ((gradientDir == GradientDir.Vertical ? uiVertex.position.y : uiVertex.position.x) - bottomY) / uiElementHeight);
|
||||
vertexList [i] = uiVertex;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < count; i++) {
|
||||
uiVertex = vertexList [i];
|
||||
if (!overwriteAllColor && !CompareCarefully (uiVertex.color, targetGraphic.color))
|
||||
continue;
|
||||
switch (gradientDir) {
|
||||
case GradientDir.Vertical:
|
||||
uiVertex.color *= (i % 4 == 0 || (i - 1) % 4 == 0) ? vertex1 : vertex2;
|
||||
break;
|
||||
case GradientDir.Horizontal:
|
||||
uiVertex.color *= (i % 4 == 0 || (i - 3) % 4 == 0) ? vertex1 : vertex2;
|
||||
break;
|
||||
case GradientDir.DiagonalLeftToRight:
|
||||
uiVertex.color *= (i % 4 == 0) ? vertex1 : ((i - 2) % 4 == 0 ? vertex2 : Color.Lerp (vertex2, vertex1, 0.5f));
|
||||
break;
|
||||
case GradientDir.DiagonalRightToLeft:
|
||||
uiVertex.color *= ((i - 1) % 4 == 0) ? vertex1 : ((i - 3) % 4 == 0 ? vertex2 : Color.Lerp (vertex2, vertex1, 0.5f));
|
||||
break;
|
||||
|
||||
}
|
||||
vertexList [i] = uiVertex;
|
||||
}
|
||||
}
|
||||
}
|
||||
private bool CompareCarefully (Color col1, Color col2)
|
||||
{
|
||||
if (Mathf.Abs (col1.r - col2.r) < 0.003f && Mathf.Abs (col1.g - col2.g) < 0.003f && Mathf.Abs (col1.b - col2.b) < 0.003f && Mathf.Abs (col1.a - col2.a) < 0.003f)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public enum GradientMode
|
||||
{
|
||||
Global,
|
||||
Local
|
||||
}
|
||||
public enum GradientDir
|
||||
{
|
||||
Vertical,
|
||||
Horizontal,
|
||||
DiagonalLeftToRight,
|
||||
DiagonalRightToLeft
|
||||
//Free
|
||||
}
|
||||
//enum color mode Additive, Multiply, Overwrite
|
||||
/// Credit Breyer
|
||||
/// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1780095
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/Gradient")]
|
||||
public class Gradient : BaseVertexEffect
|
||||
{
|
||||
public GradientMode gradientMode = GradientMode.Global;
|
||||
public GradientDir gradientDir = GradientDir.Vertical;
|
||||
public bool overwriteAllColor = false;
|
||||
public Color vertex1 = Color.white;
|
||||
public Color vertex2 = Color.black;
|
||||
private Graphic targetGraphic;
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
targetGraphic = GetComponent<Graphic>();
|
||||
}
|
||||
|
||||
public override void ModifyVertices(List<UIVertex> vertexList)
|
||||
{
|
||||
if (!IsActive() || vertexList.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int count = vertexList.Count;
|
||||
UIVertex uiVertex = vertexList[0];
|
||||
if (gradientMode == GradientMode.Global)
|
||||
{
|
||||
if (gradientDir == GradientDir.DiagonalLeftToRight || gradientDir == GradientDir.DiagonalRightToLeft)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Debug.LogWarning("Diagonal dir is not supported in Global mode");
|
||||
#endif
|
||||
gradientDir = GradientDir.Vertical;
|
||||
}
|
||||
float bottomY = gradientDir == GradientDir.Vertical ? vertexList[vertexList.Count - 1].position.y : vertexList[vertexList.Count - 1].position.x;
|
||||
float topY = gradientDir == GradientDir.Vertical ? vertexList[0].position.y : vertexList[0].position.x;
|
||||
|
||||
float uiElementHeight = topY - bottomY;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
uiVertex = vertexList[i];
|
||||
if (!overwriteAllColor && uiVertex.color != targetGraphic.color)
|
||||
continue;
|
||||
uiVertex.color *= Color.Lerp(vertex2, vertex1, ((gradientDir == GradientDir.Vertical ? uiVertex.position.y : uiVertex.position.x) - bottomY) / uiElementHeight);
|
||||
vertexList[i] = uiVertex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
uiVertex = vertexList[i];
|
||||
if (!overwriteAllColor && !CompareCarefully(uiVertex.color, targetGraphic.color))
|
||||
continue;
|
||||
switch (gradientDir)
|
||||
{
|
||||
case GradientDir.Vertical:
|
||||
uiVertex.color *= (i % 4 == 0 || (i - 1) % 4 == 0) ? vertex1 : vertex2;
|
||||
break;
|
||||
case GradientDir.Horizontal:
|
||||
uiVertex.color *= (i % 4 == 0 || (i - 3) % 4 == 0) ? vertex1 : vertex2;
|
||||
break;
|
||||
case GradientDir.DiagonalLeftToRight:
|
||||
uiVertex.color *= (i % 4 == 0) ? vertex1 : ((i - 2) % 4 == 0 ? vertex2 : Color.Lerp(vertex2, vertex1, 0.5f));
|
||||
break;
|
||||
case GradientDir.DiagonalRightToLeft:
|
||||
uiVertex.color *= ((i - 1) % 4 == 0) ? vertex1 : ((i - 3) % 4 == 0 ? vertex2 : Color.Lerp(vertex2, vertex1, 0.5f));
|
||||
break;
|
||||
|
||||
}
|
||||
vertexList[i] = uiVertex;
|
||||
}
|
||||
}
|
||||
}
|
||||
private bool CompareCarefully(Color col1, Color col2)
|
||||
{
|
||||
if (Mathf.Abs(col1.r - col2.r) < 0.003f && Mathf.Abs(col1.g - col2.g) < 0.003f && Mathf.Abs(col1.b - col2.b) < 0.003f && Mathf.Abs(col1.a - col2.a) < 0.003f)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public enum GradientMode
|
||||
{
|
||||
Global,
|
||||
Local
|
||||
}
|
||||
|
||||
public enum GradientDir
|
||||
{
|
||||
Vertical,
|
||||
Horizontal,
|
||||
DiagonalLeftToRight,
|
||||
DiagonalRightToLeft
|
||||
//Free
|
||||
}
|
||||
//enum color mode Additive, Multiply, Overwrite
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0671953a9c649e5438e4d961d1983915
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4769eefffce5c0b4181e4f9d1587b9f4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
|
@ -0,0 +1,20 @@
|
|||
///Credit judah4
|
||||
///Sourced from - http://forum.unity3d.com/threads/color-picker.267043/
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
public class ColorPickerTester : MonoBehaviour
|
||||
{
|
||||
public Renderer renderer;
|
||||
public HSVPicker picker;
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
picker.onValueChanged.AddListener(color =>
|
||||
{
|
||||
renderer.material.color = color;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 06851a815227e5044b0e3c1bf9b3a282
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,228 @@
|
|||
///Credit judah4
|
||||
///Sourced from - http://forum.unity3d.com/threads/color-picker.267043/
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
public class HSVPicker : MonoBehaviour
|
||||
{
|
||||
public HexRGB hexrgb;
|
||||
|
||||
public Color currentColor;
|
||||
public Image colorImage;
|
||||
public Image pointer;
|
||||
public Image cursor;
|
||||
public RawImage hsvSlider;
|
||||
public RawImage hsvImage;
|
||||
|
||||
//public InputField inputR;
|
||||
//public InputField inputG;
|
||||
//public InputField inputB;
|
||||
|
||||
public Slider sliderR;
|
||||
public Slider sliderG;
|
||||
public Slider sliderB;
|
||||
public Text sliderRText;
|
||||
public Text sliderGText;
|
||||
public Text sliderBText;
|
||||
|
||||
public float pointerPos = 0;
|
||||
|
||||
public float cursorX = 0;
|
||||
public float cursorY = 0;
|
||||
|
||||
|
||||
public HSVSliderEvent onValueChanged = new HSVSliderEvent();
|
||||
|
||||
private bool dontAssignUpdate = false;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
hsvSlider.texture = HSVUtil.GenerateHSVTexture((int)hsvSlider.rectTransform.rect.width, (int)hsvSlider.rectTransform.rect.height);
|
||||
|
||||
sliderR.onValueChanged.AddListener(newValue =>
|
||||
{
|
||||
currentColor.r = newValue;
|
||||
if (dontAssignUpdate == false)
|
||||
{
|
||||
AssignColor(currentColor);
|
||||
}
|
||||
sliderRText.text = "R:" + (int)(currentColor.r * 255f);
|
||||
hexrgb.ManipulateViaRGB2Hex();
|
||||
});
|
||||
sliderG.onValueChanged.AddListener(newValue =>
|
||||
{
|
||||
currentColor.g = newValue;
|
||||
if (dontAssignUpdate == false)
|
||||
{
|
||||
AssignColor(currentColor);
|
||||
}
|
||||
sliderGText.text = "G:" + (int)(currentColor.g * 255f);
|
||||
hexrgb.ManipulateViaRGB2Hex();
|
||||
});
|
||||
sliderB.onValueChanged.AddListener(newValue =>
|
||||
{
|
||||
currentColor.b = newValue;
|
||||
if (dontAssignUpdate == false)
|
||||
{
|
||||
AssignColor(currentColor);
|
||||
}
|
||||
sliderBText.text = "B:" + (int)(currentColor.b * 255f);
|
||||
hexrgb.ManipulateViaRGB2Hex();
|
||||
});
|
||||
|
||||
|
||||
hsvImage.texture = HSVUtil.GenerateColorTexture((int)hsvImage.rectTransform.rect.width, (int)hsvImage.rectTransform.rect.height, ((Texture2D)hsvSlider.texture).GetPixelBilinear(0, 0));
|
||||
MoveCursor(cursorX, cursorY);
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
//if (Input.GetKeyDown(KeyCode.R))
|
||||
//{
|
||||
// var color = new Color(45f / 255, 200f / 255, 255f / 255);
|
||||
// Debug.Log(color);
|
||||
// AssignColor(color);
|
||||
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void AssignColor(Color color)
|
||||
{
|
||||
|
||||
var hsv = HSVUtil.ConvertRgbToHsv(color);
|
||||
|
||||
// Debug.Log(hsv.ToString());
|
||||
|
||||
float hOffset = (float)(hsv.H / 360);
|
||||
|
||||
//if (hsv.S > 1)
|
||||
//{
|
||||
// hsv.S %= 1f;
|
||||
//}
|
||||
//if (hsv.V > 1)
|
||||
//{
|
||||
// hsv.V %= 1f;
|
||||
//}
|
||||
|
||||
MovePointer(hOffset, false);
|
||||
MoveCursor((float)hsv.S, (float)hsv.V, false);
|
||||
|
||||
currentColor = color;
|
||||
colorImage.color = currentColor;
|
||||
|
||||
onValueChanged.Invoke(currentColor);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public Color MoveCursor(float posX, float posY, bool updateInputs = true)
|
||||
{
|
||||
dontAssignUpdate = updateInputs;
|
||||
if (posX > 1)
|
||||
{
|
||||
posX %= 1;
|
||||
}
|
||||
if (posY > 1)
|
||||
{
|
||||
posY %= 1;
|
||||
}
|
||||
|
||||
posY = Mathf.Clamp(posY, 0, .9999f);
|
||||
posX = Mathf.Clamp(posX, 0, .9999f);
|
||||
|
||||
|
||||
cursorX = posX;
|
||||
cursorY = posY;
|
||||
cursor.rectTransform.anchoredPosition = new Vector2(posX * hsvImage.rectTransform.rect.width, posY * hsvImage.rectTransform.rect.height - hsvImage.rectTransform.rect.height);
|
||||
|
||||
currentColor = GetColor(cursorX, cursorY);
|
||||
colorImage.color = currentColor;
|
||||
|
||||
if (updateInputs)
|
||||
{
|
||||
UpdateInputs();
|
||||
onValueChanged.Invoke(currentColor);
|
||||
}
|
||||
dontAssignUpdate = false;
|
||||
return currentColor;
|
||||
}
|
||||
|
||||
public Color GetColor(float posX, float posY)
|
||||
{
|
||||
//Debug.Log(posX + " " + posY);
|
||||
return ((Texture2D)hsvImage.texture).GetPixel((int)(cursorX * hsvImage.texture.width), (int)(cursorY * hsvImage.texture.height));
|
||||
}
|
||||
|
||||
public Color MovePointer(float newPos, bool updateInputs = true)
|
||||
{
|
||||
dontAssignUpdate = updateInputs;
|
||||
if (newPos > 1)
|
||||
{
|
||||
newPos %= 1f;//hsv
|
||||
}
|
||||
pointerPos = newPos;
|
||||
|
||||
var mainColor = ((Texture2D)hsvSlider.texture).GetPixelBilinear(0, pointerPos);
|
||||
if (hsvImage.texture != null)
|
||||
{
|
||||
if ((int)hsvImage.rectTransform.rect.width != hsvImage.texture.width || (int)hsvImage.rectTransform.rect.height != hsvImage.texture.height)
|
||||
{
|
||||
Destroy(hsvImage.texture);
|
||||
hsvImage.texture = null;
|
||||
|
||||
hsvImage.texture = HSVUtil.GenerateColorTexture((int)hsvImage.rectTransform.rect.width, (int)hsvImage.rectTransform.rect.height, mainColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
HSVUtil.GenerateColorTexture(mainColor, (Texture2D)hsvImage.texture);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
hsvImage.texture = HSVUtil.GenerateColorTexture((int)hsvImage.rectTransform.rect.width, (int)hsvImage.rectTransform.rect.height, mainColor);
|
||||
}
|
||||
pointer.rectTransform.anchoredPosition = new Vector2(0, -pointerPos * hsvSlider.rectTransform.rect.height);
|
||||
|
||||
currentColor = GetColor(cursorX, cursorY);
|
||||
colorImage.color = currentColor;
|
||||
|
||||
if (updateInputs)
|
||||
{
|
||||
UpdateInputs();
|
||||
onValueChanged.Invoke(currentColor);
|
||||
}
|
||||
dontAssignUpdate = false;
|
||||
return currentColor;
|
||||
}
|
||||
|
||||
public void UpdateInputs()
|
||||
{
|
||||
|
||||
sliderR.value = currentColor.r;
|
||||
sliderG.value = currentColor.g;
|
||||
sliderB.value = currentColor.b;
|
||||
|
||||
sliderRText.text = "R:" + (currentColor.r * 255f);
|
||||
sliderGText.text = "G:" + (currentColor.g * 255f);
|
||||
sliderBText.text = "B:" + (currentColor.b * 255f);
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if (hsvSlider.texture != null)
|
||||
{
|
||||
Destroy(hsvSlider.texture);
|
||||
}
|
||||
|
||||
if (hsvImage.texture != null)
|
||||
{
|
||||
Destroy(hsvImage.texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8262e4a8322117f4da079921eaa72834
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,11 @@
|
|||
///Credit judah4
|
||||
///Sourced from - http://forum.unity3d.com/threads/color-picker.267043/
|
||||
|
||||
using UnityEngine.Events;
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
public class HSVSliderEvent : UnityEvent<Color>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ff46fbecea7739f4690e4285c88f53c5
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,278 @@
|
|||
///Credit judah4
|
||||
///Sourced from - http://forum.unity3d.com/threads/color-picker.267043/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
#region ColorUtilities
|
||||
|
||||
public static class HSVUtil
|
||||
{
|
||||
|
||||
public static HsvColor ConvertRgbToHsv(Color color)
|
||||
{
|
||||
return ConvertRgbToHsv((int)(color.r * 255), (int)(color.g * 255), (int)(color.b * 255));
|
||||
}
|
||||
|
||||
// Converts an RGB color to an HSV color.
|
||||
public static HsvColor ConvertRgbToHsv(double r, double b, double g)
|
||||
{
|
||||
|
||||
double delta, min;
|
||||
double h = 0, s, v;
|
||||
|
||||
min = Math.Min(Math.Min(r, g), b);
|
||||
v = Math.Max(Math.Max(r, g), b);
|
||||
delta = v - min;
|
||||
|
||||
if (v == 0.0)
|
||||
{
|
||||
s = 0;
|
||||
|
||||
}
|
||||
else
|
||||
s = delta / v;
|
||||
|
||||
if (s == 0)
|
||||
h = 0.0f;
|
||||
|
||||
else
|
||||
{
|
||||
if (r == v)
|
||||
h = (g - b) / delta;
|
||||
else if (g == v)
|
||||
h = 2 + (b - r) / delta;
|
||||
else if (b == v)
|
||||
h = 4 + (r - g) / delta;
|
||||
|
||||
h *= 60;
|
||||
if (h < 0.0)
|
||||
h = h + 360;
|
||||
|
||||
}
|
||||
|
||||
HsvColor hsvColor = new HsvColor();
|
||||
hsvColor.H = h;
|
||||
hsvColor.S = s;
|
||||
hsvColor.V = v / 255;
|
||||
|
||||
return hsvColor;
|
||||
|
||||
}
|
||||
|
||||
public static Color ConvertHsvToRgb(HsvColor color)
|
||||
{
|
||||
return ConvertHsvToRgb(color.H, color.S, color.V);
|
||||
}
|
||||
|
||||
// Converts an HSV color to an RGB color.
|
||||
public static Color ConvertHsvToRgb(double h, double s, double v)
|
||||
{
|
||||
|
||||
double r = 0, g = 0, b = 0;
|
||||
|
||||
if (s == 0)
|
||||
{
|
||||
r = v;
|
||||
g = v;
|
||||
b = v;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
double f, p, q, t;
|
||||
|
||||
|
||||
if (h == 360)
|
||||
h = 0;
|
||||
else
|
||||
h = h / 60;
|
||||
|
||||
i = (int)(h);
|
||||
f = h - i;
|
||||
|
||||
p = v * (1.0 - s);
|
||||
q = v * (1.0 - (s * f));
|
||||
t = v * (1.0 - (s * (1.0f - f)));
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
r = v;
|
||||
g = t;
|
||||
b = p;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
r = q;
|
||||
g = v;
|
||||
b = p;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
r = p;
|
||||
g = v;
|
||||
b = t;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
r = p;
|
||||
g = q;
|
||||
b = v;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
r = t;
|
||||
g = p;
|
||||
b = v;
|
||||
break;
|
||||
|
||||
default:
|
||||
r = v;
|
||||
g = p;
|
||||
b = q;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return new Color((float)r, (float)g, (float)b, 1);//255, (byte)(r * 255), (byte)(g * 255), (byte)(b * 255));
|
||||
|
||||
}
|
||||
|
||||
// Generates a list of colors with hues ranging from 0 360
|
||||
// and a saturation and value of 1.
|
||||
public static List<Color> GenerateHsvSpectrum()
|
||||
{
|
||||
|
||||
List<Color> colorsList = new List<Color>(8);
|
||||
|
||||
|
||||
//for (int i = 0; i < 29; i++)
|
||||
//{
|
||||
|
||||
// colorsList.Add(
|
||||
// ConvertHsvToRgb(i * 12, 1, 1)
|
||||
|
||||
// );
|
||||
|
||||
//}
|
||||
|
||||
for (int i = 0; i < 359; i++)
|
||||
{
|
||||
|
||||
colorsList.Add(
|
||||
ConvertHsvToRgb(i, 1, 1)
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
colorsList.Add(ConvertHsvToRgb(0, 1, 1));
|
||||
|
||||
|
||||
return colorsList;
|
||||
|
||||
}
|
||||
|
||||
public static Texture2D GenerateHSVTexture(int width, int height)
|
||||
{
|
||||
var list = GenerateHsvSpectrum();
|
||||
|
||||
float interval = 1;
|
||||
if (list.Count > height)
|
||||
{
|
||||
interval = (float)list.Count / height;
|
||||
}
|
||||
|
||||
var texture = new Texture2D(width, height);
|
||||
|
||||
int ySize = Mathf.Max(1, (int)(1f / (list.Count / interval) * height));
|
||||
|
||||
int colorH = 0;
|
||||
|
||||
Color color = Color.white;
|
||||
for (float cnt = 0; cnt < list.Count; cnt += interval)
|
||||
{
|
||||
color = list[(int)cnt];
|
||||
Color[] colors = new Color[width * ySize];
|
||||
for (int i = 0; i < width * ySize; i++)
|
||||
{
|
||||
colors[i] = color;
|
||||
}
|
||||
if (colorH < height)
|
||||
{
|
||||
texture.SetPixels(0, colorH, width, ySize, colors);
|
||||
}
|
||||
colorH += ySize;
|
||||
}
|
||||
|
||||
texture.Apply();
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
public static Texture2D GenerateColorTexture(Color mainColor, Texture2D texture)
|
||||
{
|
||||
int width = texture.width;
|
||||
int height = texture.height;
|
||||
|
||||
var hsvColor = ConvertRgbToHsv((int)(mainColor.r * 255), (int)(mainColor.g * 255), (int)(mainColor.b * 255));
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
var adjustedColor = hsvColor;
|
||||
adjustedColor.V = (float)y / height;
|
||||
adjustedColor.S = (float)x / width;
|
||||
var color = ConvertHsvToRgb(adjustedColor.H, adjustedColor.S, adjustedColor.V);
|
||||
texture.SetPixel(x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
texture.Apply();
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static Texture2D GenerateColorTexture(int width, int height, Color mainColor)
|
||||
{
|
||||
return GenerateColorTexture(mainColor, new Texture2D(width, height));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endregion ColorUtilities
|
||||
|
||||
|
||||
// Describes a color in terms of
|
||||
// Hue, Saturation, and Value (brightness)
|
||||
#region HsvColor
|
||||
public struct HsvColor
|
||||
{
|
||||
|
||||
public double H;
|
||||
public double S;
|
||||
public double V;
|
||||
|
||||
public HsvColor(double h, double s, double v)
|
||||
{
|
||||
this.H = h;
|
||||
this.S = s;
|
||||
this.V = v;
|
||||
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "{" + H + "," + S + "," + V + "}";
|
||||
}
|
||||
}
|
||||
#endregion HsvColor
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4f3189246d7fc204faba7a1e9c08e0af
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,79 @@
|
|||
///Credit judah4
|
||||
///Sourced from - http://forum.unity3d.com/threads/color-picker.267043/
|
||||
|
||||
using System.Globalization;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
public class HexRGB : MonoBehaviour
|
||||
{
|
||||
public Text textColor;
|
||||
|
||||
public HSVPicker hsvpicker;
|
||||
|
||||
public void ManipulateViaRGB2Hex()
|
||||
{
|
||||
Color color = hsvpicker.currentColor;
|
||||
string hex = ColorToHex(color);
|
||||
textColor.text = hex;
|
||||
}
|
||||
|
||||
public static string ColorToHex(Color color)
|
||||
{
|
||||
int r = (int)(color.r * 255);
|
||||
int g = (int)(color.g * 255);
|
||||
int b = (int)(color.b * 255);
|
||||
return string.Format("#{0:X2}{1:X2}{2:X2}", r, g, b);
|
||||
}
|
||||
|
||||
public void ManipulateViaHex2RGB()
|
||||
{
|
||||
string hex = textColor.text;
|
||||
|
||||
Vector3 rgb = Hex2RGB(hex);
|
||||
Color color = NormalizeVector4(rgb, 255f, 1f); print(rgb);
|
||||
|
||||
hsvpicker.AssignColor(color);
|
||||
}
|
||||
|
||||
static Color NormalizeVector4(Vector3 v, float r, float a)
|
||||
{
|
||||
float red = v.x / r;
|
||||
float green = v.y / r;
|
||||
float blue = v.z / r;
|
||||
return new Color(red, green, blue, a);
|
||||
}
|
||||
|
||||
Vector3 Hex2RGB(string hexColor)
|
||||
{
|
||||
//Remove # if present
|
||||
if (hexColor.IndexOf('#') != -1)
|
||||
hexColor = hexColor.Replace("#", "");
|
||||
|
||||
int red = 0;
|
||||
int green = 0;
|
||||
int blue = 0;
|
||||
|
||||
if (hexColor.Length == 6)
|
||||
{
|
||||
//#RRGGBB
|
||||
red = int.Parse(hexColor.Substring(0, 2), NumberStyles.AllowHexSpecifier);
|
||||
green = int.Parse(hexColor.Substring(2, 2), NumberStyles.AllowHexSpecifier);
|
||||
blue = int.Parse(hexColor.Substring(4, 2), NumberStyles.AllowHexSpecifier);
|
||||
|
||||
|
||||
}
|
||||
else if (hexColor.Length == 3)
|
||||
{
|
||||
//#RGB
|
||||
red = int.Parse(hexColor[0].ToString() + hexColor[0].ToString(), NumberStyles.AllowHexSpecifier);
|
||||
green = int.Parse(hexColor[1].ToString() + hexColor[1].ToString(), NumberStyles.AllowHexSpecifier);
|
||||
blue = int.Parse(hexColor[2].ToString() + hexColor[2].ToString(), NumberStyles.AllowHexSpecifier);
|
||||
}
|
||||
|
||||
return new Vector3(red, green, blue);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4b2932ecb1276c447863e4d540fc693a
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,38 @@
|
|||
///Credit judah4
|
||||
///Sourced from - http://forum.unity3d.com/threads/color-picker.267043/
|
||||
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
public class HsvBoxSelector : MonoBehaviour, IDragHandler, IPointerDownHandler
|
||||
{
|
||||
public HSVPicker picker;
|
||||
|
||||
void PlaceCursor(PointerEventData eventData)
|
||||
{
|
||||
|
||||
var pos = new Vector2(eventData.position.x - picker.hsvImage.rectTransform.position.x, picker.hsvImage.rectTransform.rect.height * picker.hsvImage.transform.lossyScale.y - (picker.hsvImage.rectTransform.position.y - eventData.position.y));
|
||||
// Debug.Log(pos);
|
||||
pos.x /= picker.hsvImage.rectTransform.rect.width * picker.hsvImage.transform.lossyScale.x;
|
||||
pos.y /= picker.hsvImage.rectTransform.rect.height * picker.hsvImage.transform.lossyScale.y;
|
||||
|
||||
pos.x = Mathf.Clamp(pos.x, 0, .9999f); //1 is the same as 0
|
||||
pos.y = Mathf.Clamp(pos.y, 0, .9999f);
|
||||
|
||||
//Debug.Log(pos);
|
||||
picker.MoveCursor(pos.x, pos.y);
|
||||
}
|
||||
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
PlaceCursor(eventData);
|
||||
}
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
PlaceCursor(eventData);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 95a3081947ad463418f853d27e477017
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,37 @@
|
|||
///Credit judah4
|
||||
///Sourced from - http://forum.unity3d.com/threads/color-picker.267043/
|
||||
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
public class HsvSliderPicker : MonoBehaviour, IDragHandler, IPointerDownHandler
|
||||
{
|
||||
public HSVPicker picker;
|
||||
|
||||
void PlacePointer(PointerEventData eventData)
|
||||
{
|
||||
|
||||
var pos = new Vector2(eventData.position.x - picker.hsvSlider.rectTransform.position.x, picker.hsvSlider.rectTransform.position.y - eventData.position.y);
|
||||
|
||||
pos.y /= picker.hsvSlider.rectTransform.rect.height * picker.hsvSlider.canvas.transform.lossyScale.y;
|
||||
|
||||
//Debug.Log(eventData.position.ToString() + " " + picker.hsvSlider.rectTransform.position + " " + picker.hsvSlider.rectTransform.rect.height);
|
||||
pos.y = Mathf.Clamp(pos.y, 0, 1f);
|
||||
|
||||
picker.MovePointer(pos.y);
|
||||
}
|
||||
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
PlacePointer(eventData);
|
||||
|
||||
}
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
PlacePointer(eventData);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7d5b03a797859a94989cdbcb68e37fb1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
Binary file not shown.
|
@ -0,0 +1,4 @@
|
|||
fileFormatVersion: 2
|
||||
guid: be7385871d213f844981bd24e601eb98
|
||||
NativeFormatImporter:
|
||||
userData:
|
Binary file not shown.
|
@ -0,0 +1,4 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ce46c07f0028e314ab7767577ab5e7a6
|
||||
DefaultImporter:
|
||||
userData:
|
|
@ -0,0 +1,283 @@
|
|||
/// Credit BinaryX
|
||||
/// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-1945602
|
||||
/// Updated by ddreaper - removed dependency on a custom ScrollRect script. Now implements drag interfaces and standard Scroll Rect.
|
||||
|
||||
using System;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(ScrollRect))]
|
||||
[AddComponentMenu("UI/Extensions/Horizontal Scroll Snap")]
|
||||
public class HorizontalScrollSnap : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
|
||||
{
|
||||
private Transform _screensContainer;
|
||||
|
||||
private int _screens = 1;
|
||||
private int _startingScreen = 1;
|
||||
|
||||
private bool _fastSwipeTimer = false;
|
||||
private int _fastSwipeCounter = 0;
|
||||
private int _fastSwipeTarget = 30;
|
||||
|
||||
|
||||
private System.Collections.Generic.List<Vector3> _positions;
|
||||
private ScrollRect _scroll_rect;
|
||||
private Vector3 _lerp_target;
|
||||
private bool _lerp;
|
||||
|
||||
private int _containerSize;
|
||||
|
||||
[Tooltip("The gameobject that contains toggles which suggest pagination. (optional)")]
|
||||
public GameObject Pagination;
|
||||
|
||||
[Tooltip("Button to go to the next page. (optional)")]
|
||||
public GameObject NextButton;
|
||||
[Tooltip("Button to go to the previous page. (optional)")]
|
||||
public GameObject PrevButton;
|
||||
|
||||
public Boolean UseFastSwipe = true;
|
||||
public int FastSwipeThreshold = 100;
|
||||
|
||||
private bool _startDrag = true;
|
||||
private Vector3 _startPosition = new Vector3();
|
||||
private int _currentScreen;
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
_scroll_rect = gameObject.GetComponent<ScrollRect>();
|
||||
_screensContainer = _scroll_rect.content;
|
||||
DistributePages();
|
||||
|
||||
_screens = _screensContainer.childCount;
|
||||
|
||||
_lerp = false;
|
||||
|
||||
_positions = new System.Collections.Generic.List<Vector3>();
|
||||
|
||||
if (_screens > 0)
|
||||
{
|
||||
for (int i = 0; i < _screens; ++i)
|
||||
{
|
||||
_scroll_rect.horizontalNormalizedPosition = (float)i / (float)(_screens - 1);
|
||||
_positions.Add(_screensContainer.localPosition);
|
||||
}
|
||||
}
|
||||
|
||||
_scroll_rect.horizontalNormalizedPosition = (float)(_startingScreen - 1) / (float)(_screens - 1);
|
||||
|
||||
_containerSize = (int)_screensContainer.gameObject.GetComponent<RectTransform>().offsetMax.x;
|
||||
|
||||
ChangeBulletsInfo(CurrentScreen());
|
||||
|
||||
if (NextButton)
|
||||
NextButton.GetComponent<Button>().onClick.AddListener(() => { NextScreen(); });
|
||||
|
||||
if (PrevButton)
|
||||
PrevButton.GetComponent<Button>().onClick.AddListener(() => { PreviousScreen(); });
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (_lerp)
|
||||
{
|
||||
_screensContainer.localPosition = Vector3.Lerp(_screensContainer.localPosition, _lerp_target, 7.5f * Time.deltaTime);
|
||||
if (Vector3.Distance(_screensContainer.localPosition, _lerp_target) < 0.005f)
|
||||
{
|
||||
_lerp = false;
|
||||
}
|
||||
|
||||
//change the info bullets at the bottom of the screen. Just for visual effect
|
||||
if (Vector3.Distance(_screensContainer.localPosition, _lerp_target) < 10f)
|
||||
{
|
||||
ChangeBulletsInfo(CurrentScreen());
|
||||
}
|
||||
}
|
||||
|
||||
if (_fastSwipeTimer)
|
||||
{
|
||||
_fastSwipeCounter++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private bool fastSwipe = false; //to determine if a fast swipe was performed
|
||||
|
||||
|
||||
//Function for switching screens with buttons
|
||||
public void NextScreen()
|
||||
{
|
||||
if (CurrentScreen() < _screens - 1)
|
||||
{
|
||||
_lerp = true;
|
||||
_lerp_target = _positions[CurrentScreen() + 1];
|
||||
|
||||
ChangeBulletsInfo(CurrentScreen() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
//Function for switching screens with buttons
|
||||
public void PreviousScreen()
|
||||
{
|
||||
if (CurrentScreen() > 0)
|
||||
{
|
||||
_lerp = true;
|
||||
_lerp_target = _positions[CurrentScreen() - 1];
|
||||
|
||||
ChangeBulletsInfo(CurrentScreen() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
//Because the CurrentScreen function is not so reliable, these are the functions used for swipes
|
||||
private void NextScreenCommand()
|
||||
{
|
||||
if (_currentScreen < _screens - 1)
|
||||
{
|
||||
_lerp = true;
|
||||
_lerp_target = _positions[_currentScreen + 1];
|
||||
|
||||
ChangeBulletsInfo(_currentScreen + 1);
|
||||
}
|
||||
}
|
||||
|
||||
//Because the CurrentScreen function is not so reliable, these are the functions used for swipes
|
||||
private void PrevScreenCommand()
|
||||
{
|
||||
if (_currentScreen > 0)
|
||||
{
|
||||
_lerp = true;
|
||||
_lerp_target = _positions[_currentScreen - 1];
|
||||
|
||||
ChangeBulletsInfo(_currentScreen - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//find the closest registered point to the releasing point
|
||||
private Vector3 FindClosestFrom(Vector3 start, System.Collections.Generic.List<Vector3> positions)
|
||||
{
|
||||
Vector3 closest = Vector3.zero;
|
||||
float distance = Mathf.Infinity;
|
||||
|
||||
foreach (Vector3 position in _positions)
|
||||
{
|
||||
if (Vector3.Distance(start, position) < distance)
|
||||
{
|
||||
distance = Vector3.Distance(start, position);
|
||||
closest = position;
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
|
||||
//returns the current screen that the is seeing
|
||||
public int CurrentScreen()
|
||||
{
|
||||
float absPoz = Math.Abs(_screensContainer.gameObject.GetComponent<RectTransform>().offsetMin.x);
|
||||
|
||||
absPoz = Mathf.Clamp(absPoz, 1, _containerSize - 1);
|
||||
|
||||
float calc = (absPoz / _containerSize) * _screens;
|
||||
|
||||
return (int)calc;
|
||||
}
|
||||
|
||||
//changes the bullets on the bottom of the page - pagination
|
||||
private void ChangeBulletsInfo(int currentScreen)
|
||||
{
|
||||
if (Pagination)
|
||||
for (int i = 0; i < Pagination.transform.childCount; i++)
|
||||
{
|
||||
Pagination.transform.GetChild(i).GetComponent<Toggle>().isOn = (currentScreen == i)
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
}
|
||||
|
||||
//used for changing between screen resolutions
|
||||
private void DistributePages()
|
||||
{
|
||||
int _offset = 0;
|
||||
int _step = Screen.width;
|
||||
int _dimension = 0;
|
||||
|
||||
int currentXPosition = 0;
|
||||
|
||||
for (int i = 0; i < _screensContainer.transform.childCount; i++)
|
||||
{
|
||||
RectTransform child = _screensContainer.transform.GetChild(i).gameObject.GetComponent<RectTransform>();
|
||||
currentXPosition = _offset + i * _step;
|
||||
child.anchoredPosition = new Vector2(currentXPosition, 0f);
|
||||
child.sizeDelta = new Vector2(gameObject.GetComponent<RectTransform>().sizeDelta.x, gameObject.GetComponent<RectTransform>().sizeDelta.y);
|
||||
}
|
||||
|
||||
_dimension = currentXPosition + _offset * -1;
|
||||
|
||||
_screensContainer.GetComponent<RectTransform>().offsetMax = new Vector2(_dimension, 0f);
|
||||
}
|
||||
|
||||
#region Interfaces
|
||||
public void OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
_startPosition = _screensContainer.localPosition;
|
||||
_fastSwipeCounter = 0;
|
||||
_fastSwipeTimer = true;
|
||||
_currentScreen = CurrentScreen();
|
||||
}
|
||||
|
||||
public void OnEndDrag(PointerEventData eventData)
|
||||
{
|
||||
_startDrag = true;
|
||||
if (_scroll_rect.horizontal)
|
||||
{
|
||||
if (UseFastSwipe)
|
||||
{
|
||||
fastSwipe = false;
|
||||
_fastSwipeTimer = false;
|
||||
if (_fastSwipeCounter <= _fastSwipeTarget)
|
||||
{
|
||||
if (Math.Abs(_startPosition.x - _screensContainer.localPosition.x) > FastSwipeThreshold)
|
||||
{
|
||||
fastSwipe = true;
|
||||
}
|
||||
}
|
||||
if (fastSwipe)
|
||||
{
|
||||
if (_startPosition.x - _screensContainer.localPosition.x > 0)
|
||||
{
|
||||
NextScreenCommand();
|
||||
}
|
||||
else
|
||||
{
|
||||
PrevScreenCommand();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_lerp = true;
|
||||
_lerp_target = FindClosestFrom(_screensContainer.localPosition, _positions);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_lerp = true;
|
||||
_lerp_target = FindClosestFrom(_screensContainer.localPosition, _positions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
_lerp = false;
|
||||
if (_startDrag)
|
||||
{
|
||||
OnBeginDrag(eventData);
|
||||
_startDrag = false;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 609dcc22aadcc16418bfac22716ee9a6
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,153 @@
|
|||
/// Credit Deeperbeige
|
||||
/// Sourced from - http://forum.unity3d.com/threads/adjustable-character-spacing-free-script.288277/
|
||||
/*
|
||||
|
||||
Produces an simple tracking/letter-spacing effect on UI Text components.
|
||||
|
||||
Set the spacing parameter to adjust letter spacing.
|
||||
Negative values cuddle the text up tighter than normal. Go too far and it'll look odd.
|
||||
Positive values spread the text out more than normal. This will NOT respect the text area you've defined.
|
||||
Zero spacing will present the font with no changes.
|
||||
|
||||
Relies on counting off characters in your Text component's text property and
|
||||
matching those against the quads passed in via the verts array. This is really
|
||||
rather primitive, but I can't see any better way at the moment. It means that
|
||||
all sorts of things can break the effect...
|
||||
|
||||
This component should be placed higher in component list than any other vertex
|
||||
modifiers that alter the total number of vertices. Eg, place this above Shadow
|
||||
or Outline effects. If you don't, the outline/shadow won't match the position
|
||||
of the letters properly. If you place the outline/shadow effect second however,
|
||||
it will just work on the altered vertices from this component, and function
|
||||
as expected.
|
||||
|
||||
This component works best if you don't allow text to automatically wrap. It also
|
||||
blows up outside of the given text area. Basically, it's a cheap and dirty effect,
|
||||
not a clever text layout engine. It can't affect how Unity chooses to break up
|
||||
your lines. If you manually use line breaks however, it should detect those and
|
||||
function more or less as you'd expect.
|
||||
|
||||
The spacing parameter is measured in pixels multiplied by the font size. This was
|
||||
chosen such that when you adjust the font size, it does not change the visual spacing
|
||||
that you've dialed in. There's also a scale factor of 1/100 in this number to
|
||||
bring it into a comfortable adjustable range. There's no limit on this parameter,
|
||||
but obviously some values will look quite strange.
|
||||
|
||||
This component doesn't really work with Rich Text. You don't need to remember to
|
||||
turn off Rich Text via the checkbox, but because it can't see what makes a
|
||||
printable character and what doesn't, it will typically miscount characters when you
|
||||
use HTML-like tags in your text. Try it out, you'll see what I mean. It doesn't
|
||||
break down entirely, but it doesn't really do what you'd want either.
|
||||
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/Letter Spacing")]
|
||||
public class LetterSpacing : BaseVertexEffect
|
||||
{
|
||||
[SerializeField]
|
||||
private float m_spacing = 0f;
|
||||
|
||||
protected LetterSpacing() { }
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate()
|
||||
{
|
||||
spacing = m_spacing;
|
||||
base.OnValidate();
|
||||
}
|
||||
#endif
|
||||
|
||||
public float spacing
|
||||
{
|
||||
get { return m_spacing; }
|
||||
set
|
||||
{
|
||||
if (m_spacing == value) return;
|
||||
m_spacing = value;
|
||||
if (graphic != null) graphic.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public override void ModifyVertices(List<UIVertex> verts)
|
||||
{
|
||||
if (! IsActive()) return;
|
||||
|
||||
Text text = GetComponent<Text>();
|
||||
if (text == null)
|
||||
{
|
||||
Debug.LogWarning("LetterSpacing: Missing Text component");
|
||||
return;
|
||||
}
|
||||
|
||||
string[] lines = text.text.Split('\n');
|
||||
Vector3 pos;
|
||||
float letterOffset = spacing * (float)text.fontSize / 100f;
|
||||
float alignmentFactor = 0;
|
||||
int glyphIdx = 0;
|
||||
|
||||
switch (text.alignment)
|
||||
{
|
||||
case TextAnchor.LowerLeft:
|
||||
case TextAnchor.MiddleLeft:
|
||||
case TextAnchor.UpperLeft:
|
||||
alignmentFactor = 0f;
|
||||
break;
|
||||
|
||||
case TextAnchor.LowerCenter:
|
||||
case TextAnchor.MiddleCenter:
|
||||
case TextAnchor.UpperCenter:
|
||||
alignmentFactor = 0.5f;
|
||||
break;
|
||||
|
||||
case TextAnchor.LowerRight:
|
||||
case TextAnchor.MiddleRight:
|
||||
case TextAnchor.UpperRight:
|
||||
alignmentFactor = 1f;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int lineIdx=0; lineIdx < lines.Length; lineIdx++)
|
||||
{
|
||||
string line = lines[lineIdx];
|
||||
float lineOffset = (line.Length -1) * letterOffset * alignmentFactor;
|
||||
|
||||
for (int charIdx = 0; charIdx < line.Length; charIdx++)
|
||||
{
|
||||
int idx1 = glyphIdx * 4 + 0;
|
||||
int idx2 = glyphIdx * 4 + 1;
|
||||
int idx3 = glyphIdx * 4 + 2;
|
||||
int idx4 = glyphIdx * 4 + 3;
|
||||
|
||||
// Check for truncated text (doesn't generate verts for all characters)
|
||||
if (idx4 > verts.Count - 1) return;
|
||||
|
||||
UIVertex vert1 = verts[idx1];
|
||||
UIVertex vert2 = verts[idx2];
|
||||
UIVertex vert3 = verts[idx3];
|
||||
UIVertex vert4 = verts[idx4];
|
||||
|
||||
pos = Vector3.right * (letterOffset * charIdx - lineOffset);
|
||||
|
||||
vert1.position += pos;
|
||||
vert2.position += pos;
|
||||
vert3.position += pos;
|
||||
vert4.position += pos;
|
||||
|
||||
verts[idx1] = vert1;
|
||||
verts[idx2] = vert2;
|
||||
verts[idx3] = vert3;
|
||||
verts[idx4] = vert4;
|
||||
|
||||
glyphIdx++;
|
||||
}
|
||||
|
||||
// Offset for carriage return character that still generates verts
|
||||
glyphIdx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8ee10f5b9a0e16c40b25e079c03a17a2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,177 @@
|
|||
/// Credit Melang
|
||||
/// Sourced from - http://forum.unity3d.com/members/melang.593409/
|
||||
|
||||
using System.Collections.Generic;
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
//An outline that looks a bit nicer than the default one. It has less "holes" in the outline by drawing more copies of the effect
|
||||
[AddComponentMenu("UI/Effects/Extensions/Nicer Outline")]
|
||||
public class NicerOutline : BaseVertexEffect
|
||||
{
|
||||
[SerializeField]
|
||||
private Color m_EffectColor = new Color (0f, 0f, 0f, 0.5f);
|
||||
|
||||
[SerializeField]
|
||||
private Vector2 m_EffectDistance = new Vector2 (1f, -1f);
|
||||
|
||||
[SerializeField]
|
||||
private bool m_UseGraphicAlpha = true;
|
||||
//
|
||||
// Properties
|
||||
//
|
||||
public Color effectColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_EffectColor;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_EffectColor = value;
|
||||
if (base.graphic != null)
|
||||
{
|
||||
base.graphic.SetVerticesDirty ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 effectDistance
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_EffectDistance;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value.x > 600f)
|
||||
{
|
||||
value.x = 600f;
|
||||
}
|
||||
if (value.x < -600f)
|
||||
{
|
||||
value.x = -600f;
|
||||
}
|
||||
if (value.y > 600f)
|
||||
{
|
||||
value.y = 600f;
|
||||
}
|
||||
if (value.y < -600f)
|
||||
{
|
||||
value.y = -600f;
|
||||
}
|
||||
if (this.m_EffectDistance == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.m_EffectDistance = value;
|
||||
if (base.graphic != null)
|
||||
{
|
||||
base.graphic.SetVerticesDirty ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool useGraphicAlpha
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_UseGraphicAlpha;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_UseGraphicAlpha = value;
|
||||
if (base.graphic != null)
|
||||
{
|
||||
base.graphic.SetVerticesDirty ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
protected void ApplyShadow (List<UIVertex> verts, Color32 color, int start, int end, float x, float y)
|
||||
{
|
||||
//Debug.Log("verts count: "+verts.Count);
|
||||
int num = verts.Count * 2;
|
||||
if (verts.Capacity < num)
|
||||
{
|
||||
verts.Capacity = num;
|
||||
}
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
UIVertex uIVertex = verts [i];
|
||||
verts.Add (uIVertex);
|
||||
|
||||
Vector3 position = uIVertex.position;
|
||||
//Debug.Log("vertex pos: "+position);
|
||||
position.x += x;
|
||||
position.y += y;
|
||||
uIVertex.position = position;
|
||||
Color32 color2 = color;
|
||||
if (this.m_UseGraphicAlpha)
|
||||
{
|
||||
color2.a = (byte)(color2.a * verts [i].color.a / 255);
|
||||
}
|
||||
uIVertex.color = color2;
|
||||
//uIVertex.color = (Color32)Color.blue;
|
||||
verts [i] = uIVertex;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ModifyVertices (List<UIVertex> verts)
|
||||
{
|
||||
if (!this.IsActive ())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Text foundtext = GetComponent<Text>();
|
||||
|
||||
float best_fit_adjustment = 1f;
|
||||
|
||||
if (foundtext && foundtext.resizeTextForBestFit)
|
||||
{
|
||||
best_fit_adjustment = (float)foundtext.cachedTextGenerator.fontSizeUsedForBestFit / (foundtext.resizeTextMaxSize-1); //max size seems to be exclusive
|
||||
|
||||
}
|
||||
|
||||
float distanceX = this.effectDistance.x * best_fit_adjustment;
|
||||
float distanceY = this.effectDistance.y * best_fit_adjustment;
|
||||
|
||||
int start = 0;
|
||||
int count = verts.Count;
|
||||
this.ApplyShadow (verts, this.effectColor, start, verts.Count, distanceX, distanceY);
|
||||
start = count;
|
||||
count = verts.Count;
|
||||
this.ApplyShadow (verts, this.effectColor, start, verts.Count, distanceX, -distanceY);
|
||||
start = count;
|
||||
count = verts.Count;
|
||||
this.ApplyShadow (verts, this.effectColor, start, verts.Count, -distanceX, distanceY);
|
||||
start = count;
|
||||
count = verts.Count;
|
||||
this.ApplyShadow (verts, this.effectColor, start, verts.Count, -distanceX, -distanceY);
|
||||
|
||||
start = count;
|
||||
count = verts.Count;
|
||||
this.ApplyShadow (verts, this.effectColor, start, verts.Count, distanceX, 0);
|
||||
start = count;
|
||||
count = verts.Count;
|
||||
this.ApplyShadow (verts, this.effectColor, start, verts.Count, -distanceX, 0);
|
||||
|
||||
start = count;
|
||||
count = verts.Count;
|
||||
this.ApplyShadow (verts, this.effectColor, start, verts.Count, 0, distanceY);
|
||||
start = count;
|
||||
count = verts.Count;
|
||||
this.ApplyShadow (verts, this.effectColor, start, verts.Count, 0, -distanceY);
|
||||
}
|
||||
|
||||
protected override void OnValidate ()
|
||||
{
|
||||
this.effectDistance = this.m_EffectDistance;
|
||||
base.OnValidate ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: db125c7de00668f4e98849d0aaf366d7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -1,123 +1,125 @@
|
|||
//Sourced from - https://github.com/senritsu/unitility/blob/master/Assets/Unitility/GUI/RaycastMask.cs
|
||||
/***************************************************************************\
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Jonas Schiegl (https://github.com/senritsu)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
\***************************************************************************/
|
||||
|
||||
#if UNITY_4_6
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[RequireComponent(typeof(Image))]
|
||||
public class RaycastMask : MonoBehaviour, ICanvasRaycastFilter
|
||||
{
|
||||
private Image _image;
|
||||
private Sprite _sprite;
|
||||
|
||||
void Start ()
|
||||
{
|
||||
_image = GetComponent<Image>();
|
||||
}
|
||||
|
||||
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
|
||||
{
|
||||
_sprite = _image.sprite;
|
||||
|
||||
var rectTransform = (RectTransform)transform;
|
||||
Vector2 localPositionPivotRelative;
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform) transform, sp, eventCamera, out localPositionPivotRelative);
|
||||
|
||||
// convert to bottom-left origin coordinates
|
||||
var localPosition = new Vector2(localPositionPivotRelative.x + rectTransform.pivot.x*rectTransform.rect.width,
|
||||
localPositionPivotRelative.y + rectTransform.pivot.y*rectTransform.rect.height);
|
||||
|
||||
var spriteRect = _sprite.textureRect;
|
||||
var maskRect = rectTransform.rect;
|
||||
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
// convert to texture space
|
||||
switch (_image.type)
|
||||
{
|
||||
|
||||
case Image.Type.Sliced:
|
||||
{
|
||||
var border = _sprite.border;
|
||||
// x slicing
|
||||
if (localPosition.x < border.x)
|
||||
{
|
||||
x = Mathf.FloorToInt(spriteRect.x + localPosition.x);
|
||||
}
|
||||
else if (localPosition.x > maskRect.width - border.z)
|
||||
{
|
||||
x = Mathf.FloorToInt(spriteRect.x + spriteRect.width - (maskRect.width - localPosition.x));
|
||||
}
|
||||
else
|
||||
{
|
||||
x = Mathf.FloorToInt(spriteRect.x + border.x +
|
||||
((localPosition.x - border.x)/
|
||||
(maskRect.width - border.x - border.z)) *
|
||||
(spriteRect.width - border.x - border.z));
|
||||
}
|
||||
// y slicing
|
||||
if (localPosition.y < border.y)
|
||||
{
|
||||
y = Mathf.FloorToInt(spriteRect.y + localPosition.y);
|
||||
}
|
||||
else if (localPosition.y > maskRect.height - border.w)
|
||||
{
|
||||
y = Mathf.FloorToInt(spriteRect.y + spriteRect.height - (maskRect.height - localPosition.y));
|
||||
}
|
||||
else
|
||||
{
|
||||
y = Mathf.FloorToInt(spriteRect.y + border.y +
|
||||
((localPosition.y - border.y) /
|
||||
(maskRect.height - border.y - border.w)) *
|
||||
(spriteRect.height - border.y - border.w));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Image.Type.Simple:
|
||||
default:
|
||||
{
|
||||
// conversion to uniform UV space
|
||||
x = Mathf.FloorToInt(spriteRect.x + spriteRect.width * localPosition.x / maskRect.width);
|
||||
y = Mathf.FloorToInt(spriteRect.y + spriteRect.height * localPosition.y / maskRect.height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// destroy component if texture import settings are wrong
|
||||
try
|
||||
{
|
||||
return _sprite.texture.GetPixel(x,y).a > 0;
|
||||
}
|
||||
catch (UnityException)
|
||||
{
|
||||
Debug.LogWarning("Mask texture not readable, set your sprite to Texture Type 'Advanced' and check 'Read/Write Enabled'");
|
||||
Destroy(this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/// Credit senritsu
|
||||
/// Sourced from - https://github.com/senritsu/unitility/blob/master/Assets/Unitility/GUI/RaycastMask.cs
|
||||
|
||||
/***************************************************************************\
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Jonas Schiegl (https://github.com/senritsu)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
\***************************************************************************/
|
||||
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[RequireComponent(typeof(Image))]
|
||||
[AddComponentMenu("UI/Extensions/Raycast Mask")]
|
||||
public class RaycastMask : MonoBehaviour, ICanvasRaycastFilter
|
||||
{
|
||||
private Image _image;
|
||||
private Sprite _sprite;
|
||||
|
||||
void Start()
|
||||
{
|
||||
_image = GetComponent<Image>();
|
||||
}
|
||||
|
||||
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
|
||||
{
|
||||
_sprite = _image.sprite;
|
||||
|
||||
var rectTransform = (RectTransform)transform;
|
||||
Vector2 localPositionPivotRelative;
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)transform, sp, eventCamera, out localPositionPivotRelative);
|
||||
|
||||
// convert to bottom-left origin coordinates
|
||||
var localPosition = new Vector2(localPositionPivotRelative.x + rectTransform.pivot.x * rectTransform.rect.width,
|
||||
localPositionPivotRelative.y + rectTransform.pivot.y * rectTransform.rect.height);
|
||||
|
||||
var spriteRect = _sprite.textureRect;
|
||||
var maskRect = rectTransform.rect;
|
||||
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
// convert to texture space
|
||||
switch (_image.type)
|
||||
{
|
||||
|
||||
case Image.Type.Sliced:
|
||||
{
|
||||
var border = _sprite.border;
|
||||
// x slicing
|
||||
if (localPosition.x < border.x)
|
||||
{
|
||||
x = Mathf.FloorToInt(spriteRect.x + localPosition.x);
|
||||
}
|
||||
else if (localPosition.x > maskRect.width - border.z)
|
||||
{
|
||||
x = Mathf.FloorToInt(spriteRect.x + spriteRect.width - (maskRect.width - localPosition.x));
|
||||
}
|
||||
else
|
||||
{
|
||||
x = Mathf.FloorToInt(spriteRect.x + border.x +
|
||||
((localPosition.x - border.x) /
|
||||
(maskRect.width - border.x - border.z)) *
|
||||
(spriteRect.width - border.x - border.z));
|
||||
}
|
||||
// y slicing
|
||||
if (localPosition.y < border.y)
|
||||
{
|
||||
y = Mathf.FloorToInt(spriteRect.y + localPosition.y);
|
||||
}
|
||||
else if (localPosition.y > maskRect.height - border.w)
|
||||
{
|
||||
y = Mathf.FloorToInt(spriteRect.y + spriteRect.height - (maskRect.height - localPosition.y));
|
||||
}
|
||||
else
|
||||
{
|
||||
y = Mathf.FloorToInt(spriteRect.y + border.y +
|
||||
((localPosition.y - border.y) /
|
||||
(maskRect.height - border.y - border.w)) *
|
||||
(spriteRect.height - border.y - border.w));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Image.Type.Simple:
|
||||
default:
|
||||
{
|
||||
// conversion to uniform UV space
|
||||
x = Mathf.FloorToInt(spriteRect.x + spriteRect.width * localPosition.x / maskRect.width);
|
||||
y = Mathf.FloorToInt(spriteRect.y + spriteRect.height * localPosition.y / maskRect.height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// destroy component if texture import settings are wrong
|
||||
try
|
||||
{
|
||||
return _sprite.texture.GetPixel(x, y).a > 0;
|
||||
}
|
||||
catch (UnityException)
|
||||
{
|
||||
Debug.LogWarning("Mask texture not readable, set your sprite to Texture Type 'Advanced' and check 'Read/Write Enabled'");
|
||||
Destroy(this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 22757922dd9d4064d8186fbef72b0772
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,36 @@
|
|||
/// Credit Melang
|
||||
/// Sourced from - http://forum.unity3d.com/members/melang.593409/
|
||||
/// Updated ddreaper - 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f08f1bd2c562a474c99ff9d746d3c99b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1e656d866043cab4fb676dba90e3734c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
|
@ -0,0 +1,95 @@
|
|||
/// Original Credit Korindian
|
||||
/// Sourced from - http://forum.unity3d.com/threads/rts-style-drag-selection-box.265739/
|
||||
/// Updated Credit BenZed
|
||||
/// Sourced from - http://forum.unity3d.com/threads/color-picker.267043/
|
||||
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
public class ExampleSelectable : MonoBehaviour, IBoxSelectable
|
||||
{
|
||||
|
||||
#region Implemented members of IBoxSelectable
|
||||
bool _selected = false;
|
||||
public bool selected
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selected;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_selected = value;
|
||||
}
|
||||
}
|
||||
|
||||
bool _preSelected = false;
|
||||
public bool preSelected
|
||||
{
|
||||
get
|
||||
{
|
||||
return _preSelected;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_preSelected = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
//We want the test object to be either a UI element, a 2D element or a 3D element, so we'll get the appropriate components
|
||||
SpriteRenderer spriteRenderer;
|
||||
Image image;
|
||||
Text text;
|
||||
|
||||
void Start()
|
||||
{
|
||||
spriteRenderer = transform.GetComponent<SpriteRenderer>();
|
||||
image = transform.GetComponent<Image>();
|
||||
text = transform.GetComponent<Text>();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
|
||||
//What the game object does with the knowledge that it is selected is entirely up to it.
|
||||
//In this case we're just going to change the color.
|
||||
|
||||
//White if deselected.
|
||||
Color color = Color.white;
|
||||
|
||||
if (preSelected)
|
||||
{
|
||||
//Yellow if preselected
|
||||
color = Color.yellow;
|
||||
}
|
||||
if (selected)
|
||||
{
|
||||
//And green if selected.
|
||||
color = Color.green;
|
||||
}
|
||||
|
||||
//Set the color depending on what the game object has.
|
||||
if (spriteRenderer)
|
||||
{
|
||||
spriteRenderer.color = color;
|
||||
}
|
||||
else if (text)
|
||||
{
|
||||
text.color = color;
|
||||
}
|
||||
else if (image)
|
||||
{
|
||||
image.color = color;
|
||||
}
|
||||
else if (renderer)
|
||||
{
|
||||
renderer.material.color = color;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d0644987412a04edd8105e64bdd008b2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,31 @@
|
|||
///Original Credit Korindian
|
||||
///Sourced from - http://forum.unity3d.com/threads/rts-style-drag-selection-box.265739/
|
||||
///Updated Credit BenZed
|
||||
///Sourced from - http://forum.unity3d.com/threads/color-picker.267043/
|
||||
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
|
||||
/*
|
||||
* Implement this interface on any MonoBehaviour that you'd like to be considered selectable.
|
||||
*/
|
||||
public interface IBoxSelectable {
|
||||
bool selected {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
bool preSelected {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
//This property doesn't actually need to be implemented, as this interface should already be placed on a MonoBehaviour, which will
|
||||
//already have it. Defining it here only allows us access to the transform property by casting through the selectable interface.
|
||||
Transform transform {
|
||||
get;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 72b70b31ccbda4bae8dd5cda36d2e02d
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
Binary file not shown.
|
@ -0,0 +1,4 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e0944d7e4f0234f3fabb9b2f33fe073e
|
||||
DefaultImporter:
|
||||
userData:
|
|
@ -0,0 +1,440 @@
|
|||
///Original Credit Korindian
|
||||
///Sourced from - http://forum.unity3d.com/threads/rts-style-drag-selection-box.265739/
|
||||
///Updated Credit BenZed
|
||||
///Sourced from - http://forum.unity3d.com/threads/color-picker.267043/
|
||||
|
||||
/*
|
||||
* What the SelectionBox component does is allow the game player to select objects using an RTS style click and drag interface:
|
||||
*
|
||||
* We want to be able to select Game Objects of any type,
|
||||
* We want to be able to drag select a group of game objects to select them,
|
||||
* We want to be able to hold the shift key and drag select a group of game objects to add them to the current selection,
|
||||
* We want to be able to single click a game object to select it,
|
||||
* We want to be able to hold the shift key and single click a game object to add it to the current selection,
|
||||
* We want to be able to hold the shift key and single click an already selected game object to remove it from the current selection.
|
||||
*
|
||||
* Most importantly, we want this behaviour to work with UI, 2D or 3D gameObjects, so it has to be smart about considering their respective screen spaces.
|
||||
*
|
||||
* Add this component to a Gameobject with a Canvas with RenderMode.ScreenSpaceOverlay
|
||||
* And implement the IBoxSelectable interface on any MonoBehaviour to make it selectable.
|
||||
*
|
||||
* Improvements that could be made:
|
||||
*
|
||||
* Control clicking a game object to select all objects of that type or tag.
|
||||
* Compatibility with Canvas Scaling
|
||||
* Filtering single click selections of objects occupying the same space. (So that, for example, you're only click selecting the game object found closest to the camera)
|
||||
*
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(Canvas))]
|
||||
[AddComponentMenu("UI/Extensions/Selection Box")]
|
||||
public class SelectionBox : MonoBehaviour
|
||||
{
|
||||
|
||||
// The color of the selection box.
|
||||
public Color color;
|
||||
|
||||
// An optional parameter, but you can add a sprite to the selection box to give it a border or a stylized look.
|
||||
// It's suggested you use a monochrome sprite so that the selection
|
||||
// Box color is still relevent.
|
||||
public Sprite art;
|
||||
|
||||
// Will store the location of wherever we first click before dragging.
|
||||
private Vector2 origin;
|
||||
|
||||
// A rectTransform set by the User that can limit which part of the screen is eligable for drag selection
|
||||
public RectTransform selectionMask;
|
||||
|
||||
//Stores the rectTransform connected to the generated gameObject being used for the selection box visuals
|
||||
private RectTransform boxRect;
|
||||
|
||||
// Stores all of the selectable game objects
|
||||
private IBoxSelectable[] selectables;
|
||||
|
||||
// A secondary storage of objects that the user can manually set.
|
||||
private MonoBehaviour[] selectableGroup;
|
||||
|
||||
//Stores the selectable that was touched when the mouse button was pressed down
|
||||
private IBoxSelectable clickedBeforeDrag;
|
||||
|
||||
//Stores the selectable that was touched when the mouse button was released
|
||||
private IBoxSelectable clickedAfterDrag;
|
||||
|
||||
//Custom UnityEvent so we can add Listeners to this instance when Selections are changed.
|
||||
public class SelectionEvent : UnityEvent<IBoxSelectable[]> {}
|
||||
public SelectionEvent onSelectionChange = new SelectionEvent();
|
||||
|
||||
//Ensures that the canvas that this component is attached to is set to the correct render mode. If not, it will not render the selection box properly.
|
||||
void ValidateCanvas(){
|
||||
var canvas = gameObject.GetComponent<Canvas>();
|
||||
|
||||
if (canvas.renderMode != RenderMode.ScreenSpaceOverlay) {
|
||||
throw new System.Exception("SelectionBox component must be placed on a canvas in Screen Space Overlay mode.");
|
||||
}
|
||||
|
||||
var canvasScaler = gameObject.GetComponent<CanvasScaler>();
|
||||
|
||||
if (canvasScaler && canvasScaler.enabled && (!Mathf.Approximately(canvasScaler.scaleFactor, 1f) || canvasScaler.uiScaleMode != CanvasScaler.ScaleMode.ConstantPixelSize)) {
|
||||
Destroy(canvasScaler);
|
||||
Debug.LogWarning("SelectionBox component is on a gameObject with a Canvas Scaler component. As of now, Canvas Scalers without the default settings throw off the coordinates of the selection box. Canvas Scaler has been removed.");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The user can manually set a group of objects with monoBehaviours to be the pool of objects considered to be selectable. The benefits of this are two fold:
|
||||
*
|
||||
* 1) The default behaviour is to check every game object in the scene, which is much slower.
|
||||
* 2) The user can filter which objects should be selectable, for example units versus menu selections
|
||||
*
|
||||
*/
|
||||
void SetSelectableGroup(IEnumerable<MonoBehaviour> behaviourCollection) {
|
||||
|
||||
// If null, the selectionbox reverts to it's default behaviour
|
||||
if (behaviourCollection == null) {
|
||||
selectableGroup = null;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//Runs a double check to ensure each of the objects in the collection can be selectable, and doesn't include them if not.
|
||||
var behaviourList = new List<MonoBehaviour>();
|
||||
|
||||
foreach(var behaviour in behaviourCollection) {
|
||||
if (behaviour as IBoxSelectable != null) {
|
||||
behaviourList.Add (behaviour);
|
||||
}
|
||||
}
|
||||
|
||||
selectableGroup = behaviourList.ToArray();
|
||||
}
|
||||
|
||||
void CreateBoxRect(){
|
||||
var selectionBoxGO = new GameObject();
|
||||
|
||||
selectionBoxGO.name = "Selection Box";
|
||||
selectionBoxGO.transform.parent = transform;
|
||||
selectionBoxGO.AddComponent<Image>();
|
||||
|
||||
boxRect = selectionBoxGO.transform as RectTransform;
|
||||
|
||||
}
|
||||
|
||||
//Set all of the relevant rectTransform properties to zero,
|
||||
//finally deactivates the boxRect gameobject since it doesn't
|
||||
//need to be enabled when not in a selection action.
|
||||
void ResetBoxRect(){
|
||||
|
||||
//Update the art and color on the off chance they've changed
|
||||
Image image = boxRect.GetComponent<Image>();
|
||||
image.color = color;
|
||||
image.sprite = art;
|
||||
|
||||
origin = Vector2.zero;
|
||||
|
||||
boxRect.anchoredPosition = Vector2.zero;
|
||||
boxRect.sizeDelta = Vector2.zero;
|
||||
boxRect.anchorMax = Vector2.zero;
|
||||
boxRect.anchorMin = Vector2.zero;
|
||||
boxRect.pivot = Vector2.zero;
|
||||
boxRect.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
|
||||
void BeginSelection(){
|
||||
// Click somewhere in the Game View.
|
||||
if (!Input.GetMouseButtonDown(0))
|
||||
return;
|
||||
|
||||
//The boxRect will be inactive up until the point we start selecting
|
||||
boxRect.gameObject.SetActive(true);
|
||||
|
||||
// Get the initial click position of the mouse.
|
||||
origin = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
|
||||
|
||||
//If the initial click point is not inside the selection mask, we abort the selection
|
||||
if (!PointIsValidAgainstSelectionMask(origin)) {
|
||||
ResetBoxRect();
|
||||
return;
|
||||
}
|
||||
|
||||
// The anchor is set to the same place.
|
||||
boxRect.anchoredPosition = origin;
|
||||
|
||||
MonoBehaviour[] behavioursToGetSelectionsFrom;
|
||||
|
||||
// If we do not have a group of selectables already set, we'll just loop through every object that's a monobehaviour, and look for selectable interfaces in them
|
||||
if (selectableGroup == null) {
|
||||
behavioursToGetSelectionsFrom = GameObject.FindObjectsOfType<MonoBehaviour>();
|
||||
} else {
|
||||
behavioursToGetSelectionsFrom = selectableGroup;
|
||||
}
|
||||
|
||||
//Temporary list to store the found selectables before converting to the main selectables array
|
||||
List<IBoxSelectable> selectableList = new List<IBoxSelectable>();
|
||||
|
||||
foreach (MonoBehaviour behaviour in behavioursToGetSelectionsFrom) {
|
||||
|
||||
//If the behaviour implements the selectable interface, we add it to the selectable list
|
||||
IBoxSelectable selectable = behaviour as IBoxSelectable;
|
||||
if (selectable != null) {
|
||||
selectableList.Add (selectable);
|
||||
|
||||
//We're using left shift to act as the "Add To Selection" command. So if left shift isn't pressed, we want everything to begin deselected
|
||||
if (!Input.GetKey (KeyCode.LeftShift)) {
|
||||
selectable.selected = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
selectables = selectableList.ToArray();
|
||||
|
||||
//For single-click actions, we need to get the selectable that was clicked when selection began (if any)
|
||||
clickedBeforeDrag = GetSelectableAtMousePosition();
|
||||
|
||||
}
|
||||
|
||||
bool PointIsValidAgainstSelectionMask(Vector2 screenPoint){
|
||||
//If there is no seleciton mask, any point is valid
|
||||
if (!selectionMask) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Camera screenPointCamera = GetScreenPointCamera(selectionMask);
|
||||
|
||||
return RectTransformUtility.RectangleContainsScreenPoint(selectionMask, screenPoint, screenPointCamera);
|
||||
}
|
||||
|
||||
IBoxSelectable GetSelectableAtMousePosition() {
|
||||
//Firstly, we cannot click on something that is not inside the selection mask (if we have one)
|
||||
if (!PointIsValidAgainstSelectionMask(Input.mousePosition)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//This gets a bit tricky, because we have to make considerations depending on the heirarchy of the selectable's gameObject
|
||||
foreach (var selectable in selectables) {
|
||||
|
||||
//First we check to see if the selectable has a rectTransform
|
||||
var rectTransform = (selectable.transform as RectTransform);
|
||||
|
||||
if (rectTransform) {
|
||||
//Because if it does, the camera we use to calulate it's screen point will vary
|
||||
var screenCamera = GetScreenPointCamera(rectTransform);
|
||||
|
||||
//Once we've found the rendering camera, we check if the selectables rectTransform contains the click. That way we
|
||||
//Can click anywhere on a rectTransform to select it.
|
||||
if (RectTransformUtility.RectangleContainsScreenPoint(rectTransform, Input.mousePosition, screenCamera)) {
|
||||
|
||||
//And if it does, we select it and send it back
|
||||
return selectable;
|
||||
}
|
||||
} else {
|
||||
//If it doesn't have a rectTransform, we need to get the radius so we can use it as an area around the center to detect a click.
|
||||
//This works because a 2D or 3D renderer will both return a radius
|
||||
var radius = selectable.transform.renderer.bounds.extents.magnitude;
|
||||
|
||||
var selectableScreenPoint = GetScreenPointOfSelectable(selectable);
|
||||
|
||||
//Check that the click fits within the screen-radius of the selectable
|
||||
if (Vector2.Distance(selectableScreenPoint, Input.mousePosition) <= radius) {
|
||||
|
||||
//And if it does, we select it and send it back
|
||||
return selectable;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
void DragSelection(){
|
||||
//Return if we're not dragging or if the selection has been aborted (BoxRect disabled)
|
||||
if (!Input.GetMouseButton(0) || !boxRect.gameObject.activeSelf)
|
||||
return;
|
||||
|
||||
// Store the current mouse position in screen space.
|
||||
Vector2 currentMousePosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
|
||||
|
||||
// How far have we moved the mouse?
|
||||
Vector2 difference = currentMousePosition - origin;
|
||||
|
||||
// Copy the initial click position to a new variable. Using the original variable will cause
|
||||
// the anchor to move around to wherever the current mouse position is,
|
||||
// which isn't desirable.
|
||||
Vector2 startPoint = origin;
|
||||
|
||||
// The following code accounts for dragging in various directions.
|
||||
if (difference.x < 0)
|
||||
{
|
||||
startPoint.x = currentMousePosition.x;
|
||||
difference.x = -difference.x;
|
||||
}
|
||||
if (difference.y < 0)
|
||||
{
|
||||
startPoint.y = currentMousePosition.y;
|
||||
difference.y = -difference.y;
|
||||
}
|
||||
|
||||
// Set the anchor, width and height every frame.
|
||||
boxRect.anchoredPosition = startPoint;
|
||||
boxRect.sizeDelta = difference;
|
||||
|
||||
//Then we check our list of Selectables to see if they're being preselected or not.
|
||||
foreach(var selectable in selectables) {
|
||||
|
||||
Vector3 screenPoint = GetScreenPointOfSelectable(selectable);
|
||||
|
||||
//If the box Rect contains the selectabels screen point and that point is inside a valid selection mask, it's being preselected, otherwise it is not.
|
||||
selectable.preSelected = RectTransformUtility.RectangleContainsScreenPoint(boxRect, screenPoint, null) && PointIsValidAgainstSelectionMask(screenPoint);
|
||||
|
||||
}
|
||||
|
||||
//Finally, since it's possible for our first clicked object to not be within the bounds of the selection box
|
||||
//If it exists, we always ensure that it is preselected.
|
||||
if (clickedBeforeDrag != null) {
|
||||
clickedBeforeDrag.preSelected = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ApplySingleClickDeselection(){
|
||||
|
||||
//If we didn't touch anything with the original mouse press, we don't need to continue checking
|
||||
if (clickedBeforeDrag == null)
|
||||
return;
|
||||
|
||||
//If we clicked a selectable without dragging, and that selectable was previously selected, we must be trying to deselect it.
|
||||
if (clickedAfterDrag != null && clickedBeforeDrag.selected && clickedBeforeDrag.transform == clickedAfterDrag.transform ) {
|
||||
clickedBeforeDrag.selected = false;
|
||||
clickedBeforeDrag.preSelected = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ApplyPreSelections(){
|
||||
|
||||
foreach(var selectable in selectables) {
|
||||
|
||||
//If the selectable was preSelected, we finalize it as selected.
|
||||
if (selectable.preSelected) {
|
||||
selectable.selected = true;
|
||||
selectable.preSelected = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Vector2 GetScreenPointOfSelectable(IBoxSelectable selectable) {
|
||||
//Getting the screen point requires it's own function, because we have to take into consideration the selectables heirarchy.
|
||||
|
||||
//Cast the transform as a rectTransform
|
||||
var rectTransform = selectable.transform as RectTransform;
|
||||
|
||||
//If it has a rectTransform component, it must be in the heirarchy of a canvas, somewhere.
|
||||
if (rectTransform) {
|
||||
|
||||
//And the camera used to calculate it's screen point will vary.
|
||||
Camera renderingCamera = GetScreenPointCamera(rectTransform);
|
||||
|
||||
return RectTransformUtility.WorldToScreenPoint(renderingCamera, selectable.transform.position);
|
||||
}
|
||||
|
||||
//If it's no in the heirarchy of a canvas, the regular Camera.main.WorldToScreenPoint will do.
|
||||
return Camera.main.WorldToScreenPoint(selectable.transform.position);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Finding the camera used to calculate the screenPoint of an object causes a couple of problems:
|
||||
*
|
||||
* If it has a rectTransform, the root Canvas that the rectTransform is a descendant of will give unusable
|
||||
* screen points depending on the Canvas.RenderMode, if we don't do any further calculation.
|
||||
*
|
||||
* This function solves that problem.
|
||||
*/
|
||||
Camera GetScreenPointCamera(RectTransform rectTransform) {
|
||||
|
||||
Canvas rootCanvas = null;
|
||||
RectTransform rectCheck = rectTransform;
|
||||
|
||||
//We're going to check all the canvases in the heirarchy of this rectTransform until we find the root.
|
||||
do {
|
||||
rootCanvas = rectCheck.GetComponent<Canvas>();
|
||||
|
||||
//If we found a canvas on this Object, and it's not the rootCanvas, then we don't want to keep it
|
||||
if (rootCanvas && !rootCanvas.isRootCanvas) {
|
||||
rootCanvas = null;
|
||||
}
|
||||
|
||||
//Then we promote the rect we're checking to it's parent.
|
||||
rectCheck = (RectTransform)rectCheck.parent;
|
||||
|
||||
} while (rootCanvas == null);
|
||||
|
||||
//Once we've found the root Canvas, we return a camera depending on it's render mode.
|
||||
switch (rootCanvas.renderMode) {
|
||||
case RenderMode.ScreenSpaceOverlay:
|
||||
//If we send back a camera when set to screen space overlay, the coordinates will not be accurate. If we return null, they will be.
|
||||
return null;
|
||||
|
||||
case RenderMode.ScreenSpaceCamera:
|
||||
//If it's set to screen space we use the world Camera that the Canvas is using.
|
||||
//If it doesn't have one set, however, we have to send back the current camera. otherwise the coordinates will not be accurate.
|
||||
return (rootCanvas.worldCamera) ? rootCanvas.worldCamera : Camera.main;
|
||||
|
||||
default:
|
||||
case RenderMode.WorldSpace:
|
||||
//World space always uses the current camera.
|
||||
return Camera.main;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public IBoxSelectable[] GetAllSelected(){
|
||||
if (selectables == null) {
|
||||
return new IBoxSelectable[0];
|
||||
}
|
||||
|
||||
var selectedList = new List<IBoxSelectable>();
|
||||
|
||||
foreach(var selectable in selectables) {
|
||||
if (selectable.selected) {
|
||||
selectedList.Add (selectable);
|
||||
}
|
||||
}
|
||||
|
||||
return selectedList.ToArray();
|
||||
}
|
||||
|
||||
void EndSelection(){
|
||||
//Get out if we haven't finished selecting, or if the selection has been aborted (boxRect disabled)
|
||||
if (!Input.GetMouseButtonUp(0) || !boxRect.gameObject.activeSelf)
|
||||
return;
|
||||
|
||||
clickedAfterDrag = GetSelectableAtMousePosition();
|
||||
|
||||
ApplySingleClickDeselection();
|
||||
ApplyPreSelections();
|
||||
ResetBoxRect();
|
||||
onSelectionChange.Invoke(GetAllSelected());
|
||||
}
|
||||
|
||||
void Start(){
|
||||
ValidateCanvas();
|
||||
CreateBoxRect();
|
||||
ResetBoxRect();
|
||||
}
|
||||
|
||||
void Update() {
|
||||
BeginSelection ();
|
||||
DragSelection ();
|
||||
EndSelection ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0f143353fa45b4df79a3722ad82431d5
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -1,65 +1,72 @@
|
|||
//Author: Melang http://forum.unity3d.com/members/melang.593409/
|
||||
//Updated omatase 10-18-14 - support for Shift + Tab as well
|
||||
// - bug fix to prevent crash if no control selected
|
||||
// - updated to support new semantics for EventSystem in later 4.6 builds
|
||||
// - autoselect "firstSelectedGameObject" since it doesn't seem to work automatically
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
/// Credit Melang
|
||||
/// Sourced from - http://forum.unity3d.com/members/melang.593409/
|
||||
/// Updated omatase 10-18-14 - support for Shift + Tab as well
|
||||
/// - bug fix to prevent crash if no control selected
|
||||
/// - updated to support new semantics for EventSystem in later 4.6 builds
|
||||
/// - autoselect "firstSelectedGameObject" since it doesn't seem to work automatically
|
||||
|
||||
using UnityEngine.EventSystems;
|
||||
using System.Collections;
|
||||
|
||||
public class TabNavigationHelper : MonoBehaviour
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
private EventSystem _system;
|
||||
|
||||
void Start()
|
||||
[RequireComponent(typeof(EventSystem))]
|
||||
[AddComponentMenu("Event/Extensions/Tab Navigation Helper")]
|
||||
public class TabNavigationHelper : MonoBehaviour
|
||||
{
|
||||
_system = EventSystem.current;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
Selectable next = null;
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Tab) && Input.GetKey(KeyCode.LeftShift))
|
||||
private EventSystem _system;
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (_system.currentSelectedGameObject != null)
|
||||
_system = GetComponent<EventSystem>();
|
||||
if (_system == null)
|
||||
{
|
||||
next = _system.currentSelectedGameObject.GetComponent<Selectable>().FindSelectableOnUp();
|
||||
Debug.LogError("Needs to be attached to the Event System component in the scene");
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
Selectable next = null;
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Tab) && Input.GetKey(KeyCode.LeftShift))
|
||||
{
|
||||
if (_system.currentSelectedGameObject != null)
|
||||
{
|
||||
next = _system.currentSelectedGameObject.GetComponent<Selectable>().FindSelectableOnUp();
|
||||
}
|
||||
else
|
||||
{
|
||||
next = _system.firstSelectedGameObject.GetComponent<Selectable>();
|
||||
}
|
||||
}
|
||||
else if (Input.GetKeyDown(KeyCode.Tab))
|
||||
{
|
||||
if (_system.currentSelectedGameObject != null)
|
||||
{
|
||||
next = _system.currentSelectedGameObject.GetComponent<Selectable>().FindSelectableOnDown();
|
||||
}
|
||||
else
|
||||
{
|
||||
next = _system.firstSelectedGameObject.GetComponent<Selectable>();
|
||||
}
|
||||
}
|
||||
else if (_system.currentSelectedGameObject == null)
|
||||
{
|
||||
next = _system.firstSelectedGameObject.GetComponent<Selectable>();
|
||||
}
|
||||
|
||||
selectGameObject(next);
|
||||
}
|
||||
else if (Input.GetKeyDown(KeyCode.Tab))
|
||||
|
||||
private void selectGameObject(Selectable selectable)
|
||||
{
|
||||
if (_system.currentSelectedGameObject != null)
|
||||
if (selectable != null)
|
||||
{
|
||||
next = _system.currentSelectedGameObject.GetComponent<Selectable>().FindSelectableOnDown();
|
||||
}
|
||||
else
|
||||
{
|
||||
next = _system.firstSelectedGameObject.GetComponent<Selectable>();
|
||||
InputField inputfield = selectable.GetComponent<InputField>();
|
||||
if (inputfield != null) inputfield.OnPointerClick(new PointerEventData(_system)); //if it's an input field, also set the text caret
|
||||
|
||||
_system.SetSelectedGameObject(selectable.gameObject, new BaseEventData(_system));
|
||||
}
|
||||
}
|
||||
else if (_system.currentSelectedGameObject == null)
|
||||
{
|
||||
next = _system.firstSelectedGameObject.GetComponent<Selectable>();
|
||||
}
|
||||
|
||||
selectGameObject(next);
|
||||
}
|
||||
|
||||
private void selectGameObject(Selectable selectable)
|
||||
{
|
||||
if (selectable != null)
|
||||
{
|
||||
InputField inputfield = selectable.GetComponent<InputField>();
|
||||
if (inputfield != null) inputfield.OnPointerClick(new PointerEventData(_system)); //if it's an input field, also set the text caret
|
||||
|
||||
_system.SetSelectedGameObject(selectable.gameObject, new BaseEventData(_system));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 62e5af56445f0d24fb5140ef754aebaf
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,168 @@
|
|||
/// Credit drHogan
|
||||
/// Sourced from - http://forum.unity3d.com/threads/screenspace-camera-tooltip-controller-sweat-and-tears.293991/#post-1938929
|
||||
/// updated ddreaper - refactored code to be more performant.
|
||||
/// *Note - only works for Screenspace Camera canvases at present, needs updating to include Screenspace and Worldspace!
|
||||
|
||||
//ToolTip is written by Emiliano Pastorelli, H&R Tallinn (Estonia), http://www.hammerandravens.com
|
||||
//Copyright (c) 2015 Emiliano Pastorelli, H&R - Hammer&Ravens, Tallinn, Estonia.
|
||||
//All rights reserved.
|
||||
|
||||
//Redistribution and use in source and binary forms are permitted
|
||||
//provided that the above copyright notice and this paragraph are
|
||||
//duplicated in all such forms and that any documentation,
|
||||
//advertising materials, and other materials related to such
|
||||
//distribution and use acknowledge that the software was developed
|
||||
//by H&R, Hammer&Ravens. The name of the
|
||||
//H&R, Hammer&Ravens may not be used to endorse or promote products derived
|
||||
//from this software without specific prior written permission.
|
||||
//THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
//IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[AddComponentMenu("UI/Extensions/Tooltip")]
|
||||
public class ToolTip : MonoBehaviour
|
||||
{
|
||||
//text of the tooltip
|
||||
private Text _text;
|
||||
private RectTransform _rectTransform;
|
||||
|
||||
//if the tooltip is inside a UI element
|
||||
private bool _inside;
|
||||
|
||||
private bool _xShifted, _yShifted = false;
|
||||
|
||||
private float width, height, canvasWidth, canvasHeight;
|
||||
|
||||
private int screenWidth, screenHeight;
|
||||
|
||||
private float YShift,xShift;
|
||||
|
||||
private RenderMode _guiMode;
|
||||
|
||||
private Camera _guiCamera;
|
||||
|
||||
// Use this for initialization
|
||||
public void Awake()
|
||||
{
|
||||
var _canvas = GetComponentInParent<Canvas>();
|
||||
_guiCamera = _canvas.worldCamera;
|
||||
_guiMode = _canvas.renderMode;
|
||||
_rectTransform = GetComponent<RectTransform>();
|
||||
|
||||
_text = GetComponentInChildren<Text>();
|
||||
|
||||
_inside = false;
|
||||
|
||||
//size of the screen
|
||||
screenWidth = Screen.width;
|
||||
screenHeight = Screen.height;
|
||||
|
||||
xShift = 0f;
|
||||
YShift = -30f;
|
||||
|
||||
_xShifted = _yShifted = false;
|
||||
|
||||
|
||||
this.gameObject.SetActive(false);
|
||||
|
||||
}
|
||||
|
||||
//Call this function externally to set the text of the template and activate the tooltip
|
||||
public void SetTooltip(string ttext)
|
||||
{
|
||||
|
||||
if (_guiMode == RenderMode.ScreenSpaceCamera)
|
||||
{
|
||||
//set the text and fit the tooltip panel to the text size
|
||||
_text.text = ttext;
|
||||
|
||||
_rectTransform.sizeDelta = new Vector2(_text.preferredWidth + 40f, _text.preferredHeight + 25f);
|
||||
|
||||
OnScreenSpaceCamera();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//call this function on mouse exit to deactivate the template
|
||||
public void HideTooltip()
|
||||
{
|
||||
if (_guiMode == RenderMode.ScreenSpaceCamera)
|
||||
{
|
||||
this.gameObject.SetActive(false);
|
||||
_inside = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void FixedUpdate()
|
||||
{
|
||||
if (_inside)
|
||||
{
|
||||
if (_guiMode == RenderMode.ScreenSpaceCamera)
|
||||
{
|
||||
OnScreenSpaceCamera();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//main tooltip edge of screen guard and movement
|
||||
public void OnScreenSpaceCamera()
|
||||
{
|
||||
Vector3 newPos = _guiCamera.ScreenToViewportPoint(Input.mousePosition - new Vector3(xShift, YShift, 0f));
|
||||
Vector3 newPosWVP = _guiCamera.ViewportToWorldPoint(newPos);
|
||||
|
||||
width = _rectTransform.sizeDelta[0];
|
||||
height = _rectTransform.sizeDelta[1];
|
||||
|
||||
// check and solve problems for the tooltip that goes out of the screen on the horizontal axis
|
||||
float val;
|
||||
|
||||
Vector3 lowerLeft = _guiCamera.ViewportToWorldPoint(new Vector3(0.0f, 0.0f, 0.0f));
|
||||
Vector3 upperRight = _guiCamera.ViewportToWorldPoint(new Vector3(1.0f, 1.0f, 0.0f));
|
||||
|
||||
//check for right edge of screen
|
||||
val = (newPosWVP.x + width / 2);
|
||||
if (val > upperRight.x)
|
||||
{
|
||||
Vector3 shifter = new Vector3(val - upperRight.x, 0f, 0f);
|
||||
Vector3 newWorldPos = new Vector3(newPosWVP.x - shifter.x, newPos.y, 0f);
|
||||
newPos.x = _guiCamera.WorldToViewportPoint(newWorldPos).x;
|
||||
}
|
||||
//check for left edge of screen
|
||||
val = (newPosWVP.x - width / 2);
|
||||
if (val < lowerLeft.x)
|
||||
{
|
||||
Vector3 shifter = new Vector3(lowerLeft.x - val, 0f, 0f);
|
||||
Vector3 newWorldPos = new Vector3(newPosWVP.x + shifter.x, newPos.y, 0f);
|
||||
newPos.x = _guiCamera.WorldToViewportPoint(newWorldPos).x;
|
||||
}
|
||||
|
||||
// check and solve problems for the tooltip that goes out of the screen on the vertical axis
|
||||
|
||||
//check for upper edge of the screen
|
||||
val = (newPosWVP.y + height / 2);
|
||||
if (val > upperRight.y)
|
||||
{
|
||||
Vector3 shifter = new Vector3(0f, 35f + height / 2, 0f);
|
||||
Vector3 newWorldPos = new Vector3(newPos.x, newPosWVP.y - shifter.y, 0f);
|
||||
newPos.y = _guiCamera.WorldToViewportPoint(newWorldPos).y;
|
||||
}
|
||||
|
||||
//check for lower edge of the screen (if the shifts of the tooltip are kept as in this code, no need for this as the tooltip always appears above the mouse bu default)
|
||||
val = (newPosWVP.y - height / 2);
|
||||
if (val < lowerLeft.y)
|
||||
{
|
||||
Vector3 shifter = new Vector3(0f, 35f + height / 2, 0f);
|
||||
Vector3 newWorldPos = new Vector3(newPos.x, newPosWVP.y + shifter.y, 0f);
|
||||
newPos.y = _guiCamera.WorldToViewportPoint(newWorldPos).y;
|
||||
}
|
||||
|
||||
this.transform.position = new Vector3(newPosWVP.x, newPosWVP.y, 0f);
|
||||
this.gameObject.SetActive(true);
|
||||
_inside = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8a649d0fc284fb7458094a7a02315f07
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,58 @@
|
|||
/// Credit AriathTheWise
|
||||
/// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-1796783
|
||||
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// UIButton
|
||||
/// </summary>
|
||||
[AddComponentMenu("UI/Extensions/UI Button")]
|
||||
public class UIButton : Button, IPointerDownHandler, IPointerUpHandler
|
||||
{
|
||||
#region Sub-Classes
|
||||
[System.Serializable]
|
||||
public class UIButtonEvent : UnityEvent<PointerEventData.InputButton> { }
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
public UIButtonEvent OnButtonClick;
|
||||
public UIButtonEvent OnButtonPress;
|
||||
public UIButtonEvent OnButtonRelease;
|
||||
#endregion
|
||||
|
||||
public override void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
base.OnSubmit(eventData);
|
||||
|
||||
if (OnButtonClick != null)
|
||||
{
|
||||
OnButtonClick.Invoke(eventData.button);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IPointerDownHandler.OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
DoStateTransition(SelectionState.Pressed, false);
|
||||
|
||||
if (OnButtonPress != null)
|
||||
{
|
||||
OnButtonPress.Invoke(eventData.button);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IPointerUpHandler.OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
DoStateTransition(SelectionState.Normal, false);
|
||||
|
||||
if (OnButtonRelease != null)
|
||||
{
|
||||
OnButtonRelease.Invoke(eventData.button);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f2e459a0f758bc947ace4872e13f1da0
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -0,0 +1,60 @@
|
|||
/// Credit ChoMPHi
|
||||
/// Sourced from - http://forum.unity3d.com/threads/script-flippable-for-ui-graphics.291711/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(RectTransform), typeof(Graphic)), DisallowMultipleComponent]
|
||||
[AddComponentMenu("UI/Effects/Extensions/Flippable")]
|
||||
public class UIFlippable : MonoBehaviour, IVertexModifier
|
||||
{
|
||||
[SerializeField] private bool m_Horizontal = false;
|
||||
[SerializeField] private bool m_Veritical = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="UnityEngine.UI.UIFlippable"/> should be flipped horizontally.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if horizontal; otherwise, <c>false</c>.</value>
|
||||
public bool horizontal
|
||||
{
|
||||
get { return this.m_Horizontal; }
|
||||
set { this.m_Horizontal = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="UnityEngine.UI.UIFlippable"/> should be flipped vertically.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if vertical; otherwise, <c>false</c>.</value>
|
||||
public bool vertical
|
||||
{
|
||||
get { return this.m_Veritical; }
|
||||
set { this.m_Veritical = value; }
|
||||
}
|
||||
|
||||
protected void OnValidate()
|
||||
{
|
||||
this.GetComponent<Graphic>().SetVerticesDirty();
|
||||
}
|
||||
|
||||
public void ModifyVertices(List<UIVertex> verts)
|
||||
{
|
||||
RectTransform rt = this.transform as RectTransform;
|
||||
|
||||
for (int i = 0; i < verts.Count; ++i)
|
||||
{
|
||||
UIVertex v = verts[i];
|
||||
|
||||
// Modify positions
|
||||
v.position = new Vector3(
|
||||
(this.m_Horizontal ? (v.position.x + (rt.rect.center.x - v.position.x) * 2) : v.position.x),
|
||||
(this.m_Veritical ? (v.position.y + (rt.rect.center.y - v.position.y) * 2) : v.position.y),
|
||||
v.position.z
|
||||
);
|
||||
|
||||
// Apply
|
||||
verts[i] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 67f304b9bd84e9848bcfb79f47790081
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -1,108 +1,114 @@
|
|||
// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-1834806 (with corrections)
|
||||
// Scaling fixed for non overlay canvases - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1780612
|
||||
// Canvas border fix - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1781658
|
||||
// Canvas reset position fix - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1782214
|
||||
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
/// <summary>
|
||||
/// Includes a few fixes of my own, mainly to tidy up duplicates, remove unneeded stuff and testing. (nothing major, all the crew above did the hard work!)
|
||||
/// </summary>
|
||||
public class UIWindowBase : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
|
||||
{
|
||||
RectTransform m_transform = null;
|
||||
private bool _isDragging = false;
|
||||
public static bool ResetCoords = false;
|
||||
private Vector3 m_originalCoods = Vector3.zero;
|
||||
private Canvas m_canvas;
|
||||
private RectTransform m_canvasRectTransform;
|
||||
public int KeepWindowInCanvas = 5; // # of pixels of the window that must stay inside the canvas view.
|
||||
|
||||
// Use this for initialization
|
||||
void Start () {
|
||||
m_transform = GetComponent<RectTransform>();
|
||||
m_originalCoods = m_transform.position;
|
||||
m_canvas = GetComponentInParent<Canvas>();
|
||||
m_canvasRectTransform = m_canvas.GetComponent<RectTransform>();
|
||||
}
|
||||
|
||||
void Update(){
|
||||
if (ResetCoords)
|
||||
resetCoordinatePosition();
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
if (_isDragging)
|
||||
{
|
||||
var delta = ScreenToCanvas(eventData.position) - ScreenToCanvas(eventData.position - eventData.delta);
|
||||
m_transform.localPosition += delta;
|
||||
}
|
||||
}
|
||||
|
||||
//Note, the begin drag and end drag aren't actually needed to control the drag. However, I'd recommend keeping it in case you want to do somethind else when draggging starts and stops
|
||||
public void OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
|
||||
if (eventData.pointerCurrentRaycast.gameObject == null)
|
||||
return;
|
||||
|
||||
if (eventData.pointerCurrentRaycast.gameObject.name == name)
|
||||
{
|
||||
_isDragging = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEndDrag(PointerEventData eventData)
|
||||
{
|
||||
_isDragging = false;
|
||||
}
|
||||
|
||||
void resetCoordinatePosition()
|
||||
{
|
||||
m_transform.position = m_originalCoods;
|
||||
ResetCoords = false;
|
||||
}
|
||||
|
||||
private Vector3 ScreenToCanvas(Vector3 screenPosition)
|
||||
{
|
||||
Vector3 localPosition;
|
||||
Vector2 min;
|
||||
Vector2 max;
|
||||
var canvasSize = m_canvasRectTransform.sizeDelta;
|
||||
|
||||
if (m_canvas.renderMode == RenderMode.ScreenSpaceOverlay || (m_canvas.renderMode == RenderMode.ScreenSpaceCamera && m_canvas.worldCamera == null))
|
||||
{
|
||||
localPosition = screenPosition;
|
||||
|
||||
min = Vector2.zero;
|
||||
max = canvasSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
var ray = m_canvas.worldCamera.ScreenPointToRay(screenPosition);
|
||||
var plane = new Plane(m_canvasRectTransform.forward, m_canvasRectTransform.position);
|
||||
|
||||
float distance;
|
||||
if (plane.Raycast(ray, out distance) == false)
|
||||
{
|
||||
throw new Exception("Is it practically possible?");
|
||||
};
|
||||
var worldPosition = ray.origin + ray.direction * distance;
|
||||
localPosition = m_canvasRectTransform.InverseTransformPoint(worldPosition);
|
||||
|
||||
min = -Vector2.Scale(canvasSize, m_canvasRectTransform.pivot);
|
||||
max = Vector2.Scale(canvasSize, Vector2.one - m_canvasRectTransform.pivot);
|
||||
}
|
||||
|
||||
// keep window inside canvas
|
||||
localPosition.x = Mathf.Clamp(localPosition.x, min.x + KeepWindowInCanvas, max.x - KeepWindowInCanvas);
|
||||
localPosition.y = Mathf.Clamp(localPosition.y, min.y + KeepWindowInCanvas, max.y - KeepWindowInCanvas);
|
||||
|
||||
return localPosition;
|
||||
}
|
||||
|
||||
/// Credit GXMark, alexzzzz, CaoMengde777, TroyDavis
|
||||
/// Original Sourced from (GXMark) - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-1834806 (with corrections)
|
||||
/// Scaling fixed for non overlay canvases (alexzzzz) - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1780612
|
||||
/// Canvas border fix (CaoMengde777) - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1781658
|
||||
/// Canvas reset position fix (TroyDavis)- http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1782214
|
||||
|
||||
|
||||
using System;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Includes a few fixes of my own, mainly to tidy up duplicates, remove unneeded stuff and testing. (nothing major, all the crew above did the hard work!)
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[AddComponentMenu("UI/Extensions/UI Window Base")]
|
||||
public class UIWindowBase : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
|
||||
{
|
||||
RectTransform m_transform = null;
|
||||
private bool _isDragging = false;
|
||||
public static bool ResetCoords = false;
|
||||
private Vector3 m_originalCoods = Vector3.zero;
|
||||
private Canvas m_canvas;
|
||||
private RectTransform m_canvasRectTransform;
|
||||
public int KeepWindowInCanvas = 5; // # of pixels of the window that must stay inside the canvas view.
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
m_transform = GetComponent<RectTransform>();
|
||||
m_originalCoods = m_transform.position;
|
||||
m_canvas = GetComponentInParent<Canvas>();
|
||||
m_canvasRectTransform = m_canvas.GetComponent<RectTransform>();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (ResetCoords)
|
||||
resetCoordinatePosition();
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
if (_isDragging)
|
||||
{
|
||||
var delta = ScreenToCanvas(eventData.position) - ScreenToCanvas(eventData.position - eventData.delta);
|
||||
m_transform.localPosition += delta;
|
||||
}
|
||||
}
|
||||
|
||||
//Note, the begin drag and end drag aren't actually needed to control the drag. However, I'd recommend keeping it in case you want to do somethind else when draggging starts and stops
|
||||
public void OnBeginDrag(PointerEventData eventData)
|
||||
{
|
||||
|
||||
if (eventData.pointerCurrentRaycast.gameObject == null)
|
||||
return;
|
||||
|
||||
if (eventData.pointerCurrentRaycast.gameObject.name == name)
|
||||
{
|
||||
_isDragging = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEndDrag(PointerEventData eventData)
|
||||
{
|
||||
_isDragging = false;
|
||||
}
|
||||
|
||||
void resetCoordinatePosition()
|
||||
{
|
||||
m_transform.position = m_originalCoods;
|
||||
ResetCoords = false;
|
||||
}
|
||||
|
||||
private Vector3 ScreenToCanvas(Vector3 screenPosition)
|
||||
{
|
||||
Vector3 localPosition;
|
||||
Vector2 min;
|
||||
Vector2 max;
|
||||
var canvasSize = m_canvasRectTransform.sizeDelta;
|
||||
|
||||
if (m_canvas.renderMode == RenderMode.ScreenSpaceOverlay || (m_canvas.renderMode == RenderMode.ScreenSpaceCamera && m_canvas.worldCamera == null))
|
||||
{
|
||||
localPosition = screenPosition;
|
||||
|
||||
min = Vector2.zero;
|
||||
max = canvasSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
var ray = m_canvas.worldCamera.ScreenPointToRay(screenPosition);
|
||||
var plane = new Plane(m_canvasRectTransform.forward, m_canvasRectTransform.position);
|
||||
|
||||
float distance;
|
||||
if (plane.Raycast(ray, out distance) == false)
|
||||
{
|
||||
throw new Exception("Is it practically possible?");
|
||||
};
|
||||
var worldPosition = ray.origin + ray.direction * distance;
|
||||
localPosition = m_canvasRectTransform.InverseTransformPoint(worldPosition);
|
||||
|
||||
min = -Vector2.Scale(canvasSize, m_canvasRectTransform.pivot);
|
||||
max = Vector2.Scale(canvasSize, Vector2.one - m_canvasRectTransform.pivot);
|
||||
}
|
||||
|
||||
// keep window inside canvas
|
||||
localPosition.x = Mathf.Clamp(localPosition.x, min.x + KeepWindowInCanvas, max.x - KeepWindowInCanvas);
|
||||
localPosition.y = Mathf.Clamp(localPosition.y, min.y + KeepWindowInCanvas, max.y - KeepWindowInCanvas);
|
||||
|
||||
return localPosition;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8803d62703eac8a44a3e9884c71009da
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
|
@ -1,98 +1,115 @@
|
|||
//Sourced From - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/ (uGUITools link)
|
||||
/// Credit Senshi
|
||||
/// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/ (uGUITools link)
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public class uGUITools : MonoBehaviour {
|
||||
[MenuItem("uGUI/Anchors to Corners %[")]
|
||||
static void AnchorsToCorners(){
|
||||
foreach(Transform transform in Selection.transforms){
|
||||
RectTransform t = transform as RectTransform;
|
||||
RectTransform pt = Selection.activeTransform.parent as RectTransform;
|
||||
|
||||
if(t == null || pt == null) return;
|
||||
|
||||
Vector2 newAnchorsMin = new Vector2(t.anchorMin.x + t.offsetMin.x / pt.rect.width,
|
||||
t.anchorMin.y + t.offsetMin.y / pt.rect.height);
|
||||
Vector2 newAnchorsMax = new Vector2(t.anchorMax.x + t.offsetMax.x / pt.rect.width,
|
||||
t.anchorMax.y + t.offsetMax.y / pt.rect.height);
|
||||
|
||||
t.anchorMin = newAnchorsMin;
|
||||
t.anchorMax = newAnchorsMax;
|
||||
t.offsetMin = t.offsetMax = new Vector2(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("uGUI/Corners to Anchors %]")]
|
||||
static void CornersToAnchors(){
|
||||
foreach(Transform transform in Selection.transforms){
|
||||
RectTransform t = transform as RectTransform;
|
||||
|
||||
if(t == null) return;
|
||||
|
||||
t.offsetMin = t.offsetMax = new Vector2(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("uGUI/Mirror Horizontally Around Anchors %;")]
|
||||
static void MirrorHorizontallyAnchors(){
|
||||
MirrorHorizontally(false);
|
||||
}
|
||||
|
||||
[MenuItem("uGUI/Mirror Horizontally Around Parent Center %:")]
|
||||
static void MirrorHorizontallyParent(){
|
||||
MirrorHorizontally(true);
|
||||
}
|
||||
|
||||
static void MirrorHorizontally(bool mirrorAnchors){
|
||||
foreach(Transform transform in Selection.transforms){
|
||||
RectTransform t = transform as RectTransform;
|
||||
RectTransform pt = Selection.activeTransform.parent as RectTransform;
|
||||
|
||||
if(t == null || pt == null) return;
|
||||
|
||||
if(mirrorAnchors){
|
||||
Vector2 oldAnchorMin = t.anchorMin;
|
||||
t.anchorMin = new Vector2(1 - t.anchorMax.x, t.anchorMin.y);
|
||||
t.anchorMax = new Vector2(1 - oldAnchorMin.x, t.anchorMax.y);
|
||||
}
|
||||
|
||||
Vector2 oldOffsetMin = t.offsetMin;
|
||||
t.offsetMin = new Vector2(-t.offsetMax.x, t.offsetMin.y);
|
||||
t.offsetMax = new Vector2(-oldOffsetMin.x, t.offsetMax.y);
|
||||
|
||||
t.localScale = new Vector3(-t.localScale.x, t.localScale.y, t.localScale.z);
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("uGUI/Mirror Vertically Around Anchors %'")]
|
||||
static void MirrorVerticallyAnchors(){
|
||||
MirrorVertically(false);
|
||||
}
|
||||
|
||||
[MenuItem("uGUI/Mirror Vertically Around Parent Center %\"")]
|
||||
static void MirrorVerticallyParent(){
|
||||
MirrorVertically(true);
|
||||
}
|
||||
|
||||
static void MirrorVertically(bool mirrorAnchors){
|
||||
foreach(Transform transform in Selection.transforms){
|
||||
RectTransform t = transform as RectTransform;
|
||||
RectTransform pt = Selection.activeTransform.parent as RectTransform;
|
||||
|
||||
if(t == null || pt == null) return;
|
||||
|
||||
if(mirrorAnchors){
|
||||
Vector2 oldAnchorMin = t.anchorMin;
|
||||
t.anchorMin = new Vector2(t.anchorMin.x, 1 - t.anchorMax.y);
|
||||
t.anchorMax = new Vector2(t.anchorMax.x, 1 - oldAnchorMin.y);
|
||||
}
|
||||
|
||||
Vector2 oldOffsetMin = t.offsetMin;
|
||||
t.offsetMin = new Vector2(t.offsetMin.x, -t.offsetMax.y);
|
||||
t.offsetMax = new Vector2(t.offsetMax.x, -oldOffsetMin.y);
|
||||
|
||||
t.localScale = new Vector3(t.localScale.x, -t.localScale.y, t.localScale.z);
|
||||
}
|
||||
}
|
||||
using UnityEditor;
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
public class uGUITools : MonoBehaviour
|
||||
{
|
||||
[MenuItem("uGUI/Anchors to Corners %[")]
|
||||
static void AnchorsToCorners()
|
||||
{
|
||||
foreach (Transform transform in Selection.transforms)
|
||||
{
|
||||
RectTransform t = transform as RectTransform;
|
||||
RectTransform pt = Selection.activeTransform.parent as RectTransform;
|
||||
|
||||
if (t == null || pt == null) return;
|
||||
|
||||
Vector2 newAnchorsMin = new Vector2(t.anchorMin.x + t.offsetMin.x / pt.rect.width,
|
||||
t.anchorMin.y + t.offsetMin.y / pt.rect.height);
|
||||
Vector2 newAnchorsMax = new Vector2(t.anchorMax.x + t.offsetMax.x / pt.rect.width,
|
||||
t.anchorMax.y + t.offsetMax.y / pt.rect.height);
|
||||
|
||||
t.anchorMin = newAnchorsMin;
|
||||
t.anchorMax = newAnchorsMax;
|
||||
t.offsetMin = t.offsetMax = new Vector2(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("uGUI/Corners to Anchors %]")]
|
||||
static void CornersToAnchors()
|
||||
{
|
||||
foreach (Transform transform in Selection.transforms)
|
||||
{
|
||||
RectTransform t = transform as RectTransform;
|
||||
|
||||
if (t == null) return;
|
||||
|
||||
t.offsetMin = t.offsetMax = new Vector2(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("uGUI/Mirror Horizontally Around Anchors %;")]
|
||||
static void MirrorHorizontallyAnchors()
|
||||
{
|
||||
MirrorHorizontally(false);
|
||||
}
|
||||
|
||||
[MenuItem("uGUI/Mirror Horizontally Around Parent Center %:")]
|
||||
static void MirrorHorizontallyParent()
|
||||
{
|
||||
MirrorHorizontally(true);
|
||||
}
|
||||
|
||||
static void MirrorHorizontally(bool mirrorAnchors)
|
||||
{
|
||||
foreach (Transform transform in Selection.transforms)
|
||||
{
|
||||
RectTransform t = transform as RectTransform;
|
||||
RectTransform pt = Selection.activeTransform.parent as RectTransform;
|
||||
|
||||
if (t == null || pt == null) return;
|
||||
|
||||
if (mirrorAnchors)
|
||||
{
|
||||
Vector2 oldAnchorMin = t.anchorMin;
|
||||
t.anchorMin = new Vector2(1 - t.anchorMax.x, t.anchorMin.y);
|
||||
t.anchorMax = new Vector2(1 - oldAnchorMin.x, t.anchorMax.y);
|
||||
}
|
||||
|
||||
Vector2 oldOffsetMin = t.offsetMin;
|
||||
t.offsetMin = new Vector2(-t.offsetMax.x, t.offsetMin.y);
|
||||
t.offsetMax = new Vector2(-oldOffsetMin.x, t.offsetMax.y);
|
||||
|
||||
t.localScale = new Vector3(-t.localScale.x, t.localScale.y, t.localScale.z);
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("uGUI/Mirror Vertically Around Anchors %'")]
|
||||
static void MirrorVerticallyAnchors()
|
||||
{
|
||||
MirrorVertically(false);
|
||||
}
|
||||
|
||||
[MenuItem("uGUI/Mirror Vertically Around Parent Center %\"")]
|
||||
static void MirrorVerticallyParent()
|
||||
{
|
||||
MirrorVertically(true);
|
||||
}
|
||||
|
||||
static void MirrorVertically(bool mirrorAnchors)
|
||||
{
|
||||
foreach (Transform transform in Selection.transforms)
|
||||
{
|
||||
RectTransform t = transform as RectTransform;
|
||||
RectTransform pt = Selection.activeTransform.parent as RectTransform;
|
||||
|
||||
if (t == null || pt == null) return;
|
||||
|
||||
if (mirrorAnchors)
|
||||
{
|
||||
Vector2 oldAnchorMin = t.anchorMin;
|
||||
t.anchorMin = new Vector2(t.anchorMin.x, 1 - t.anchorMax.y);
|
||||
t.anchorMax = new Vector2(t.anchorMax.x, 1 - oldAnchorMin.y);
|
||||
}
|
||||
|
||||
Vector2 oldOffsetMin = t.offsetMin;
|
||||
t.offsetMin = new Vector2(t.offsetMin.x, -t.offsetMax.y);
|
||||
t.offsetMax = new Vector2(t.offsetMax.x, -oldOffsetMin.y);
|
||||
|
||||
t.localScale = new Vector3(t.localScale.x, -t.localScale.y, t.localScale.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b896154a8dbdc524092e78923478d27a
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
Loading…
Reference in New Issue