Setting Actor fields not working/saving

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
Herchey
Posts: 1
Joined: Mon Jan 01, 2018 10:58 pm

Setting Actor fields not working/saving

Post by Herchey »

Preemptively, I apologize if this ends up being word salad, but I'm at a bit of a loss in a couple aspects.
This may be partially me not understanding the database as well as needed, but I need to be able to dynamically create new Actors, and update Actor fields (name, description, as well as any other custom fields) because of a character customization mechanic.

Currently, I'm using the DialogueDatabase.actors.Add(Actor name) function to add a new Actor, which works on its own, and it shows up in the dialogue editor as it should. Using the Actor(Actor sourceActor) constructor works mostly ok (outside of problems I'll get to shortly). However, using the Actor() constructor allows me to edit the new Actor's id, but gives me a NullReference if I try to edit the Name, add additional Fields, or quite frankly do anything else with it outside of adding it to the database, which does work. Am I missing something with a blank Actor object?


As for using a copied Actor, like I mentioned before, the .Add function works. The new Actor appears immediately in the Dialogue Editor, and leaving play mode keeps this new object in the DE as well. My confusion is that field edits appear to work in play mode, but do not visually update in the DE, nor do they save after leaving play mode.

Code: Select all

Actor newNPC = new Actor(database.GetActor("Monster_Base"));
newNPC.id = database.actors.Count + 1;
newNPC.Name = "Brent";
database.actors.Add (newNPC);
DialogueLua.SetActorField (database.actors[database.actors.Count - 1].Name, "Experience", 10);
print (DialogueLua.GetActorField("Brent", "Experience").AsString);
This code properly prints out "10", but does not save after leaving play mode, and does not visually update the Dialogue Editor at any point. (Experience shows 0 at all times even after the SetActorField function) At what point is my understanding lacking here?

Thank you in advance.
User avatar
Tony Li
Posts: 22061
Joined: Thu Jul 18, 2013 1:27 pm

Re: Setting Actor fields not working/saving

Post by Tony Li »

Hi,

The fact that you can see the added actor in the Dialogue Editor is a side effect of running the game in the Unity editor. In a build, dialogue database assets in your project are read-only. The Dialogue Editor doesn't officially support showing new actors, etc., that are added to the asset at runtime.

(This isn't entirely true. If you tick the Dialogue Manager's Instantiate Database checkbox, it creates an editable copy in memory. But this isn't the best way to add new content because it doesn't update the Lua environment. Please see below.)

The typical way to add new database content at runtime is to create another dialogue database in memory (rather than an asset file), and add it to the Dialogue System using DialogueManager.AddDatabase(). ID numbers should be unique across both databases. If actors in your initial database use IDs under 1000, you could just set the IDs of your new actors to 1000+.

At runtime, the Dialogue System maintains data in two places: the dialogue database (which it treats as read-only) and the Lua environment (which is read/write). Content that isn't expected to change, such as conversation text, isn't loaded into the Lua environment.

If you only need to change fields in existing actors, it's much easier. Let's say you let the player change his name and age. Use DialogueLua.SetActorField:

Code: Select all

DialogueLua.SetActorField("Player", "Display Name", customName);
DialogueLua.SetActorField("Player", "Age", customAge);
However, if you absolutely need to create additional actors, you can do it like this:

Code: Select all

// Create actor:
var baseNPC = DialogueManager.MasterDatabase.GetActor("Monster_Base");
var newNPC = new Actor(baseNPC)); // Copy of base.
newNPC.id = 1000; // Assign unique ID.
Field.SetValue(newNPC.fields, "Experience", 10);

// Create a new database and add new actor:
var newDatabase = ScriptableObject.CreateInstance<DialogueDatabase>();
newDatabase.actors.Add(newNPC);

// Add new database to runtime environment, which puts its info in Lua:
DialogueManager.AddDatabase(newDatabase);
At this point, since DialogueManager.AddDatabase also set up Lua, you should be able to use DialogueLua.GetActorField to get Brent's Experience.
Post Reply