I have a simple variable:
public enum something { one, two }
public something variable = something.one;
And I want to don’t let user to change that variable in the inspector during run-time. I need to somehow make it read-only. Any ideas?
I have a simple variable:
public enum something { one, two }
public something variable = something.one;
And I want to don’t let user to change that variable in the inspector during run-time. I need to somehow make it read-only. Any ideas?
I adapted the scripts from this article to achieve this.
ReadOnlyWhenPlayingAttribute.cs:
using UnityEngine;
public class ReadOnlyWhenPlayingAttribute : PropertyAttribute { }
Editor/ReadOnlyWhenPlayingAttributeDrawer.cs
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(ReadOnlyWhenPlayingAttribute))]
public class ReadOnlyWhenPlayingAttributeDrawer : PropertyDrawer
{
// Necessary since some properties tend to collapse smaller than their content
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUI.GetPropertyHeight(property, label, true);
}
// Draw a disabled property field
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
GUI.enabled = !Application.isPlaying;
EditorGUI.PropertyField(position, property, label, true);
GUI.enabled = true;
}
}
Usage:
[ReadOnlyWhenPlaying]
public something variable = something.one;
You need to make the field private and add [SerializeField] then expose it as a read only property:
[SerializeField]
private something _variable;
public something variable { get { return _variable; } }
For anyone still interested on how to achieve this behavior do as follow:
[SerializeField]
private <Type> InternalVariable = default;
//To be accessed from this class or other scripts.
public <Type> Variable { get {return InternalVariable;}; }
void Update()
{
UpdateInternals();
}
void UpdateInternals()
{
if (InternalVariable != Variable)
{
Debug.Log("InternalVariable can only be set at compile time. Your change will not be applied.");
InternalVariable = Variable;
}
//Process any other internals
}
What actually happens is that whatever is set at startup in InternalVariable is then used while Unity runs. You can even make it such as just in certain circumstances this will be disabled.
I like to use that variable as private and use “Internal” in its name so its purpose is clear. If I want to handle it from scripting I use its property instead (create a setter for it, of course).
Not the best pattern but the nice thing is you can use C# partial classes to remove the Inspector behavior from the actual class. Having a classInspector.cs will clearly indicate what you will find there.