Skip to content

Instantly share code, notes, and snippets.

@h-sigma
Last active June 7, 2020 19:30
Show Gist options
  • Save h-sigma/60410fcda7cb4f10f6124767ad8ec596 to your computer and use it in GitHub Desktop.
Save h-sigma/60410fcda7cb4f10f6124767ad8ec596 to your computer and use it in GitHub Desktop.
An attribute in Unity to display radians, vectors, and quaternions in the form of human-readable Euler angles in the Editor.
using UnityEngine;
namespace Utility
{
public class DisplayAsEulerAttribute : PropertyAttribute
{
public float min;
public float max;
public DisplayAsEulerAttribute(float min = 0, float max = 359.9999f)
{
this.min = min;
this.max = max;
}
}
}
using UnityEditor;
using UnityEngine;
namespace Utility
{
[CustomPropertyDrawer(typeof(DisplayAsEulerAttribute))]
public class DisplayAsEulerDrawer : PropertyDrawer
{
private DisplayAsEulerAttribute attr;
private float angle = 0.0f;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
angle = GetAngle(property);
attr = attribute as DisplayAsEulerAttribute;
if (attr == null) return;
angle = Mathf.Clamp(angle, attr.min, attr.max);
Rect r = new Rect(position);
EditorGUI.BeginChangeCheck();
angle = EditorGUI.Slider(r, property.displayName, angle, attr.min, attr.max);
angle = Mathf.Clamp(angle, attr.min, attr.max);
if (EditorGUI.EndChangeCheck())
{
SetAngle(property, angle);
}
}
/*
* Float -> Radians
* Vector2 -> Vector about Z-axis
* Vector3 -> Vector with Z-rotation 0
* Quaternion -> Quaternion.Euler(0, 0, angle) => needs rework, should display 3 angles
*/
private float GetAngle(SerializedProperty property)
{
switch (property.propertyType)
{
case SerializedPropertyType.Float:
return property.floatValue * Mathf.Rad2Deg;
case SerializedPropertyType.Vector2:
var angle2 = Mathf.Atan2(property.vector2Value.y, property.vector2Value.x);
if (angle2 < 0f)
angle2 += 2 * Mathf.PI;
return angle2 * Mathf.Rad2Deg;
case SerializedPropertyType.Vector3:
var angle3 = Mathf.Atan2(property.vector3Value.y, property.vector3Value.x);
if (angle3 < 0f)
angle3 += 2 * Mathf.PI;
return angle3 * Mathf.Rad2Deg;
case SerializedPropertyType.Quaternion:
return property.quaternionValue.eulerAngles.z;
default:
Debug.Log("DisplayAsEuler attribute set on incompatible field.");
return 0.0f;
}
}
public void SetAngle(SerializedProperty property, float angle)
{
if (!property.editable) return;
switch (property.propertyType)
{
case SerializedPropertyType.Float:
property.floatValue = angle * Mathf.Deg2Rad;
break;
case SerializedPropertyType.Vector2:
angle *= Mathf.Deg2Rad;
property.vector2Value = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
break;
case SerializedPropertyType.Vector3:
angle *= Mathf.Deg2Rad;
property.vector3Value = new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0.0f);
break;
case SerializedPropertyType.Quaternion:
property.quaternionValue = Quaternion.Euler(0, 0, angle);
break;
default:
Debug.Log("DisplayAsAngle attribute set on incompatible field.");
break;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment