@yraiv

Как использовать json?

Как использовать json? Я не понимаю, он мне возвращает null и логично, т.к. у меня ещё ничего не сохранено, но как лучше заготовку сделать, которая будет с 0, но не null?
Тип, чтоб я мог перезаписать потом нужные мне очки

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class LevelListManager : MonoBehaviour
{
    public GameObject[] ObjectsForDestroy;
    public int CountLevelComplet;
    private List<GameObject> ButtonsList = new List<GameObject>();
    [SerializeField]
    private string keyName;
    [SerializeField]
    private int CountStars;
    [SerializeField]
    private Transform parent;
    [SerializeField]
    private GameObject PrefabButton;

   

    public void OnMouseDown()
    {
        for(int i = 0; i < ObjectsForDestroy.Length; i++)
        {
            ObjectsForDestroy[i].SetActive(false);
        }

        for(int i = 0; i< 60; i++)
        {
            var tempButton =Instantiate(PrefabButton, parent);
            ButtonsList.Add(tempButton);
        }
        var a = 1;

        for (int i = 0; i < 60; i++)
        {
            Debug.Log(i);
            ButtonsList[i].transform.GetChild(0).GetChild(0).GetComponent<TextMeshProUGUI>().text = a.ToString();
            a++;
        }


        for (int i = 0; i < 60; i++)
        {
        keyName = i.ToString();
        LoadLvlList();
        if (CountStars == 0)
        {
            ButtonsList[i].GetComponent<Button>().interactable = false;
            Debug.Log("нет звезд");
        }
         }

        this.gameObject.SetActive(false);
    }

    public void SaveLvlList()
    {
        PlayerPrefs.SetString(keyName, JsonUtility.ToJson(CountStars));

    }
    public void LoadLvlList()
    {
        CountStars = JsonUtility.FromJson<int>(PlayerPrefs.GetString(keyName));       
    }
}
  • Вопрос задан
  • 139 просмотров
Решения вопроса 2
K0TlK
@K0TlK
Буллю людей.
public GameObject[] ObjectsForDestroy;

Что за объекты?

Json в PlayerPrefs сохранять не надо, как и строки в принципе, сохраняй в отдельный файл.

То, что у тебя в OnMouseDown происходит я вообще не понимаю
Что за а? Что эта переменная вообще означает?
.GetChild(0).GetChild(0) Когда у тебя порядок в иерархии поменяется, будешь искать ошибку.

Про Manager, надеюсь, говорить не надо.

TL;DR

Создать пустую директорию
private void CreateDirectory()
        {
            if (Directory.Exists(_directoryPath) == false)
            {
                Directory.CreateDirectory(_directoryPath);
            }
        }


Создать файл с нулевыми значениями
private void CreateFile()
        {
            if (File.Exists(_path)) return;
            
            var json = JsonUtility.ToJson(CompleteStatus.Locked);
                
            using (var writer = File.CreateText(_path))
            {
                writer.Write(json);
                writer.Close();
            }
        }



Как использовать Json:

Есть какой-то уровень:

namespace Levels
{
    public interface ILevel : IVisualization<ILevelView>
    {
        void Load();
        void Complete(CompleteStatus status);
    }
}

namespace Levels
{
    public interface IVisualization<in TView>
    {
        void Visualize(TView view);
    }
}



Есть его вьюшка:

namespace Levels
{
    public enum CompleteStatus
    {
        Locked,
        Uncompleted,
        OneStar,
        TwoStars,
        ThreeStars
    }
    public interface ILevelView
    {
        void DrawCompletion(CompleteStatus status);
    }
}



Реализация уровня:

