Firstborn/Assets/SWAN Dev/DynamicUI/DCanvasLayerHandler.cs

170 lines
4.2 KiB
C#
Raw Normal View History

/// <summary>
/// Created by SWAN DEV 2018
/// </summary>
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// Dynamic UI - Canvas Layer Handler script for handling UGUI canvas sorting layer: place the last clicked canvas on top layer.
/// </summary>
public class DCanvasLayerHandler : MonoBehaviour
{
/// <summary> The base sorting order of handled canvases. Canvas with larger sorting order will show on top. </summary>
public static int baseLayer = 100;
/// <summary> A list of Canvases to be handled by this script. </summary>
private static List<Canvas> handledCanvasList = new List<Canvas>();
private static DCanvasLayerHandler _instance = null;
public enum SortLayerEventType
{
OnTouchUp = 0,
OnTouchDown,
OnTap,
}
public SortLayerEventType sortLayerEventType = SortLayerEventType.OnTouchDown;
float onTouchDownTime = 0f;
float onTapInterval = 0.3f;
bool isTouchDown = false;
bool isTouchUp = true;
GameObject touchedObject;
PointerEventData cursor = new PointerEventData(EventSystem.current);
List<RaycastResult> objectsHit = new List<RaycastResult> ();
/// Set the target canvas to be managed by this handler,
/// for automatically handle the canvas layers when the user drag/tap on the UI.
public static void iAddCanvas(Canvas canvas, bool createCanvasLayerHandlerIfNotExist = true)
{
if(canvas == null) return;
if (_instance == null && createCanvasLayerHandlerIfNotExist)
{
_instance = new GameObject("[DCanvasLayerHandler]").AddComponent<DCanvasLayerHandler>();
}
if(_instance && !handledCanvasList.Contains(canvas))
{
canvas.sortingOrder = baseLayer + handledCanvasList.Count;
handledCanvasList.Add(canvas);
}
}
/// Set the target canvas to be managed by this handler,
/// for automatically handle the canvas layers when the user drag/tap on the UI.
public void AddCanvas(Canvas canvas)
{
iAddCanvas(canvas);
}
void Awake()
{
if(_instance == null)
{
_instance = this;
}
else
{
Debug.LogWarning("Duplicated DCanvasLayerHandler removed in gameObject: " + this.name);
Destroy(this);
}
}
void Update()
{
if(isTouchUp)
{
isTouchDown = SDev.Util.UnifyInputUtil.WasTouchOrMousePressed();
if(isTouchDown)
{
//A mouse/touch down event detected.
isTouchUp = false;
onTouchDownTime = Time.time;
cursor.position = SDev.Util.UnifyInputUtil.GetCursorPosition();
EventSystem.current.RaycastAll(cursor, objectsHit);
if(objectsHit.Count > 0)
{
touchedObject = objectsHit[0].gameObject;
}
if(sortLayerEventType == SortLayerEventType.OnTouchDown) _SortLayer();
}
}
else if(isTouchDown)
{
isTouchUp = SDev.Util.UnifyInputUtil.WasTouchOrMouseReleased();
if(isTouchUp)
{
//A mouse/touch up event detected.
isTouchDown = false;
if(sortLayerEventType == SortLayerEventType.OnTouchUp)
{
_SortLayer();
}
else if(sortLayerEventType == SortLayerEventType.OnTap)
{
if(onTouchDownTime + onTapInterval > Time.time)
{
_SortLayer();
}
}
}
}
}
private void _SortLayer()
{
cursor.position = SDev.Util.UnifyInputUtil.GetCursorPosition();
EventSystem.current.RaycastAll(cursor, objectsHit);
if(objectsHit.Count > 0)
{
if(touchedObject != null && touchedObject == objectsHit[0].gameObject)
{
for(int i=0; i<handledCanvasList.Count; i++)
{
if(handledCanvasList[i] == null)
{
handledCanvasList.RemoveAt(i);
}
handledCanvasList.TrimExcess();
}
Transform tf = objectsHit[0].gameObject.transform;
Transform root = tf.root;
Canvas getCanvas = null;
do{
tf = tf.parent;
if(tf.gameObject.GetComponent<Canvas>() != null)
{
getCanvas = tf.gameObject.GetComponent<Canvas>();
}
}
while(tf != root && getCanvas == null);
if(getCanvas != null && handledCanvasList.Contains(getCanvas))
{
handledCanvasList.Remove(getCanvas);
handledCanvasList.Add(getCanvas);
for(int i=0; i<handledCanvasList.Count; i++)
{
if(handledCanvasList[i] != null) handledCanvasList[i].sortingOrder = baseLayer + i;
}
}
}
}
}
}