Page 1 of 1

[Solved] Swap the ID of two actors? (not at runtime)

Posted: Fri Oct 26, 2018 6:25 am
by Japtor
Hi,

Is it possible to swap the ID of two actors? Of course not at runtime. I just don't want to delete the characters and create them again to have the ID's of the actors in a specific order that I need.

Thanks! :)

Re: Swap the ID of two actors? (not at runtime)

Posted: Fri Oct 26, 2018 9:03 am
by Tony Li
Hi,

It's not easy. Think of the IDs as internal values, kind of like GUIDs that Unity assigns to asset files in a Unity project. If you change an asset's GUID, you need to open all scenes and prefabs that reference the asset and update the reference.

Why do you need the IDs in a specific order? Maybe I can suggest a different approach.

If you really need the IDs in a specific order, you can do the following. Let's say your actors are:
  • (1) Player
  • (2) Bob
  • (3) Adam
And your conversation involves the Player and Bob. Internally, the conversation involves actor IDs 1 & 2. Inspect the conversation's properties (click on empty canvas area), and change the conversant to Adam. Now internally the conversation involves actor IDs 1 & 3. Repeat for all conversations that involve Bob.

Then go to the Actors tab. Rename Bob to Adam, and rename Adam to Bob. So your actors will be:
  • (1) Player
  • (2) Adam
  • (3) Bob
Since your conversation involves actor IDs 1 & 3, it will now involve Player and Bob again.

You could also process the dialogue database asset in a custom script. It's just a ScriptableObject. Let's use the example above, where Bob=2 and Adam=3. You could loop through all conversations and all dialogue entries, and replace all references to ActorID=2 with a temporary value such as -1. Then loop through again replace all ActorID=3 with 2. Finally loop through one more time and replace all ActorID=-1 with 3.

In either case, make a backup of your database before doing any of this.

Then again, if you don't mind describing what your requirements are, maybe there's an easier solution than swapping IDs.

Re: Swap the ID of two actors? (not at runtime)

Posted: Fri Oct 26, 2018 10:29 am
by Japtor
Hi,

I have thought of something that could work. If it doesn't work I will let you know. However, I have a doubt.

In the last post about getting the current id of the actor, I have checked that "PixelCrushers.DialogueSystem.DialogueManager.currentConversationState.subtitle.speakerInfo.id" gets the actor ID from the last dialogue node and not from the current node.

What I have done is: Inside the dialogue node which I am interested to get its actor ID, I have written inside the script panel a Lua function which basically calls the method at the top of this post.

Any idea to solve it? :)

Thanks!

Re: Swap the ID of two actors? (not at runtime)

Posted: Fri Oct 26, 2018 10:48 am
by Tony Li
Japtor wrote: Fri Oct 26, 2018 10:29 amIn the last post about getting the current id of the actor, I have checked that "PixelCrushers.DialogueSystem.DialogueManager.currentConversationState.subtitle.speakerInfo.id" gets the actor ID from the last dialogue node and not from the current node.
If you use this code in OnPrepareConversationLine, that's correct. This is because it's only considering the node; it hasn't chosen it yet. If you use the code in OnConversationLine, speakerInfo.id should be the actor ID of the current node.
Japtor wrote: Fri Oct 26, 2018 10:29 amWhat I have done is: Inside the dialogue node which I am interested to get its actor ID, I have written inside the script panel a Lua function which basically calls the method at the top of this post.
I'm sorry, I don't understand. Would you please describe an example case?

Re: Swap the ID of two actors? (not at runtime)

Posted: Fri Oct 26, 2018 12:14 pm
by Japtor
Hi,

Sorry for my explanation. I was just saying that for now, I have a script which registers a Lua function (very basic just for debugging).

Code: Select all

  void OnEnable()
  {
    Lua.RegisterFunction("GetActualActorID", this, typeof(DialogueCharactersInfo).GetMethod("GetActualActorID"));
  }

  void OnDisable()
  {
    Lua.UnregisterFunction("GetActualActorID");
  }
Inside the registered function, it only calls a Debug.Log of "PixelCrushers.DialogueSystem.DialogueManager.currentConversationState.subtitle.speakerInfo.id"

Code: Select all

  public void GetActualActorID()
  {        
    Debug.Log(PixelCrushers.DialogueSystem.DialogueManager.currentConversationState.subtitle.speakerInfo.id);
  }
So, inside some Dialogue Nodes, I've just written the function name GetActualActorID() inside the Script panel which runs Lua code.

About the OnConversationLine function. Where and how should I run it?

Thanks! :)

Re: Swap the ID of two actors? (not at runtime)

Posted: Fri Oct 26, 2018 2:42 pm
by Tony Li
Add it to a C# script on the Dialogue Manager. More info: Script Messages. You can look at the ConversationLogger.cs script for an example.

Another example:

Code: Select all

void OnConversationLine(Subtitle subtitle)
{
    Debug.Log("Actor #" + subtitle.speakerInfo.id + " says: " + subtitle.formattedText.text);
}

Re: Swap the ID of two actors? (not at runtime)

Posted: Fri Oct 26, 2018 3:38 pm
by Japtor
Hi,

I have created a basic script and added as you told me inside the Dialogue Manager. I have created a "static Subtitle m_DialogueEntry".

Code: Select all

public static Subtitle m_DialogueEntry;

  public void OnConversationLine(Subtitle subtitle)
  {
    m_DialogueEntry = subtitle;
    Debug.Log("Process: " + subtitle.speakerInfo.id);
  }
I keep the Lua function, which now calls to a Debug.Log of the m_DialogueEntry:

Code: Select all

void OnEnable()
  {
    Lua.RegisterFunction("GetActualActorID", this, typeof(DialogueCharactersInfo).GetMethod("GetActualActorID"));
  }

  void OnDisable()
  {
    Lua.UnregisterFunction("GetActualActorID");
  }
  
  public void GetActualActorID()
  {        
    Debug.Log("Lua: " + ProcessActualDialogueNode.m_DialogueEntry.speakerInfo.id);
  }
It seems that the GetActualActorID() function is called (remember that is written inside the Dialogue Node -> Script) before the OnConversationLine(Subtitle subtitle). Is there a way OnConversationLine could be called before the Lua script.

Thanks!

Re: Swap the ID of two actors? (not at runtime)

Posted: Fri Oct 26, 2018 4:12 pm
by Tony Li
You can use OnPrepareConversationLine for that. This method is called before the dialogue entry's Script. It's also called before the Subtitle object is set up, so it passes a DialogueEntry:

Code: Select all

public void OnPrepareConversationLine(DialogueEntry entry)
{
    m_DialogueEntry = entry;
    Debug.Log("Process: " + entry.ActorID);
}

Re: Swap the ID of two actors? (not at runtime)

Posted: Fri Oct 26, 2018 4:17 pm
by Japtor
Hi,

Yeah, that worked out. Thank you so much for your help! :)

See you all!