Skip to content

Instantly share code, notes, and snippets.

@Alexander-van-der-Zalm
Created August 9, 2018 19:26
Show Gist options
  • Select an option

  • Save Alexander-van-der-Zalm/fa08cc0400d68950fc08fa09ed232ed0 to your computer and use it in GitHub Desktop.

Select an option

Save Alexander-van-der-Zalm/fa08cc0400d68950fc08fa09ed232ed0 to your computer and use it in GitHub Desktop.
OneLineFields - Easily display all the fields of one class or struct with the [OneLineFields] property. Contains options for formatting and making it read only.
using System.Collections;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
/*
Usage:
[OneLineFields]
public MyClass/MyStruct myVar;
Optionally assign a weight per variable to alter display space.
[OneLineFields(new float[]{1,2,0.5f})]
public MyClass/MyStruct myVar;
Weight Parameter Options:
positive to show [OneLineFields(new float[]{1,2,0.5f})]
0 to not show [OneLineFields(new float[]{1,2,0f})] // hides the bool
negative to make it readonly [OneLineFields(new float[]{1,-2,1})] // makes the int editor read only
public MyClass
{
public int A;
public int B;
public bool C;
}
*/
public class OneLineFieldsAttribute : PropertyAttribute
{
public float[] memberSizeWeights;
public OneLineFieldsAttribute()
{
memberSizeWeights = new float[0];
}
public OneLineFieldsAttribute(float[] memberSizeWeights)
{
this.memberSizeWeights = memberSizeWeights;
}
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(OneLineFieldsAttribute))]
public class OneLineFieldAttributePropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
OneLineFieldsAttribute oneline = attribute as OneLineFieldsAttribute;
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
var indent = EditorGUI.indentLevel; // Start fields prep
EditorGUI.indentLevel = 0;
int memberAmount = Mathf.Max(1, property.GetMemberCount());
float totalWidthWeights = 0;
for (int i = 0; i < memberAmount; i++) // Sum up all the weights (undifined = 1)
{
if(i < oneline.memberSizeWeights.Length)
totalWidthWeights += Mathf.Max(0,Mathf.Abs(oneline.memberSizeWeights[i]));
else
totalWidthWeights += 1;
}
totalWidthWeights = Mathf.Max(totalWidthWeights, 0.00000001f); // prevent division by 0
float widthPart = position.width / totalWidthWeights; // total width = totalweights * widthPart
int j = 0;
property.IterateFieldsSmart(x =>
{
// Find current width
float currentWidthWeight = j < oneline.memberSizeWeights.Length ? oneline.memberSizeWeights[j] : 1;
// Negative numbers make it readonly
bool readOnly = currentWidthWeight < 0;
currentWidthWeight = Mathf.Abs(currentWidthWeight);
if (currentWidthWeight > 0)
{
position.width = widthPart * currentWidthWeight;
if(readOnly) GUI.enabled = false;
EditorGUI.PropertyField(position, x, GUIContent.none, false);
GUI.enabled = true;
position.x += position.width;
}
j++;
});
EditorGUI.indentLevel = indent;
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment