Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Fourthings · Jan 22, 2015 at 04:00 PM · listinspectorserialization

*Really* need help on Serialisation, stuck on this for over a week now, deadline looming

--Edit---------------

Ok, I've tried all of the below suggestions to no avail.

The current behaviour is this: Any changes made to the CheckPointAttributes list immediately after compile do work correctly, but once I've entered play mode the list is "frozen" in it's current state. So if I added an element before entering play mode, once I've entered play mode from that point onwards that element will be stuck in the list and I cannot add/remove/clear it. The same behaviour is observed when I enter play mode with no elements in the list, it is stuck that way until I recompile.

But, when I print the .Count of the list it does return as zero if I have cleared it even though I can clearly see an element in the list, once I enter and exit play mode however it will continue to return as 1.

This problem has delayed me for over a week, I had no idea Unity editor scripting was so finicky and I'm going to need to find an alternate method to creating a custom inspector if I can't solve this by the end of the day, as I have a deadline in one week. So any and all suggestions are welcome. I've updated the scripts below

Panel_Controller, the class on the object being inspected

 using UnityEngine;
 using System;
 using System.Collections;
 using System.Collections.Generic;
 /*
 # ===================================================================
 
 # Notes:            Controls each panel's attributes, which define 
                     it's behavious; 
                     Animation of transform/rotation/scale
 # ===================================================================
 */
  
 public class Panel_Controller :  MonoBehaviour
 {
     public List<Checkpoint_Attributes> CheckpointAttributes = new List<Checkpoint_Attributes>();
     public List<bool> Foldouts = new List<bool>();
 
     public enum PanelType {SelectType, GameObj, CanvasObj};
     public PanelType TypeOfPanel;
 
     private GameObject gameManager;
     private Game_Manager gameManClass;
 
 
     private bool gameObjPanWasTrue = false;
     private bool gameObjPan = false;
     private bool gameObjTween = false;
     private int i = 0;
     private int activeCheckpIndex = 0;
 
     void Awake ()
     {
         gameManager = GameObject.Find("Game_Manager");
         gameManClass = gameManager.GetComponent<Game_Manager>();
 
     }
     
     void Update ()
     {
         if (gameManClass.Moving)
         {
             CheckForTargetCheckpointMatch();
             
             if (gameObjPan)
             {
                 PanGameObjPanel();
             }
         }
         else
         {
             if (gameObjPanWasTrue)
             {
                 TweenGameObjPanel();
             }
         }
     }
             
     void CheckForTargetCheckpointMatch ()
     {
         for (i=0; i<CheckpointAttributes.Count; i++)
         {
             if (CheckpointAttributes[i].TargetCheckpoint == gameManClass.TargetCheckpoint)
             {
                 if (TypeOfPanel == PanelType.GameObj)
                 {
                     activeCheckpIndex = i;
                     gameObjPan = true;
                 }
                 break;
             }
         }
     }
 
     void PanGameObjPanel ()
     {
         gameObjPanWasTrue = true;
         if (gameObjTween)
         {
             gameObjTween = false;
             if (iTween.Count(gameObject) > 0)
             {
                 iTween.Stop(gameObject);
             }
         }
         if (CheckpointAttributes[activeCheckpIndex].DoesMove)
         {
             transform.position = Vector3.Lerp(transform.position, CheckpointAttributes[activeCheckpIndex].TargetPosition, Time.deltaTime*(gameManClass.AbsMoveDelta*CheckpointAttributes[activeCheckpIndex].MoveSpeed));
         }
     }
 
     void TweenGameObjPanel ()
     {
         gameObjPanWasTrue = false;
         gameObjTween = true;
         if (CheckpointAttributes[activeCheckpIndex].DoesMove)
         {
             gameObjTween = true;
             iTween.MoveTo(gameObject, iTween.Hash("name",gameObject.name, "position",CheckpointAttributes[activeCheckpIndex].TargetPosition, "time",CheckpointAttributes[activeCheckpIndex].MoveSpeed, "easeType","easeOutCubic"));
         }
     }
 }
 

