Skip to content

Instantly share code, notes, and snippets.

@majstudio
Created January 26, 2018 04:50
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save majstudio/6c96cb80d301f0563716d1bbaa60c330 to your computer and use it in GitHub Desktop.
Save majstudio/6c96cb80d301f0563716d1bbaa60c330 to your computer and use it in GitHub Desktop.
Fancy Vector3 Range in Unity Inspector
using UnitEngine;
public class Example : MonoBehaviour
{
//As easy as this !
//You can adjust the slider limits in the inspector as well
public Vector3Range v3Range;
//...
}
using UnityEngine;
[System.Serializable]
public class Vector3Range
{
public Vector3 min;
public Vector3 max;
//For slider limits (Dont touch)
[SerializeField]
private float minWindow;
[SerializeField]
private float maxWindow;
public Vector3Range(Vector3 min, Vector3 max)
{
this.min = min;
this.max = max;
}
public Vector3 Lerp(float t)
{
return Vector3.Lerp(min, max, t);
}
public Vector3 RandomNumberInRange()
{
return Extensions.RandomRangeVector(min, max);
}
public void Invert()
{
Vector3 temp = this.max;
this.max = this.min;
this.min = temp;
}
//You can add more functions of your own
}
using UnityEngine;
using System.Collections;
using UnityEditor;
//PLACE THIS SCRIPT IN EDITOR FOLDER ***
[CustomPropertyDrawer(typeof(Vector3Range), true)]
public class Vector3RangeDrawer : PropertyDrawer
{
Color neutral;
Vector3 rangeMin = Vector3.zero;
Vector3 rangeMax = Vector3.one;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
neutral = GUI.color;
label = EditorGUI.BeginProperty(position, label, property);
rangeMin.x = property.FindPropertyRelative("minWindow").floatValue;
rangeMax.x = property.FindPropertyRelative("maxWindow").floatValue;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel(label);
rangeMin = Vector3.one * EditorGUILayout.DelayedFloatField(rangeMin.x, GUILayout.MaxWidth(40));
EditorGUILayout.LabelField(" - ", GUILayout.MaxWidth(20));
rangeMax = Vector3.one * EditorGUILayout.DelayedFloatField(rangeMax.x, GUILayout.MaxWidth(40));
EditorGUILayout.EndHorizontal();
property.FindPropertyRelative("minWindow").floatValue = rangeMin.x;
property.FindPropertyRelative("maxWindow").floatValue = rangeMax.x;
SerializedProperty minProp = property.FindPropertyRelative("min");
SerializedProperty maxProp = property.FindPropertyRelative("max");
Vector3 minValue = minProp.vector3Value;
Vector3 maxValue = maxProp.vector3Value;
EditorGUILayout.BeginVertical();
EditorGUILayout.BeginHorizontal();
//X
GUIStyle guis = new GUIStyle();
guis.alignment = TextAnchor.MiddleRight;
guis.fontStyle = FontStyle.Bold;
EditorGUILayout.LabelField("X", guis, GUILayout.MaxWidth(30));
GUI.backgroundColor = Extensions.HexToColor("#fc9494");
minProp.vector3Value = new Vector3(EditorGUILayout.FloatField(minProp.vector3Value.x, GUILayout.MaxWidth(60)), minProp.vector3Value.y, minProp.vector3Value.z);
GUI.color = neutral;
EditorGUI.BeginChangeCheck();
GUI.color = Extensions.HexToColor("#ff3d3d");
EditorGUILayout.MinMaxSlider(ref minValue.x, ref maxValue.x, rangeMin.x, rangeMax.x);
GUI.color = neutral;
if (EditorGUI.EndChangeCheck())
{
minProp.vector3Value = new Vector3(minValue.x, minProp.vector3Value.y, minProp.vector3Value.z);
maxProp.vector3Value = new Vector3(maxValue.x, maxProp.vector3Value.y, maxProp.vector3Value.z);
}
GUI.backgroundColor = Extensions.HexToColor("#fc9494");
maxProp.vector3Value = new Vector3(EditorGUILayout.FloatField(maxProp.vector3Value.x, GUILayout.MaxWidth(60)), maxProp.vector3Value.y, maxProp.vector3Value.z);
GUI.color = neutral;
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
//Y
EditorGUILayout.LabelField("Y", guis, GUILayout.MaxWidth(30));
GUI.backgroundColor = Extensions.HexToColor("#dcff8e");
minProp.vector3Value = new Vector3(minProp.vector3Value.x, EditorGUILayout.FloatField(minProp.vector3Value.y, GUILayout.MaxWidth(60)), minProp.vector3Value.z);
GUI.color = neutral;
EditorGUI.BeginChangeCheck();
GUI.color = Extensions.HexToColor("#b0ff00");
EditorGUILayout.MinMaxSlider(ref minValue.y, ref maxValue.y, rangeMin.y, rangeMax.y);
GUI.color = neutral;
if (EditorGUI.EndChangeCheck())
{
minProp.vector3Value = new Vector3(minProp.vector3Value.x, minValue.y, minProp.vector3Value.z);
maxProp.vector3Value = new Vector3(maxProp.vector3Value.x, maxValue.y, maxProp.vector3Value.z);
}
GUI.backgroundColor = Extensions.HexToColor("#dcff8e");
maxProp.vector3Value = new Vector3(maxProp.vector3Value.x, EditorGUILayout.FloatField(maxProp.vector3Value.y, GUILayout.MaxWidth(60)), maxProp.vector3Value.z);
GUI.color = neutral;
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
//Z
EditorGUILayout.LabelField("Z", guis, GUILayout.MaxWidth(30));
GUI.backgroundColor = Extensions.HexToColor("#7a97ff");
minProp.vector3Value = new Vector3(minProp.vector3Value.x, minProp.vector3Value.y, EditorGUILayout.FloatField(minProp.vector3Value.z, GUILayout.MaxWidth(60)));
GUI.color = neutral;
EditorGUI.BeginChangeCheck();
GUI.color = Extensions.HexToColor("#3d67ff");
EditorGUILayout.MinMaxSlider(ref minValue.z, ref maxValue.z, rangeMin.z, rangeMax.z);
GUI.color = neutral;
if (EditorGUI.EndChangeCheck())
{
minProp.vector3Value = new Vector3(minProp.vector3Value.x, minProp.vector3Value.y, minValue.z);
maxProp.vector3Value = new Vector3(maxProp.vector3Value.x, maxProp.vector3Value.y, maxValue.z);
}
GUI.backgroundColor = Extensions.HexToColor("#7a97ff");
maxProp.vector3Value = new Vector3(maxProp.vector3Value.x, maxProp.vector3Value.y, EditorGUILayout.FloatField(maxProp.vector3Value.z, GUILayout.MaxWidth(60)));
GUI.color = neutral;
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
EditorGUI.EndProperty();
}
}
//MISC, DON'T CARE ABOUT
public class Vector3RangeMisc : MonoBehaviour
{
Vector3Range v3r;
}
[CustomEditor(typeof(Vector3Range))]
public class Vector3RangeEditorMisc : Editor
{
}
@majstudio
Copy link
Author

