How to manipulate tasks in one quest

Announcements, support questions, and discussion for Quest Machine.
Daffy
Posts: 19
Joined: Wed Feb 06, 2019 1:17 pm

How to manipulate tasks in one quest

Post by Daffy »

Hello, I'm a bit confused about how this asset works.
I want to achieve this situation:

1. Player received a Quest1 from NPC (quest giver). I have this part

2. This Quest1 has 3 tasks:
A. Collect 0/20 trashes. Node called "Collect the trashes"
B. Collect the clothes 0/20. Node "Ciuchy"
C. Fix the elecricity in home. Node "Prąd"
I have this part

3. Now Task A and B should be shown from the start. I have this part

4. But Task C is hidden from the start. It will appear when player enter the trigger. If this task appear I want to block (not hide) the task B. I don't have this part. And I have no idea how to setup this. I don't know how the tree in quest editor should look

5. if the player goes to different trigger the task C will be done, it will hide and task B should be available again.

6. And now the 4 and 5 step should be in a loop. I mean if the player once again goes to a trigger in 4 point it will do the logic one more time.

So want I understand I can use message to the node "Prąd", but it dont receive anything if has state inactive (which I want from the start). Also counters doesn't work when the state is inactive. I tought I can use 0 - electricity on and 1- electricity off - just like a switch light. But not working.


Bug 1. I also have problem with Inspector when I have focus quest or questdatabase. Very often it doesnt recognize any clicks or changes. Only this asset have this problem.
Bug 2. Also I don't have runtime view how the quest is flowing. I always sees every condition as inactive, even if they are working fine (I see for example alerts on active state)
Bug 3. How I can change the order of headers in journayl. I want the Queast1 to be above the tasks (screenshot)

In attachmenst should be 2 screenshots.
Attachments
q1.png
q1.png (898.39 KiB) Viewed 1414 times
q2.png
q2.png (40.16 KiB) Viewed 1414 times
Daffy
Posts: 19
Joined: Wed Feb 06, 2019 1:17 pm

Re: How to manipulate tasks in one quest

Post by Daffy »

Oh and just in case, I want to interupt during the Task B instead of completed it, checking and then revert it.
I need the if the task C appear, the task B become "pause" until the task C is completed.

For example go to the circle from tutorial on youtube, but suddenly there is an ambush, so you need to first kill a monster. After that the tasks with go to the cirlce go back to active. and now this monster can appear again, and again
User avatar
Tony Li
Posts: 22001
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to manipulate tasks in one quest

Post by Tony Li »

Hi,

Set up your quest like this:

daffy.png
daffy.png (29.96 KiB) Viewed 1393 times
  • The Both True node has conditions that (A) Collect Trash and (B) Cuichy are true.
  • The Enter Trigger 1 node listens for a message that the player has entered a trigger collider. The Trigger 1 GameObject might look something like this:
    trigger1.png
    trigger1.png (40.35 KiB) Viewed 1393 times
    and your Enter Trigger 1 node would listen for the message "Entered" + "Trigger 1".
  • The Prąd node's Active state > Actions should set Cuichy inactive. Use a Set Quest Node State action.
  • The Prąd node's True state > Actions should set Cuichy active again, and set Enter Trigger 1 and Prąd inactive again.

> Bug 1. I also have problem with Inspector when I have focus quest or questdatabase. Very often it doesnt recognize any clicks or changes. Only this asset have this problem.

There are no known issues like this. What versions of Unity and Quest Machine are you using? What OS version?


> Bug 2. Also I don't have runtime view how the quest is flowing. I always sees every condition as inactive, even if they are working fine (I see for example alerts on active state)

Make sure you're inspecting the GameObject that has the Quest Journal component. The Quest Journal will have the active instance of the quest. The Quest Giver will have an inactive instance of the quest. Also make sure you're not inspecting the original quest asset file itself. You must inspect the Quest Journal component to see its active state.


> Bug 3. How I can change the order of headers in journal. I want the Queast1 to be above the tasks (screenshot)

The main quest's Journal Text appears first. Put the quest heading in the main info's Journal Text. (Click on blank canvas space instead of a node to see the main info.) Then quest nodes' Journal Text appears below it. To change the order of the quest nodes' text, inspect the main info's Node Order For UIs, which is at the bottom of the inspector.
Daffy
Posts: 19
Joined: Wed Feb 06, 2019 1:17 pm

Re: How to manipulate tasks in one quest

Post by Daffy »

Thank you so much! Is working.

