Решил доделать фичу с заданиями. Добавил новые скрипты и немного поменял старые. Новые: WalletData, Wallet, WalletView, ISaveServices, JsonSaveServices, SceneManager, SceneType. Изменил: GameplayInstaller, TaskManager, TaskConfig, Task.
[System.Serializable] public struct WalletData
{
public int Money; }
}
WalletData - это структура данных, которые я сохраняю и подгружаю, данные для Wallet.
using Data;
using SaveServices;
using System;
namespace Wallet
{
public class Wallet
{
private int _money;
private ISaveServices<WalletData> _saveServices;
public event Action<int> MoneyChanged;
public Wallet(ISaveServices<WalletData> saveServices)
{
_saveServices = saveServices;
Money = _saveServices.Load(new WalletData()
{
Money = 0,
}).Money;
}
public int Money
{
get => _money;
set
{
if (value < 0)
return;
_money = value;
MoneyChanged?.Invoke(_money);
}
}
public void AddValue(int value)
{
Money += value;
Save();
}
public void SpendValue(int value)
{
Money -= value;
Save();
}
private void Save()
{
_saveServices.Save(new WalletData()
{
Money = Money,
});
}
private void Clear()
{
_saveServices.Save(new WalletData()
{
Money = 0,
});
}
}
}
Wallet - скрипт, отвечающий за деньги игрока. Подгружает, сохраняет, чистит данные, работает с ними.
using Zenject;
namespace Wallet{
public class WalletView : MonoBehaviour {
[SerializeField] private TextMeshProUGUI _text;
private Wallet _wallet;
[Inject] public void Construct(Wallet wallet)
{ _wallet = wallet;
DisplayMoney(_wallet.Money);
}
public void DisplayMoney(int money) => _text.text = "Money: " + money.ToString();
public void OnEnable() => _wallet.MoneyChanged += DisplayMoney;
public void OnDisable() => _wallet.MoneyChanged -= DisplayMoney; }
}
WalletView - монобех для отображения количества денег игрока.
using Data;
namespace SaveServices
{
public interface ISaveServices<T>
{
public void Save(object saveFile);
public T Load(object defaultSaveFile);
}
}
ISaveServices - интерфейс, которого наследуется JsonSaveServices.
using System.IO;
using UnityEngine;
namespace SaveServices
{
public class JsonSaveServices<T> : ISaveServices<T>
{
private string SavePath => Path.Combine(Application.dataPath, FullName);
private readonly string FullName;
public JsonSaveServices(string fileName) => FullName = fileName;
public T Load(object defaultSaveFile)
{
T walletData;
if (!File.Exists(SavePath))
{
Debug.Log("Error");
walletData = (T) defaultSaveFile;
}
else
{
string json = File.ReadAllText(SavePath);
walletData = JsonUtility.FromJson<T>(json);
}
return walletData;
}
public void Save(object saveFile)
{
string json = JsonUtility.ToJson(saveFile, true);
File.WriteAllText(SavePath, json);
}
}
}
JsonSaveServices - наследник IsaveServices. Его цель загружать и сохранять данные в Json файл.
public class SceneManager {
public SceneManager(TaskType type, string name) {
if (type == TaskType.NewScene) UnityEngine.SceneManagement.SceneManager.LoadScene(name);
else if (type == TaskType.ReloadSecne) UnityEngine.SceneManagement.SceneManager.LoadScene(UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex);
}
public SceneManager(TaskType type) {
if (type == TaskType.ReloadSecne) UnityEngine.SceneManagement.SceneManager.LoadScene(UnityEngine.SceneManagement.
SceneManager.GetActiveScene().buildIndex); }
}}
SceneManager - скрипт, с помощью TaskType который решает на какую сцены перейти или не перейти после оканчания всех заданий.
using Data;
using Factory;
using SaveServices;
using Tasks;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Wallet;
using Zenject;
namespace Installers
{
public class GameplayInstaller : MonoInstaller
{
private const string WalletFileSaveName = "walletData";
[SerializeField] private Button _taskExecuteButton;
[SerializeField] private TasksConfig _taskConfig;
[SerializeField] private RectTransform _canvas;
[SerializeField] private TaskSpawner _taskSpawner;
[SerializeField] private TextMeshProUGUI _text;
[SerializeField] private WalletView _walletView;
public override void InstallBindings()
{
BindTasks();
}
private void BindTasks()
{
Container.Bind<ITaskExecuter>().To<ButtonTaskExecuter>().AsSingle().WithArguments(_taskExecuteButton);
Container.Bind<TasksConfig>().FromInstance(_taskConfig).AsSingle();
Container.Bind<ISpawnerFactory>().To<SpawnerFactory>().AsSingle().WithArguments(_canvas);
Container.Bind<TaskSpawner>().FromInstance(_taskSpawner).AsSingle().NonLazy();
Container.Bind<ISaveServices<WalletData>>().To<JsonSaveServices<WalletData>>().AsSingle().WithArguments(WalletFileSaveName);
Container.Bind<Wallet.Wallet>().AsSingle();
Container.Bind<WalletView>().FromInstance(_walletView).AsSingle();
Container.BindInterfacesAndSelfTo<TaskManager>().AsSingle().NonLazy();
}
}
}
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Tasks
{
public class TaskManager : IDisposable
{
private TasksConfig _tasksConfig;
private ITaskExecuter _taskExecuter;
private Task _currentTask;
private TaskSpawner _spawner;
private Wallet.Wallet _wallet;
private List<Task> _tasks;
public TaskManager(TasksConfig tasksConfig, ITaskExecuter taskExecuter, TaskSpawner spawner, Wallet.Wallet wallet)
{
_tasksConfig = tasksConfig;
_taskExecuter = taskExecuter;
_tasks = new List<Task>();
_spawner = spawner;
_wallet = wallet;
for (int i = 0; i < _tasksConfig.Tasks.Count; i++)
_tasks.Add(_tasksConfig.Tasks[i]);
_currentTask = _tasks[0];
_taskExecuter.Executed += NextTask;
}
private void NextTask()
{
_wallet.AddValue(_currentTask.AmountMoney);
_tasks.Remove(_currentTask);
_spawner.DestroyTask();
if (_tasks.Count >= 1)
{
Debug.Log(_currentTask.TaskName);
_currentTask = _tasks[0];
}
else if (_tasks.Count == 0)
{
Debug.Log(_currentTask.TaskName);
SceneManager.SceneManager sceneManager =
new SceneManager.SceneManager(_tasksConfig.TaskType, _tasksConfig.NameSceneToWin);
}
}
public void Dispose()
{
_taskExecuter.Executed -= NextTask;
}
}
}
using System;
using System.Collections.Generic;
using Tasks.SceneManager;
using UnityEngine;
[CreateAssetMenu(fileName = "TaskConfig", menuName = "Game/new TaskConfig")]
public class TasksConfig : ScriptableObject
{
[field: SerializeField] private List<Task>_tasks;
[SerializeField] private TaskType _taskType;
[SerializeField] private string _nameSceneToWin;
public List<Task> Tasks => _tasks;
public TaskType TaskType => _taskType;
public string NameSceneToWin => _nameSceneToWin;
}
[Serializable]
public struct Task
{
public Sprite Background;
public string TaskName;
public int AmountMoney;
}
TaskConfig и Task теперь хранят : Количество денег за выполнение задания, Тип задания, Сцену, на которую перейдет игрок после окончания заданий, если тип будет new Scene.