59. Saveable Quest Progress(save load failed quest)

I checked my code with teacher’s. And download github source code, but it is failed to save and load a quest. My unity console has some information as below:

Error detecting Visual Studio installations: System.ArgumentException: JSON parse error: Invalid escape character in string.
  at (wrapper managed-to-native) UnityEngine.JsonUtility.FromJsonInternal(string,object,System.Type)
  at UnityEngine.JsonUtility.FromJson (System.String json, System.Type type) [0x0005c] in <bd9566cca22541e58ad28d1fa2849830>:0 

I also found the CaptureState and RestoreState function in QuetList.cs didi not be trigger when I receive a quest and reload game.

The error message doesn’t appear related to this issue. It’s telling you that it can’t find Visual Studio. Make sure your Visual Studio or Visual Studio Code plugins are up to date in the Package Manager, and that the correct editor is selected in Edit|Preferences|External Script Editor

For the QuestList issue, post your QuestList.cs code here. Don’t forget to format it with the </> button.

Here are my QuestList.cs. Thank you!

using GameDevTV.Saving;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace RPG.Quests
{
	public class QuestList : MonoBehaviour, ISaveable
	{
		List<QuestStatus> statuses = new List<QuestStatus>();

		public event Action onUpdate;

		public void AddQuest(Quest quest)
		{
			if (HasQuest(quest)) return;

			QuestStatus newStatus = new QuestStatus(quest);
			statuses.Add(newStatus);
			if (onUpdate != null)
			{
				onUpdate();
			}
			
		}

		public void CompleteObjective(Quest quest, string objective)
		{
			QuestStatus status = GetQuestStatus(quest);
			status.CompleteObjective(objective);
			if (onUpdate != null)
			{
				onUpdate();
			}
		}

		public bool HasQuest(Quest quest)
		{
			return GetQuestStatus(quest) != null;
		}

		public IEnumerable<QuestStatus> GetStatuses()
		{
			return statuses;
		}

		private QuestStatus GetQuestStatus(Quest quest)
		{
			foreach (QuestStatus status in statuses)
			{
				if (status.GetQuest() == quest)
				{
					return status;
				}
			}

			return null;
		}

		public object CaptureState()
		{
			List<object> state = new List<object>();
			foreach (QuestStatus status in statuses)
			{
				state.Add(status.CaptureState());
			}

			return state;
		}

		public void RestoreState(object state)
		{
			List<object> stateList = state as List<object>;
			if (stateList == null) return;

			statuses.Clear();
			foreach (object objectState in stateList)
			{
				statuses.Add(new QuestStatus(objectState));
			}
		}
	}
}


Odd, if the QuestList is on the player, it should definitely be picked up. Let’s add a quick set of Debugs to see if that’s happening:

	public object CaptureState()
	{
        Debug.Log("QuestList.CaptureState()");
		List<object> state = new List<object>();
		foreach (QuestStatus status in statuses)
		{
            Debug.Log($"Adding {status.GetQuest().name}");
			state.Add(status.CaptureState());
		}

		return state;
	}

	public void RestoreState(object state)
	{
        Debug.Log($"QuestList.RestoreState");
		List<object> stateList = state as List<object>;
		if (stateList == null) return;

		statuses.Clear();
		foreach (object objectState in stateList)
		{
            QuestStatus status = new QuestStatus(objectState);
			statuses.Add(status);
            Debug.Log($"Restoring {status.GetQuest().name}");
		}
	}

The visual studio code set breakpoint in CaptureState and RestoreState, but the breakpoints do not trigger when start game and end game.

Do you have ISaveable in the class Declaration?

public class QuestList:MonoBehavior, ISaveable

Sorry! It is my problem in my visual studio code.

UnityDebug: Initializing
UnityDebug: Searching for Unity process 'Unity Editor'
UnityDebug: Attached to Unity process 'Unity Editor (Unity)' (1232)
UnityDebug: Disconnected

namespace RPG.Quests
{
public class QuestList : MonoBehaviour, ISaveable

I just realized you’d already posted the code higher in the thread.

If the QuestList is on the Player but is still not calling CaptureState and RestoreState, then something very odd is happening. Zip up your project and upload it to https://gdev.tv/projectupload and I’ll take a look at it. Don’t forget to remove the Library folder to save space. I’m stepping out the door, so I won’t be able to look at it until this evening.