Сохранение нужно вынести отдельно, но мне лень это делать.
При вызове Load загружается уровень.
При вызове Complete уровень завершается и сохраняется количество звезд на которое пройден уровень, у меня здесь максимум три звезды, если нужно сохранять какой-то счет, создавай структуру, которую будешь сохранять вместо перечисления.
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace Levels
{
    public abstract class Level : ILevel
    {
        private readonly string _name;

        private readonly string _path;

        private readonly string _directoryPath = $"{Application.persistentDataPath}/Saves";

        protected Level(string name)
        {
            _name = name;
            _path = $"{_directoryPath}/{_name}.json";
            CreateDirectory();
            CreateFile();
        }

        public void Load()
        {
            SceneManager.LoadScene(_name);
        }

        public void Complete(CompleteStatus status)
        {
            SaveStatus(status);
        }

        public void Visualize(ILevelView view)
        {
            view.DrawCompletion(LoadStatusFromJson());
        }

        private void CreateDirectory()
        {
            if (Directory.Exists(_directoryPath) == false)
            {
                Directory.CreateDirectory(_directoryPath);
            }
        }

        private void CreateFile()
        {
            if (File.Exists(_path)) return;
            
            var json = JsonUtility.ToJson(CompleteStatus.Locked);
                
            using (var writer = File.CreateText(_path))
            {
                writer.Write(json);
                writer.Close();
            }
        }
        
        private void SaveStatus(CompleteStatus status)
        {
            var json = JsonUtility.ToJson(status);
            File.WriteAllText(_path, json);
        }
        
        private CompleteStatus LoadStatusFromJson()
        {
            var file = File.ReadAllText(_path);
            return JsonUtility.FromJson<CompleteStatus>(file);
        }
        
    }
}


Собственно, так выглядит уровень:
namespace Levels
{
    public class SecondLevel : Level
    {
        public SecondLevel() : base(nameof(SecondLevel))
        {
        }
    }
}



Реализация вьюшки:

т.к. это вьюшка, можно говнокодить как хочешь.
На основании статуса у звезд устанавливается конкретный цвет и активность кнопки.
using System;
using UnityEngine;
using UnityEngine.UI;

namespace Levels
{
    public class LevelView : MonoBehaviour, ILevelView
    {
        [SerializeField] private Image _firstStar, _secondStar, _thirdStar;
        [SerializeField] private Button _button;
        [SerializeField] private Color _inactiveStarColor, _activeStarColor;
        
        public void DrawCompletion(CompleteStatus status)
        {
            switch (status)
            {
                case CompleteStatus.Locked:
                    _firstStar.color = _inactiveStarColor;
                    _secondStar.color = _inactiveStarColor;
                    _thirdStar.color = _inactiveStarColor;
                    _button.interactable = false;
                    break;
                case CompleteStatus.Uncompleted:
                    _button.interactable = true;
                    _firstStar.color = _inactiveStarColor;
                    _secondStar.color = _inactiveStarColor;
                    _thirdStar.color = _inactiveStarColor;
                    break;
                case CompleteStatus.OneStar:
                    _button.interactable = true;
                    _firstStar.color = _activeStarColor;
                    _secondStar.color = _inactiveStarColor;
                    _thirdStar.color = _inactiveStarColor;
                    break;
                case CompleteStatus.TwoStars:
                    _button.interactable = true;
                    _firstStar.color = _activeStarColor;
                    _secondStar.color = _activeStarColor;
                    _thirdStar.color = _inactiveStarColor;
                    break;
                case CompleteStatus.ThreeStars:
                    _button.interactable = true;
                    _firstStar.color = _activeStarColor;
                    _secondStar.color = _activeStarColor;
                    _thirdStar.color = _activeStarColor;
                    break;
                default: throw new ArgumentException();
            }
        }
    }
}



И тест

using System.Collections.Generic;
using UnityEngine;

namespace Levels
{
    public class LevelList : MonoBehaviour
    {
        [SerializeField] private LevelView _levelViewPrefab;
        [SerializeField] private Transform _levelsParent;

        private ILevel[] _levels;
        
        private void Awake()
        {
            var first = new FirstLevel();
            var second = new SecondLevel();
            var third = new ThirdLevel();
            var fourth = new FourthLevel();
            var fifth = new FifthLevel();
            
            _levels = new ILevel[]
            {
                first, second, third, fourth, fifth
            };

            //test
            first.Complete(CompleteStatus.OneStar);
            second.Complete(CompleteStatus.TwoStars);
            third.Complete(CompleteStatus.ThreeStars);
            fourth.Complete(CompleteStatus.Uncompleted);
            fifth.Complete(CompleteStatus.Locked);

            VisualizeLevels(_levels);
        }

        private void VisualizeLevels(IEnumerable<ILevel> levels)
        {
            foreach (var level in levels)
            {
                var view = Instantiate(_levelViewPrefab, _levelsParent);
                level.Visualize(view);
            }
        }
    }
}



Так выглядит:
63144a1583e29173450114.jpeg
Ответ написан
firedragon
@firedragon
Не джун-мидл-сеньор, а трус-балбес-бывалый.
private int CountStars = 0;
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы