Writing Custom Sequencer for Movement

Announcements, support questions, and discussion for the Dialogue System.
User avatar
Tony Li
Posts: 22055
Joined: Thu Jul 18, 2013 1:27 pm

Re: Writing Custom Sequencer for Movement

Post by Tony Li »

Hi,

Try changing the Sequence to:

Code: Select all

WalkToPoint(Owen, 1, 4, true);
SetDialoguePanel(false);
required SetDialoguePanel(true)@Message(FinishedWalking);
Continue()@Message(FinishedWalking)
The 'required' keyword should guarantee that the SetDialoguePanel(true) command runs.
Mackerel_Sky
Posts: 111
Joined: Mon Apr 08, 2019 8:01 am

Re: Writing Custom Sequencer for Movement

Post by Mackerel_Sky »

That was the trick, thanks!
User avatar
Tony Li
Posts: 22055
Joined: Thu Jul 18, 2013 1:27 pm

Re: Writing Custom Sequencer for Movement

Post by Tony Li »

Glad to help! :-)
Mackerel_Sky
Posts: 111
Joined: Mon Apr 08, 2019 8:01 am

Re: Writing Custom Sequencer for Movement

Post by Mackerel_Sky »

Hey there,

I figured this is somewhat tangentially related and not really worth setting up a new thread. I'm now trying to write a sequencer command that will check if the player has enough of a certain item to hand in a collection quest. The idea I had in mind was that on Awake the sequencer will run a check of the player inventory and set a database variable to true if the player is ready to hand the quest in, and false if it is not.

I planned to use the command on the NPC greeting dialogue so that if the player didn't hand in the quest, lost some items and came back, the variable is reset to false. If the variable is true, I use a condition in the child nodes to add an option to hand in the quest items. If it is false, the option doesn't show up.

Only problem is, I'm not sure how to set the variable to true within the sequencer script. I've browsed through the documentation and nothing seems to stand out, as I can't use SetVariable within the command.

My code looks like this:

Code: Select all

            foreach (InventoryObjectTemplate item in inventory.inventoryList) //look through the player inventory
            {
                if (item != null && item.objectID == itemToFind) //if there is an item that this quest needs
                {
                    if (item.numberOfObjects >= amountRequired)
                    {
                        XXXXX
                        Stop();
                    }
                }
            }
            Stop();
            

On another note, I've somehow forgotten where the Actor variables are and can't seem to find them again. Do you know where I could access them? They look like this:

Code: Select all

Actor["Perisher"].HasSpoken = true
Thanks!
User avatar
Tony Li
Posts: 22055
Joined: Thu Jul 18, 2013 1:27 pm

Re: Writing Custom Sequencer for Movement

Post by Tony Li »

I recommend using a Lua function for that. Let's say you have a C# method called GetItemCount("item"). You can register the function with Lua. Then set the Conditions field to check GetItemCount. For example, say the quest is to fetch 3 apples. Your greeting node could link to these 2 nodes:
  • Dialogue Text: "Great job! Those 3 apples will do perfectly."
  • Conditions: GetItemCount("Apple") >= 3
  • Dialogue Text: "Hurry up and get all 3 apples. I'm waiting."
  • Conditions: GetItemCount("Apple") < 3
You can either type in the Conditions manually or configure Custom Lua Function Info to make it available in the "..." dropdown. (Scroll down a bit in the link above for info about Custom Lua Function Info.)

Typically you'll also have corresponding AddItem("item", amount) and RemoveItem("item", amount) methods that are registered with Lua so you can use them in Script fields:
  • Dialogue Text: "Great job! Those 3 apples will do perfectly."
  • Conditions: GetItemCount("Apple") >= 3
  • Script: RemoveItem("Apple", 3)
Mackerel_Sky wrote: Thu Jan 09, 2020 4:40 amOn another note, I've somehow forgotten where the Actor variables are and can't seem to find them again. Do you know where I could access them? They look like this:

Code: Select all

Actor["Perisher"].HasSpoken = true
In the Dialogue Editor, the actor variables are in the Actors tab, inside the actor's All Fields foldout.

In C#, you can use DialogueLua.GetActorField("Perisher", "HasSpoken").asBool to get a value and DialogueLua.SetActorField("Perisher", "HasSpoken", true) to set it.
Mackerel_Sky
Posts: 111
Joined: Mon Apr 08, 2019 8:01 am

