using System; using System.Collections.Generic; using UnityEngine; namespace Cryville.Input.Unity { /// /// An that handles Unity GUI input. /// /// The GUI event receiver type. public class UnityGuiInputHandler : InputHandler where T : UnityGuiEventReceiver { readonly GameObject _receiver; readonly T _recvComp; /// /// Creates an instance of the class. /// public UnityGuiInputHandler() { _receiver = new GameObject("__guiRecv__"); _recvComp = _receiver.AddComponent(); _recvComp.SetFeedCallback(Feed); _recvComp.SetBatchCallback(Batch); } /// protected override void Activate() { _recvComp.enabled = true; } /// protected override void Deactivate() { if (_recvComp) _recvComp.enabled = false; } /// public override void Dispose(bool disposing) { if (disposing) { Deactivate(); } } /// public override bool IsNullable { get { return true; } } /// public override byte Dimension { get { return 0; } } static readonly ReferenceCue _refCue = new ReferenceCue { }; /// public override ReferenceCue ReferenceCue => _refCue; /// public override string GetTypeName(int type) { return _recvComp.GetKeyName(type); } /// public override double GetCurrentTimestamp() { return Time.realtimeSinceStartupAsDouble; } } /// /// Unity GUI event receiver. /// public abstract class UnityGuiEventReceiver : MonoBehaviour { /// /// The callback function to be called when a new input frame is received. /// protected Action Feed; /// /// Sets the callback function to be called when a new input frame is received. /// /// The callback function to be called when a new input frame is received. public void SetFeedCallback(Action h) { Feed = h; } /// /// The callback function to be called when the current input batch is finished receiving. /// protected Action Batch; /// /// Sets the callback function to be called when the current input batch is finished receiving. /// /// The callback function to be called when the current input batch is finished receiving. public void SetBatchCallback(Action h) { Batch = h; } /// /// The set of currently active keys. /// protected readonly HashSet ActiveKeys = new HashSet(); /// /// Gets the friendly name of the specified key. /// /// The key. /// The friendly name of the specified key. public abstract string GetKeyName(int key); void Awake() { useGUILayout = false; } void Update() { Batch(Time.realtimeSinceStartupAsDouble); } } public class UnityKeyReceiver : UnityGuiEventReceiver { /// public override string GetKeyName(int type) { return Enum.GetName(typeof(KeyCode), type); } void OnGUI() { var e = Event.current; if (e.keyCode == KeyCode.None) return; double time = Time.realtimeSinceStartupAsDouble; var key = (int)e.keyCode; switch (e.type) { case EventType.KeyDown: if (!ActiveKeys.Contains(key)) { Feed(key, 0, new InputFrame(time, new InputVector())); ActiveKeys.Add(key); } break; case EventType.KeyUp: ActiveKeys.Remove(key); Feed(key, 0, new InputFrame(time)); break; } } } public class UnityMouseReceiver : UnityGuiEventReceiver { /// public override string GetKeyName(int type) { switch (type) { case 0: return "Mouse Left Button"; case 1: return "Mouse Right Button"; case 2: return "Mouse Middle Button"; default: return string.Format("Mouse Button {0}", type); } } void OnGUI() { var e = Event.current; double time = Time.realtimeSinceStartupAsDouble; var key = e.button; switch (e.type) { case EventType.MouseDown: if (!ActiveKeys.Contains(key)) { Feed(key, 0, new InputFrame(time, new InputVector())); ActiveKeys.Add(key); } break; case EventType.MouseUp: ActiveKeys.Remove(key); Feed(key, 0, new InputFrame(time)); break; } } } }