Hey,
I have two scenes. In the first scene the user sees the quest (Take a picture of the church) and then has to switch to the second scene to solve it. After that he has to switch back to the first scene and sees a new task (for example: take a picture of the town hall).
In the first scene I have a Gameobject with several deactivated texts/quests. When starting the scene a random quest is selected from a list and activated.
If the user now switches to the second scene and solves the task (look at the right gameobject and after 2 seconds a flash animation starts) and switches back to the first scene, I want the quest to be done/deactivated and a new one selected.
So all i want is to call my method QuestCompleted() from scene 1 after my animation ‘flash-light’ in scene 2 was triggered.
I have already tried to keep my gameobject containing this script active with DontDestroyOnLoad(), but then the quest list becomes empty.
What can i do?
public class QuestManager : MonoBehaviour
{
public List<GameObject> quests;
private GameObject activeQuest;
// Start is called before the first frame update
void Start()
{
PickAQuest();
}
// Update is called once per frame
public void PickAQuest()
{
activeQuest = quests[Random.Range(0, quests.Count)];
activeQuest.SetActive(true);
Debug.Log("Chosen quest: " + activeQuest.name);
}
public void QuestCompleted()
{
quests.Remove(activeQuest);
PickAQuest();
}
}
Thanks
Read about ScriptableObjects. If a quest is a scriptable object, the task is easy. Just mark it solved and it will be seen as solved in all scenes.
I don’t think the quest list is becoming empty, but rather, that you are referencing objects on it that are not set to not be destroyed on load.
So you have your list of quests pointing to objects in one scene, changes scene, loses all the references because the objects were destroyed with the scene, then moves back and the objects are not referenced anymore.
What I would suggest is to NOT use DontDestroyOnLoad(). But rather remember the quest stage with a permanent variable, like PlayerPrefs, static variable or save file.
Thank you both!
Unfortunately, my approach doesn’t work as expected.
I first turned my gameobjects into texts and declared my active quest as static.
When I go back from my second scene to the first one, activeScene in QuestCompleted() won’t recognize “MissingReferenceException: The object of type ‘Text’ has been destroyed but you are still trying to access it.”
How can I fix this?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class QuestManager : MonoBehaviour
{
public List<Text> quests;
private static Text activeQuest;
public static bool questDone;
// Start is called before the first frame update
void Start()
{
foreach (Text quest in quests) //disable all texts
{
quest.GetComponent<Text>().enabled = false;
}
if (questDone == true)
{
QuestCompleted();
PickAQuest();
}
else
{
PickAQuest(); //pick a Quest for the first time
}
}
// Update is called once per frame
public void PickAQuest()
{
activeQuest = quests[Random.Range(0, quests.Count)]; //pick a random quest
activeQuest.GetComponent<Text>().enabled = true; //enable text of chosen quest
PlayerPrefs.SetString("myActiveQuest", activeQuest.name); //save name to a PlayerPrefs as myActiveQuest
Debug.Log("Chosen quest: " + PlayerPrefs.GetString("myActiveQuest"));
}
public void QuestCompleted()
{
Debug.Log("Will delete following quest: " + activeQuest.name);
quests.Remove(activeQuest);
questDone = false; //Set it to false so I can take a new quest
PickAQuest()
}
}
Here is the short excerpt of how the bool variable is changed:
else if (imgGaze.fillAmount == 1 && hit.transform.CompareTag("Photo"))
{
photoAnim.SetBool("TakeAPhoto", true);
Debug.Log("Foto geschossen mit " + hit.transform.name);
if (PlayerPrefs.GetString("myActiveQuest") == hit.transform.name)
{
Debug.Log("ActiveQuestName and hit.transform.name are equal ");
QuestManager.questDone = true;
}
}
Thanks
I don’t see any value on keeping a static declaration for Text, since Text is a reference to a scene object rather than actual useful data. So I’d recommend not having it static.
What you want to keep either static or in playerprefs is the quest stage value, like, 1, 2 , 3 ,4, or a string. So when you read it, you know what to do with it.
Furthermore, it seems like you’re getting missing reference issue because you destroyed the text objects, are you still keeping the questmanager object active during the scene? If so, stop doing that in order to avoid losing reference.
If the issue persists after changing it, please let us know how your scene is organized, is the global quest spawned dynamically? Or is it part of the scene hierarchy? Are the texts referenced on it by code or by inspector? Does changing the scene cause objects or components to get duplicated?
I did a short screen capture so that you could see how everything is structured and how my project runs.
At the top is always the task, which is always according to the same scheme: Take a picture of the house or take a picture of a tent… The user then selects the appropriate platform and jumps to the position in VR. This is the scene change.
I hope this helps you.
I have tried a little and the following works so far
public void QuestCompleted()
{
activeQuest = GameObject.Find(PlayerPrefs.GetString("myActiveQuest")).GetComponent<Text>() as Text;
//activeQuest = GameObject.Find(activeQuestName).GetComponent<Text>() as Text; //static version
Debug.Log("Will delete following quest: " + activeQuest.name);
quests.Remove(activeQuest);
}
But only the first time. So the correct quest is saved and when you are back in the first scene, this quest is also removed from the list and a new quest is displayed. If you now switch back to the second scene, complete the new quest there and switch back to the first scene, it will not be removed from the list of quests. The Debug.log command before will be executed.
Then why isn’t the quest removed from the list?
EDIT: ok, it gets removed, but the first quest gets back on the list. Why?
My quest list will be re-created over and over again. This is the problem at the moment.
When I start my program the following is done:
- list is created and all quests are added.
- one of them is randomly selected and activated
- I change into the new scene and solve this task
- I’m going back to the first scene.
- a new list is created and all quests are added.
- the selected quest is deleted from the newly created list.
- it starts again at 2.
Now I know my problem, but I can’t solve it 