Now I have two more questions

1. How to show animations that the task in journal is completed (for example green text). I know now that I can change <color> but the Enter Trigger 1 and Prąd nodes are going in a loop logic. Node Prąd has a string asset "Fix the electricity in house" and showing it in journal. It will appear and disappear, but now how to achieve to show as completed, and after that disappear it. (without coding if possilbe).

2. Ok so now let's says I have Quest2 which is exactly the same as this Quest1. It also has this electricity logic loop.
Player has both quest in active. In Quest2 he goes to Enter Trigger1 and turn off the electricity in house. So now the Quest1 should also change, because there is one source od electro in house.

2B. the same as above but the Quest1 is not active and Quest2 is active. Quest2 goes to Enter Trigger, disable electro in house AND now the player will gain Quest1. So it should check the electro state from the very beginning but inactive nodes don't listening to the message or anything.

2C. how to resolve this maybe more globally like per house which will have 20 quests to do something with washing machine, dishwasher, fridge, TV and more. If the electrifcity goes off then all of this quests should listen to this event, no matter if they are active or not (because they can be active at any time)
User avatar
Tony Li
Posts: 22001
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to manipulate tasks in one quest

Post by Tony Li »

Hi,
Daffy wrote: Thu Aug 15, 2024 5:38 am1. How to show animations that the task in journal is completed (for example green text). I know now that I can change <color> but the Enter Trigger 1 and Prąd nodes are going in a loop logic. Node Prąd has a string asset "Fix the electricity in house" and showing it in journal. It will appear and disappear, but now how to achieve to show as completed, and after that disappear it. (without coding if possilbe).
You will probably need to do some coding. The methods in UnityUIQuestJournalUI are virtual to make it easy for you to make a subclass to extend it with whatever features you want to add.
Daffy wrote: Thu Aug 15, 2024 5:38 am2. Ok so now let's says I have Quest2 which is exactly the same as this Quest1. It also has this electricity logic loop.
Player has both quest in active. In Quest2 he goes to Enter Trigger1 and turn off the electricity in house. So now the Quest1 should also change, because there is one source od electro in house.

2B. the same as above but the Quest1 is not active and Quest2 is active. Quest2 goes to Enter Trigger, disable electro in house AND now the player will gain Quest1. So it should check the electro state from the very beginning but inactive nodes don't listening to the message or anything.

2C. how to resolve this maybe more globally like per house which will have 20 quests to do something with washing machine, dishwasher, fridge, TV and more. If the electrifcity goes off then all of this quests should listen to this event, no matter if they are active or not (because they can be active at any time)
Write a custom quest condition that checks if the electricity is on or off. For example, your quest might look like this:

checkElectricity.png
checkElectricity.png (36.94 KiB) Viewed 1320 times

The "Is Electricity On?" node uses the custom quest condition to require that the electricity is on.

For active quests: Any number of quests can listen for the same message (e.g., "Electricity" + "Off"). If you send this message, any quest nodes that are listening for it will handle it.
Daffy
Posts: 19
Joined: Wed Feb 06, 2019 1:17 pm

Re: How to manipulate tasks in one quest

Post by Daffy »

Hmmm ok so I made a custom script. It receiving the message but after I send one (after checking if there is electricity in home) the states doesn't change. I can see that the messages are correct. Here is a code:

Code: Select all

public bool ElectroStateSwitch
{
    get => _electroState;
    set => _electroState = value;
    
}
[SerializeField] private bool _electroState;
[SerializeField] private string _messageElectroOn; //Q1:E1
[SerializeField] private string _messageElectroOff; //Q:E

private void Start()
{
    MessageSystem.AddListener(this, "Is", "Electro"); // subscribe for a message sending from quest node "Is Electro?"
}
private void Awake()
{
    foreach(var socket in _electroSockets)
    {
        socket.ElectroFuseBox = this;
    }

}
public void TurnOffElectro()
{
    ElectroStateSwitch = false;
    SendToMessageSystem(_messageElectroOff);
}

public void SendInformationAboutElectro()
{
    ElectroStateSwitch = !ElectroStateSwitch;
    SendToMessageSystem(ElectroStateSwitch? _messageElectroOn : _messageElectroOff); //this one works perfeclty fine. If the player will turn on/off electricity by fusebox then all nodes are responding to this
}

