Invector FSM AI and Quest Machine - pause AI character
Invector FSM AI and Quest Machine - pause AI character
Hi! I'm absolutely loving Quest Machine, and the integration you provide for Invector is absolutely brilliant and works perfectly.
One thing I'd like to do is use Quest Giver with my patrolling AIs. This works, but when I launch the dialog via `StartDialogWithPlayer`, while my character pauses (thanks to `QuestMachinePausePlayer`), my NPC continues his patrol.
Happy to code around this, but wondered if there were any components that I could attach to my AIs to pause their movement during quest dialog? I've obviously tried `QuestMachinePausePlayer` with no success).
I have also tried creating a new state in my AI FSM ("Converse"), but need an Event on the Quest Giver that I can call to toggle the decision for that state to be selected. I can't see any public Event that I can hook into.
Any ideas?
Thank you!
One thing I'd like to do is use Quest Giver with my patrolling AIs. This works, but when I launch the dialog via `StartDialogWithPlayer`, while my character pauses (thanks to `QuestMachinePausePlayer`), my NPC continues his patrol.
Happy to code around this, but wondered if there were any components that I could attach to my AIs to pause their movement during quest dialog? I've obviously tried `QuestMachinePausePlayer` with no success).
I have also tried creating a new state in my AI FSM ("Converse"), but need an Event on the Quest Giver that I can call to toggle the decision for that state to be selected. I can't see any public Event that I can hook into.
Any ideas?
Thank you!
Re: Invector FSM AI and Quest Machine - pause AI character
So, I think I sorta answered my own question! I've taken "Quest Machine Pause Player" and created "Quest Machine Pause Npc". I've replaced all of the code with code that simply toggles a boolean on a custom NPC component, subscribing to the same event messages as player. I have a state in my AI FSM called "Converse", that has no action, and is driven by a simple custom Decision that returns the boolean value to the state machine.
So when I start a conversation, the NPC state goes from "Patrol" to "Converse", and when the conversation ends, the state returns to "Patrol".
All working nicely!
EDIT: Ah, so I'm guessing this will put ALL of my NPCs into the "Converse" state! Back to the drawing board!
So when I start a conversation, the NPC state goes from "Patrol" to "Converse", and when the conversation ends, the state returns to "Patrol".
All working nicely!
EDIT: Ah, so I'm guessing this will put ALL of my NPCs into the "Converse" state! Back to the drawing board!
Re: Invector FSM AI and Quest Machine - pause AI character
Hi,
If you only want to stop the NPC that the player is conversing with, make a subclass of QuestGiver and use it on the NPC. Override StartMostRelevantDialogue() and StopDialogue():
If you really do want all of your NPCs to pause -- for example, to stop shooting at the player during dialogue -- then see below:
If you only want to stop the NPC that the player is conversing with, make a subclass of QuestGiver and use it on the NPC. Override StartMostRelevantDialogue() and StopDialogue():
Code: Select all
public class InvectorQuestGiver : QuestGiver
{
protected override void StartMostRelevantDialogue()
{
base.StartMostRelevantDialogue();
// (Pause NPC here)
}
protected override void StopDialogue() // [EDIT: See follow-up below. Don't use this method]
{
base.StopDialogue();
// (Unpause NPC here)
}
}
If you really do want all of your NPCs to pause -- for example, to stop shooting at the player during dialogue -- then see below:
Pause all NPCs
The default Quest Dialogue UI prefab sends the messages "Pause Player" when dialogue starts and "Unpause Player" when dialogue ends. This uses Quest Machine's Message System.
You can add a script to your patrolling AIs that listen for these messages by implementing IMessageHandler. Rough example:
You can add a script to your patrolling AIs that listen for these messages by implementing IMessageHandler. Rough example:
Code: Select all
using UnityEngine;
using PixelCrushers;
public class PauseAIDuringDialogue : MonoBehaviour, IMessageHandler
{
void OnEnable()
{
MessageSystem.AddListener(this, "Pause Player", string.Empty);
MessageSystem.AddListener(this, "Unpause Player", string.Empty);
}
void OnDisable()
{
MessageSystem.RemoveListener(this);
}
void OnMessage(MessageArgs messageArgs)
{
switch (messageArgs.message)
{
case "Pause Player":
// (Your code here to pause AI)
break;
case "Unpause Player":
// (Your code here to unpause AI)
break;
}
}
}
Re: Invector FSM AI and Quest Machine - pause AI character
Wow, what an amazing response! Thanks Tony!
Re: Invector FSM AI and Quest Machine - pause AI character
This works great with , but doesn't seem to get invoked, whichever way I close the dialog.
I had to tweak your code a little, replacing "protected" for "public", though not sure that's the problem:
Code: Select all
StartMostRelevantDialogue
Code: Select all
StopDialogue
I had to tweak your code a little, replacing "protected" for "public", though not sure that's the problem:
Code: Select all
public override void StopDialogue()
{
_npc.isInConversation = false;
base.StopDialogue();
}
Re: Invector FSM AI and Quest Machine - pause AI character
Sorry about that. StopDialogue() is used to manually interrupt a dialogue before it finishes normally.
Instead, adjust your subclass to do something like this, which uses the message system to listen for the message "Unpause Player" that the dialogue UI sends when closing.
Instead, adjust your subclass to do something like this, which uses the message system to listen for the message "Unpause Player" that the dialogue UI sends when closing.
Code: Select all
using PixelCrushers;
using PixelCrushers.QuestMachine;
public class InvectorQuestGiver : QuestGiver
{
protected override void StartMostRelevantDialogue()
{
base.StartMostRelevantDialogue();
MessageSystem.AddListener(this, "Unpause Player", string.Empty);
// Pause NPC here
}
public override void OnMessage(MessageArgs messageArgs)
{
if (messageArgs.message == "Unpause Player")
{
// Unpause NPC here
MessageSystem.RemoveListener(this, "Unpause Player", string.Empty);
}
base.OnMessage(messageArgs);
}
// Clean up just in case we disable the quest giver before receiving "Unpause Player":
public override void OnDisable()
{
base.OnDisable();
MessageSystem.RemoveListener(this, "Unpause Player", string.Empty);
}
}
Re: Invector FSM AI and Quest Machine - pause AI character
Perfect Tony, that works a treat!
Re: Invector FSM AI and Quest Machine - pause AI character
It sounds like you've made some progress in customizing NPC behavior for conversations. However, as you've noted, your current approach would indeed affect all NPCs uniformly. Magic 8 Ballmroshaw wrote: ↑Sat Jan 22, 2022 12:13 pm So, I think I sorta answered my own question! I've taken "Quest Machine Pause Player" and created "Quest Machine Pause Npc". I've replaced all of the code with code that simply toggles a boolean on a custom NPC component, subscribing to the same event messages as player. I have a state in my AI FSM called "Converse", that has no action, and is driven by a simple custom Decision that returns the boolean value to the state machine.
So when I start a conversation, the NPC state goes from "Patrol" to "Converse", and when the conversation ends, the state returns to "Patrol".
All working nicely!
EDIT: Ah, so I'm guessing this will put ALL of my NPCs into the "Converse" state! Back to the drawing board!