serjeq_unity
serjeq_unity

Reputation: 1

How to show a read-only variable in the Inspector?

using System;
using UnityEngine;

[CreateAssetMenu(fileName = "Weapon",  menuName = "Item/Weapon")]
public class WeaponItemSprite : ItemTypeScriptableObject
{
    public GameObject gameObject;
    public Sprite sprite;
    public string weaponName = "Weapon name";
    public Rarity rarity = Rarity.Normal;
    public ItemType itemType = ItemType.Weapon;
    [Range(0f, 1000f)]
    public float damage = 1f;
    [Range(0f, 20f)]
    public int cost = 1;
}

enter image description here

I want it so that Item.type will be shown in the Inspector and be "greyed out" and you cannot change it.

Upvotes: 0

Views: 2899

Answers (2)

Ujjwal Raut
Ujjwal Raut

Reputation: 149

I use these small snippets of code, and it works like a charm.

using UnityEngine;

public class ReadOnlyAttribute : PropertyAttribute { }

Put this specific script in the Editor folder

using UnityEngine;
using UnityEditor;

// Put this script in the "Editor" folder
[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;
    }
}

Then you can mark any variable that needs to be greyed out with the attribute as [ReadOnly] and it won't be editable in the inspector.

Upvotes: 3

derHugo
derHugo

Reputation: 90580

You need a custom Editor or PropertyDrawer for this using e.g. EditorGUI.DisabledGroupScope or if going for UIElements VisualElement.SetEnabled(false)

There are assets that already implement handy decorator drawers like e.g. NaughtyAtttributes


As a complete alternative approach - assuming that this "field" is actually to be implemented by all inheritors of ItemTypeScriptableObject anyway - you could rather use a property

public abstract class ItemTypeScriptableObject : ScriptableObject
{
    public abstract ItemType itemType { get; }
}

and then inheritors can still decide whether they want to expose it

[field: SerilaizeField]
public override ItemType itemType { get; private set; }

or - like in your case - have a fixed value (not visible in the Inspector, though)

public override ItemType itemType => ItemType.Weapon;

Upvotes: 0

Related Questions