Skip to content

Instantly share code, notes, and snippets.

@soraphis
Last active January 5, 2019 13:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save soraphis/c15fb8f2047c0c089b8042baf592ab75 to your computer and use it in GitHub Desktop.
Save soraphis/c15fb8f2047c0c089b8042baf592ab75 to your computer and use it in GitHub Desktop.
Unity3D more Complex Input. Differentiate between UI clicks and world clicks, check if mouse is dragging
using System.Linq;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Experimental.LowLevel;
using UnityEngine.Experimental.PlayerLoop;
using UInput = UnityEngine.Input;
public static class CInput {
[RuntimeInitializeOnLoadMethod]
private static void init() {
/// attaching this class's Update method to the PreUpdate Loop (were 'NewInputUpdate' and 'SendMouseEvents' are)
/// so this class does not need to be a monobehaviour it'll work out of the box
/// note: those classes are experimental and may change in the future.
var defaultSystems = PlayerLoop.GetDefaultPlayerLoop();
var index = defaultSystems.subSystemList.ToList().FindIndex(0, s => s.type == typeof(PreUpdate));
var updateSubSystem = defaultSystems.subSystemList[index];
var list = updateSubSystem.subSystemList.ToList();
list.Add(new PlayerLoopSystem() {
updateDelegate = Update,
type = typeof(CInput)
});
updateSubSystem.subSystemList = list.ToArray();
defaultSystems.subSystemList[index] = updateSubSystem;
PlayerLoop.SetPlayerLoop(defaultSystems);
}
private static Vector3 lastMousePosition;
private static Vector3 dragDelta;
private static void Update() {
if (Input.GetMouseButtonDown(0)) {
lastMousePosition = Input.mousePosition;
dragDelta = Vector3.zero;
}
if (Input.GetMouseButton(0)) {
dragDelta += Input.mousePosition - lastMousePosition;
lastMousePosition = Input.mousePosition;
}
}
public static bool IsDraging() {
if (!Input.GetMouseButton(0) && !Input.GetMouseButtonUp(0)) return false;
return Vector3.SqrMagnitude(dragDelta) > 9;
}
public static bool IsUIInput() { return (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject()); }
public static bool GetMouseButtonUI(int index) {
return IsUIInput() && UInput.GetMouseButton(index);
}
public static bool GetMouseButtonWorld(int index) {
return !IsUIInput() && UInput.GetMouseButton(index);
}
public static bool GetMouseButtonUpWorld(int index) {
return !IsUIInput() && UInput.GetMouseButtonUp(index);
}
public static bool GetMouseButtonDownWorld(int index) {
return !IsUIInput() && UInput.GetMouseButtonDown(index);
}
}
@soraphis
Copy link
Author

soraphis commented Jan 5, 2019

Example usage:

have a game object which should be "selectable", so you want to check if it was clicked but not dragged - also it should not be behind a UI window:

[RequireComponent(typeof(Collider))]
public class SelectController : MonoBehaviour {
	private bool clicked = false;
	private void OnMouseDown() { clicked = true; }
	private void OnMouseUp() {
		if(!clicked || CInput.IsUIInput() || CInput.IsDraging()) return;

		// do something
	}
}

private void Update() { // or LateUpdate
	if(! CInput.GetMouseButtonWorld(0)) clicked = false;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment