private var _worldVelocity : Vector3;
public function get worldVelocity () : Vector3 { return _worldVelocity; }
private function set worldVelocity (value : Vector3) { _worldVelocity = value;
This is the end-all answer - it will allow you to mark -any- field as readonly with a single property attribute / property drawer. It’s partially based on scottmontgomerie’s answer. This version also dispatches the property height based on how “expanded” the property is.
public class ReadOnlyAttribute : PropertyAttribute
{
}
[CustomPropertyDrawer(typeof(ReadOnlyAttribute))]
public class ReadOnlyDrawer : PropertyDrawer
{
public override float GetPropertyHeight(SerializedProperty property,
GUIContent label)
{
return EditorGUI.GetPropertyHeight(property, label, true);
}
public override void OnGUI(Rect position,
SerializedProperty property,
GUIContent label)
{
GUI.enabled = false;
EditorGUI.PropertyField(position, property, label, true);
GUI.enabled = true;
}
}
public class Test
{
[ReadOnly] public string a;
[ReadOnly] public int b;
[ReadOnly] public Material c;
[ReadOnly] public List<int> d = new List<int>();
}
Works like a charm.
Just tried this code - works great: [33206-showonlypropertydrawer.png|33206] And you dont need to override GetPropertyHeight - just remove it and code will be simpler.
using UnityEngine;
public class ShowOnlyAttribute : PropertyAttribute
{
}
Assets/Editor/ShowOnlyDrawer:
using UnityEditor;
using UnityEngine;
[CustomPropertyDrawer(typeof(ShowOnlyAttribute))]
public class ShowOnlyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label)
{
string valueStr;
switch (prop.propertyType)
{
case SerializedPropertyType.Integer:
valueStr = prop.intValue.ToString();
break;
case SerializedPropertyType.Boolean:
valueStr = prop.boolValue.ToString();
break;
case SerializedPropertyType.Float:
valueStr = prop.floatValue.ToString("0.00000");
break;
case SerializedPropertyType.String:
valueStr = prop.stringValue;
break;
default:
valueStr = "(not supported)";
break;
}
EditorGUI.LabelField(position,label.text, valueStr);
}
}
Use in your object:
public class MyClass : MonoBehaviour
{
[ShowOnly] public float aaa = 123.45678f;
[ShowOnly] public int bbb = 234;
[ShowOnly] public bool ccc = false;
[ShowOnly] [SerializeField] bool ddd = true;
}
You will get this:
This worked for me, thanks! It only works for ints, bools, floats, and strings tho. If anyone needs this code for enumerators, insert these lines into "ShowOnlyDrawer.cs", just before "default:": case SerializedPropertyType.Enum: valueStr = prop.enumNames[prop.enumValueIndex]; break;
This worked for me but I wanted to use this to also have GameObjects [ShowOnly]. So after several hours of trying different things and reading documentation, this is what I came up with: case SerializedPropertyType.ObjectReference: try { valueStr = prop.objectReferenceValue.ToString (); } catch (NullReferenceException) { valueStr = "None (Game Object)"; } break; Hope this helps someone.
Works very nicely for me as well in Unity 2019.4.13f1, thanks for this! Note that [many other value types][1] are possible in SerializedProperty (the prop param in ShowOnlyDrawer#OnGUI). [1]: https://docs.unity3d.com/ScriptReference/SerializedProperty.html
This did help - thank you! I also had to add using: System; to my class to use the 'NullReferenceException', so VisualStudio didn't yell at me. :) But this is a nice and simple solution that gives you a lot of flexibility over display per type. Thanks!
The solution posted by @It3ration does not work with fields that already have a CustomPropertyDrawer.
.
Using the ReadOnly attribute will cause the field to be displayed with the default property drawer instead of the custom property drawer.
.
This solution expands on the solution by @It3ration to add 2 new attributes ( BeginReadOnlyAttribute and EndReadOnlyAttribute ) so that any fields in between the two attribute tags will be read-only. Using this method will allow CustomPropertyDrawers to work. The important part is that the new attributes use DecoratorDrawers instead of a PropertyDrawer.
.
For convenience, the ReadOnlyAttribute is also implemented but will only work for a single field with a default property drawer.
.
ReadOnlyAttribute.cs (MUST NOT be in Editor folder)
Using UnityEngine;
/// <summary>
/// Display a field as read-only in the inspector.
/// CustomPropertyDrawers will not work when this attribute is used.
/// </summary>
/// <seealso cref="BeginReadOnlyGroupAttribute"/>
/// <seealso cref="EndReadOnlyGroupAttribute"/>
public class ReadOnlyAttribute : PropertyAttribute { }
/// <summary>
/// Display one or more fields as read-only in the inspector.
/// Use <see cref="EndReadOnlyGroupAttribute"/> to close the group.
/// Works with CustomPropertyDrawers.
/// </summary>
/// <seealso cref="EndReadOnlyGroupAttribute"/>
/// <seealso cref="ReadOnlyAttribute"/>
public class BeginReadOnlyGroupAttribute : PropertyAttribute { }
/// <summary>
/// Use with <see cref="BeginReadOnlyGroupAttribute"/>.
/// Close the read-only group and resume editable fields.
/// </summary>
/// <seealso cref="BeginReadOnlyGroupAttribute"/>
/// <seealso cref="ReadOnlyAttribute"/>
public class EndReadOnlyGroupAttribute : PropertyAttribute { }
ReadOnlyDrawer.cs (MUST be in Editor folder)
using UnityEditor;
using UnityEngine;
[CustomPropertyDrawer( typeof( ReadOnlyAttribute ) )]
public class ReadOnlyDrawer : PropertyDrawer {
public override float GetPropertyHeight( SerializedProperty property, GUIContent label ) {
return EditorGUI.GetPropertyHeight( property, label, true );
}
public override void OnGUI( Rect position, SerializedProperty property, GUIContent label ) {
using (var scope = new EditorGUI.DisabledGroupScope(true)) {
EditorGUI.PropertyField( position, property, label, true );
}
}
}
[CustomPropertyDrawer( typeof( BeginReadOnlyGroupAttribute ) )]
public class BeginReadOnlyGroupDrawer : DecoratorDrawer {
public override float GetHeight() { return 0; }
public override void OnGUI( Rect position ) {
EditorGUI.BeginDisabledGroup( true );
}
}
[CustomPropertyDrawer( typeof( EndReadOnlyGroupAttribute ) )]
public class EndReadOnlyGroupDrawer : DecoratorDrawer {
public override float GetHeight() { return 0; }
public override void OnGUI( Rect position ) {
EditorGUI.EndDisabledGroup();
}
}
Example.cs
using UnityEngine;
public class ReadOnlyExample : MonoBehaviour {
[BeginReadOnlyGroup] // tag a group of fields as ReadOnly
public string a;
public int b;
public Material c;
public List<int> d = new List<int>();
public CustomTypeWithPropertyDrawer e; // Works!
[EndReadOnlyGroup]
[ReadOnly] public string a2;
[ReadOnly] public CustomTypeWithPropertyDrawer e2; // DOES NOT USE CustomPropertyDrawer!
[BeginReadOnlyGroup]
public int b2;
public Material c2;
public List<int> d2 = new List<int>();
// Attribute tags apply to the next field of which there are no more so Unity/C# complains.
// Since there are no more fields, we can omit the closing tag.
// [EndReadOnlyGroup]
}
Should be accepted answer, Works Great, thanks! Useful in conjunction with [SerializeField] to expose private/protected values.
Duplicating my comment on the other answer, but new EditorGUI.DisabledScope(true) is now recommended over DisabledGroupScope as it's a struct instead of a class and offers a slight advantage on memory usage. Otherwise, works fine! (I only tested the first version for members without custom property drawers)
If you just want to see the value of a variable without being able to edit, it’s good enough to just leave it private and then put the Inspector in Debug Mode
The problem is when you need the variable to be public (so other scripts can read/write its values) but you don't want it to be editable via the inspector (avoiding human error), HOWEVER, you would still like to be able to see the variable in the inspector. This helps tremendously for testing purposes, this way, you can see if your math is playing out as intended in real time, during runtime without having to write a debug.log for every single variable.
replying to @GoblinGameWorks You can also use public getters for those private members to make them accessible to other classes/scripts. Depends on your usecase
The solution provided by @Lev-Lukomskyi worked for me!!
I was missing some things though so I added them, for anyone wondering how to do these here they are.
Here is an option in case you want to be able to edit values in the inspector but then have the resulting class/struct be readonly later. Here’s an example of a Translation, Rotation, Scale struct. I’m using the Unity.Mathematics package btw. The idea here is that you create a readonly class/struct and then have a public nested class/struct marked serializable which has an implicit operator to return the readonly version you want in the end.
public readonly struct TRS
{
public float3 Translation { get; }
public quaternion Rotation { get; }
public float3 Scale { get; }
public float4x4 Matrix => float4x4.TRS(Translation, Rotation, Scale);
public TRS(float3 translation, quaternion rotation, float3 scale)
{
Translation = translation;
Rotation = rotation;
Scale = scale;
}
public TRS(float3 translation, float3 rotationDegrees, float3 scale)
{
Translation = translation;
Rotation = quaternion.Euler(rotationDegrees);
Scale = scale;
}
[System.Serializable]
public struct InspectorVersion
{
public float3 translation;
public float3 rotationDegrees;
public float3 scale;
public static implicit operator TRS(InspectorVersion i)
{
return new TRS(i.translation, i.rotationDegrees, i.scale);
}
}
}
public class ExampleBehaviour : MonoBehaviour
{
public TRS.InspectorVersion trs;
public void Start()
{
TRS t = trs;
}
}
So many repeated codes(variables). It's not a suitable solution.
Just tried this code - works great: [33206-showonlypropertydrawer.png|33206] And you dont need to override GetPropertyHeight - just remove it and code will be simpler.
– Lev-LukomskyiAs of 4.6 this stopped working for me, maybe something is missing for the script?
– Ash-BlueWhy setting
– QuantumHiveGUI.enabled = true;after setting it to false?because otherwise all controls following this one would be disabled
– It3rationDid anyone manage to get this to work in Unity 4.6 and 5?
– Ben-BearFish