Can't edit referenced class in the inspector

Hi everyone,

I’ve come across a weird issue. I hope I can make it clear with the following example:

Ok, I’m working on a turn based game, where I want to keep all players in a List<>, which can be viewed and edited in the inspector. I also want the current player to be referenced in a variable called “current”.

Now, the weird thing is that as soon as I reference a Player from the List<> into “current”,

current = players[index];

I can no longer edit that Player from the List<> displayed in the inspector. However, all other Players in the list CAN be edited. Why is that?

Please note that editing the player using its reference (current) updates it’s values in the list as expected. Editing values inside the script itself also works without a problem.

current.health= 10;
players[index].health = 20;

Obviously this isn’t much of a problem, but I am curious as to what I’m missing. Thanks for taking the time!

Code I’m using.

[System.Serializable]
public class Player
{
    public float health;

    public Player() {}
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyClass : MonoBehaviour
{
    public List<Player> players;
    public Player current;
    public int index = 0;

    // Use this for initialization
    private void Start()
    {
        players= new List<Player>();
        for (int i = 0; i < 10; i++)
        {
            players.Add(new Player());
        }
        current = players[index];
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            index++;
            current = players[index];
        }
        if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            index--;
            current = players[index];
        }
    }
}

That has to do with the way Unity displays and then checks the edit fields for the default inspector. Since you have 2 fields for the same value – they interfere. There are two scenarios (roughly):

  • You edit first field. Unity sees first field, sets value. Unity sees second field, sets value.
  • You edit second field. Unity sees first field, sets value. Unity sees second field, sets value.

So, no matter what you do, in the end, it just grabs the second field’s value as the last.

Swap the order of public List players; and public Player current; and you’ll see that you won’t be able to “edit” the current anymore, because list’s entry is last.

What you have would work for a custom inspector (CustomEditor), where you could manually go field by field and immediately update the value so any further fields have the new value instantly. For example, this would work from both fields:

value = EditorGUILayout.IntField(value);
value = EditorGUILayout.IntField(value);

However, Unity by default internally does closer to SerializedObject and such, which do things “in bulk” and fail under certain scenarios, like this one.

I would suggest not pointing to the same value with default inspectors. Perhaps:

[NonSerialized]
public Player current;