NewN_UAVPlane/Assets/3rdParty/ZFBrowser/Scripts/BrowserUI/Legacy/ClickMeshBrowserUI.cs

201 lines
6.3 KiB
C#

#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
#define ZF_OSX
#endif
using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace ZenFulcrum.EmbeddedBrowser {
/**
* This class will handle input to a browser based on the mouse position and a mesh collider on the browser.
* Mouse positions are looked up according to the UVs on the *collider* mesh. Generally, you will want to use
* the same or a visually similar (including UVs) mesh for the renderer.
*/
[Obsolete("Use PointerUIMesh instead.")]
public class ClickMeshBrowserUI : MonoBehaviour, IBrowserUI {
/**
* Creates a new UI handler.
* We will attach to {parent}, which must have the mesh we are interacting with.
* In most cases, this will also be the same object that has the Browser we will be fed to. (a la browser.UIHandler)
*/
public static ClickMeshBrowserUI Create(MeshCollider meshCollider) {
var ui = meshCollider.gameObject.AddComponent<ClickMeshBrowserUI>();
ui.meshCollider = meshCollider;
return ui;
}
public void Awake() {
BrowserCursor = new BrowserCursor();
BrowserCursor.cursorChange += CursorUpdated;
InputSettings = new BrowserInputSettings();
}
protected MeshCollider meshCollider;
/**
* How far can we reach to touch a browser?
*
* HideInInspector:
* Showing it in the inspector would imply that changing the value would be used, but in most practical cases
* with FPSBrowserUI, the value will be overridden by the FPSCursorRenderer.
*/
[HideInInspector]
public float maxDistance = float.PositiveInfinity;
/** Fills up with key events as they happen. */
protected List<Event> keyEvents = new List<Event>();
/** Swaps with keyEvents on InputUpdate and is returned in the main getter. */
protected List<Event> keyEventsLast = new List<Event>();
/** Returns the user's interacting ray, usually the mouse pointer in some form. */
protected virtual Ray LookRay {
get { return Camera.main.ScreenPointToRay(Input.mousePosition); }
}
/** List of keys Unity won't give us events for. So we have to poll. */
static readonly KeyCode[] keysToCheck = {
#if ZF_OSX
//On windows you get GUI events for ctrl, super, alt. On mac...you don't!
KeyCode.LeftCommand,
KeyCode.RightCommand,
KeyCode.LeftControl,
KeyCode.RightControl,
KeyCode.LeftAlt,
KeyCode.RightAlt,
//KeyCode.CapsLock, unity refuses to inform us of this, so there's not much we can do
#endif
//Unity consistently doesn't send events for shift across all platforms.
KeyCode.LeftShift,
KeyCode.RightShift,
};
public virtual void InputUpdate() {
//Note: keyEvents gets filled in OnGUI as things happen. InputUpdate get called just before it's read.
//To get the right events to the right place at the right time, swap the "double buffer" of key events.
var tmp = keyEvents;
keyEvents = keyEventsLast;
keyEventsLast = tmp;
keyEvents.Clear();
//Trace mouse from the main camera
var mouseRay = LookRay;
RaycastHit hit;
Physics.Raycast(mouseRay, out hit, maxDistance);
if (hit.transform != meshCollider.transform) {
//not looking at it.
MousePosition = new Vector3(0, 0);
MouseButtons = 0;
MouseScroll = new Vector2(0, 0);
MouseHasFocus = false;
KeyboardHasFocus = false;
LookOff();
return;
}
LookOn();
MouseHasFocus = true;
KeyboardHasFocus = true;
//convert ray hit to useful mouse position on page
var localPoint = hit.textureCoord;
MousePosition = localPoint;
var buttons = (MouseButton)0;
if (Input.GetMouseButton(0)) buttons |= MouseButton.Left;
if (Input.GetMouseButton(1)) buttons |= MouseButton.Right;
if (Input.GetMouseButton(2)) buttons |= MouseButton.Middle;
MouseButtons = buttons;
MouseScroll = Input.mouseScrollDelta;
//Unity doesn't include events for some keys, so fake it by checking each frame.
for (int i = 0; i < keysToCheck.Length; i++) {
if (Input.GetKeyDown(keysToCheck[i])) {
//Prepend down, postpend up. We don't know which happened first, but pressing
//modifiers usually precedes other key presses and releasing tends to follow.
keyEventsLast.Insert(0, new Event() {type = EventType.KeyDown, keyCode = keysToCheck[i]});
} else if (Input.GetKeyUp(keysToCheck[i])) {
keyEventsLast.Add(new Event() {type = EventType.KeyUp, keyCode = keysToCheck[i]});
}
}
}
public void OnGUI() {
var ev = Event.current;
if (ev.type != EventType.KeyDown && ev.type != EventType.KeyUp) return;
// if (ev.character != 0) Debug.Log("ev >>> " + ev.character);
// else if (ev.type == EventType.KeyUp) Debug.Log("ev ^^^ " + ev.keyCode);
// else if (ev.type == EventType.KeyDown) Debug.Log("ev vvv " + ev.keyCode);
keyEvents.Add(new Event(ev));
}
protected bool mouseWasOver = false;
protected void LookOn() {
if (BrowserCursor != null) {
CursorUpdated();
}
mouseWasOver = true;
}
protected void LookOff() {
if (BrowserCursor != null && mouseWasOver) {
SetCursor(null);
}
mouseWasOver = false;
}
protected void CursorUpdated() {
SetCursor(BrowserCursor);
}
/**
* Sets the current mouse cursor.
* If the cursor is null we are not looking at this browser.
*
* This base implementation changes the mouse cursor, but you could change an in-game reticle, etc.
*/
protected virtual void SetCursor(BrowserCursor newCursor) {
//note that HandleKeyInputBrowserCursor can change while we don't have focus.
//In such a case, don't do anything
if (!MouseHasFocus && newCursor != null) return;
if (newCursor == null) {
Cursor.visible = true;
Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
} else {
if (newCursor.Texture != null) {
Cursor.visible = true;
Cursor.SetCursor(newCursor.Texture, newCursor.Hotspot, CursorMode.Auto);
} else {
Cursor.visible = false;
Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
}
}
}
public bool MouseHasFocus { get; protected set; }
public Vector2 MousePosition { get; protected set; }
public MouseButton MouseButtons { get; protected set; }
public Vector2 MouseScroll { get; protected set; }
public bool KeyboardHasFocus { get; protected set; }
public List<Event> KeyEvents { get { return keyEventsLast; } }
public BrowserCursor BrowserCursor { get; protected set; }
public BrowserInputSettings InputSettings { get; protected set; }
}
}