0

At the dialogue trigger script top I added a new List type string:

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;

public class DialogueTrigger : MonoBehaviour
{
    public List<string> conversation = new List<string>();
    public List<Dialogue> dialogue = new List<Dialogue>();

    [HideInInspector]
    public int dialogueNum = 0;

    private bool triggered = false;
    private List<Dialogue> oldDialogue;

    private void Start()
    {
        //oldDialogue = dialogue.ToList();
    }

    public void TriggerDialogue()
    {
        if (triggered == false)
        {
            if (FindObjectOfType<DialogueManager>() != null)
            {
                FindObjectOfType<DialogueManager>().StartDialogue(dialogue[dialogueNum]);
                dialogueNum += 1;
            }
            triggered = true;
        }
    }

    private void Update()
    {
        if (DialogueManager.dialogueEnded == true)
        {
            if (dialogueNum == dialogue.Count)
            {
                return;
            }
            else
            {
                FindObjectOfType<DialogueManager>().StartDialogue(dialogue[dialogueNum]);
                DialogueManager.dialogueEnded = false;
                dialogueNum += 1;
            }
        }
    }
}

Then in the editor script:

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

[CustomEditor(typeof(DialogueTrigger))]
public class DialogueTriggerEditor : Editor
{
    private SerializedProperty _dialogues;
    private SerializedProperty _conversations;

    private void OnEnable()
    {
        // do this only once here
        _dialogues = serializedObject.FindProperty("dialogue");
        _conversations = serializedObject.FindProperty("conversation");
    }

    public override void OnInspectorGUI()
    {
        //base.OnInspectorGUI();

        serializedObject.Update();

        _conversations.arraySize = EditorGUILayout.IntField("Conversation Size", _conversations.arraySize);

        // Ofcourse you also want to change the list size here
        _dialogues.arraySize = EditorGUILayout.IntField("Dialogue Size", _dialogues.arraySize);

        for (int x = 0; x < _conversations.arraySize; x++)
        {
            for (int i = 0; i < _dialogues.arraySize; i++)
            {
                var dialogue = _dialogues.GetArrayElementAtIndex(i);
                EditorGUILayout.PropertyField(dialogue, new GUIContent("Dialogue " + i), true);
            }
        }

        // Note: You also forgot to add this
        serializedObject.ApplyModifiedProperties();
    }
}

I'm doing a loop of the _conversations on the loop of the _dialogues. But this is not what I wanted.

I want that in the Inspector on the top level there will be only "Conversations Size".

If the Conversations Size is 0 there is nothing. But if the Conversations Size for example is 5.

Then it will create 5 Conversations(Conversation 1, Conversation 2....Conversation5). And under each Conversation there will be a Dialouge Size and then I can make many dialogues per conversation.

That way it will be easier to identify later the conversations and dialogues. Instead as before that there was one long dialogues.

I added the conversation List before that it was just without the conversation/s and working fine but now I want to add the conversations. So each conversation will have it's own dialogues.

This is the scripts according to the solution:

Created the class:

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

[System.Serializable]
public class Conversation
{
    public string Id;
    public List<Dialogue> Dialogues = new List<Dialogue>();
}

Then the trigger script:

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;

public class DialogueTrigger : MonoBehaviour
{
    public List<Conversation> conversations = new List<Conversation>();
    public List<Dialogue> dialogue = new List<Dialogue>();

    [HideInInspector]
    public int dialogueNum = 0;

    private bool triggered = false;
    private List<Dialogue> oldDialogue;

    private void Start()
    {
        //oldDialogue = dialogue.ToList();
    }

    public void TriggerDialogue()
    {
        if (triggered == false)
        {
            if (FindObjectOfType<DialogueManager>() != null)
            {
                FindObjectOfType<DialogueManager>().StartDialogue(dialogue[dialogueNum]);
                dialogueNum += 1;
            }
            triggered = true;
        }
    }

    private void Update()
    {
        if (DialogueManager.dialogueEnded == true)
        {
            if (dialogueNum == dialogue.Count)
            {
                return;
            }
            else
            {
                FindObjectOfType<DialogueManager>().StartDialogue(dialogue[dialogueNum]);
                DialogueManager.dialogueEnded = false;
                dialogueNum += 1;
            }
        }
    }
}

And last the trigger editor script:

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

[CustomEditor(typeof(DialogueTrigger))]
public class DialogueTriggerEditor : Editor
{
    private SerializedProperty _dialogues;
    private SerializedProperty _conversations;