image

@shahilsaha05uk
Copy link

hey there!! I have come across these scripts of yours while searching for something similar I needed for my project and wanted to implement it... But I couldnt figure out what the Extensions is all about... coz its throwing me errors.

Thanks

@majstudio
Copy link
Author

majstudio commented Mar 29, 2023

Hi ! Wow it's been a while but I confirm it still works with newer version of Unity.
Here is the code for the utility function HexToColor :

public static Color HexToColor(string hex)
{
    Color c = Color.black;
    ColorUtility.TryParseHtmlString(hex, out c);
    return c;
}

You can put it in a static class named Extensions or wherever you want to call it.

Enjoy :)

@shahilsaha05uk
Copy link

Hi!! Thanks for the quick reply...
There is another function in the Extension class:
Extensions.RandomRangeVector(min, max);
😅

@majstudio
Copy link
Author

Here it is :

    public static Vector3 RandomRangeVector(Vector3 min, Vector3 max)
    {
        return new Vector3(UnityEngine.Random.Range(min.x, max.x), UnityEngine.Random.Range(min.y, max.y), UnityEngine.Random.Range(min.z, max.z));
    }

@shahilsaha05uk
Copy link

shahilsaha05uk commented Mar 29, 2023

I managed to eliminate all the errors in the script but when applying the script on a gameobject, I am getting the following exceptions and the variable doesnt show up in the inspector

Unity Version: 2021.2.20f1

ArgumentException: Getting control 1's position in a group with only 1 controls when doing repaint Aborting UnityEngine.GUILayoutGroup.GetNext () (at <2880c19c3b344d8cb20d5ad03e3efbe5>:0) UnityEngine.GUILayoutUtility.BeginLayoutGroup (UnityEngine.GUIStyle style, UnityEngine.GUILayoutOption[] options, System.Type layoutType) (at <2880c19c3b344d8cb20d5ad03e3efbe5>:0) UnityEditor.EditorGUILayout.BeginHorizontal (UnityEngine.GUIContent content, UnityEngine.GUIStyle style, UnityEngine.GUILayoutOption[] options) (at <6e08e61cfda04255b3972ba7f0515fae>:0) UnityEditor.EditorGUILayout.BeginHorizontal (UnityEngine.GUILayoutOption[] options) (at <6e08e61cfda04255b3972ba7f0515fae>:0) Vector3RangeDrawer.OnGUI (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at Assets/Scripts/Editor_Scripts/Vector3RangeDrawer.cs:23) UnityEditor.PropertyDrawer.OnGUISafe (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at <6e08e61cfda04255b3972ba7f0515fae>:0) UnityEditor.PropertyHandler.OnGUI (UnityEngine.Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, System.Boolean includeChildren, UnityEngine.Rect visibleArea) (at <6e08e61cfda04255b3972ba7f0515fae>:0) UnityEditor.GenericInspector.OnOptimizedInspectorGUI (UnityEngine.Rect contentRect) (at <6e08e61cfda04255b3972ba7f0515fae>:0) UnityEditor.UIElements.InspectorElement+<>c__DisplayClass59_0.<CreateIMGUIInspectorFromEditor>b__0 () (at <0b6946f339094457a3044596a1876af8>:0) UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)

@majstudio
Copy link
Author

Hey did you put Vector3RangeDrawer.cs in Editor folder ?
What version of Unity are you using ?

This script should not be directly applied to GameObject, it is a new variable type you can put inside other MonoBehaviour C# scripts.
See example file above (first file).

@shahilsaha05uk
Copy link

shahilsaha05uk commented Mar 29, 2023

Yes the Drawer class was put inside the editor folder

the unity version: 2021.2.20f1

Yeah, I have created a variable of this data type and tried it... but didnt work.. I thought I was missing out something so I directly added the example script on a gameobject but still getting this error😶
Screenshot 2023-03-29 162804

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