public void OnMessage(MessageArgs messageArgs)
{
    Debug.Log(messageArgs.sender + messageArgs.message + messageArgs.parameter); // It is debuging correctly, is sender and Is Electro   
    SendToMessageSystem(ElectroStateSwitch ? _messageElectroOn : _messageElectroOff); //in debug log is ok, but the nodes doesnt bother about it
}
Node Is Electro? on active action is sending a message Is Electro
On conditions is listening back for Q1 E1 (which means there is a electro in house), but doesn't change to true state.

On your manual there aren't any code sample for receiving message via script, but I think I have a correct method and codes.
It also doesn't matter where I will put Addlistener (awake, start, onenabled), there will be the same problem
Attachments
obraz_2024-08-16_154730115.png
obraz_2024-08-16_154730115.png (270.42 KiB) Viewed 1261 times
User avatar
Tony Li
Posts: 22001
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to manipulate tasks in one quest

Post by Tony Li »

Hi,

The article How To: Respond To Quest State Changes in Script contains example code that shows how to listen for messages.

However, for the Is Electro node, I recommend making a custom quest condition script. To do this, duplicate QuestConditionTemplate.cs, move the duplicate into your own scripts folder, rename it, and fill in your code where the comments indicate. You can look at any of the existing quest condition scripts for examples, and also refer to the QuestCondition API reference.
Daffy
Posts: 19
Joined: Wed Feb 06, 2019 1:17 pm

Re: How to manipulate tasks in one quest

Post by Daffy »

Ok I checked with this and still nodes doesn't responding for the messages sending via script (the second one in my script above, the first one is working). I would love to resolve in my way because I'm preparing for a fishnet synchronizations so I need to make working via messages.
User avatar
Tony Li
Posts: 22001
Joined: Thu Jul 18, 2013 1:27 pm

Re: How to manipulate tasks in one quest

Post by Tony Li »

Hi,

Here's a working example:

QM_DaffyExample_2024-08-16.unitypackage

The scene looks like this:

daffyScene.png
daffyScene.png (58.79 KiB) Viewed 1183 times

And the quest looks like this:

daffyScene.png
daffyScene.png (58.79 KiB) Viewed 1183 times

This is the simple Power script for the example scene:
Power.cs

Code: Select all

using UnityEngine;
using UnityEngine.UI;

namespace PixelCrushers.QuestMachine.Examples
{

    public class Power : MonoBehaviour, IMessageHandler
    {
        public bool isPowerOn = true;
        public Button getClothesButton;

        private void OnEnable()
        {
            MessageSystem.AddListener(this, "Power", "");
        }

        private void OnDisable()
        {
            MessageSystem.RemoveListener(this);
        }

        public void OnMessage(MessageArgs messageArgs)
        {
            isPowerOn = string.Equals(messageArgs.parameter, "on", System.StringComparison.OrdinalIgnoreCase);
            QuestMachine.defaultQuestAlertUI.ShowAlert($"Power: {isPowerOn.ToString().ToUpper()}");
            getClothesButton.interactable = isPowerOn;
        }
    }
}
And this is the custom quest condition that checks if power is on:
CheckPowerQuestCondition.cs

Code: Select all

namespace PixelCrushers.QuestMachine.Examples
{

    /// <summary>
    /// Condition becomes true if Power is on.
    /// </summary>
    public class CheckPowerQuestCondition : QuestCondition, IMessageHandler
    {

        private Power power => FindObjectOfType<Power>();

        public override string GetEditorName() => "Is Power On?";

        public override void StartChecking(System.Action trueAction)
        {
            base.StartChecking(trueAction);
            if (power.isPowerOn)
            {
                SetTrue();
            }
            else
            {
                MessageSystem.AddListener(this, "Power", "");
            }
        }

        public override void StopChecking()
        {
            base.StopChecking();
            MessageSystem.RemoveListener(this);
        }

        public void OnMessage(MessageArgs messageArgs)
        {
            if (power.isPowerOn)
            {
                SetTrue();
            }
        }

    }

}
Attachments
daffyQuest.png
daffyQuest.png (31.05 KiB) Viewed 1183 times
Daffy
Posts: 19
Joined: Wed Feb 06, 2019 1:17 pm

Re: How to manipulate tasks in one quest

Post by Daffy »

Ok thanks, I checked and I understand this way, but I still want to know why SendTomeesageSystem() method doesn't work in method OnMessage(MessageArgs messageArgs). Could you please tell me why this doesn't work.
Because it is like this, or maybe there is something wrong.

I even put SendTomeesageSystem() method in your script Power.cs (also in OnMessage method) you provide to me, and still, quest don't receive this Messages.
Post Reply