- Home /
Hide null scripts in the inspector
I'm working on a game and I designed it so each character is given a script. The player holds items which also have scripts. It works something like this
public class MyPlayer {
int health;
int mana;
ItemInfo weapon;
ItemInfo shield;
}
ItemInfo is a script I made that has simple infomation in it. I use it for all my items. The problem is the character isn't always holding a weapon or shield, so I check to see if weapon == null. Normally this always works, but if I view MyPlayer in the inspector then it automatically creates a blank scripts for ItemInfo, making them not null... I could hide them, but I would like to be able to see them in they aren't null, for testing purposes.
As for my question, is there a way to hide null scripts in the inspector?
There is and it's custom inspector. Edit your script like this:
public class $$anonymous$$yPlayer : $$anonymous$$onoBehaviour{
public int health;
public int mana;
[SerializeField] public ItemInfo weapon;
[SerializeField] public ItemInfo shield;
}
And put this class in a folder named Editor:
[CustomEditor(typeof($$anonymous$$yPlayer))]
public class $$anonymous$$yPlayerEditor : Editor {
SerializedProperty weapon;
SerializedProperty shield;
private void OnEnable() {
weapon = serializedObject.FindProperty("weapon");
shield = serializedObject.FindProperty("shield");
}
public override void OnInspectorGUI() {
var myPlayer = target as $$anonymous$$yPlayer;
serializedObject.Update();
myPlayer.health = EditorGUILayout.IntField("Health", myPlayer.health);
myPlayer.mana = EditorGUILayout.IntField("$$anonymous$$ana", myPlayer.mana);
//Show this item in the inspector only if it's not null
if(myPlayer.weapon != null){
EditorGUILayout.PropertyField(weapon, GUIContent.none);
serializedObject.Apply$$anonymous$$odifiedProperties();
}
if(myPlayer.shield != null){
EditorGUILayout.PropertyField(shield, GUIContent.none);
serializedObject.Apply$$anonymous$$odifiedProperties();
}
}
}
Wow thanks, but there's a problem. It's seems that even if I hide the null script unity still makes a instants of it if I look at the class it's attached to.
It's not a problem, it's how it's meant to be. Yea there is a reference to that fields but it will be a null reference unless you don't assign anything to it. Editor has nothing to do with class itself it just manipulates how your class is being rendered. Your ItemInfo
fields will always be there but they won't be rendered to inspector as long as they are null.
If you want a non Unity nullable type to be null, do not serialize it. And by serialize it, I mean make it visible on inspector. Each time Unity Editor Updates (not game update) a serialization/ deserialization will occure for all objects, now Unity doesn't like null so it will replace it with an actual instance, so once it will deserialize the object, you no longer have a null, ex. try this
[System.Serializable]
public class $$anonymous$$SerializableClass
{
public int mInt;
}
public class $$anonymous$$Behaviour : $$anonymous$$onoBehavirour{
public $$anonymous$$SerializableClass mClass = null;
void Start(){
mClass.mInt = 2; //this will not throw an error!
mClass = null;
StartCoroutine($$anonymous$$Routine());
}
IEnumerator $$anonymous$$Routine()
{
yield return new WaitForSeconds(1);
mclass.mInt = 3; //this will not throw an error!
}
Anyhow the above code will not work in a build.
Cheers
Answer by Bunny83 · Apr 13, 2019 at 04:57 PM
That's not possible for custom serializable classes if you want them to be serialized and therefore visible in the inspector. The serialization system treats custom serializable classes like structs. So the inspector will always automatically create an instance of those classes. That's also the reason why self and circular references are not supported.
Make sure you read the documentation about script serialization carefully. Especially the part about custom serializable classes which starts at the line:
When might the serializer behave unexpectedly?
If you actually want references to classes, those classes need to be derived either from MonoBehaviour (and attached to a gameobject) or from ScriptableObject. In this case they are seperate objects and the field in the inspector doesn't show the class fields inline but just a reference to the referenced object.