Editor拡張ではSerializedPropertyを使おう。

UnityのEditor拡張は便利だが、よく紹介されているEditorGUILayout.FloatValue()などの直接値を返すものを使用すると、Prefabモードでは値が反映されない。 その場合は、SerializedProperty経由のEditorGUILayout.PropertyFieldを使うと、Prefabモードでも正しく値が反映される。

以下のようなEditor拡張はサンプルとしてもよく見ると思う。

using UnityEngine;
using UnityEditor;

public class EditorSample1 : MonoBehaviour
{
    public float a;
    public GameObject b;

#if UNITY_EDITOR
    [CustomEditor(typeof(EditorSample1))]
    class InternalEditor : Editor
    {
        EditorSample1 _self;

        private void OnEnable()
        {
            _self = target as EditorSample1;
        }

        public override void OnInspectorGUI()
        {
            _self.a = EditorGUILayout.FloatField(_self.a);
            _self.b = EditorGUILayout.ObjectField(_self.b, typeof(GameObject), false) as GameObject;
        }
    }
#endif
}

このコンポーネントをアタッチすると、Projectビューから直接選択した場合には問題なく編集することができる。

しかしUnity2018.3から追加されたPrefabモードでは値を変更することができない。

代わりにSerializedObjectからSerializedPropertyを取得して、EditorGUILayout.PropertyField()を使用するように変更する。 (Editorクラスのみ抜粋)

[CustomEditor(typeof(EditorSample1))]
class InternalEditor : Editor
{
    EditorSample1 _self;
    SerializedObject _sObj;

    private void OnEnable()
    {
        _self = target as EditorSample1;
        _sObj = serializedObject;
    }

    public override void OnInspectorGUI()
    {
        var propA = _sObj.FindProperty("a");
        var propB = _sObj.FindProperty("b");
            
        EditorGUILayout.PropertyField(propA);
        EditorGUILayout.PropertyField(propB);

        if(_sObj.hasModifiedProperties)
        {
            _sObj.ApplyModifiedProperties();
        }
    }
}

これによりPrefabモードでも値を変更することができる。