Files
tianrunCRM/Assets/CoolapeFrame/3rd/NGUI_Enhance/Scripts/Interaction/UIKeyNavigation.cs
2020-07-04 14:41:25 +08:00

230 lines
5.5 KiB
C#

//----------------------------------------------
// NGUI: Next-Gen UI kit
// Copyright © 2011-2015 Tasharen Entertainment
//----------------------------------------------
using UnityEngine;
/// <summary>
/// Attaching this script to a widget makes it react to key events such as tab, up, down, etc.
/// </summary>
[AddComponentMenu("NGUI/Interaction/Key Navigation")]
public class UIKeyNavigation : MonoBehaviour
{
/// <summary>
/// List of all the active UINavigation components.
/// </summary>
static public BetterList<UIKeyNavigation> list = new BetterList<UIKeyNavigation>();
public enum Constraint
{
None,
Vertical,
Horizontal,
Explicit,
}
/// <summary>
/// If a selection target is not set, the target can be determined automatically, restricted by this constraint.
/// 'None' means free movement on both horizontal and vertical axis. 'Explicit' means the automatic logic will
/// not execute, and only the explicitly set values will be used.
/// </summary>
public Constraint constraint = Constraint.None;
/// <summary>
/// Which object will be selected when the Up button is pressed.
/// </summary>
public GameObject onUp;
/// <summary>
/// Which object will be selected when the Down button is pressed.
/// </summary>
public GameObject onDown;
/// <summary>
/// Which object will be selected when the Left button is pressed.
/// </summary>
public GameObject onLeft;
/// <summary>
/// Which object will be selected when the Right button is pressed.
/// </summary>
public GameObject onRight;
/// <summary>
/// Which object will get selected on click.
/// </summary>
public GameObject onClick;
/// <summary>
/// Whether the object this script is attached to will get selected as soon as this script is enabled.
/// </summary>
public bool startsSelected = false;
protected virtual void OnEnable ()
{
list.Add(this);
if (startsSelected)
{
#if UNITY_EDITOR
if (!Application.isPlaying) return;
#endif
if (UICamera.selectedObject == null || !NGUITools.GetActive(UICamera.selectedObject))
{
UICamera.currentScheme = UICamera.ControlScheme.Controller;
UICamera.selectedObject = gameObject;
}
}
}
protected virtual void OnDisable () { list.Remove(this); }
protected GameObject GetLeft ()
{
if (NGUITools.GetActive(onLeft)) return onLeft;
if (constraint == Constraint.Vertical || constraint == Constraint.Explicit) return null;
return Get(Vector3.left, true);
}
GameObject GetRight ()
{
if (NGUITools.GetActive(onRight)) return onRight;
if (constraint == Constraint.Vertical || constraint == Constraint.Explicit) return null;
return Get(Vector3.right, true);
}
protected GameObject GetUp ()
{
if (NGUITools.GetActive(onUp)) return onUp;
if (constraint == Constraint.Horizontal || constraint == Constraint.Explicit) return null;
return Get(Vector3.up, false);
}
protected GameObject GetDown ()
{
if (NGUITools.GetActive(onDown)) return onDown;
if (constraint == Constraint.Horizontal || constraint == Constraint.Explicit) return null;
return Get(Vector3.down, false);
}
protected GameObject Get (Vector3 myDir, bool horizontal)
{
Transform t = transform;
myDir = t.TransformDirection(myDir);
Vector3 myCenter = GetCenter(gameObject);
float min = float.MaxValue;
GameObject go = null;
for (int i = 0; i < list.size; ++i)
{
UIKeyNavigation nav = list[i];
if (nav == this) continue;
// Ignore disabled buttons
UIButton btn = nav.GetComponent<UIButton>();
if (btn != null && !btn.isEnabled) continue;
// Reject objects that are not within a 45 degree angle of the desired direction
Vector3 dir = GetCenter(nav.gameObject) - myCenter;
float dot = Vector3.Dot(myDir, dir.normalized);
if (dot < 0.707f) continue;
// Exaggerate the movement in the undesired direction
dir = t.InverseTransformDirection(dir);
if (horizontal) dir.y *= 2f;
else dir.x *= 2f;
// Compare the distance
float mag = dir.sqrMagnitude;
if (mag > min) continue;
go = nav.gameObject;
min = mag;
}
return go;
}
static protected Vector3 GetCenter (GameObject go)
{
UIWidget w = go.GetComponent<UIWidget>();
UICamera cam = UICamera.FindCameraForLayer(go.layer);
if (cam != null)
{
Vector3 center = go.transform.position;
if (w != null)
{
Vector3[] corners = w.worldCorners;
center = (corners[0] + corners[2]) * 0.5f;
}
center = cam.cachedCamera.WorldToScreenPoint(center);
center.z = 0;
return center;
}
else if (w != null)
{
Vector3[] corners = w.worldCorners;
return (corners[0] + corners[2]) * 0.5f;
}
return go.transform.position;
}
protected virtual void OnKey (KeyCode key)
{
if (!NGUITools.GetActive(this)) return;
GameObject go = null;
switch (key)
{
case KeyCode.LeftArrow:
go = GetLeft();
break;
case KeyCode.RightArrow:
go = GetRight();
break;
case KeyCode.UpArrow:
go = GetUp();
break;
case KeyCode.DownArrow:
go = GetDown();
break;
case KeyCode.Tab:
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
{
go = GetLeft();
if (go == null) go = GetUp();
if (go == null) go = GetDown();
if (go == null) go = GetRight();
}
else
{
go = GetRight();
if (go == null) go = GetDown();
if (go == null) go = GetUp();
if (go == null) go = GetLeft();
}
break;
}
if (go != null) UICamera.selectedObject = go;
}
protected virtual void OnClick ()
{
if (NGUITools.GetActive(this) && NGUITools.GetActive(onClick))
UICamera.selectedObject = onClick;
}
}