Generic actors and dynamic conditions

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
Sp1d3r
Posts: 3
Joined: Fri Apr 16, 2021 7:31 am

Generic actors and dynamic conditions

Post by Sp1d3r »

Hey there!

I am wondering if there is a easy way to do the following:
Lets say at the begin of my game I want to spawn 10 actors which all share the same conversation tree.
But each of those actors has a different condition, for example a item which he responds to.
So [actor1] only responds positively to [item1], [actor2] to [item2]...

The way I think it works is I have to add an additional script to the actor which sets a global variable of say: 'validItem' to the one the actor I'm interacting with will respond to.
In the condition of the dialogue I will then compare this set value, with the items the player is currently holding.
That way the condition can stay generic, but will adapt to a local value I can either set in the editor or while instantiating actors.

This method however, feels kinda off to me because it features a separate script and setting global values 'on use'.

My question is, is there a better way to do this, or would this be the intended route?
User avatar
Tony Li
Posts: 22049
Joined: Thu Jul 18, 2013 1:27 pm

Re: Generic actors and dynamic conditions

Post by Tony Li »

Hi,

You can probably take advantage of Variable["ConversantIndex"].

When you start a conversation, you can specify the two primary participants, the actor and conversant. Details: Character GameObject Assignments.

When a conversation starts, it sets 4 variables:
  • Variable["ActorIndex"]: The index in the Actor[] table of the character currently being used as the actor (e.g., "Player").
  • Variable["Actor"]: The display name of the character currently being used as the actor (e.g., "The Chosen One").
  • Variable["ConversantIndex"]: The Index in the Actor[] table of the character currently being used as the conversant (e.g., "NPC_3")
  • Variable["Conversant"]: The display name of the character currently being used as the conversant (e.g., "Joe the NPC").
You could add a custom "validItem" field to each actor that specifies the actor's valid item:

customActorField.png
customActorField.png (11.46 KiB) Viewed 233 times

To access this in Lua, you could use:

Code: Select all

Actor["NPC_3"].validItem
Say the active conversation is using NPC 3 as the conversant. Then this would be equivalent to:

Code: Select all

Actor[Variable["ConversantIndex"]].validItem
Now let's say you have a C# method PlayerHasItem("itemName") that checks if the player has an item. You've registered this C# method with Lua so you can use it in conversations' Conditions fields. Then you could check it like this:

validItemCondition.png
validItemCondition.png (18.2 KiB) Viewed 233 times

If you don't want to do that, you could always check it all in a C# method. Let's say you have a C# method IsDynamicConditionTrue() that you've registered with Lua. Example:

Code: Select all

bool IsDynamicConditionTrue()
{
    string conversantIndex = DialogueLua.GetVariable("ConversantIndex").asString;
    string validItem = DialogueLua.GetActorField(conversantIndex, "validItem").asString;
    return PlayerHasItem(validItem);
}
Then you can just set the dialogue entry node's Conditions field to IsDynamicConditionTrue().
Sp1d3r
Posts: 3
Joined: Fri Apr 16, 2021 7:31 am

Re: Generic actors and dynamic conditions

Post by Sp1d3r »

Hi Tony,

Thank you so much for your swift response!

I get what you are saying, but, and correct me if I am wrong.
But if I spawn X amount of duplicates of a prefab actor, won't they all have the exact same conversantIndex assigned to them?

The intended goal is to spawn X actors which share the same dialogue tree, but (determined at random) they all require a different valid item and won't accept anything else.
So maybe I am misreading part of your explanation, but right now you have banana 'hardcoded' on NPC_3.
I know it is possible to change these values from outside, but my worry is that each NPC_3 conversant will want the exact same valid item.
User avatar
Tony Li
Posts: 22049
Joined: Thu Jul 18, 2013 1:27 pm

Re: Generic actors and dynamic conditions

Post by Tony Li »

I assumed each actor would be unique. You can create new actors at runtime. Example:

Code: Select all

for (int i = 1; i <= 10; i++)
{
    string npcName = "NPC " + i;
    Lua.Run("Actor['NPC_" + i + "'] = { Name='" + npcName + "' }); // Create an empty actor.
    DialogueLua.SetActorField(npcName, "validItem", SomeRandomItem());
}
---

However, if you don't want to do that, you could take a completely different approach and go by the actor's GameObject. For example, say the prefab has this script:

Code: Select all

public class ActorItemInfo : MonoBehaviour
{
    public string validItem;
}
Then:

Code: Select all

var actor = Instantiate(myPrefab);
actor.GetComponent<ActorItemInfo>().validItem = SomeRandomItem();
You can write a C# method that checks the current conversant's validItem:

Code: Select all

bool DoesPlayerHaveValidItem()
{
    var actorItemInfo = DialogueManager.currentConversant.GetComponent<ActorItemInfo>();
    return DoesPlayerHaveItem(actorItemInfo.validItem);
}
Then register that method with Lua, and check it in a dialogue entry's Conditions field.
Sp1d3r
Posts: 3
Joined: Fri Apr 16, 2021 7:31 am

Re: Generic actors and dynamic conditions

Post by Sp1d3r »

Ah excellent!

Both options would work very well with what I have in mind!
I wasn't aware that it was that easy to create new actors at runtime with custom values.

Right now I have the system working with the second method you supplied and it works wonders.

Thank you very much for your help with figuring this out!
Another reason why I don't mind that I bought this asset right before it went on sale ;)
User avatar
Tony Li
Posts: 22049
Joined: Thu Jul 18, 2013 1:27 pm

Re: Generic actors and dynamic conditions

Post by Tony Li »

Sp1d3r wrote: Fri Apr 16, 2021 10:59 amAnother reason why I don't mind that I bought this asset right before it went on sale ;)
Ah, sorry about that. I do that all the time, too! I'll try to make sure you get your money's worth. If any other questions come up, just let me know.
Post Reply