- Home /
Custom Editor: Objectfield clears on play
Hi there Uniteers o/ I am in the need of help once again. I am now trying to mess around with my own custom Editor for a script, though I am having issues with the EditorGuiLayout.ObjectField(); I have created an ObjectField, which shows in the inspector. In the ObjectField I assign a GameObject from the scene. As soon I play the scene, the ObjectField simply clear itself, and then UnassignedReferenceExceptions starts to pop up in the console. I am pretty sure it is just me who is missing some vital part / understanding of using custom editors. The code I use is:
using UnityEngine;
using System.Collections;
using UnityEditor;
[System.Serializable]
[CustomEditor (typeof(IronManScript))]
public class IronManScriptEditor : Editor{
public TransitionMethod _TransistionMethod;
public GameObject _TargetObject;
public override void OnInspectorGUI()
{
IronManScript _TargetSys = (IronManScript)target;
GUILayout.Label ("Transition methods", EditorStyles.boldLabel);
_TransistionMethod = (TransitionMethod)EditorGUILayout.EnumPopup("Transition: ", _TransistionMethod);
_TargetObject = (GameObject)EditorGUILayout.ObjectField("Target: ", _TargetObject, typeof(GameObject), true);
_TargetSys._Transition = _TransistionMethod;
_TargetSys._Target = _TargetObject;
}
}
The "IronManScript" is the class in which takes all my inspector values, and I am (nearly) sure that the IronManScript doesn't intefer with the custom editor.
EDIT: I just figured out, the Objectfield's value isn't cleared if I change the ObjectField value during runtime. The Objectfield only clears itself if you assign the value before you play the scene.
EDIT EDIT ** Okay, by the look of it it could be something about serializing. As far as I have read, it is about custom classes who doesn't extends from Monobehavior have to be serialized with [System.Serializable]. But even when implementing it it doesn't work. I have updated the code.
you should add your edit as an answer then mark as answered :)
Well that really doesn't resolve my issue. The problem is the changes in the inspector before play isn't saved. And that is what I really want. So far I guess my issue is serialization, but I am not sure how to implement that.
Answer by Freaking-Pingo · Nov 25, 2012 at 06:56 PM
Okay, I am not really hundred percent sure of what I did, but I got it fixed. Following this persons class setup, I got it working: http://answers.unity3d.com/questions/235595/custom-editor-losing-settings-on-play.html
Apparently, the object which is suppose to be assigned in the inspector, has to be in a custom made class which doesn't extend from Monobehavior, followed by utillizing [System.Serializable]
Why I don't really know, but it works. About the EditorUtillity.SetDirty(target); it isn't necessary. It still works even without it.
If anyone is stuck with the same problem, feel free to contact me and I'll share my experience.
Answer by RiccardoCescon · Dec 14, 2020 at 11:11 AM
Hi i know it's an old post, but i have a similar error and i can't find a way to fix this. Editor:
[CustomEditor(typeof(TilesDB))]
public class TileEditor : Editor
{
public List<Object> source = new List<Object>();
public List<Color> color = new List<Color>();
public List<string> names = new List<string>();
GUIStyle myStyle;
void OnGui() {
myStyle = new GUIStyle(GUI.skin.textField);
}
public override void OnInspectorGUI(){
base.OnInspectorGUI();
myStyle.alignment = TextAnchor.MiddleCenter;
TilesDB tiles = (TilesDB)target;
Init(tiles);
for(int i = 0; i < tiles.custom_tiles.Count; i++){
GUILayout.BeginHorizontal("", myStyle);
EditorGUIUtility.labelWidth = 1f;
EditorGUILayout.LabelField( "Tile: " + i, myStyle);
GUILayout.BeginVertical();
GUILayout.FlexibleSpace();
names[i] = EditorGUILayout.TextField("Tile Name", names[i] ,myStyle);
GUILayout.FlexibleSpace();
GUILayout.EndVertical();
source[i] = EditorGUILayout.ObjectField(source[i], typeof(Object), true, GUILayout.Width(80), GUILayout.Height(80));
color[i] = EditorGUILayout.ColorField(color[i], GUILayout.Width(80), GUILayout.Height(80));
GUILayout.EndHorizontal();
tiles.AddTile(source[i], color[i]);
}
GUILayout.BeginHorizontal("", myStyle);
if(GUILayout.Button("Add Tile", GUILayout.Width(100), GUILayout.Height(100))){
tiles.Add();
}
if(GUILayout.Button("Delete Last Tile", GUILayout.Width(100), GUILayout.Height(100))){//
tiles.DeleteLast();
}
GUILayout.EndHorizontal();
}
public void Init(TilesDB tiles){
for(int i = 0; i < tiles.custom_tiles.Count; i++){
source.Add(new Object());
color.Add(new Color());
names.Add("Tile Name");
}
}
}
Script:
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public struct ImageTiles{
public GameObject tile;
public Color color;
}
[System.Serializable]
public class TilesDB : MonoBehaviour{
[SerializeField]
public List<ImageTiles> custom_tiles;//add them on start to tiles and check
private static Dictionary<GameObject, Color> tiles = new Dictionary<GameObject, Color>(); //Save every tile and it's PNG color
void Start() {
foreach(ImageTiles it in custom_tiles){
//tiles.Add(it.tile, it.color); //save all tiles on the inspector inside tile variable
}
}
public void Add(){
custom_tiles.Add(new ImageTiles());//
}
public void AddTile(Object tile, Color color){
if(tile == null){
Debug.LogError("You created a new Tile but forgot to assign that a GameObject");
return;
}
GameObject _tile = GetTile(tile.name);
if(_tile == null){
Debug.LogError("Tile does not exists.");
return;
}
foreach(KeyValuePair<GameObject, Color> t in tiles){ //look for every tile saved on the Dictionary
if(t.Key == _tile)return;
}
tiles.Add(_tile, color);
}
public GameObject GetTile(string name){
List<GameObject> temp_tiles = Resources.LoadAll<GameObject>("Prefabs/Tiles/").ToList<GameObject>();
foreach(GameObject tile in temp_tiles){
if(name == tile.name)return tile;
}
return null;
}
public void DeleteLast(){
custom_tiles.RemoveAt(custom_tiles.Count - 1);
}
public static GameObject GetTile(Color hexColor){ //Get Tile GameObject based on the Color recieved
foreach(KeyValuePair<GameObject, Color> tile in tiles){ //look for every tile saved on the Dictionary
if(tile.Value == hexColor)return tile.Key; //If Color matches, then return Tile's GameObject
}
Debug.LogError("This Color is not saved -> " + hexColor + "\n Make sure to add all Tiles inside TilesDB.SetTiles()"); //Error message + hint
return null;
}
}
i can set everything on the inspector and it should save it on Dictionary, but when i press start button, custom editor disappear and Dictionary got cleared. Really i can't fix this, please need help.