PanelController_Editor, the editor script used for PanelController

 using UnityEditor;
 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 /*
  # ===================================================================
 
  # Notes:            Creates the custom inspector on the Panel's
                      Panel_Controller component
  # ===================================================================
  */
 [CustomEditor(typeof(Panel_Controller))]
 public class PanelController_Editor : Editor 
 {
     private Vector3 tempPos;
     private Quaternion tempRot;
     private Vector3 tempScale;
     
     private bool tempDoesMove = false;
     private bool tempDoesRot = false;
     private bool tempDoesScale = false;
     private float tempMoveSpeed = 1f;
     private float tempRotSpeed = 1f;
     private float tempScaleSpeed = 1f;
     private int inputCheckpoint = 0;
     private Panel_Controller panelCtrlClass;
     
     
     void OnEnable () 
     {
 
     }
     
     public override void OnInspectorGUI() 
     {
         DrawDefaultInspector();
         panelCtrlClass = target as Panel_Controller;
         GUI.changed = false;
         
         //Display Panel Type Enum to choose the type for this panel
         panelCtrlClass.TypeOfPanel = (Panel_Controller.PanelType)EditorGUILayout.EnumPopup ("Panel Type", panelCtrlClass.TypeOfPanel);
         
         //Execute method for this panel type
         switch(panelCtrlClass.TypeOfPanel) 
         {
             case Panel_Controller.PanelType.GameObj:
                 GameObjectType();
                 break;
             case Panel_Controller.PanelType.CanvasObj:            
                 //Code
                 break;
         }
     
         //Update Panel Controller script's values
         if (GUI.changed)
         {
             EditorUtility.SetDirty(panelCtrlClass);
         }
     }
     
     void GameObjectType ()
     {
         //Draw the checkpoint input and add/remove buttons
         DrawInputBox("Target Checkpoint:");
         if (GUILayout.Button("Add Checkpoint"))
         {
             AddGameObjCheckpoint();
         }
         if (GUILayout.Button("Clear All Checkpoints"))
         {
             ClearCheckpoints();
         }
         if (GUILayout.Button("Print checkpoint count"))
         {
             LogCheckpoints();
         }
     }
 
     void AddGameObjCheckpoint ()
     {
         //Add new item to main CheckpointAttributes List on Panel Controller, values passed in are all zero
         panelCtrlClass.CheckpointAttributes.Add(new Checkpoint_Attributes(inputCheckpoint, tempPos, tempRot, tempScale, tempDoesMove, tempDoesRot, tempDoesScale, tempMoveSpeed, tempRotSpeed, tempScaleSpeed));
         Debug.Log("Checkpoint added, list count = " + panelCtrlClass.CheckpointAttributes.Count);
     }
     
     void ClearCheckpoints ()
     {
         if (panelCtrlClass.CheckpointAttributes.Count < 1)
         {
             Debug.Log("List already cleared, list count = " + panelCtrlClass.CheckpointAttributes.Count);
             return;
         }
         //Empty the main CheckpointAttributes list on Panel Controller
         panelCtrlClass.CheckpointAttributes.Clear();
         Debug.Log("All checkpoints cleared, list count = " + panelCtrlClass.CheckpointAttributes.Count);
 
 //        panelCtrlClass.Foldouts.Clear();
     }
 
     void LogCheckpoints ()
     {
         Debug.Log("List count = " + panelCtrlClass.CheckpointAttributes.Count);
     }
     
     void DrawCheckpointMenu (int menuID)
     {
         
         if (panelCtrlClass.Foldouts.Count < (menuID+1))
         {
             bool tempBool = new bool();
             panelCtrlClass.Foldouts.Add(tempBool);
             panelCtrlClass.Foldouts[menuID] = true;
         }
         if (panelCtrlClass.CheckpointAttributes.Count < (menuID+1))
         {
             panelCtrlClass.Foldouts[menuID] = EditorGUILayout.Foldout(panelCtrlClass.Foldouts[menuID], "Checkpoint " +  inputCheckpoint);
         }
         else
         {
             if (panelCtrlClass.CheckpointAttributes[menuID].TargetCheckpoint == -1)
             {
                 panelCtrlClass.CheckpointAttributes[menuID].TargetCheckpoint = inputCheckpoint;
             }
             panelCtrlClass.Foldouts[menuID] = EditorGUILayout.Foldout(panelCtrlClass.Foldouts[menuID], "Checkpoint " +  panelCtrlClass.CheckpointAttributes[menuID].TargetCheckpoint);
         }
         if (panelCtrlClass.Foldouts[menuID])
         {
             EditorGUI.indentLevel = 1;
             DrawCheckpointFoldouts(menuID);
         }
         EditorGUI.indentLevel = 0;
     }
     
     void DrawCheckpointFoldouts (int menuID)
     {
         if (GUILayout.Button("Remove Checkpoint"))
         {
             RemoveCheckpoint(menuID);
         }
         EditorGUILayout.Space();
         if (panelCtrlClass.CheckpointAttributes.Count < (menuID+1))
         {
             //            tempTargTran = EditorGUILayout.ObjectField("Target", tempTargTran, typeof(Transform), true) as Transform;
             tempDoesMove = EditorGUILayout.Toggle("Does Move?", tempDoesMove);
             if (tempDoesMove)
             {
                 EditorGUI.indentLevel = 2;
                 tempMoveSpeed = EditorGUILayout.FloatField("Speed", tempMoveSpeed);
                 tempPos = EditorGUILayout.Vector3Field(" Position", tempPos);
                 
                 EditorGUI.indentLevel = 1;
             }
             tempDoesRot = EditorGUILayout.Toggle("Does Rotate?", tempDoesRot);
             if (tempDoesRot)
             {
                 EditorGUI.indentLevel = 2;
                 tempRotSpeed = EditorGUILayout.FloatField("Speed", tempRotSpeed);
                 EditorGUI.indentLevel = 1;
             }
             tempDoesScale = EditorGUILayout.Toggle("Does Scale?", tempDoesScale);
             if (tempDoesScale)
             {
                 EditorGUI.indentLevel = 2;
                 tempScaleSpeed = EditorGUILayout.FloatField("Speed", tempScaleSpeed);
                 EditorGUI.indentLevel = 1;
             }
             
             panelCtrlClass.CheckpointAttributes.Add(new Checkpoint_Attributes(inputCheckpoint, tempPos, tempRot, tempScale, tempDoesMove, tempDoesRot, tempDoesScale, tempMoveSpeed, tempRotSpeed, tempScaleSpeed));
             return;
         }
         //        panelCtrlClass.CheckpointAttributes[menuID].TargetTransform = EditorGUILayout.ObjectField("Target", panelCtrlClass.CheckpointAttributes[menuID].TargetTransform, typeof(Transform), true) as Transform;
         panelCtrlClass.CheckpointAttributes[menuID].DoesMove = EditorGUILayout.Toggle("Does Move?", panelCtrlClass.CheckpointAttributes[menuID].DoesMove);
         if (panelCtrlClass.CheckpointAttributes[menuID].DoesMove)
         {
             EditorGUI.indentLevel = 2;
             panelCtrlClass.CheckpointAttributes[menuID].MoveSpeed = EditorGUILayout.FloatField("Speed", panelCtrlClass.CheckpointAttributes[menuID].MoveSpeed);
             
             
             panelCtrlClass.CheckpointAttributes[menuID].TargetPosition = EditorGUILayout.Vector3Field("Target Position", panelCtrlClass.CheckpointAttributes[menuID].TargetPosition);
             
             
             EditorGUI.indentLevel = 1;
         }
         panelCtrlClass.CheckpointAttributes[menuID].DoesRotate = EditorGUILayout.Toggle("Does Rotate?", panelCtrlClass.CheckpointAttributes[menuID].DoesRotate);
         if (panelCtrlClass.CheckpointAttributes[menuID].DoesRotate)
         {
             EditorGUI.indentLevel = 2;
             panelCtrlClass.CheckpointAttributes[menuID].RotateSpeed = EditorGUILayout.FloatField("Speed", panelCtrlClass.CheckpointAttributes[menuID].RotateSpeed);
             EditorGUI.indentLevel = 1;
         }
         panelCtrlClass.CheckpointAttributes[menuID].DoesScale = EditorGUILayout.Toggle("Does Scale?", panelCtrlClass.CheckpointAttributes[menuID].DoesScale);
         if (panelCtrlClass.CheckpointAttributes[menuID].DoesScale)
         {
             EditorGUI.indentLevel = 2;
             panelCtrlClass.CheckpointAttributes[menuID].ScaleSpeed = EditorGUILayout.FloatField("Speed", panelCtrlClass.CheckpointAttributes[menuID].ScaleSpeed);
             EditorGUI.indentLevel = 1;
         }
     }
     
     void RemoveCheckpoint (int mID)
     {
         panelCtrlClass.CheckpointAttributes.RemoveAt(mID);
     }
     
     
     
     
     void DrawInputBox (string txt)
     {
         EditorGUILayout.BeginHorizontal();
         EditorGUILayout.PrefixLabel(txt);
         inputCheckpoint = EditorGUILayout.IntField(inputCheckpoint);
         EditorGUILayout.EndHorizontal();
     }
     
 
     
     
     
     /*
     void SetClassDirty ()
     {
         EditorUtility.SetDirty(target);
 //        EditorUtility.SetDirty(panelCtrlClass);
 //        EditorUtility.SetDirty(panelCtrlClass.gameObject);
     }
     */
 }
 


Checkpoint_Attributes, the struct class used for the CheckpointAttributes List

 using UnityEngine;
 using System;
 using System.Collections;
 
 [Serializable] 
 public class Checkpoint_Attributes 
 {
     public int TargetCheckpoint = -1;
 
     public Vector3 TargetPosition;
     public Quaternion TargetRotation;
     public Vector3 TargetScale;
 
     public bool DoesMove = false;
     public bool DoesRotate = false;
     public bool DoesScale = false;
     public float MoveSpeed = 1f;
     public float RotateSpeed = 1f;
     public float ScaleSpeed = 1f;
     
     public Checkpoint_Attributes (int tCheck, Vector3 targPos, Quaternion targRot, Vector3 targScale, bool dMove, bool dRot, bool dScale, float mSpeed, float rSpeed, float sSpeed)
     {
         tCheck = TargetCheckpoint;
 
         targPos = TargetPosition;
         targRot = TargetRotation;
         targScale = TargetScale;
 
         dMove = DoesMove;
         dRot = DoesRotate;
         dScale = DoesScale;
         mSpeed = MoveSpeed;
         rSpeed = RotateSpeed;
         sSpeed = ScaleSpeed;
     }
 }

The desired results are;

  1. Create gameobject in scene

  2. Drag and drop Panel_Controller class onto said gameobject

  3. PanelController_Editor script displays a custom inspector

  4. Inspector asks you to choose what type of object this gameobject is (options are canvas and gameobject)

  5. You type in a checkpoint id into an int field in the inspector, this checkpoint tells the object when it needs to move

  6. You click add checkpoint and a new element is added to a List on Panel_Controller, the List inherits from a Checkpoint_Attributes constructor with various parameters

The problem is the List elements and their parameters are not being stored correctly, below is what the inspector looks like

alt text

Comment
Add comment · Show 6
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image _dns_ · Jan 22, 2015 at 05:26 PM 0
Share

Hi, I answered your previous question yesterday, but saw someone else posted the same answer a few seconds before that so I removed my answer to keep "Answers" clean :) Usually it's preferable to edit your question or add a comment to bump it on top of the list as it may help the community to better know the problem and remove the risk of duplicated questions.

For your problem: the code seems ok. You used SetDirty on the component, I already had strange behaviors with using it only on the component: can you try using it also on the target.gameObject to see if it makes things better ?

I would also try using DrawDefaultInspector() at the beginning of the OnInspectorGUI: it will help you see what Unity "see", inspect your data and help debug.

You can also remove the serializable attribute on the monobehavior-based class (but I don't thing it changes anything)

avatar image Fourthings · Jan 22, 2015 at 06:15 PM 0
Share

Sorry I figured since the problem has changed into something a bit different a new post would be best.

I tried SetDirty(panelCtrlClass.gameObject) and SetDirty(panelCtrlClass) but both resulted in the same behaviour as SetDirty(target), although I did not try SetDirty(target.gameObject).

I didn't realise the serializable on the monobehaviour was unnecesary, so will remove that. I'm out of the office at the moment though so can't try until tomorrow morning.

What puzzles me is why the SetDirty seems to work perfectly immediately after a compile, but at no other time, perhaps I'm losing a reference or something? I experiemented with ScriptableObject but after reading the docs it didn't seem appropriate for my case.

avatar image Fourthings · Jan 22, 2015 at 06:18 PM 0
Share

Could it be that I am referencing panelCtrlClass in OnEnable, then using that to set my values in OnInspectorGUI, rather than using target? Perhaps that reference is lost after the OnEnable?

avatar image _dns_ · Jan 22, 2015 at 06:19 PM 0
Share

Hummm, then maybe you could set panelCtrlClass to target at the beginning of OnInspectorGUI then, as I think OnEnable is called after a recompile. $$anonymous$$aybe try first without the CanEdit$$anonymous$$ultipleObjects attribute too, just in case.

Edit: ha ha, same thought at the same time abpout OnEnable :)

avatar image Fourthings · Jan 22, 2015 at 06:26 PM 0
Share

I'll give that a go in the morning so, thank you very much for your help!

Out of curiousity, why is the [serializable] on the mono class not necesary? Because all of the variables used by the editor script are public?

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Fourthings · Jan 26, 2015 at 02:26 PM

So I think I found the problem, you know the little Lock icon in the top right of the inspector? I had the component I was watching locked and it seems after making changes to the component, then playing, and then exiting play, where the gameobject would normally be deselected the connection between the inspector component you're viewing and the object you still appear to have selected is severed. Meaning you're looking at old values that are not reflecting the current actual values.

This also caused bizarre behaviour when logging these values. Once I unchecked that lock icon everything started behaving as it should. I don't think this is the entire answer but everything works as it should now. I'll update with any further pertinent information

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Difference between assigning a value in inspector and with a custom editor script 1 Answer

Serialising subclass variables in inspector 2 Answers

How do I make child classes in a list editable from the Inspector? 1 Answer

A node in a childnode? 1 Answer

Serialize variables of elements in a list ? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges