Multiple Player Controlled Characters
Multiple Player Controlled Characters
I'm looking to utilize Quest Machine in a squad based RPG game where the player controls multiple characters. The ideal state is that when any character interacts with a quest giver and is given a quest, it goes to game wide quest journal instead of an individual player character. Any other characters that the player controls can complete the quests, and which ever character turns in the quest, will receive the associated reward.
In some initial testing, I'm able to pickup and complete quests with multiple characters as intended, however I'm having difficulty displaying the associated UI elements (Alerts work fine, but not Journal/HUD). In my testing, I gave each character the Quest Journal component.
Is there a "delivered" way of achieving something like this or will I need to create new classes extending QuestListContainer? My initial thought was to have a quest journal like component that sits on a playermanager and each time a character picks up a quest, it adds it to the quest journal component sitting on the playermanager. The UI's would then be hooked up to the playermanager to display all quests.
In some initial testing, I'm able to pickup and complete quests with multiple characters as intended, however I'm having difficulty displaying the associated UI elements (Alerts work fine, but not Journal/HUD). In my testing, I gave each character the Quest Journal component.
Is there a "delivered" way of achieving something like this or will I need to create new classes extending QuestListContainer? My initial thought was to have a quest journal like component that sits on a playermanager and each time a character picks up a quest, it adds it to the quest journal component sitting on the playermanager. The UI's would then be hooked up to the playermanager to display all quests.
Re: Multiple Player Controlled Characters
Hi,
No need for any custom scripting. Just put the Quest Journal component on your player manager.
That should be all you need to do. If you have quests that check for specific quester IDs, give it an ID of "Player". Give each player GameObject a Quest Entity component and assign an EntityType asset whose Display Name is "Player". You can assign the same asset to all of them.
No need for any custom scripting. Just put the Quest Journal component on your player manager.
That should be all you need to do. If you have quests that check for specific quester IDs, give it an ID of "Player". Give each player GameObject a Quest Entity component and assign an EntityType asset whose Display Name is "Player". You can assign the same asset to all of them.
Re: Multiple Player Controlled Characters
That was my original thought as well, but I'm also creating custom actions to grant Item rewards on certain quests. The intended behavior would be to grant the character interacting with the quest giver, the reward, not all characters.
How would I go about doing this without having a Quest Journal component on that particular character? In addition, how would Quest machine tell me which character interacted with the quest giver (in order to know which player's inventory to add the quest reward for example).
How would I go about doing this without having a Quest Journal component on that particular character? In addition, how would Quest machine tell me which character interacted with the quest giver (in order to know which player's inventory to add the quest reward for example).
Re: Multiple Player Controlled Characters
In that case you will need to make a subclass of QuestGiver that can handle the player GameObject separately from the Quest Journal GameObject. Here's an example:
QM_MultiplePlayerSharedJournalExample_2019-04-03.unitypackage
You can probably just use the ExampleCustomQuestGiver.cs script as-is, although you may want to rename the class to something better than "ExampleCustomQuestGiver".
I included a dummy action that reports "give item to player 1" or "give item to player 2" depending on which player you use to complete the quest.
(Exported from Unity 2018.2.0, Quest Machine 1.1.6.)
QM_MultiplePlayerSharedJournalExample_2019-04-03.unitypackage
You can probably just use the ExampleCustomQuestGiver.cs script as-is, although you may want to rename the class to something better than "ExampleCustomQuestGiver".
I included a dummy action that reports "give item to player 1" or "give item to player 2" depending on which player you use to complete the quest.
(Exported from Unity 2018.2.0, Quest Machine 1.1.6.)
Re: Multiple Player Controlled Characters
Thank you very much for that. This certainly helps. I'll need to modify things slightly to handle NPC interaction (I won't be able to define ahead of time the player objects in the inspector), but this points me in a direction for sure.
Since there will be procedural generated characters the player can "Recruit", I'll need to create new player entities at runtime. Is there in issue with my instantiating a copy of the player entity scriptable object? That's the method I use for inventory items as well.
Also again thank you for the example on giving an item. I see you have string reference to the questor ID, are there built in methods for returning the associated gameobject from that string? (so I can get the appropriate player inventory component). Or is this a utility style function I'll need to create myself?
Since there will be procedural generated characters the player can "Recruit", I'll need to create new player entities at runtime. Is there in issue with my instantiating a copy of the player entity scriptable object? That's the method I use for inventory items as well.
Also again thank you for the example on giving an item. I see you have string reference to the questor ID, are there built in methods for returning the associated gameobject from that string? (so I can get the appropriate player inventory component). Or is this a utility style function I'll need to create myself?
Re: Multiple Player Controlled Characters
There's no issue instantiating a copy of player entity ScriptableObject. Just remember to Destroy it when you're done with it.Thoranar wrote: ↑Wed Apr 03, 2019 10:48 pmSince there will be procedural generated characters the player can "Recruit", I'll need to create new player entities at runtime. Is there in issue with my instantiating a copy of the player entity scriptable object? That's the method I use for inventory items as well.
Alternatively, if you don't want to bother with instantiating a copy, there's another way to assign a unique ID & Display Name to a GameObject. Make a subclass of IdentifiableQuestListContainer. It can be an empty subclass, just to make it accessible in the editor. It can be a one-line script, such as:
PlayerDummyIdentifiableQuestListContainer.cs
Code: Select all
public class PlayerDummyIdentifiableQuestListContainer : PixelCrushers.QuestMachine.IdentifiableQuestListContainer { }
Then assign StringFields to the id and displayName properties:
Code: Select all
var newPlayer = new GameObject("Adam");
var dummyList = newPlayer.AddComponent<PlayerDummyIdentifiableQuestListContainer>();
dummyList.id = new StringField("adam");
dummyList.displayName = new StringField("Adam the Adventurer");
If you use QuestEntity, call QuestMachineMessages.FindGameObjectWithID:Thoranar wrote: ↑Wed Apr 03, 2019 10:48 pmAlso again thank you for the example on giving an item. I see you have string reference to the questor ID, are there built in methods for returning the associated gameobject from that string? (so I can get the appropriate player inventory component). Or is this a utility style function I'll need to create myself?
Code: Select all
var player = QuestMachineMessages.FindGameObjectWithID(quest.questerID);
Code: Select all
var newPlayer = new GameObject("Adam");
var dummyList = newPlayer.AddComponent<PlayerDummyIdentifiableQuestListContainer>();
dummyList.id = new StringField("adam");
dummyList.displayName = new StringField("Adam the Adventurer");
QuestMachine.RegisterQuestListContainer(dummyList); //<-- ADD THIS LINE.
When you destroy the player, unregister the IdentifiableQuestListContainer using QuestMachine.UnregisterQuestListContainer.
---
As an alternative to all that, you could always grab the quest giver instead of the quester. (quest.questGiverID) Then use the quest giver's 'player' property, which points to the player GameObject.
Re: Multiple Player Controlled Characters
Simply perfect. All integrated in and working nicely.
Thank you Tony for the amazing response time.
Thank you Tony for the amazing response time.
Re: Multiple Player Controlled Characters
Glad to help!
Re: Multiple Player Controlled Characters
In a related question. I've create custom UI list templates and item templates to show the specific item quest reward content types. However I'm unable to reference the new classes in the UnityUIBaseUI class and associate Dialogue/Journal classes. (The classes just can't seem to find/reference them) and thus unable to add those elements.
Is this not the process for creating new UIs or is there some method I'm missing? The documentation was a bit vague in this area.
Is this not the process for creating new UIs or is there some method I'm missing? The documentation was a bit vague in this area.
Re: Multiple Player Controlled Characters
Hi,
I'm not sure what you're trying to do. Can you provide a sketch or mock-up image?
If you only want to define new UI content types, copy QuestContentTemplate.cs to make new subclasses of QuestContent. Your new subclasses should show up when you click "+" in the lower right of a content section such as Offer Text or States > Active > Dialogue Text.
If you want to change how the UIs work -- such as adding a separate panel to show rewards -- make a subclass of the corresponding UI (e.g., UnityUIQuestDialogueUI or UnityUIQuestJournalUI). If you make a subclass of UnityUIQuestDialogueUI, override the AddContents and/or AddContent methods. If you make a subclass of UnityUIQuestJournalUI, override the RefreshNow and/or RepaintSelectedQuest method.
I'm not sure what you're trying to do. Can you provide a sketch or mock-up image?
If you only want to define new UI content types, copy QuestContentTemplate.cs to make new subclasses of QuestContent. Your new subclasses should show up when you click "+" in the lower right of a content section such as Offer Text or States > Active > Dialogue Text.
If you want to change how the UIs work -- such as adding a separate panel to show rewards -- make a subclass of the corresponding UI (e.g., UnityUIQuestDialogueUI or UnityUIQuestJournalUI). If you make a subclass of UnityUIQuestDialogueUI, override the AddContents and/or AddContent methods. If you make a subclass of UnityUIQuestJournalUI, override the RefreshNow and/or RepaintSelectedQuest method.