워리어 콤보 모작 개발일지

워리어콤보 모작 개발일지 - 04 [StageInfo, StageReader][연습]

다모아 2023. 9. 14. 16:01

https://docs.unity3d.com/ScriptReference/JsonUtility.ToJson.html

 

Unity - Scripting API: JsonUtility.ToJson

Internally, this method uses the Unity serializer; therefore the object you pass in must be supported by the serializer: it must be a MonoBehaviour, ScriptableObject, or plain class/struct with the Serializable attribute applied. The types of fields that y

docs.unity3d.com

참고

https://ninezmk2.blogspot.com/2019/11/blog-post_12.html

 

4. 파일에서 스테이지 데이터 로드하기

유니티 3매치 퍼즐 게임 개발 과정을 공유하는 블로그입니다.

ninezmk2.blogspot.com

JsonUtility.FromJson과 JsonConvert.DeserializeObject의 차이

전자는 유니티 내에 있는 json기능이고

후자는 라이브러리에서 제공하는 Json기능이다.

 


추가

CellFactory

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public static class CellFactory
{
    public static Cell SpawnCell(StageInfo stageInfo, int nRow, int nCol)
    {
        Debug.Assert(stageInfo != null);
        Debug.Assert(nRow < stageInfo.row && nCol < stageInfo.col);

        return SpawnCell(stageInfo.GetCellType(nRow, nCol));
    }

    public static Cell SpawnCell(CellType cellType)
    {
        return new Cell(cellType);
    }
}

 

StageReader

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public static class StageReader
{
    public static StageInfo LoadStage(int nStage)
    {
        Debug.Log($"Load Stage : Stage/{GetFileName(nStage)}");

        TextAsset asset = Resources.Load<TextAsset>($"Stage/{GetFileName(nStage)}");
        if (asset != null)
        {
            StageInfo stageInfo = JsonUtility.FromJson<StageInfo>(asset.text);

            Debug.Assert(stageInfo.DoValidation());

            return stageInfo;
        }

        return null;
    }

    //파일 이름 숫자 4자리 읽어오기
    private static string GetFileName(int nStage)
    {
        return string.Format("stage_{0:D4}", nStage);
    }
}

 

StageInfo

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[Serializable]
public class StageInfo
{
    public int row;
    public int col;

    public int[] cells;

    public override string ToString()
    {
        return JsonUtility.ToJson(this);
    }

    //요청한 위치에 해당되는 CellType을 리턴하는 메서드
    public CellType GetCellType(int nRow, int nCol)
    {
        //요청한 위치가 유효한지 체크
        Debug.Assert(cells != null && cells.Length > nRow * col + nCol);

        if (cells.Length > nRow * col + nCol)
        {
            return (CellType)cells[nRow * col + nCol];
        }

        Debug.Assert(false);

        return CellType.EMPTY;
    }

    //Json 데이터가 맞는지 검사 및 블럭크기랑 배열크기가 다른 경우 false 아니면 true
    public bool DoValidation()
    {
        Debug.Assert(cells.Length == row * col);
        Debug.Log($"cell length : {cells.Length}, row, col = ({row}, {col})");

        if (cells.Length != row * col)
            return false;

        return true;
    }
}

변경

StageBuilder

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StageBuilder
{
    private int m_nStage;

    private StageInfo m_StageInfo;

    public StageBuilder(int nStage)
    {
        this.m_nStage = nStage;
    }

    public Stage ComposeStage()
    {
        //스테이지 번호가 유효한지 검사
        Debug.Assert(this.m_nStage > 0, $"Invalide Stage : {m_nStage}");

        this.m_StageInfo = LoadStage(this.m_nStage);

        Stage stage = new Stage(this, this.m_StageInfo.row, this.m_StageInfo.col);

        //Cell, Block 초기 값 생성
        for (int nRow = 0; nRow < this.m_StageInfo.row; nRow++)
        {
            for (int nCol = 0; nCol < this.m_StageInfo.col; nCol++)
            {
                stage.blocks[nRow, nCol] = SpawnBlockForStage(nRow, nCol);
                stage.cells[nRow, nCol] = SpawnCellForStage(nRow, nCol);
            }
        }

        return stage;
    }

    private StageInfo LoadStage(int nStage)
    {
        StageInfo stageInfo = StageReader.LoadStage(nStage);
        if (stageInfo != null)
        {
            Debug.Log(stageInfo.ToString());
        }

        return stageInfo;
    }

    private Block SpawnBlockForStage(int nRow, int nCol)
    {
        if (this.m_StageInfo.GetCellType(nRow, nCol) == CellType.EMPTY)
            return SpawnEmptyBlock();

        return SpawnBlock();
    }

    public Block SpawnBlock()
    {
        return BlockFactory.SpawnBlock(BlockType.BASIC);
    }

    public Block SpawnEmptyBlock()
    {
        Block newBlock = BlockFactory.SpawnBlock(BlockType.EMPTY);

        return newBlock;
    }
    private Cell SpawnCellForStage(int nRow, int nCol)
    {
        Debug.Assert(this.m_StageInfo != null);
        Debug.Assert(nRow < this.m_StageInfo.row && nCol < this.m_StageInfo.col);

        return CellFactory.SpawnCell(this.m_StageInfo, nRow, nCol);
    }

    public static Stage BuildStage(int nStage)
    {
        StageBuilder stageBuilder = new StageBuilder(nStage);
        Stage stage = stageBuilder.ComposeStage();

        return stage;
    }
}

 

StageController

row, col이 필요없어짐