I am trying to modify Brackeys quest system to allow for multiple quests instead of just one.
When the player accepts a quest from the quest window, the first quest in the list of quests becomes active, once that quest is completed it becomes inactive and then when they open the quest window again they can accept the next quest in the list, which then that quest becomes active, however the main problem is quest.isActive never returns true (even though the correct quest shows as active in the inspector). I’m wondering if it is because I need to called quests[currentQuest].isActive instead, however that creates many errors. I am completely lost any help is appreciated.
Quest Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[System.Serializable]
public class Quest
{
public bool isActive; // quest accepted or not
public string title; // quest name
public string description; // quest description
public int money; // quest reward
public QuestGoal goal;
[SerializeField] private Text moneyText;
[SerializeField] private Text completedText;
[SerializeField] private Text rewardText;
[SerializeField] private Animator completedAnim;
[SerializeField] private GameObject completedNotice;
public void Complete()
{
isActive = false;
completedNotice.SetActive(true);
completedText.text = title + " was completed!";
completedAnim.Play("QuestCompleted");
QuestGiver.questAccepted = false; // just for the ui
}
public void Reward(int amount)
{
money += amount;
moneyText.text = money.ToString();
rewardText.text = "Reward: " + amount.ToString();
QuestGiver.currentQuest += 1;
}
}
QuestGiver Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class QuestGiver : MonoBehaviour
{
[Header("Script Reference")]
public CustomisationGet stats;
public List<Quest> quests = new List<Quest>();
[Header("Quest")]
public static int currentQuest;
public static bool questAccepted = false;
public GameObject questWindow;
public GameObject lockedWindow;
public Button acceptButton;
public GameObject declineButton;
public Text acceptedText;
public Text title;
public Text description;
public Text reward;
private void Start()
{
currentQuest = 0;
lockedWindow.SetActive(false);
acceptButton.enabled = true;
declineButton.SetActive(true);
}
private void Update()
{
// opens and closes the quest window
if (Input.GetKeyDown(KeyCode.Q))
{
if (questWindow.activeSelf)
{
questWindow.SetActive(false);
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
else
{
questWindow.SetActive(true);
OpenQuestWindow();
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}
// quests restricted by level (health is the temporarily referenced stat)
if (currentQuest >= 2 && stats.health <= 20)
{
lockedWindow.SetActive(true);
}
if (questAccepted == true)
{
acceptButton.enabled = false;
declineButton.SetActive(false);
acceptedText.text = "QUEST ACCEPTED!";
}
else
{
acceptButton.enabled = true;
acceptedText.text = "ACCEPT QUEST";
declineButton.SetActive(true);
}
}
public void OpenQuestWindow()
{
questWindow.SetActive(true);
title.text = quests[currentQuest].title;
description.text = quests[currentQuest].description;
reward.text = quests[currentQuest].money.ToString();
}
public void AcceptQuest()
{
quests[currentQuest].isActive = true;
stats.quest = quests[currentQuest];
questAccepted = true; // just for the ui
}
}
QuestGoal Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class QuestGoal
{
public GoalType goalType;
public int requiredAmount;
public int currentAmount;
// if requirements are met
public bool isReached()
{
return (currentAmount >= requiredAmount);
}
// if inventory is opened
public void InventoryOpened()
{
if (goalType == GoalType.Tutorial)
{
currentAmount++;
}
}
// if a NPC is given a talkin to
public void TalkToNPC()
{
if(goalType == GoalType.Tutorial)
{
currentAmount++;
}
}
}
// holds the types of quests
public enum GoalType
{
Tutorial
}
The first quest involves just opening the inventory as shown below.
Inventory Script
private void Update()
{
// if I is pressed
if(Input.GetKeyDown(KeyCode.I))
{
// if open, close inventory
if (InventoryGameObject.activeSelf)
{
InventoryGameObject.SetActive(false);
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
// if closed, open inventory
else
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
InventoryGameObject.SetActive(true);
DisplayItemsCanvas();
// completing the 1st quest
if (quest.isActive) // quest.isActive doesn't return true? (it shows as active in inspector)
{
quest.goal.InventoryOpened();
if (quest.goal.isReached())
{
quest.Complete();
quest.Reward(20);
}
}
}
}
}
The second quest is just talk to an NPC
Dialogue Script
private void Update()
{
//if interact key is pressed
if (BindingManager.BindingHeld("Interact"))
{
// info on what ray hits
RaycastHit hit;
// shoots ray forward
Vector3 forward = raycastObject.transform.TransformDirection(Vector3.forward);
// makes the ray visible for debugging purposes
Debug.DrawRay(raycastObject.transform.position, forward * 10, Color.red);
//if ray hits something within 10 units
if (Physics.Raycast(raycastObject.transform.position, forward, out hit, 10))
{
// opens dialogue
if (hit.collider.CompareTag("NPC") && inConversation == false)
{
inConversation = true;
DialogueManager.theManager.LoadDialogue(this);
// completing the 2nd quest
if (quest.isActive)
{
quest.goal.TalkToNPC();
if (quest.goal.isReached())
{
quest.Complete();
quest.Reward(50);
}
}
}
}
}
}