How to Serialize Monobehaviours for EditorScripts

Hi all,

I’m working on a simple tool so I can DragAndDrop multiple Objects to an Editor Window that will assign it to a Monobehaviour Object that I set in the same Window.

Currently it works until I hit play then it removes all of the objects.
I took a look at this blog post on by Tim Cooper Unity Serialization | Unity Blog
but it doesn’t seem to work for me so far.

Below is my editor script and two Monobehaviour classes that are used with it, all are C#.
Please note this is my first time working with Editor Scripts.

LevelArrayEditorWindow.cs

using UnityEngine;
using UnityEditor;
using System.Collections;

public class LevelArrayEditorWindow : EditorWindow {
	
	private SerializedObject m_Object;
	private Level level;
	private SerializedProperty m_ObstaclesCount;
	[MenuItem("Level Tools/Level Array")]
	public static void ShowLevelArrayEditorWindow()
	{
		LevelArrayEditorWindow.GetWindow(typeof(LevelArrayEditorWindow));
	}
	
	public void OnGUI(){
		
		EditorGUILayout.BeginHorizontal();
		GUILayout.Label ("Level", EditorStyles.boldLabel);
        level = (Level)EditorGUILayout.ObjectField(level, typeof(Level));
        EditorGUILayout.EndHorizontal();

		GUILayout.Label ("Level Objects", EditorStyles.boldLabel);
		
		DropAreaGUI();
	}
	
	private void DropAreaGUI()
	{
		Event evt = Event.current;
		
		Rect dropArea = GUILayoutUtility.GetRect(0.0f, 100.0f, GUILayout.ExpandWidth(true));
		GUI.Box(dropArea, "Add Obstacles");
		
		switch(evt.type)
		{
		case EventType.DragUpdated:
		case EventType.DragPerform:
			
			if(!dropArea.Contains (evt.mousePosition)){
				break;
			}
			
			DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
			
			if(evt.type == EventType.DragPerform){
				DragAndDrop.AcceptDrag();
				
				foreach(GameObject draggedObject in DragAndDrop.objectReferences)
				{
					GameObject go = (GameObject)draggedObject;	
					if(!go)
						continue;
					
					Obstacle obs = go.GetComponent<Obstacle>();
					
					if(!obs)
						continue;
					
					AddObstacle(obs);
				}
			}
			
			Event.current.Use ();
			break;
		}
	}
	
	private void AddObstacle(Obstacle _obs){
		bool hasObs=false;
		foreach(Obstacle ob in level.obstacles)
		{
			hasObs = ob.Equals(_obs);	
		}
		if(!hasObs){
			level.obstacles.Add(_obs);
		}	
	}
}

Level.cs

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

[Serializable]
public class Level : MonoBehaviour 
{
	public string levelName = "";
	public string levelTheme = "";
	public int levelIndex = 0;
	public Texture backgroundTexture;
	[SerializeField]
	public List<Obstacle> obstacles;
	public List<Obstacle> powerUps;
	public List<Star> endStars;
	public Pet pet;
	public AudioSource audioSource;
	
	private List<Obstacle> resetObstacles;
	
	private List<Star> resetEndStars;
	
	void Start () 
	{
		
		if(backgroundTexture != null)
		{
			Debug.Log("SET THE TEXTURE");
			Material sky = new Material (Shader.Find ("RenderFX/Skybox"));
			sky.SetTexture("_FrontTex", backgroundTexture);
			
			RenderSettings.skybox = sky;
		}
		
		resetObstacles = obstacles;
		resetObstacles.AddRange(powerUps);
	}
	
	public void ResetLevel()
	{
		foreach(Obstacle obs in resetObstacles)
		{
			obs.LevelReset();
		}
		pet.ResetPet();
	}
}

Obstacle.cs

using System;
using UnityEngine;
using System.Collections;
using SmoothMoves;
[Serializable]
public class Obstacle : TextureFunctionMonoBehaviour 
{
	#region Attributes
	public float rollProbability;
	
	[HideInInspector]
	public float roll;
	public bool isActive = true;//Used for determining whether or not the item should be on the stack
	public bool isItem = false;
	public bool isDestroy = false;
	public int score;
	public Transform petTransform;
	public ParticleSystem particle;
	public AudioSource audioSource;
	public BoneAnimation boneAnimation;
	public bool isObserver = false;
	protected Transform startTransform;
	#endregion
	
	// Use this for initialization
	void Awake(){
		startTransform = transform;
	}
	void Start () {
		isActive = true;
	}
	
	// Update is called once per frame
	void Update () {
	}
	
	public float Roll(){
		roll = UnityEngine.Random.Range(0, rollProbability);
		return roll;
	}
	
	public virtual void OnDestroy(){
		if(particle != null){
			particle.enableEmission = true;	
			particle.Play ();
		}
		if(audioSource != null){
			audioSource.Play();
		}
		isActive = false;
		if(GameTypes.currentGameType != GameTypes.GameType.Endless){	
			gameObject.active = false;
		}
	}
	
	public virtual IEnumerator OnDestroy(float waitLength){		
		if(particle != null){
			particle.enableEmission = true;
			particle.Play();
		}
		if(audioSource != null){
			audioSource.Play();
		}
		yield return new WaitForSeconds(waitLength);

		isActive = false;
		if(GameTypes.currentGameType != GameTypes.GameType.Endless){	
			Debug.Log ("Destroy the object");	
			gameObject.active = false;
		}
	}
	
	public virtual void LevelReset(){
		gameObject.active = true;
		isActive = true;
		transform.position = startTransform.position;
		transform.rotation = startTransform.rotation;
		transform.localScale = startTransform.localScale;
	}
}

I was hoping to get this done fairly quickly but I just can’t get past this snag.

Ok so you don’t need [Serializable] on MonoBehaviours or anything else that inherits from UnityEngine.Object - but it shouldn’t be causing you a problem. Other than that the code for adding the objects looks fine to me on first reading.

You do have some problems however that might be the cause of your problem:

 resetObstacles = obstacles;

 startTransform = transform;

It appears you think that these lines are making copies, where in fact they are copying references. Transform and List are classes so you cannot copy them like that, the code you have is making a copy of a reference to exactly the same object. For example your LevelReset() function does nothing to the position of the object, because you are just setting its position back to the same value it currently has. In the Start() of Level you are adding the PowerUps to the obstacles List because resetObstacles and obstacles have become references to the same List.