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; } }
Oh I've got what you want now - that is not possible - I'm struggling to think of why you are worrying about changing it in the inspector at run time? Why would you want to do that??
– whydoidoitI need it because if user changes character movement type during run-time, the whole movement system doesn't work anymore. So there isn't better solution than creating another variable, changing it's value when script starts and then in Update() setting the original variable to the new? Would look like [this][1] [1]: http://pastebin.com/1HFSWVPS
– GintasBut why would the user be messing around in the inspector? At runtime? Well fair enough - yes - you have to have a private variable initialized from a public variable during Start or Awake.
– whydoidoitFor 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.
We use [this plugin][1] to make public variable read-only in the inspector. It provides a [NotEditableInInspector] attribute. [1]: https://www.assetstore.unity3d.com/#!/content/66996
– freshingrain