Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Feedback Create objects from a CSV file that have references

Discussion in 'General Discussion' started by Long2904, Jul 31, 2021.

  1. Long2904

    Long2904

    Joined:
    May 13, 2019
    Posts:
    81
    I currently have a dialogue system that looks like this:
    Code (CSharp):
    1. class Dialogue : ScriptableObject
    2. {
    3.      public string[] dialogues;
    4.      /* Other stuff */
    5.      public Dialogue nextDialogue;
    6. }
    Then I write all the dialogues in an excel file, export them to CSV, and make an Editor script that creates the corresponding dialogue object with OnPostprocessAllAssets. Here's the problem: because nextDialogue is a reference, I can't assign it in the excel file, and because I create all dialogue objects sequentially, there's no way for me to get the correct reference because it may haven't been initialized yet. I'm figuring out 2 ways to solve this:
    1. Add a string dialogueID to Dialogue, change the nextDialogue to nextDialogueID. I also need something like a dictionary to store all the dialogues. This is the simplest solution. I can assign it in excel, and it helps to debug because a normal string is more readable than a reference. Also, in the init function, I don't need to care if I already create the object because all objects are referenced by id.
    Code (CSharp):
    1. class Dialogue : ScriptableObject
    2. {
    3.      public string dialogueID;
    4.      public string[] dialogues;
    5.      /* Other stuff */
    6.      public string nextDialogueID;
    7. }
    8.  
    9. private Dictionary<string, Dialogue> dialogues;
    10.  
    2. Also add an id, but the id only exists in the excel file. When I read the file, loop through all the dialogues 2 times. The first time initialize all dialogue objects (except for nextDialogue), assign all of them to a temp dictionary with keys as id. Then loop through it a second time to assign the corresponding reference base on the dictionary. All of this happens in the OnPostprocessAllAssets. This has the benefits of accessing directly the nextDialogue reference rather than some potentially slow functions like GetDialogueByID (which I guess that you need to loop through all the keys to find the correct one). Directly expose the reference also help when you want to change it in code, or read it in the inspector then click it and it will automatically jump to the correct file in the project view, and when you want to assign it through the inspector, it's just a simple drag-and-drop.

    What should I use? How would you implement it? Are there any other options?
     
  2. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,660
    I would focus on what you want to do in Excel first and foremost. Is extra columns for 'dialogue ID' and 'next ID' actually the most convenient thing for you to author? Is there another way of writing the dialogue in Excel which would be more intuitive/natural, convenient, or robust?

    Beyond that I would ask: how many dialogue entries do you actually expect to have in one of these files, how long will it actually take to process them in OnPostprocessAllAssets (or ScriptedImporter), and how much do you care about memory usage?
     
    JoNax97 likes this.
  3. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,633
    If you intend to edit referneces in unity, but not excel, do not make "dialogue ID" a part of the the dialogue entry and make them something that only appears during serialization.

    If you intend to edit references in excel, then make it a part of dialogue entry.

    Additionally rather than making "Dialogue" a scriptable objects just so it can store references, you can make a "Dialogue Container" which will contain a flat array with all the dialogues, and a reference will be an index in the array. In this case an individual dialogue can be a plain class or a plain struct.

    Code (csharp):
    1.  
    2. [System.Serializable]
    3. public struct DialogueEntry{
    4.     public string[] lines;
    5.     public int nextIndex;
    6. };
    7.  
    8. public class DialogueStorage: ScriptableObject{
    9.      public DialogueEntry[] entries = new DialogueEntry[0];//you an also make it a list.
    10. }
    11.  
    In this case you'll have many lines stored in one place instead of having to hunt them through the references.
     
  4. Long2904

    Long2904

    Joined:
    May 13, 2019
    Posts:
    81
    @superpig I don't really know any other way of writing the reference in excel, that's why I asked if anybody has any other options. My game doesn't have that many dialogues, so about 100 dialogue objects is enough. Each language that my game support will have a different excel file for localization. Because this process happens in the editor rather than runtime, I don't really care about memory usage that much.
     
  5. Long2904

    Long2904

    Joined:
    May 13, 2019
    Posts:
    81
    @neginfinity I don't know upfront which index a particular object will be in (so I still can't edit in excel), and editing some number rather than a string id (e.g "dungeon_player_02") in excel would make it more error-prone, hard to debug and less intuitive (what happen if I want to rearrange the order of some dialogue objects in excel?).