How do I add a task to an instanced quest from a script?

I need an instanced quest for each NPC.
The NPCs will appear randomly and each will be a quest with a task waiting for delivery of equipment.
The quest will end with Fail after a certain amount of time.
Tasks are registered in MakinomEditor's Tasks, from which they are randomly assigned to each NPC's Quest.

In AutoMachine's Schemics, the following custom nodes were created and set for each NPC.
However, the ConsoleLog with the Quest activated appears, but the Tutorial QuestHUD is not turned on.
(We have confirmed that the QuestHUD works as normal. So it is not a problem with the HUD settings. When Quest is Active in the editor, the HUD appears as in the 3d Action tutorial).
When I look at the debug watch in VisualStudio, it is registered as ActiveQuests.
How do I write to assign a task in Runtime from a script and make the newly created Quest Active?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GamingIsLove.Makinom.Schematics;
using GamingIsLove.Makinom;
using GamingIsLove.ORKFramework;
using GamingIsLove.Makinom.Schematics.Nodes;
using System.Linq;

[EditorHelp("Customer Order Quest Add", "Add a quest for customers to order food.", "")]
// INFO: The 'NodeInfo' attribute manages in which section the node can be found in the add node selection.
[NodeInfo("CustomNode")]
public class ORKCustomNodeCustomerQuestAdd : BaseSchematicNode
{
//[EditorTitleLabel("Combatant")]
//public SchematicObjectSelection usedObject = new SchematicObjectSelection();

//[EditorTitleLabel("Equipment")]
//public SchematicObjectSelection usedEquipment = new SchematicObjectSelection(SchematicObjectType.SelectedData);

public override void Execute(Schematic schematic)
{
QuestSetting orderRecipeQuestSetting = new QuestSetting();
QuestSetting makinomEditorQuestTemplate = ORK.Quests.Get(0);
orderRecipeQuestSetting.taskStatusIcons = makinomEditorQuestTemplate.taskStatusIcons;
orderRecipeQuestSetting.EditorName = "OrderRecipe:" + schematic.MachineObject.GameObjects.FirstOrDefault().name;
orderRecipeQuestSetting.GUID = schematic.MachineObject.GameObjects.FirstOrDefault().name;
var idInt = schematic.MachineObject.GameObjects.FirstOrDefault().name.Split("_");
orderRecipeQuestSetting.ID = int.Parse(idInt[1]);

AssetSelection<QuestAsset> newQuestAssetSelection = new AssetSelection<QuestAsset>();
QuestAsset newQuestAsset = new QuestAsset();
newQuestAsset.Settings = orderRecipeQuestSetting;
newQuestAssetSelection.SetAsset(newQuestAsset);
var randomTaskID = Random.RandomRange(0, ORK.QuestTasks.Count - 1);
QuestTaskSetting testMenuTaskRecipe1 = ORK.QuestTasks.Get(randomTaskID); // TODO:Get Random Tasks From MakinomEditor - Game - Quest Tasks
testMenuTaskRecipe1.quest = newQuestAssetSelection;

ORK.Game.Quests.AddQuest(orderRecipeQuestSetting, false, true,true);
schematic.NodeFinished(this.next);
}
}
  • The assets are scriptable objects, i.e. new QuestAsset doesn't work for them (usually).

    You can create a new one like this:
    QuestAsset asset = ScriptableObject.CreateInstance<QuestAsset>();

    However, I'm not 100% sure if creating a new quest at runtime and the system recognizing it is possible.
    Please consider rating/reviewing my products on the Asset Store (hopefully positively), as that helps tremendously with getting found.
    If you're enjoying my products, updates and support, please consider supporting me on patreon.com!
  • When I look at Runtime's Quest in DebugWatch, the "task" of the non public member in Quest (Not Quest Setting) is 0.
    I cannot tie a Runtime task to a Runtime quest.

    Perhaps in Quest.cs
    public void InitTasks(bool register)
    {
    this.tasks = new Dictionary<QuestTaskSetting, QuestTask>();

    List<QuestTaskSetting> list = ORK.QuestTasks.GetQuestTasks(this.setting);
    for(int i = 0; i < list.Count; i++)
    {
    this.tasks.Add(list[i], new QuestTask(this, list[i], register));
    }
    }

    I think it is because ORK.QuestTasks is 0 in
    But I don't know how to register in Runtime to ORK.QuestTasks.
    Is there any better way to do this?

    Here is the current custom C# that is not working.

    [EditorHelp("Customer Order Quest Add", "客が料理を注文するクエストを追加する.客自身のGameObjectに追加するSchematicの想定(テーブルではない)", "")]
    // INFO: The 'NodeInfo' attribute manages in which section the node can be found in the add node selection.
    [NodeInfo("CustomNode")]
    public class ORKCustomNodeCustomerQuestAdd : BaseSchematicNode
    {
    //[EditorTitleLabel("Combatant")]
    //public SchematicObjectSelection usedObject = new SchematicObjectSelection();

    //[EditorTitleLabel("Equipment")]
    //public SchematicObjectSelection usedEquipment = new SchematicObjectSelection(SchematicObjectType.SelectedData);

    async public override void Execute(Schematic schematic)
    {
    GameObject machineGameObject = schematic.MachineObject.GameObjects.FirstOrDefault();
    QuestSetting orderRecipeQuestSetting = new QuestSetting();
    QuestSetting makinomEditorQuestTemplate = ORK.Quests.Get(0);
    orderRecipeQuestSetting.SetData(makinomEditorQuestTemplate.GetData());
    orderRecipeQuestSetting.EditorName = "OrderRecipe:" + machineGameObject.name;
    orderRecipeQuestSetting.GUID = machineGameObject.name;
    string[] idInt = machineGameObject.name.Split("_");
    orderRecipeQuestSetting.ID = int.Parse(idInt[1]);

    AssetSelection<QuestAsset> newQuestAssetSelection = new AssetSelection<QuestAsset>();
    //QuestAsset newQuestAsset = new QuestAsset();
    QuestAsset newQuestAsset = ScriptableObject.CreateInstance<QuestAsset>();
    newQuestAsset.SetData(orderRecipeQuestSetting.GetData());
    //newQuestAsset.Settings = orderRecipeQuestSetting;
    newQuestAssetSelection.SetAsset(newQuestAsset);
    IEnumerable<Equipment> cookingList = ORK.Equipment.GetNames()
    .Select(x => ORK.Equipment.Find(x).Settings)
    .Where(x => x.itemType.settings.Get().Settings.ID == MyGame.ItemTypes.料理);
    Equipment randomCooking = cookingList.ElementAt(Random.Range(0, cookingList.Count()));

    QuestTaskSetting templateTask = ORK.QuestTasks.Get(0);
    QuestTaskSetting orderTaskSetting = new QuestTaskSetting();
    orderTaskSetting.SetData(templateTask.GetData());
    EquipmentItemSelection equipItemSelection = new EquipmentItemSelection();
    //EquipmentAsset equipmentAsset = new EquipmentAsset();
    EquipmentAsset equipmentAsset = ScriptableObject.CreateInstance<EquipmentAsset>();
    equipmentAsset.Settings = randomCooking;
    AssetSelection<EquipmentAsset> assetSelection = new AssetSelection<EquipmentAsset>();
    assetSelection.SetAsset(equipmentAsset);
    equipItemSelection.equipment = assetSelection;
    orderTaskSetting.finishRequirements.item[0].item.settings = equipItemSelection;
    orderTaskSetting.autoActivate = true;
    orderTaskSetting.quest = newQuestAssetSelection;

    // テーブルにSelectedQuestを設定
    CombatantTriggerComponent combatantTrigger = machineGameObject.GetComponentInChildren<CombatantTriggerComponent>();
    Combatant tableCombatant = combatantTrigger.InTrigger.FirstOrDefault(x => x.GetName().Contains("客用テーブル"));
    ObjectVariablesComponent tableObjectVariable = tableCombatant.GameObject.GetComponent<ObjectVariablesComponent>();

    var taskAsset = QuestTaskAsset.CreateInstance<QuestTaskAsset>();
    taskAsset.SetData(orderTaskSetting.GetData());
    taskAsset.Settings.quest = newQuestAssetSelection;
    List<QuestTaskAsset> tasks = new List<QuestTaskAsset>() { taskAsset};
    ORK.QuestTasks.SetAssets(tasks);

    // クエスト生成
    Quest quest = new Quest(orderRecipeQuestSetting, true, false, true, true);
    QuestTask task = new QuestTask(quest, orderTaskSetting, true);
    quest.SetActive(ORK.Game.ActiveGroup.Leader,true,true);
    task.SetActive(ORK.Game.ActiveGroup.Leader,true,true);



    tableObjectVariable.SelectedData.Change("OrderQuest",orderRecipeQuestSetting,ListChangeType.Add);
    tableObjectVariable.SelectedData.Change("OrderQuestGUID",orderRecipeQuestSetting.GUID,ListChangeType.Add);
    tableObjectVariable.SelectedData.Change("OrderCooking",randomCooking,ListChangeType.Add);

    // 客自身にもOrder情報をSelectedDataに保存
    Combatant customerCombatant = ORKComponentHelper.GetCombatant(machineGameObject);
    customerCombatant.SelectedData.Change("OrderCooking", randomCooking, ListChangeType.Set);
    customerCombatant.SelectedData.Change("OrderQuestGUID", orderRecipeQuestSetting.GUID, ListChangeType.Set);
    // テーブルにCombatantを記憶
    tableObjectVariable.SelectedData.Change("OrderCombatant", customerCombatant, ListChangeType.Add);


    await UniTask.DelayFrame(3);
    var addedQuest = ORK.Game.Quests.GetQuest(orderRecipeQuestSetting);
    var addedTask = ORK.Game.Quests.GetTask(orderTaskSetting);

    schematic.NodeFinished(this.next);
    }
    }
  • Instances of a quest are created based on the settings of the quest, i.e. it's tasks, etc.
    You need to add your task to your created quest's settings befor creating a Quest instance.

    Also, you don't need to use AssetSelection classes here - they're just used to be able to get an asset from different sources (e.g. direct reference, asset bundles, etc.) and have that setup in the editor. You can directly use your created asset instead.
    Please consider rating/reviewing my products on the Asset Store (hopefully positively), as that helps tremendously with getting found.
    If you're enjoying my products, updates and support, please consider supporting me on patreon.com!
  • You need to add your task to your created quest's settings befor creating a Quest instance.
    How do you do that?
    QuestSetting class has no fields with references to tasks and I can't find any methods to set them.
  • Ah, yeah - sorry about that.
    You need to set the task's quest, based on your code:
    taskAsset.Settings.quest.SetAsset(newQuestAsset);

    However, you also need to add the task to ORK.QuestTasks - but adding new content at runtine is currently not possible.
    Please consider rating/reviewing my products on the Asset Store (hopefully positively), as that helps tremendously with getting found.
    If you're enjoying my products, updates and support, please consider supporting me on patreon.com!
Sign In or Register to comment.