[골드메탈 BE4] 따라하기 9

배근철·2022년 8월 5일
0

GoldMetal BE4

목록 보기
9/11

✍ 텍스트파일을 이용한 커스텀 배치

  • 구조체스크립트를 이용해서 Stage에 따라 커스텀배치를 함
  • Spawn스크립트를 만들고 나머지를 모두 제거하고, 필요한 변수만 생성한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spawn
{
    public float delay;
    public string type;
    public int point;
}
  • 메모장을 켜서 구조체 변수에 맞도록 구분자를 지어 입력한다.
    • ex) 1,S,1 : delay 1, type S, point 1
    • 원하는 적 출현을 위한 다중 데이터 작성
  • Resources 폴더를 생성 : 런타임에서 불러오는 에셋이 저장된 폴더
    • 폴더에 메모장으로 만든 Stage 0 파일을 읽고 SpawnEnemy에서 소환한다.

파일 읽기

  • ReadSpawnFile함수를 만들고 적 출현에 관련된 변수를 초기화 시켜준다.
  • 파일 읽기를 위해 System.IO 라이브러리를 사용한다 (유니티 라이브러리가 아닌 C# 라이브러리)
  • TextAsset : 텍스트 파일 에셋 클래스

  • Resources.Load() : Resources 폴더 내 파일 불러오기

  • Resources.Load("텍스트파일명") as TextAsset
    • as TextAsset을 써줘야 텍스트 파일인지 알 수 있음.
    • 만약 텍스트 파일이 아닐 경우 NULL 처리
  • StringReader : 파일 내의 문자열 데이터 읽기 클래스

  • stringReader.ReadLine() : 텍스트 데이터를 한 줄 씩 반환(자동 줄 바꿈)

  • Split을 이용해 문자열을 나누고, 자료형에 맞게 Parse해준다.
    • delay는 float.Parse, point는 int.Parse
  • 구조체 변수를 채우고 리스트에 저장한 후 , while문으로 텍스트 끝에 다다를 때까지 읽는다.
  • StringReader로 열어둔 파일은 작업이 끝난 후 꼭 닫아 줘야함 -> Close();

  • 파일을 읽고 초기화를 다 해준 뒤 , 기존 적 생성 로직을 구조체를 활용한 로직으로 교체한다.
  • List의 길이는 Count

  • 읽은 파일 디버그로 확인

  • 설계한대로 Enemy가 생성


바뀐 코드

1. GameManager.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using UnityEngine;
using System.IO;
public class GameManager : MonoBehaviour
{

    string[] enemyObjs;

    public Transform[] enemyPoints;

    public GameObject player;

    public float nextSpawnDelay;
    public float curSpawnDelay;

    public Text scoreText;
    public Image[] lifeImage;
    public Image[] boomImage;
    public GameObject gameOverSet;
    public ObjectManager objectManager;

    public List<Spawn> spawnList;
    public int spawnIdx;
    public bool spawnEnd;

    private void Awake()
    {
        spawnList = new List<Spawn>();
        enemyObjs = new string[] { "EnemyS", "EnemyM", "EnemyL" };
        ReadSpawnList();
    }

    void ReadSpawnList()
    {
        // #. 변수 초기화
        spawnList.Clear();
        spawnIdx = 0;
        spawnEnd = false;

        // #. 리스폰 파일 읽기
        TextAsset textFile = Resources.Load("Stage 0") as TextAsset;
        StringReader stringReader = new StringReader(textFile.text);

        while(stringReader != null)
        {
            string line = stringReader.ReadLine();
            if (line == null)
                break;

            // #. 리스폰 데이터 생성
            Spawn spawnData = new Spawn();
            spawnData.delay = float.Parse(line.Split(',')[0]);
            spawnData.type = line.Split(',')[1];
            spawnData.point = int.Parse(line.Split(',')[2]);
            spawnList.Add(spawnData);
        }

        // #. 파일 닫기
        stringReader.Close();

        // #. 첫번째 스폰 딜레이 적용
        nextSpawnDelay = spawnList[0].delay;
    }

    void Update()
    {
        curSpawnDelay += Time.deltaTime;
        
        if(curSpawnDelay > nextSpawnDelay && !spawnEnd)
        {
            SpawnEnemy();
            curSpawnDelay = 0;
        }

        // UI Score Update

        Player playerLogic = player.GetComponent<Player>();
        scoreText.text = string.Format("{0:n0}", playerLogic.score);


    }

    void SpawnEnemy()
    {
        int enemyIdx = 0;

        switch(spawnList[spawnIdx].type)
        {
            case "L":
                enemyIdx = 2;
                break;
            case "M":
                enemyIdx = 1;
                break;
            case "S":
                enemyIdx = 0;
                break;
        }

        int enemyPoint = spawnList[spawnIdx].point;

        GameObject enemy = objectManager.MakeObj(enemyObjs[enemyIdx]);
        enemy.transform.position = enemyPoints[enemyPoint].position;

        Rigidbody2D rigid = enemy.GetComponent<Rigidbody2D>();
        Enemy enemyLogic = enemy.GetComponent<Enemy>();
        enemyLogic.player = player;
        enemyLogic.objectManager = objectManager;

        if(enemyPoint == 5) // Left Spawn
        {
            enemy.transform.Rotate(Vector3.forward * 90);
            rigid.velocity = new Vector2(1, -enemyLogic.speed);
        }

        else if(enemyPoint == 6) // Right Spawn
        {
            enemy.transform.Rotate(Vector3.back * 90);
            rigid.velocity = new Vector2(-1, -enemyLogic.speed);
        }

        else // Front Spawn
        {
            rigid.velocity = new Vector2(0, -enemyLogic.speed);
        }


        // #. 리스폰 인덱스 증가
        spawnIdx++;
        if (spawnIdx == spawnList.Count)
        {
            spawnEnd = true;
            return;
        }

        // #. 딜레이 갱신
        nextSpawnDelay = spawnList[spawnIdx].delay;
    }

    public void RespawnPlayer()
    {
        Invoke("RespawnPlayerExe", 2f);
    }

    public void RespawnPlayerExe()
    {
        Player playerLogic = player.GetComponent<Player>();
        playerLogic.isHit = false;
        player.transform.position = Vector3.down * 4f;
        player.SetActive(true);
    }

    public void UpdateLife(int Life)
    {
        // #. UI Init Disable
        for (int i = 0; i < 3; i++)
            lifeImage[i].color = new Color(1, 1, 1, 0);

        // #. Life Active
        for (int i = 0; i < Life; i++)
            lifeImage[i].color = new Color(1, 1, 1, 1);
    }
    public void UpdateBoom(int boom)
    {
        // #. UI Init Disable
        for (int i = 0; i < 3; i++)
            boomImage[i].color = new Color(1, 1, 1, 0);

        // #. Life Active
        for (int i = 0; i < boom; i++)
            boomImage[i].color = new Color(1, 1, 1, 1);
    }
    public void GameOver()
    {
        gameOverSet.SetActive(true);
    }

    public void Retry()
    {
        SceneManager.LoadScene(0);
    }

}

2. Spawn.cs

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

public class Spawn
{
public float delay;
public string type;
public int point;
}


출처 - https://www.youtube.com/c/GoldMetal

0개의 댓글