- 구조체스크립트를 이용해서 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
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);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spawn
{
public float delay;
public string type;
public int point;
}