forked from Shardstone/trail-into-darkness
added more utilty packges
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace InspectorToolkit {
|
||||
public class UniformVector3Attribute : PropertyAttribute {
|
||||
public UniformVector3Attribute() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace InspectorToolkit.Internal {
|
||||
[CustomPropertyDrawer(typeof(UniformVector3Attribute))]
|
||||
public class UniformVector3AttributeDrawer : PropertyDrawer {
|
||||
|
||||
private GUIContent linkedIconContent;
|
||||
private GUIContent unlinkedIconContent;
|
||||
private GUIStyle linkButtonStyle;
|
||||
|
||||
private const int CHILD_COUNT = 3;
|
||||
private const float LABEL_WIDTH = 13f;
|
||||
private const float COMBINED_LABEL_WIDTH = 26f;
|
||||
private const float INDENT_WIDTH = 15f;
|
||||
private const float CHILD_HORIZONTAL_SPACING = 4f;
|
||||
private static readonly string[] childPropertyNames = new string[] { "x", "y", "z" };
|
||||
private static bool IsCompactLayout => Screen.width <= 333f;
|
||||
private static bool IsNoLabelLayout => Screen.width <= 240f;
|
||||
|
||||
private enum LinkState {
|
||||
Unknown,
|
||||
Linked,
|
||||
Unlinked
|
||||
}
|
||||
|
||||
private LinkState linkState = LinkState.Unknown;
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
|
||||
if(IsCompactLayout) { // Unity Vector2 + Vector3 go multi-line at this point
|
||||
return EditorGUIUtility.singleLineHeight * 2f + EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
return EditorGUIUtility.singleLineHeight;
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
|
||||
if(property.propertyType != SerializedPropertyType.Vector3) {
|
||||
GUI.Label(position, "Error, SerializedProperty must be 'Vector3' type");
|
||||
return;
|
||||
}
|
||||
|
||||
if(linkedIconContent == null || unlinkedIconContent == null || linkButtonStyle == null) {
|
||||
linkedIconContent = EditorGUIUtility.IconContent(EditorGUIUtility.isProSkin ? "d_Linked" : "Linked");
|
||||
unlinkedIconContent = EditorGUIUtility.IconContent(EditorGUIUtility.isProSkin ? "d_Unlinked" : "Unlinked");
|
||||
linkButtonStyle = new GUIStyle(GUI.skin.button);
|
||||
linkButtonStyle.padding = new RectOffset(1, 1, 0, 0);
|
||||
linkButtonStyle.imagePosition = ImagePosition.ImageOnly;
|
||||
}
|
||||
|
||||
if(linkState == LinkState.Unknown) {
|
||||
linkState = GetLinkState(property);
|
||||
}
|
||||
|
||||
EditorGUI.BeginProperty(position, label, property);
|
||||
|
||||
if(IsCompactLayout) {
|
||||
EditorGUIUtility.labelWidth = position.width;
|
||||
}
|
||||
Rect labelRect = new Rect(position) { height = EditorGUIUtility.singleLineHeight };
|
||||
Rect fieldRect = EditorGUI.PrefixLabel(labelRect, label);
|
||||
fieldRect.height = EditorGUIUtility.singleLineHeight;
|
||||
|
||||
float height = Mathf.Min(20f, position.height) - 2f;
|
||||
Rect buttonRect = new Rect(fieldRect);
|
||||
buttonRect.width = 18f;
|
||||
buttonRect.height = height;
|
||||
buttonRect.y += 1f;
|
||||
buttonRect.x -= buttonRect.width + 2f;
|
||||
|
||||
if(GUI.Button(buttonRect, linkState == LinkState.Linked ? linkedIconContent : unlinkedIconContent, linkButtonStyle)) {
|
||||
linkState = linkState == LinkState.Linked ? LinkState.Unlinked : LinkState.Linked;
|
||||
}
|
||||
|
||||
if(IsCompactLayout) {
|
||||
fieldRect.y = labelRect.yMax + EditorGUIUtility.standardVerticalSpacing;
|
||||
fieldRect.x = labelRect.x + (IsNoLabelLayout ? 0f : INDENT_WIDTH); // 15 = single indent
|
||||
fieldRect.width = position.xMax - fieldRect.xMin;
|
||||
}
|
||||
|
||||
|
||||
if(linkState == LinkState.Linked) {
|
||||
EditorGUIUtility.labelWidth = IsNoLabelLayout ? 0.01f : COMBINED_LABEL_WIDTH;
|
||||
SerializedProperty childProperty = property.FindPropertyRelative(childPropertyNames[0]);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
float newValue = EditorGUI.FloatField(fieldRect, "XYZ", childProperty.floatValue);
|
||||
if(EditorGUI.EndChangeCheck()) {
|
||||
for(int i = 0; i < CHILD_COUNT; i++) {
|
||||
SerializedProperty otherChildProperty = property.FindPropertyRelative(childPropertyNames[i]);
|
||||
otherChildProperty.floatValue = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
EditorGUIUtility.labelWidth = IsNoLabelLayout ? 0.01f : LABEL_WIDTH;
|
||||
float childSpacing = IsNoLabelLayout ? CHILD_HORIZONTAL_SPACING / 2f : CHILD_HORIZONTAL_SPACING;
|
||||
float childWidth = ((fieldRect.width + childSpacing) / CHILD_COUNT) - childSpacing;
|
||||
|
||||
for(int i = 0; i < CHILD_COUNT; i++) {
|
||||
SerializedProperty childProperty = property.FindPropertyRelative(childPropertyNames[i]);
|
||||
Rect childRect = new Rect(fieldRect);
|
||||
childRect.width = childWidth; // add spacing
|
||||
childRect.x += i * (childWidth + childSpacing);
|
||||
EditorGUI.PropertyField(childRect, childProperty);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
|
||||
private LinkState GetLinkState(SerializedProperty property) {
|
||||
float value0 = property.FindPropertyRelative(childPropertyNames[0]).floatValue;
|
||||
for(int i = 1; i < CHILD_COUNT; i++) {
|
||||
SerializedProperty childProperty = property.FindPropertyRelative(childPropertyNames[i]);
|
||||
if(Mathf.Approximately(value0, childProperty.floatValue) == false) {
|
||||
return LinkState.Unlinked;
|
||||
}
|
||||
}
|
||||
return LinkState.Linked;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user