Unity Editor: Many elements with Dropdown lists

Hello!

I’m trying to make a Visual Novel game and to make the things easier I made an script that “Helps”, somehow, creating the dialogue between the characters.

What I did is an Editor Script ( pretty much based on this one ) where you add a text and select the character, pose, voice and write the text that will be shown on game, but I got some problems with the Dropdown list I made for the character selection.

What I would love to do is:
To have a visual way to place texts for the VN, as the picture above shows, but the dropdown code is giving me problems, since it changes the whole number of dropdown menus I place.

I used an EnumPopup to do that, and the code is like this:

    using UnityEngine;
    using System;
    using System.Collections.Generic; // Import the System.Collections.Generic class to give us access to List<>
  
    public class CustomList : MonoBehaviour {
  
  
        //This is our custom class with our variables
        [System.Serializable]
        public class DialogueList{
            public int characterId;
            public string text;
            public int pose;
            public int voice;
        }
  
        //This is our list we want to use to represent our class as an array.
        public List<DialogueList> MyList = new List<DialogueList>(1);
  
  
        void AddNew(){
            //Add a new index position to the end of our list
            MyList.Add(new DialogueList());
        }
  
        void Remove(int index){
            //Remove an index position from our list at a point in our list array
            MyList.RemoveAt(index);
        }
    }
using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEditor;
  
    [CustomEditor(typeof(CustomList))]
  
    public class CustomListEditor : Editor {
        enum Characters {None, Helena, Rin}
        Characters characterSel;
  
        CustomList t;
        SerializedObject GetTarget;
        SerializedProperty ThisList;
  
        void OnEnable(){
            t = (CustomList)target;
            GetTarget = new SerializedObject(t);
            ThisList = GetTarget.FindProperty("MyList"); // Find the List in our script and create a refrence of it
        }
  
        public override void OnInspectorGUI(){
            base.OnInspectorGUI();
            //Update our list
            GetTarget.Update();
  
            //Choose how to display the list<> Example purposes only
            EditorGUILayout.Space ();
            EditorGUILayout.Space ();
            EditorGUILayout.Space ();
  
            //Or add a new item to the List<> with a button
            EditorGUILayout.LabelField("Add a text with its properties!");
  
            if(GUILayout.Button("Add Text")){
                t.MyList.Add(new CustomList.DialogueList());
            }
  
            EditorGUILayout.Space ();
            EditorGUILayout.Space ();
  
            //Display our list to the inspector window
            for(int i = 0; i < ThisList.arraySize; i++){
                SerializedProperty MyListRef = ThisList.GetArrayElementAtIndex(i);
                SerializedProperty MyInt = MyListRef.FindPropertyRelative("characterId");
                SerializedProperty MyFloat = MyListRef.FindPropertyRelative("text");
                SerializedProperty MyVect3 = MyListRef.FindPropertyRelative("pose");
                SerializedProperty MyGO = MyListRef.FindPropertyRelative("voice");
  
                EditorGUILayout.LabelField("                        -- ♦ --");
                EditorGUILayout.LabelField("           -- ♦ -- Dialogue Starts -- ♦ --");
                characterSel = (Characters)EditorGUILayout.EnumPopup("Character",characterSel);
                MyInt.intValue = getCharacterId (characterSel);
                EditorGUILayout.PropertyField(MyFloat);
                EditorGUILayout.PropertyField(MyGO);
                EditorGUILayout.PropertyField(MyVect3);
  
                EditorGUILayout.Space ();
  
                //Remove this index from the List
                if(GUILayout.Button("Remove Text (" + i.ToString() + ")")){
                    ThisList.DeleteArrayElementAtIndex(i);
                }
                EditorGUILayout.LabelField("           -- ♦ -- Dialogue Ends -- ♦ --");
            }
  
            EditorGUILayout.Space ();
            EditorGUILayout.Space ();
  
            if(GUILayout.Button("Add Text")){
                t.MyList.Add(new CustomList.DialogueList());
            }
  
            EditorGUILayout.Space ();
  
            //Apply the changes to our list
            GetTarget.ApplyModifiedProperties();
        }
  
        private int getCharacterId(Characters characterSel){
  
            int characterId = 0;
  
            switch (characterSel) {
            case Characters.Helena:
                characterId = 0;
                break;
            case Characters.Rin:
                characterId = 3;
                break;
  
            default:
                characterId = 999;
                break;
            }
  
            return characterId;
        }
    }

