TL;DR: How do I implement Unity's 'color from screen' functionality but with vectors?
Ok so title is pretty simplified for what I'm trying to do:
Have the user click a button, then click a position on the screen to have that [world] position be saved as the vector. - This is mostly working, except it won't detect left clicks outside of the inspector.
Disable left click for everything else on the unity editor (so when you click a position it doesn't change focus to another GameObject). - This is the main problem.
Tracking the mouse and getting the world position was pretty easy, it's just a bool to save if the mouse is being tracked and a SerializedProperty to save which value the mouse position is being saved to.
Here's what my attribute looks like:
public class VectorPickerAttribute : PropertyAttribute {
readonly bool relative;
/// <summary>
/// Works a lot like the color picker, except for vectors.
/// </summary>
/// <param name="relative">Make the final vector relative to the transform?</param>
public VectorPickerAttribute(bool relative = false) {
this.relative = relative;
}
}
Here is the PropertyDrawer:
[CustomPropertyDrawer(typeof(VectorPickerAttribute))]
public class VectorPickerDrawer : PropertyDrawer {
bool trackMouse = false;
SerializedProperty v;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
if(property.propertyType == SerializedPropertyType.Vector2) {
Rect button = new Rect(position);
button.x = position.width - 2;
button.width = position.height;
bool pressed = GUI.Button(button, "");
if(pressed) {
trackMouse = true;
v = property;
}
else if(Input.GetMouseButtonDown(0)) trackMouse = false;
bool tracking = trackMouse && v.propertyPath == property.propertyPath;
if(tracking) {
property.vector2Value =
Camera.main.ScreenToWorldPoint(
GUIUtility.GUIToScreenPoint(
Event.current.mousePosition
));
}
GUI.enabled = !tracking;
EditorGUI.Vector2Field(position, label.text, property.vector2Value);
GUI.enabled = true;
EditorUtility.SetDirty(property.serializedObject.targetObject);
}
}
}
And here's what it does so far:
You click the button on the right, and it will update the vector to the mouse position until it detects a left click with Input.GetMouseButtonDown(0).
Problems with this:
It will only detect a click when it's actually on the inspector window.
When you click outside the inspector window it will either not change anything or it will select something else so it will close the inspector (but since it saves the mouse position every
OnGUI()that point where you clicked will be saved to the vector, so I guess it works??).
I've tried covering the screen with a blank window, but I couldn't get GUI.Window or GUI.ModalWindow to do anything in the PropertyDrawer. I've also tried using GUI.UnfocusWindow(), but either it doesn't work in PropertyDrawer or it's only meant for Unity's windows or something.

