Last active
April 21, 2023 02:13
-
-
Save EmreDogann/d8c0d146a17321baa016d84baffef458 to your computer and use it in GitHub Desktop.
A small Unity Property Attribute I made which aims to modify the rendering of a Vector3 field to only allow the input of an orthogonal unit direction vector.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // This file should go inside a normal directory (i.e. not /Editor) somewhere in your project. | |
| using System; | |
| using UnityEngine; | |
| [AttributeUsage(AttributeTargets.Field, AllowMultiple = true)] | |
| public class OrthogonalUnitVector3Attribute : PropertyAttribute {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // This file should go inside a /Editor directory somewhere in your project. | |
| using UnityEditor; | |
| using UnityEngine; | |
| [CustomPropertyDrawer(typeof(OrthogonalUnitVector3Attribute))] [CanEditMultipleObjects] | |
| public class OrthogonalUnitVector3Drawer : PropertyDrawer | |
| { | |
| private readonly string[] _enumNames = { "X", "Y", "Z" }; | |
| private int _axis; | |
| private bool _invert; | |
| public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |
| { | |
| // Get existing axis value. | |
| if (property.vector3Value.x != 0) | |
| { | |
| _axis = 0; | |
| _invert = !(property.vector3Value.x > 0); | |
| } | |
| else if (property.vector3Value.y != 0) | |
| { | |
| _axis = 1; | |
| _invert = !(property.vector3Value.y > 0); | |
| } | |
| else | |
| { | |
| _axis = 2; | |
| _invert = !(property.vector3Value.z > 0); | |
| } | |
| Rect initialRect = position; | |
| position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); | |
| // Wrap property drawer fields to new line if screen size is too small. | |
| if (Screen.width < 332) | |
| { | |
| position.x = initialRect.xMin; | |
| position.y += EditorGUIUtility.singleLineHeight; | |
| position.width = initialRect.width; | |
| position.height = EditorGUIUtility.singleLineHeight; | |
| EditorGUI.indentLevel = 1; | |
| position = EditorGUI.IndentedRect(position); | |
| } | |
| EditorGUI.indentLevel = 0; | |
| Rect column = new Rect(position.x, position.y, position.width / 3, position.height); | |
| Rect axisRect = new Rect(column.x, column.y, column.width / 4, column.height); | |
| Rect invertRect = new Rect(column.xMax, column.y, column.width / 4 * 3, column.height); | |
| Rect vector3Rect = new Rect(column.xMax + 2, column.y, position.width / 3 * 2 - 2, position.height); | |
| EditorGUI.BeginChangeCheck(); | |
| int chosenAxis = EditorGUI.Popup(axisRect, _axis, _enumNames, EditorStyles.miniButton); | |
| GUIContent toggleLabel = new GUIContent("Invert"); | |
| float labelWidth = EditorGUIUtility.labelWidth; | |
| EditorGUIUtility.labelWidth = EditorStyles.label.CalcSize(toggleLabel).x + 2; | |
| invertRect.x -= EditorStyles.toggle.CalcSize(toggleLabel).x + EditorStyles.toggle.margin.right + | |
| EditorStyles.toggle.margin.left; | |
| bool chosenInvert = EditorGUI.Toggle(invertRect, toggleLabel, _invert, EditorStyles.toggle); | |
| EditorGUIUtility.labelWidth = labelWidth; | |
| if (EditorGUI.EndChangeCheck()) | |
| { | |
| _axis = chosenAxis; | |
| _invert = chosenInvert; | |
| if (chosenInvert) SetVectorComponent(property, _enumNames[_axis], -1.0f); | |
| else SetVectorComponent(property, _enumNames[_axis], 1.0f); | |
| } | |
| GUI.enabled = false; | |
| EditorGUI.Vector3Field(vector3Rect, "", property.vector3Value); | |
| GUI.enabled = true; | |
| } | |
| public override float GetPropertyHeight(SerializedProperty property, GUIContent label) | |
| { | |
| return Screen.width < 332 ? EditorGUIUtility.singleLineHeight * 2 : EditorGUIUtility.singleLineHeight; | |
| } | |
| private void SetVectorComponent(SerializedProperty property, string componentName, float invert) | |
| { | |
| if (componentName == "X") property.vector3Value = Vector3.right * invert; | |
| else if (componentName == "Y") property.vector3Value = Vector3.up * invert; | |
| else property.vector3Value = Vector3.forward * invert; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // You might also have to import the OrthogonalUnitVector3Attribute.cs file depending on where you put it... | |
| using UnityEngine; | |
| public class Example : MonoBehaviour | |
| { | |
| [OrthogonalUnitVector3] public Vector3 axis = Vector3.forward; | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Screenshot of UsageExample.cs in Inspector:
