Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

List<List<Transform>> in inspector

Discussion in 'Scripting' started by Themp, Oct 4, 2013.

  1. Themp

    Themp

    Joined:
    Nov 8, 2011
    Posts:
    96
    Okay straight to the point.

    I need to be able to see and save a List<List<Transform>> in the inspector/editor

    I need to do this because I need a 2 dimensional dynamic array, and the tool I wrote for the Editor saves the values of a certain object in the prefab of that object,

    some visual help:

    this is the object I need to save the List<List<Transform>> to:
    Code (csharp):
    1.  
    2. public class Pather : MonoBehaviour
    3. {
    4.     Transform car;
    5.    
    6.     public List<List<Transform>> roads = new List<List<Transform>>();  
    7.    
    8.     public static int usingRoad = 0;
    9.     Transform target;
    10.     public int PATHLENGTH = 999;
    11.     public bool move = true;
    12.     public int speed= 20;
    13.     public Vector3 heightDifference = new Vector3(0,5,0);
    14.     enum RoadSide{Out,Inner}
    15.    
    16.     RoadSide roadSide = RoadSide.Inner;
    17.    
    18.     Vector3 finalPosObj;
    19.     void Start()
    20.     {
    21.         if(roads.Count > Pather.usingRoad)
    22.         {
    23.             target = roads[Pather.usingRoad][0];
    24.             transform.position = target.position-heightDifference;
    25.         }
    26.         else
    27.         {
    28.             throw new UnityException("No Begin Path found (Empty array in Car Inspector?)");   
    29.         }
    30.     }
    31. }
    32.  
    And I do this from the editorwindow with this: //note this is not the whole code
    Code (csharp):
    1.  
    2. public class CarPath : EditorWindow
    3. {
    4. [HideInInspector]
    5.     static public int currentPathNumber = 0;
    6.     [HideInInspector]
    7.     static public Transform car;
    8.     [HideInInspector]
    9.     static public bool carSelected = false;
    10.     [HideInInspector]
    11.     static public Pather p;
    12.     [HideInInspector]
    13.     List<Transform> road = new List<Transform>();
    14.    
    15.     [MenuItem ("Window/CarPath")]
    16.     static void Init ()
    17.     {
    18.         CarPath window = (CarPath)EditorWindow.GetWindow (typeof (CarPath));
    19.     }
    20. void AddToPatherRTycoon(Transform t)
    21.     {
    22.         if(t.tag != "Bend2x90"  t.tag != "Bend3x90")
    23.         {
    24.             RaycastHit hit0;
    25.             if(Physics.Raycast(t.position,Vector3.forward,out hit0,t.collider.bounds.size.x/2+1))
    26.             {
    27.                 if(GUI.Button(new Rect(20,0,20,20),"F"))
    28.                 {
    29.                     while(CarPath.p.roads.Count < Pather.usingRoad+1)
    30.                     {
    31.                         CarPath.p.roads.Add(new List<Transform>());
    32.                     }
    33.                     if(CarPath.p.roads[Pather.usingRoad].Count > 0)
    34.                     {
    35.                         SetTurn(CarPath.p.roads[Pather.usingRoad][CarPath.p.roads[Pather.usingRoad].Count-1],t,hit0.transform);
    36.                     }
    37.                    
    38.                     CarPath.p.roads[Pather.usingRoad].Add(t); //<-----------------   see this
    39.                     Selection.activeTransform = car;
    40.                     EditorApplication.ExecuteMenuItem("GameObject/Apply Changes To Prefab");   //<-----------------   see this  (this won't work because the List<List<Transform>> is not showing in the inspector thus it won't save it to the current prefab, (all changes are lost when I press Play))
    41.                     Selection.activeTransform = hit0.transform;
    42.                 }
    43.  
    44. }      
    45. }
    46. }
    47. }
    48.  
    49.  
    note: EditorApplication.ExecuteMenuItem("GameObject/Apply Changes To Prefab"); DOES work with the other showable values.. so if I edit a integer with the function and use this.. it will get saved and stay when I press Play

    ..

    So can anyone help me get this to work?..
    Basically I figured out.. If I can manually add a List<Transform> to the List<List<Transform>> in the inspector and then edit loose Transforms in for example List[0][x] it will get saved and stay that way....
     
  2. Jallen182

    Jallen182

    Joined:
    Aug 21, 2012
    Posts:
    97
    Unity does not serialize multidimensional arrays. You could however create a class representing what the List<Transform> represents in List<List<Transform>>.

    Code (csharp):
    1.  
    2.  
    3. [System.Serializable]
    4. public class Road {
    5.      public List<Transform> list;
    6. }
    7.  
    8. public class Pather : MonoBehaviour
    9. {
    10.     Transform car;  
    11.     // public List<List<Transform>> roads = new List<List<Transform>>();      
    12.  
    13.     // List<Transform> is replaced with the Road class which contains a list
    14.     // of Transforms and is serialized so it shows in the inspector.
    15.     public List<Road> roads = new List<List<Road>>();      
    16.     public static int usingRoad = 0;
    17.     Transform target;
    18.     public int PATHLENGTH = 999;
    19.     public bool move = true;
    20.     public int speed= 20;
    21.     public Vector3 heightDifference = new Vector3(0,5,0);
    22.     enum RoadSide{Out,Inner}
    23.     RoadSide roadSide = RoadSide.Inner;
    24.     Vector3 finalPosObj;
    25.  
    26.     void Start()
    27.     {
    28.         if(roads.Count > Pather.usingRoad)
    29.         {
    30.             // target = roads[Pather.usingRoad][0];
    31.  
    32.             // Instead of accessing the Transform in the list at roads[Pather.usingRoad]
    33.             // the Transform is accessed through the Road class's Transform list.
    34.             target = roads[Pather.usingRoad].list[0];
    35.             transform.position = target.position-heightDifference;
    36.         }
    37.         else
    38.         {
    39.             throw new UnityException("No Begin Path found (Empty array in Car Inspector?)");    
    40.         }
    41.     }
    42. }
    Haven't tested it but should work as far as serializing the Transform list you want to edit in the inspector.
     
    Last edited: Oct 4, 2013
  3. Themp

    Themp

    Joined:
    Nov 8, 2011
    Posts:
    96
    Perfect! It works!, Thanks very much,

    Seems I'll need to look a bit more into serializing...

    (also typo with the serializable)
    [System.Serializable] not [System.Serializeable] (for the other people who might see this post and needed the same)
     
  4. Jallen182

    Jallen182

    Joined:
    Aug 21, 2012
    Posts:
    97
    Yeah I'm hopeless without Intelli-sense, I'll edit the post so it doesn't cause issues for anyone who uses it. Unity's serialization is a pain, but it's never stopped me from doing what I need to do so I don't mind. It just takes some researching and practice to get the hang of. Glad I could help, good luck!
     
  5. Themp

    Themp

    Joined:
    Nov 8, 2011
    Posts:
    96
    Always those things you've read once or twice about it and then forgot it.. only to have it needed at a much later time..

    (Also ended up with like 200 lines (spread over a few files) I had to edit to get it working again but it does work.