How Can I Build String Array Also Visual And Save It To A Json File ?

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

[CustomEditor(typeof(DialogueTrigger))]
public class DialogueTriggerEditor : Editor
{
    private SerializedProperty _conversations;
    private SerializedProperty _dialogues;
    private SerializedProperty _dialogue;
    private SerializedProperty name;
    private SerializedProperty sentences;
    private bool save = false;
    private bool saved = false;

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

    public override void OnInspectorGUI()
    {
        serializedObject.Update();

        if (_conversations.arraySize == 0)
        {
            _conversations.ClearArray();
            save = false;
        }

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

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

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

            EditorGUI.indentLevel++;
            _dialogues = conversation.FindPropertyRelative("Dialogues");

            if (_dialogues.arraySize == 0)
            {
                save = false;
            }
           
            _dialogues.arraySize = EditorGUILayout.IntField("Dialogues size", _dialogues.arraySize);

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

                name = _dialogue.FindPropertyRelative("name");
                sentences = _dialogue.FindPropertyRelative("sentences");
                for (int y = 0; y < sentences.arraySize; y++)
                {
                    var sentence = sentences.GetArrayElementAtIndex(y).stringValue;
                    if (name.stringValue != "" && sentence != "" && saved == false)
                    {
                        save = true;
                    }
                    else
                    {
                        save = false;
                    }
                }

                EditorGUI.indentLevel--;
            }

            EditorGUI.indentLevel--;
            EditorGUI.indentLevel--;
        }

        serializedObject.ApplyModifiedProperties();

        if (save == false)
        {
            GUI.enabled = false;
        }
        else
        {
            GUI.enabled = true;
        }
        if (GUILayout.Button("Save Conversations"))
        {
           
            //string[] test = new string[1];
            //JsonHelper.ToJson(test, true);
            saved = true;
        }
    }
}

Inside the button “Save Conversations” I want to save the conversations and dialogues name/s and sentences the same structure it is in the three loops:

for (int x = 0; x < _conversations.arraySize; x++)

And

for (int i = 0; i < _dialogues.arraySize; i++)

And

for (int y = 0; y < sentences.arraySize; y++)

The structure in the json file or could be text file should be like in the inspector in the editor :

And then to add a new button for loading and if I press the load button it will load the jkson file and assign it back to the editor to all vars same structure like in the screenshot.

You don’t need loops, check this man page: Unity - Manual: JSON Serialization
Also, the task you’re trying to solve looks like good application for ScripableObject. Imagine you don’t need all that buttons and coding, just select an asset from the project hierarchy and voila - your arrays are in place. Check this: Introduction to Scriptable Objects - Unity Learn

1 Like

Ok I did it so far this way:

And the scriptableobject:

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

[CreateAssetMenu(fileName = "Dialogue System" , menuName = "Conversation")]
public class DSConversation : ScriptableObject
{
    public Conversation[] conversationsSize;
}

And Conversation class:

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

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

And Dialogue class:

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

[System.Serializable]
public class Dialogue
{
    public string name;

    [TextArea(1, 10)]
    public List<string> sentences = new List<string>();
}

But two things with the ScriptableObject script.

Why it put the asset when create a new one in the Assets ? I thought I can drag it to the Hierarchy or it should be in the Assets ?

And how can I change the names Element 0 for example to Conversation 0 and then Element 1 to Conversation 1 or to any conversation name I want it to be by giving it the name typing it in the Assets asset when creating it ?

ScriptableObject is the special type for creating custom assets so yes, it should be there. If you type something into name field, it should stand there. You may want also to create custom editors for your assets later, check this links:
https://unity3d.com/learn/tutorials/topics/interface-essentials/building-custom-inspector