Reward System?

Announcements, support questions, and discussion for Quest Machine.
Post Reply
aallenfx
Posts: 4
Joined: Mon May 15, 2023 6:47 pm

Reward System?

Post by aallenfx »

Hey, is there a reward system functionality? I wanted to add it on the "Success" node under "Actions". I didn't see any option for auto-triggering reward functionality.

I tried adding a "Unity Event" action and assigning my function under "OnExecute" though that's less than ideal since it's really nested in there and I would need to do this for every quest. And if a script rename happened, I'd need to fix this on every quest ever (if i could even find the unity event i created incase it turns into multiples).

There's also a lack of multi-object editing which makes it difficult to bulk edit things as well. Trying to find ways to streamline or automate the process of adding rewards. Any ideas on how to resolve this?
aallenfx
Posts: 4
Joined: Mon May 15, 2023 6:47 pm

Re: Reward System?

Post by aallenfx »

Image
User avatar
Tony Li
Posts: 22106
Joined: Thu Jul 18, 2013 1:27 pm

Re: Reward System?

Post by Tony Li »

Hi,

I recommend writing a custom quest action instead of using the UnityEvent quest action. You can find a starter script in Plugins / Pixel Crushers / Quest Machine / Templates. Just duplicate QuestActionTemplate.cs, rename it and move it into your scripts folder, and add your reward code where the comments indicate.

Alternatively, you can add a script that implements IMessageHandler to listen for quest state change messages (see this post) to the player or Quest Machine GameObject. When the quest changes to success, give the reward. If you plan to give the same reward(s) with every quest, you could create counters for them. For example, if you plan to give gold and XP with each quest, you can add "gold" and "xp" counters to each quest. In your IMessageHandler script's OnMessage() method, look up the quest's gold and xp counter values and give those rewards to the player.
TrueHumanSoul
Posts: 6
Joined: Thu Nov 30, 2023 10:00 am

Re: Reward System?

Post by TrueHumanSoul »

Good day!
I'm writing a reward system and encountered a similar problem.
From Actions at some quest state I send a Message:
Sender: Quest Giver
Target: Any
Message: Give
Parameter: Coins
Value: int 50

How should I subscribe my MessageSystemListener to actually listen this action messages I send? I`ve spend all day but couldn`t figure it out. What should I add instead of QuestMachineMessages.QuestStateChangedMessage?

Code: Select all

 public class RewardSystemController : MonoBehaviour, IMessageHandler
    {
        [SerializeField] private RewardSystemDatabase _rewardsDatabase;

        private void OnEnable()
        {
            // Listen for Quest State Changed messages:
            MessageSystem.AddListener(this, QuestMachineMessages.QuestStateChangedMessage, string.Empty);
        }

        private void OnDisable()
        {
            // Stop listening:
            MessageSystem.RemoveListener(this);
        }

        public void OnMessage(MessageArgs messageArgs)
        {
                string parameter = messageArgs.parameter;
                string message = messageArgs.message;
                object[] value = messageArgs.values;

                Debug.Log("Message Recieved: Parameter: " + parameter + ". Message: " + message + ". Value: " + value[0].ToString());
            
        }

        public void RecieveMessageFromQuest(string message, string parameter, int value) 
        {
            switch (message) 
            {
                case "Give":
                    RewardSystemDatabase.Reward reward = _rewardsDatabase.SeekForRewardByName(parameter);
                    if (reward != null) 
                    {
                        Debug.Log("GIVE!");
                    }
                    break;
                case "Remove":
                    break;
            }
        }
    }
User avatar
Tony Li
Posts: 22106
Joined: Thu Jul 18, 2013 1:27 pm

Re: Reward System?

Post by Tony Li »

Hi,

Try this:

Code: Select all

public class RewardSystemController : MonoBehaviour, IMessageHandler
{
	[SerializeField] private RewardSystemDatabase _rewardsDatabase;

	private void OnEnable()
	{
		// Listen for "Give" + (reward) messages: (first value will be amount to give)
		MessageSystem.AddListener(this, "Give", string.Empty);
		// Listen for "Remove" + (reward) messages: (first value will be amount to remove)
		MessageSystem.AddListener(this, "Remove", string.Empty);
	}

	private void OnDisable()
	{
		// Stop listening:
		MessageSystem.RemoveListener(this);
	}

	public void OnMessage(MessageArgs messageArgs)
	{			
		string rewardName = messageArgs.parameter;
		int amount = messageArgs.intValue;
		switch (messageArgs.message)
		{
			case "Give":
				RewardSystemDatabase.Reward reward = _rewardsDatabase.SeekForRewardByName(rewardName);
				if (reward != null) 
				{
					Debug.Log($"GIVE {amount} {rewardName}!");
				}
				break;
			case "Remove":
				Debug.Log($"REMOVE {amount} {rewardName}!");
				break;
		}
	}
}
Alternatively, if you're giving rewards in a quest, it's better to make a new quest action:
  • Duplicate QuestActionTemplate.cs
  • Move the duplicate to your own scripts folder
  • Rename it to something like GiveRewardQuestAction.cs
  • Fill in your code where the comments indicate
  • In the quest's Success node (for example), in the True state > Actions section, add your Give Reward action.
Post Reply