    private void OnEnable()
    {
        _conversations = serializedObject.FindProperty("conversations");
    }

    public override void OnInspectorGUI()
    {
        //base.OnInspectorGUI();

        serializedObject.Update();

        _conversations.arraySize = EditorGUILayout.IntField("Conversations Size", _conversations.arraySize);

        for (int x = 0; x < _conversations.arraySize; x++)
        {
            var conversation = _conversations.GetArrayElementAtIndex(x);

            var Id = conversation.FindPropertyRelative("Id");
            EditorGUILayout.PropertyField(Id);

            _dialogues = conversation.FindPropertyRelative("Dialogues");

            _dialogues.arraySize = EditorGUILayout.IntField("Dialogues size", _dialogues.arraySize);

            for (int i = 0; i < _dialogues.arraySize; i++)
            {
                var dialogue = _dialogues.GetArrayElementAtIndex(i);
                EditorGUILayout.PropertyField(dialogue, new GUIContent("Dialogue " + i), true);
            }
        }

        serializedObject.ApplyModifiedProperties();
    }
}

And a screenshot result:

Conversations

I think that all the Id's in the Inspector should be children of the Conversations Size and all the Dialogues Size should be child of the Id and then the Dialogues should be childs of the Dialogues Size.

Conversation Size
   Id 1
    Dialogues Size
      Dialogue 1
        Name
        Sentences
      Dialogue 2

Something like that.

Dubi Duboni
  • 813
  • 2
  • 17
  • 33

1 Answers1

1

You should instead have a proper class

[Serializable]
public class Conversation
{
    public string Id;
    public List<Dialogue> Dialogues = new List<Dialogue>();
}

and than instead have a list of that in

public DialogueTrigget : MonoBehaviour
{
    public List<Conversation> Conversations = new List<Conversation> ();
    ...
}

Than you can use exactly the same script I gave you last time but with

_conversations = serializedObject.FindProperty("Conversations");

and accordingly one for loop more similar to what you tried already .. something like

[CustomEditor(typeof(DialogueTrigger))]
public class DialogueTriggerEditor : Editor
{
    private SerializedProperty _dialogues;
    private SerializedProperty _conversations;

    private void OnEnable()
    {
        _conversations = serializedObject.FindProperty("conversation");
    }

    public override void OnInspectorGUI()
    {
        //base.OnInspectorGUI();

        serializedObject.Update();

        _conversations.arraySize = EditorGUILayout.IntField("Conversation Size", _conversations.arraySize);

        for (int x = 0; x < _conversations.arraySize; x++)
        {
            var conversation = _conversations.GetArrayElementAtIndex(x);

            var id = conversation.FindPropertyRelative("I'd");

            EditorGUI.indentLevel ++;
            EditorGUILayout.PropertyField(Id);

            var dialogues = conversation.FindPropertyRelative("Dialogues");

            dialogues.arraySize = EditorGUILayout.IntField("Dialogues size", dialogues.arraySize);

            for (int i = 0; i < dialogues.arraySize; i++)
            {
                var dialogue = _dialogues.GetArrayElementAtIndex(i);
                EditorGUI.indentLevel++;
                EditorGUILayout.PropertyField(dialogue, new GUIContent("Dialogue " + i), true);

                EditorGUI.indentLevel--;
            }

            EditorGUI.indentLevel--;
        }

        serializedObject.ApplyModifiedProperties();
    }
}

or alternatively simply

EditorGUILayout.PropertyField(_conversations, new GUIContent ("Conversations"), true);

but this would not print "Dialogue 1, Dialogue 2" etc


Again I strongly recommend you have a look at the nested ReorderableList you will see it is awesome once you got it working.


Typed on my smartphone so no warranty

derHugo
  • 83,094
  • 9
  • 75
  • 115
  • This is almost working like I wanted. The idea is working but the dialogues per conversation are not under the conversation. I made a screenshot in the link https://imgur.com/a/O3Lp0W8 You can see that the Id's are not under Conversations Size. I think they should be all under the Conversations Size and then you can see that the dialogues of each conv 1 and conv 2 not under the conv's. The dialogues of conv 1 should be childs of conv 1 and same for conv 2 and conv 3 and so on. – Dubi Duboni Mar 30 '19 at 19:27
  • Of you mean the indentation you can control it with `EditorGUI.indentLevel`. I added to where I think it is needed ;) – derHugo Mar 31 '19 at 10:17