Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Custom Editor: Save values edited in methods

Discussion in 'Scripting' started by LeLoicLe, Jul 26, 2021.

  1. LeLoicLe

    LeLoicLe

    Joined:
    May 27, 2020
    Posts:
    25
    HI
    So, I would like to store angles from all neighbours to all same neighbours of multiple nodes (WaypointPassage) in an array of dictionnaries for each node, from a button from the Editor.

    Basically, each node X has an array of dictionnaries, the index represent the From (Of Vector3.Angle()) while the dictionnary of that index, will store every angles with all other neighbours, which are going to be To, the center of the angle is going to be X itselfs.

    But the thing is when I click on the button, the whole data come, but gets vqnished everytime I press Play/Quit the project/Change scenes.

    How can I fix this? Thank you. :)

    Here are the codes:
    WaypointManager, the scripts which stores all nodes:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class waypointManager : MonoBehaviour
    6. {
    7.     public GameObject[] waypointsPassage;
    8.     public WPPassageController[] infoWPP;
    9.     public void FindEveryWays()
    10.     {
    11.         waypointsPassage = GameObject.FindGameObjectsWithTag("WaypointPassage");
    12.         infoWPP = new WPPassageController[waypointsPassage.Length];
    13.  
    14.         for (int i = 0; i < infoWPP.Length; i++)
    15.         {
    16.             infoWPP[i] = waypointsPassage[i].GetComponent<WPPassageController>();
    17.         }
    18.         for (int i = 0; i < infoWPP.Length; i++)
    19.         {
    20.             infoWPP[i].FindNeighbours();
    21.         }
    22.     }
    23. }
    Its Editor cousin:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [CustomEditor(typeof(waypointManager))]
    5. public class WaypointManagerEditor : Editor
    6. {
    7.     public override void OnInspectorGUI()
    8.     {
    9.         base.OnInspectorGUI();
    10.  
    11.         waypointManager WPM = (waypointManager)target;
    12.         if (GUILayout.Button("FindAllPassages"))
    13.         {
    14.             WPM.FindEveryWays();
    15.         }
    16.     }
    17. }
    18.  
    WaypointPassageController, which is attached to every node:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class WPPassageController : MonoBehaviour
    6. {
    7.     public List<GameObject> Neighbours; // Already assigned by me in the Inspector.
    8.     public Dictionary<int, float>[] angles;
    9.     public void FindNeighbours()
    10.     {
    11.         angles = new Dictionary<int, float>[Neighbours.Count];// Initialise the array of dictionnaries.
    12.         for (int i = 0; i < angles.Length; i++)
    13.         {
    14.             angles[i] = new Dictionary<int, float>();
    15.         }
    16.         for (int i = 0; i < Neighbours.Count; i++)// First, lets pick a Start neighbour...
    17.         {
    18.             for (int j = 0; j < Neighbours.Count; j++)// Then a To neighbour
    19.             {
    20.                 if (j != i)
    21.                 {
    22.                     float a = Vector3.Angle(Neighbours[i].transform.position - transform.position, Neighbours[j].transform.position);
    23.                     if (a > 180)
    24.                     {
    25.                         Mathf.Abs(a -= 360);
    26.                     }
    27.                     angles[i].Add(j, a);
    28.                 }
    29.             }
    30.         }
    31.     }
    32. }
    33.  
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,519
    Assuming you are correctly changing the values (it sounds like you are), the only thing you need to do is tell Unity "hey this has changed, be sure to save it!!"

    For that, I like to use this handy function:

    https://docs.unity3d.com/ScriptReference/Undo.RecordObject.html
     
    LeLoicLe likes this.
  3. LeLoicLe

    LeLoicLe

    Joined:
    May 27, 2020
    Posts:
    25
    Thank you very much for this. :)
    Just would like to know, how can I apply it? Assuming the fact I need to affect multiple scripts on the same button, and I dont really understqnd the unity example.
    Thank you very much. :)
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,519
    Well there is also Undo.RecordObjects() (plural). You would call that on any UnityEngine.Object-derived things you want to update the status of.

    I just noticed you are serializing Dictionaries... I don't think Unity will natively handle that as a public field the way you expect it to work, but there are workarounds. Just google for unity serialize dictionary before you go too much further into things, make sure that part works.