using System.IO; using System.Collections.Generic; using UnityEngine; public class SaveSystem : MonoBehaviour { private string savePath; [Header("References")] public MapGenerator mapGenerator; public GameObject enemyPrefab; public GameObject orbPrefab; public Transform playerTransform; void Awake() { savePath = Path.Combine(Application.persistentDataPath, "savegame.json"); } public void SaveGame() { GameData data = new GameData(); // 1. Stats from GameManager data.orbsCollected = GameManager.Instance.GetOrbsInternal(); data.remainingTimer = GameManager.Instance.timeRemaining; data.mapSeed = mapGenerator.noiseData.seed; // 2. Player Transform data.playerPos = new float[] { playerTransform.position.x, playerTransform.position.y, playerTransform.position.z }; data.playerRot = new float[] { playerTransform.eulerAngles.x, playerTransform.eulerAngles.y, playerTransform.eulerAngles.z }; // 3. Collectibles - Ensure lists are initialized data.orbPositions = new List(); GameObject[] orbs = GameObject.FindGameObjectsWithTag("Collectible"); Debug.Log("SaveSystem: Found " + orbs.Length + " orbs to save."); foreach (GameObject orb in orbs) { data.orbPositions.Add(new SaveVector3(orb.transform.position)); } // 4. Enemies - Ensure lists are initialized data.enemyPositions = new List(); data.enemyStates = new List(); GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy"); Debug.Log("SaveSystem: Found " + enemies.Length + " enemies to save."); foreach (GameObject enemy in enemies) { EnemyAI ai = enemy.GetComponent(); if (ai != null) { data.enemyPositions.Add(new SaveVector3(enemy.transform.position)); data.enemyStates.Add((int)ai.currentState); } } // Convert to JSON and save string json = JsonUtility.ToJson(data, true); File.WriteAllText(savePath, json); Debug.Log("Save file written to: " + savePath); } public void LoadGame() { if (!File.Exists(savePath)) { Debug.LogWarning("No Save File Found at " + savePath); return; } string json = File.ReadAllText(savePath); GameData data = JsonUtility.FromJson(json); // 1. Restore Map Seed & Regenerate mapGenerator.noiseData.seed = data.mapSeed; mapGenerator.DrawMapInEditor(); // Refresh Collider for the new terrain shape MeshFilter mf = mapGenerator.GetComponent(); mapGenerator.GetComponent().sharedMesh = mf.sharedMesh; // 2. Restore Stats in GameManager GameManager.Instance.SetDataInternal(data.orbsCollected, data.remainingTimer); // 3. Restore Player Position CharacterController cc = playerTransform.GetComponent(); cc.enabled = false; // Disable to allow direct position setting playerTransform.position = new Vector3(data.playerPos[0], data.playerPos[1], data.playerPos[2]); playerTransform.rotation = Quaternion.Euler(data.playerRot[0], data.playerRot[1], data.playerRot[2]); cc.enabled = true; // 4. Restore Orbs Debug.Log("Attempting to load " + data.orbPositions.Count + " orbs."); foreach (GameObject o in GameObject.FindGameObjectsWithTag("Collectible")) Destroy(o); foreach (SaveVector3 sPos in data.orbPositions) { Instantiate(orbPrefab, sPos.ToVector3(), Quaternion.identity); } // 5. Restore Enemies Debug.Log("Attempting to load " + data.enemyPositions.Count + " enemies."); foreach (GameObject e in GameObject.FindGameObjectsWithTag("Enemy")) Destroy(e); for (int i = 0; i < data.enemyPositions.Count; i++) { GameObject newEnemy = Instantiate(enemyPrefab, data.enemyPositions[i].ToVector3(), Quaternion.identity); newEnemy.GetComponent().currentState = (EnemyAI.EnemyState)data.enemyStates[i]; } Debug.Log("Detailed JSON Load Complete!"); } }