save / load dans un fichier

problème : le save et le load fonctionnait avec un string en mémoire

solution : créer un fichier save.txt dans les assets quand on sauvegarde, et lire de ce fichier quand on load.
This commit is contained in:
Felix Boucher 2023-05-28 17:37:54 -04:00
parent d4f32e439f
commit f1a328122c
6 changed files with 64 additions and 34 deletions

View File

@ -407,7 +407,7 @@ MonoBehaviour:
_isInvisible: 0
_isCollidable: 0
_isTrigger: 0
_renderOrder: 0
_renderOrder: 1
_renderLayer: Default
- _key: Spawners
_tiles:

View File

@ -3,6 +3,12 @@ using UnityEngine;
public interface ILevelObject
{
public enum ObjectType
{
Tile = 0,
Prefab = 1
}
string Name { get; }
Vector3 Position { get; }
void LevelUpdate();

View File

@ -5,6 +5,8 @@ using UnityEngine;
using UnityEngine.Tilemaps;
using GatherAndDefend.LevelEditor;
using Unity.VisualScripting.YamlDotNet.Core.Tokens;
using System.Text;
using System.IO;
#region [custom inspector]
#if UNITY_EDITOR
@ -32,6 +34,7 @@ public class LevelManagerEditor : Editor
#region [singleton level manager]
public class LevelManager : Singleton<LevelManager>
{
string SavePath => Application.dataPath + "/save.txt";
public delegate void LevelAction(ILevelObject levelObject);
public delegate bool LevelPredicate<T>(T levelObject) where T : ILevelObject;
public event LevelAction Added;
@ -121,8 +124,6 @@ public class LevelManager : Singleton<LevelManager>
toRemove.Clear();
}
private string saved;
public void ClearLevel()
{
foreach (var obj in _levelObjects)
@ -131,22 +132,15 @@ public class LevelManager : Singleton<LevelManager>
}
Clear();
}
public void SaveFile()
{
var list = _levelObjects.Select(obj => obj.ToDictionary()).ToList();
list.Add(new Dictionary<string, object>()
{
{Database.TYPE, "Level" },
{"Name", _currentLevel.name }
});
saved = JsonConvert.SerializeObject(list);
Debug.Log("game saved successfully");
}
public void LoadLevel(Level level, bool clear = false)
/// <summary>
/// permet de loader un scriptable object de niveau
/// </summary>
/// <param name="level">le niveau à loader</param>
/// <param name="shouldClear">est ce qu'on veut effacer ce qui est déjà là?</param>
public void LoadLevel(Level level, bool shouldClear = false)
{
if (clear)
if (shouldClear)
{
ClearLevel();
}
@ -177,9 +171,15 @@ public class LevelManager : Singleton<LevelManager>
}
Debug.Log("level loaded successfully");
}
public void LoadLevel(string levelName, bool clear = false)
/// <summary>
/// permet de loader un scriptable object de niveau
/// </summary>
/// <param name="levelName">le nom du niveau à loader</param>
/// <param name="shouldClear">est ce qu'on veut effacer ce qui est déjà là?</param>
public void LoadLevel(string levelName, bool shouldClear = false)
{
if (clear)
if (shouldClear)
{
ClearLevel();
}
@ -187,18 +187,31 @@ public class LevelManager : Singleton<LevelManager>
//fetch level from database
_currentLevel = Database.Instance.ScriptableObjects[levelName] as Level;
LoadLevel(_currentLevel, clear);
LoadLevel(_currentLevel, shouldClear);
}
public void SaveFile()
{
var list = _levelObjects.Select(obj => obj.ToDictionary()).ToList();
string saved = JsonConvert.SerializeObject(list);
File.WriteAllText(SavePath, saved, Encoding.UTF8);
Debug.Log("game saved successfully");
}
public void LoadFile()
{
ClearLevel();
string saved = File.ReadAllText(SavePath, Encoding.UTF8);
var dicts = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(saved);
var prefabDicts = dicts.FindAll(x => x[Database.TYPE].ToString() == nameof(Database.Prefabs));
ClearLevel();
var prefabDicts = dicts.FindAll(x => x[nameof(ILevelObject.ObjectType)].ToString() == nameof(ILevelObject.ObjectType.Prefab));
foreach (var prefabDict in prefabDicts) CreatePrefab(prefabDict);
var tileDicts = dicts.FindAll(x => x[Database.TYPE].ToString() == nameof(Database.ScriptableObjects));
var tileDicts = dicts.FindAll(x => x[nameof(ILevelObject.ObjectType)].ToString() == nameof(ILevelObject.ObjectType.Tile));
foreach (var tileDict in tileDicts) CreateTile(tileDict);
Debug.Log("game loaded successfully");
@ -232,11 +245,21 @@ public class LevelManagerScript : MonoBehaviour
void Awake()
{
if (!_instance) _instance = this;
else Destroy(gameObject);
//we don't want to ever have two LevelManagerScript at the same time in the game.
//We prevent that by erasing any instances that are not registered as our main instance.
if (!_instance)
{
_instance = this;
}
else
{
Destroy(gameObject);
return;
}
DontDestroyOnLoad(gameObject);
LevelManager.Instance.LoadLevel(firstLevel.name, true);
if (!firstLevel) throw new System.Exception("there is no first level set in the level manager script");
LevelManager.Instance.LoadLevel(firstLevel, true);
}
void Update()
{

View File

@ -40,7 +40,7 @@ public abstract class LevelObject : MonoBehaviour, ILevelObject
{
{nameof(Name), Name },
{nameof(Position), new float[]{Position.x, Position.y, Position.z } },
{Database.TYPE, nameof(Database.Prefabs) }
{nameof(ILevelObject.ObjectType), nameof(ILevelObject.ObjectType.Prefab) }
};
}
public virtual void LoadDictionary(Dictionary<string, object> dict)

View File

@ -78,15 +78,16 @@ public abstract class LevelTile : TileBase, ILevelObject
{nameof(Name), Name },
{nameof(Position), new float[]{Position.x, Position.y, Position.z } },
{nameof(Tilemap), Tilemap },
{Database.TYPE, nameof(Database.ScriptableObjects) }
{nameof(ILevelObject.ObjectType), nameof(ILevelObject.ObjectType.Tile) }
};
}
public virtual void LoadDictionary(Dictionary<string, object> dict)
{
Name = dict[nameof(Name)].ToString();
Position = dict[nameof(Position)].ToVector3();
var tilemapName = dict[nameof(Tilemap)].ToString();
_tilemap = FindObjectOfType<Grid>().GetComponentInChildren<Tilemap>(tilemapName);
}

View File

@ -29,8 +29,8 @@ public class Opponent : Entity
void AttackEnemy() {
//Attack Cooldown
if(AttackSpeed < AttackSpeedWait) {
if(AttackSpeed < AttackSpeedWait)
{
Enemy.Hp-=AttackDamage;
Debug.Log("Ally Hp = " + Enemy.Hp);