오늘은 팀에서 진행했던 프로젝트의 발표날이다. 우리는 GitHub의 Readme파일에 발표 내용을 정리했다. 주요 정리점은 다음과 같다.
이렇게 정리한 내용을 토대로 발표 준비를 진행하였으며, 곧 타팀들의 발표도 시작되었다.
다음으로 지금까지 이 velog에 작성했던 TIL Post를 어떻게 더 효과적으로 작성할 수 있을지에 대해 수강하였다.
오늘 남은 시간은 랜덤 타워 디펜스에서 핵심 기능 중 하나인 타워 업그레이드 기능을 만들도록 하겠다. 랜덤 타워 디펜스의 타워 업그레이드 시스템은 다음과 같다.
타워 업그레이드 시스템
이 시스템을 충족시킬 수 있도록 구현 순서를 구상해보겠다.
Grade 와 Number 정보를 갖도록 만든다.Tower.cspublic class Tower : MonoBehaviour
{
[Header("타워 정보")]
public string towerGrade; // 예: "Normal", "Rare", "Unique", ...
public int towerTypeNumber; // 예: 1 ~ 8
}
towerGrade: "Normal"towerTypeNumber: 1TryUpgrade() 정의 void TryUpgrade()
{//타워 탐색
Tower[] allTowers = FindObjectsOfType<Tower>();
foreach (Tower other in allTowers)
{
if (other != this &&
other.towerGrade == this.towerGrade &&
other.towerTypeNumber == this.towerTypeNumber)
{
Vector3 spawnPos = transform.position;
// 다음 등급의 타워 생성
TowerSpawner.Instance.SpawnUpgradedTower(towerGrade, towerTypeNumber, spawnPos);
// 선택된 타워와 대상 타워 제거
Destroy(other.gameObject);
Destroy(this.gameObject);
return;
}
}
}
tile.isOccupied를 false로 바꿔준다. private void OnDestroy()
{
RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.zero);
if (hit.collider != null)
{
Tile tile = hit.collider.GetComponent<Tile>();
if (tile != null)
{
tile.isOccupied = false;
}
}
}
tile이 있는지를 물리적으로 확인하여 만약 tile이 존재하면 그 tile 오브젝트를 가져오고, 그 tile의 isOccupied값을 false로 돌린다.E키와 함께 마우스 클릭을 하면 TryUpgrade()함수를 불러온다.private void OnMouseDown()
{
if (Input.GetKey(KeyCode.E))
{
TryUpgrade();
}
}
TowerSpawner에 업그레이드 생성 함수 만들기SpawnUpgradedTower()public void SpawnUpgradedTower(string currentGrade, int currentType, Vector3 position)
{
string nextGrade = GetNextGrade(currentGrade); // 다음 등급 이름 반환
GameObject[] pool = GetTowerPool(nextGrade); // 해당 등급 프리팹 배열 가져옴
if (pool == null || pool.Length == 0)
{
Debug.LogWarning($"[Upgrade 실패] {nextGrade} 등급 타워 프리팹이 없음");
return;
}
int rand = Random.Range(0, pool.Length); // 0~7 중 랜덤
GameObject newTower = pool[rand];
Instantiate(newTower, position, Quaternion.identity); // 선택한 타워 위치에 다음 등급의 랜덤 타워 생성
}
GetNextGrade(): 현재 등급에서 다음 등급으로 넘어감GetTowerPool(): 다음 등급에 해당하는 배열을 가져옴 private string GetNextGrade(string grade)
{
switch (grade)
{
case "Normal": return "Rare";
case "Rare": return "Unique";
case "Unique": return "Epic";
case "Epic": return "Legendary";
default: return null;
}
}
private GameObject[] GetTowerPool(string grade)
{
switch (grade)
{
case "Normal": return normalTowers;
case "Rare": return rareTowers;
case "Unique": return uniqueTowers;
case "Epic": return epicTowers;
case "Legendary": return legendaryTowers;
default: return null;
}
}
TowerSpawner 오브젝트에 각 타워들을 연결시킨다.Tower_Normal의 스케일을 0.3으로 조절하고 등급이 올라갈 때마다 0.1씩 키웠다.Tower_Normal의 사정거리가 3이고, 공격속도가 1이므로, 등급이 올라갈 때마다 사정거리를 1씩 늘리고, 공격속도는 두배씩 빠르게 만들었다.이후 게임을 실행해보았다.

의도한 대로 실행되고 있음을 확인했다.
다음 시간에는 무엇을 더 추가할 지 구상해보고 오늘 TIL을 마치고자 한다.
투사체 이펙트
적 사망 이펙트
UI: 체력바, 골드 표시, 다음 웨이브까지 남은 시간 등
게임 클리어/ 오버 화면
현재 카드 프리팹을 하나하나 지정하고 있는데, 이를 코드로 리팩토링하여 타워 정보를 분리.
앞으로 있을 다양한 프로젝트의 방향성을 어림잡아 볼 수 있는 한 주 였다고 생각한다.
다음주의 발제 내용은 C# 문법이다. 지금까지 Unity 실습하면서 C#을 계속 접했는데, 그만큼 C# 문법을 익히는 것이 중요함을 알고, 다음주 학습에 더욱 집중하도록 하겠다.