How can I make this to work?

Thanks in advance.

Hey Anshie,

Would like to help, but it’s not clear (to me) exactly what the problem is. Can you describe in more detail what you are having trouble with?

Thanks for your quick response!

The problem I have is that when I change the value of the dropdown list, let’s say, I want to the character Helena talk in the first text, but in the second one I would like to have Rin answering. Something like:

Helena: Hello!
Rin: Hey!

When I select the character on the second dropdown list, it changes the value of all others element’s dropdown menus.

I need each element to have its own character selected, but everytime I change one, it changes all of them.

Thank you in advance!

Ah I see! There are a lot of ways you can fix this, but perhaps the simplest is just to store the characterID as an enum itself.

using UnityEngine;
using System;
using System.Collections.Generic; // Import the System.Collections.Generic class to give us access to List<>

public class CustomList : MonoBehaviour {

    public enum Character {None, Helena, Rin}

    //This is our custom class with our variables
    [System.Serializable]
    public class DialogueList{
        public Character character;
        public string text;
        public int pose;
        public int voice;
    }

    //This is our list we want to use to represent our class as an array.
    public List<DialogueList> MyList = new List<DialogueList>(1);


    void AddNew(){
        //Add a new index position to the end of our list
        MyList.Add(new DialogueList());
    }

    void Remove(int index){
        //Remove an index position from our list at a point in our list array
        MyList.RemoveAt(index);
    }
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;

[CustomEditor(typeof(CustomList))]

public class CustomListEditor : Editor {

    CustomList t;
    SerializedObject GetTarget;
    SerializedProperty ThisList;

    void OnEnable(){
        t = (CustomList)target;
        GetTarget = new SerializedObject(t);
        ThisList = GetTarget.FindProperty("MyList"); // Find the List in our script and create a refrence of it
    }

    public override void OnInspectorGUI(){
        base.OnInspectorGUI();
        //Update our list
        GetTarget.Update();

        //Choose how to display the list<> Example purposes only
        EditorGUILayout.Space ();
        EditorGUILayout.Space ();
        EditorGUILayout.Space ();

        //Or add a new item to the List<> with a button
        EditorGUILayout.LabelField("Add a text with its properties!");

        if(GUILayout.Button("Add Text")){
            t.MyList.Add(new CustomList.DialogueList());
        }

        EditorGUILayout.Space ();
        EditorGUILayout.Space ();

        //Display our list to the inspector window
        for(int i = 0; i < ThisList.arraySize; i++){
            SerializedProperty MyListRef = ThisList.GetArrayElementAtIndex(i);
            SerializedProperty MyCharacter = MyListRef.FindPropertyRelative("character");
            SerializedProperty MyFloat = MyListRef.FindPropertyRelative("text");
            SerializedProperty MyVect3 = MyListRef.FindPropertyRelative("pose");
            SerializedProperty MyGO = MyListRef.FindPropertyRelative("voice");

            EditorGUILayout.LabelField("                        -- ♦ --");
            EditorGUILayout.LabelField("           -- ♦ -- Dialogue Starts -- ♦ --");
            EditorGUILayout.PropertyField(MyCharacter);
            EditorGUILayout.PropertyField(MyFloat);
            EditorGUILayout.PropertyField(MyGO);
            EditorGUILayout.PropertyField(MyVect3);

            EditorGUILayout.Space ();

            //Remove this index from the List
            if(GUILayout.Button("Remove Text (" + i.ToString() + ")")){
                ThisList.DeleteArrayElementAtIndex(i);
            }
            EditorGUILayout.LabelField("           -- ♦ -- Dialogue Ends -- ♦ --");
        }

        EditorGUILayout.Space ();
        EditorGUILayout.Space ();

        if(GUILayout.Button("Add Text")){
            t.MyList.Add(new CustomList.DialogueList());
        }

        EditorGUILayout.Space ();

        //Apply the changes to our list
        GetTarget.ApplyModifiedProperties();
    }
}
1 Like

Oh my God, it was so simple…I’ve been stucked with this for like two days.

Thank you so much!! Now it works perfectly!

1 Like