Re: Writing Custom Sequencer for Movement

Post by Mackerel_Sky »

Hey,

Thanks for the information. I gave the Lua functions a shot but don't think I'm doing it correctly. My code looks like this- I just copied it over from the documentation as instructed and added my function in.

Code: Select all

using UnityEngine;
using PixelCrushers.DialogueSystem;

public class MyLuaFunctions : MonoBehaviour
{
    PlayerInventory inventory;
   // double itemToFind; //Lua refers to ints as doubles
   // double amountRequired;

    void OnEnable()
    {
        Lua.RegisterFunction("CheckForItem", this, SymbolExtensions.GetMethodInfo(() => CheckForItem(0,0)));
    }

    void OnDisable()
    {
        // Note: If this script is on your Dialogue Manager & the Dialogue Manager is configured
        // as Don't Destroy On Load (on by default), don't unregister Lua functions.
       // Lua.UnregisterFunction("GameObjectExists"); // <-- Only if not on Dialogue Manager.
    }

    public bool CheckForItem(double itemToFind, double amountRequired)
    {
        foreach (InventoryObjectTemplate item in inventory.inventoryList) //look through the player inventory
        {
            if (item ~= null && item.objectID == itemToFind) //if there is an item that this quest needs
            {
                if (item.numberOfObjects >= amountRequired)
                {
                    return true;
                }
            }
        }
        return false;
    }
}
When I try to drag it onto the dialogue manager game object it doesn't get added like a normal script. I'm also not sure if I did the SymbolExtensions.GetMethodInfo(() => CheckForItem(0,0))); part correctly either- the script should take two ints, an item ID and an amount required.
User avatar
Tony Li
Posts: 22055
Joined: Thu Jul 18, 2013 1:27 pm

Re: Writing Custom Sequencer for Movement

Post by Tony Li »

Hi,

Change this part:

Code: Select all

CheckForItem(0,0))
to this:

Code: Select all

CheckForItem((double)0,(double)0))
just to make it totally clear that it will be sending doubles.
Mackerel_Sky wrote: Fri Jan 10, 2020 7:08 amWhen I try to drag it onto the dialogue manager game object it doesn't get added like a normal script.
It should look like a normal script, albeit one without any fields in the inspector since there aren't any public variables in the script. Make sure the class name (MyLuaFunctions) exactly matches the script filename.
Mackerel_Sky
Posts: 111
Joined: Mon Apr 08, 2019 8:01 am

Re: Writing Custom Sequencer for Movement

Post by Mackerel_Sky »

I've made the changes as instructed, and also changed ~= back to != because Visual Studio didn't like it for some reason. I was able to add it to the game object after changing the class name too. Now I'm trying to figure out how to configure CustomLuaFunction to add it to the dropdown wizard. It looks like this at the moment:

Image

I'm pretty sure it's supposed to be a script function as it should run in the starting dialogue and set the variable to true/false so the manager can set the response option later on. However I can't seem to see it visible in the dropdown wizard. Do I have to put the CustomLuaFunctionInfo script somewhere else?

Thanks for your help so far.
User avatar
Tony Li
Posts: 22055
Joined: Thu Jul 18, 2013 1:27 pm

Re: Writing Custom Sequencer for Movement

Post by Tony Li »

You're almost there! It should be in the Condition Functions section. Presumably you're going to use it in a dialogue entry node's Conditions field to check if the player has a certain amount of an item. Set the Function Name to CheckForItem. The parameters and return value should be exactly like in your screenshot, except in the Condition Functions section.

If you need another function to add/remove items, add it to your C# script in a similar manner. Then add it to the Script Functions section of your CustomLuaFunctionInfo asset.
Mackerel_Sky
Posts: 111
Joined: Mon Apr 08, 2019 8:01 am

Re: Writing Custom Sequencer for Movement

Post by Mackerel_Sky »

I was able to get it to display properly- the conditions line looks like this now:

(CurrentQuestState("Test Quest - Collect") == "active") and (LuaCheckItem(0, 2) == true)

Now the error is:

Dialogue System: Lua code 'return (CurrentQuestState("Test Quest - Collect") == "active") and (LuaCheckItem(0, 2) == true)' threw exception 'Tried to invoke a function call on a non-function value. If you're calling a function, is it registered with Lua?'

I'm pretty sure I register the function using OnEnable() as per the example script, so I'm not sure what else is going on. Do you have any clues?
Post Reply