개발중인 로그라이크 게임에 강화 기능을 구현중이었다.
원래 기획은, 각 아이템마다 3개의 강화 테크가 있고,
매 웨이브가 끝날 때마다 게임 진행동안 획득한 재화를 통해 각 테크별로 강화를 구매할 수 있는 방식이었다.
웨이브를 마칠 때마다 아이템 하나 지급과 함께, 보유 중인 아이템 중에서 3개가 랜덤으로 강화 가능 아이템으로 등장하고
그 중 하나를 선택하면 다시 강화 테크 3개가 등장(데미지 증가, 딜레이 감소, 투사체 추가 등)하여 재화를 주고 구매하는 것이다. 강화 단계는 또 따로 있어서 3개의 테크 모두 강화 단계를 +N강 하는것이 가능하다.
이렇게 구현하다보니 처음 생각했던 것보다 재화 관련하여 밸런스 맞출 것이 훨씬 많아지고, 강화 단계마다 텍스트와 효과를 모조리 구현하는 동시에 또 강화를 어디까지 했는지 각 강화테크별로 기록해야 했다.
아이템 하나당 테크가 3개고 강화 단계가 5단계까지만 있다고 하더라도 15개의 강화단계에 대한 효과, 재화 밸런스를 맞춰야 하는 것이다...
게다가 강화에 있어서는 랜덤성이 확 떨어져서, 어차피 강화하지 않은 아이템은 강화된 아이템에 비해 아주 약할텐데 결국 로그라이크에서 중요한 운의 요소가 줄어들고 매번 새로운 플레이가 불가능해질 것이라고 생각이 들었다.
따라서 어느정도 구현하다가 강화 방식을 바꾸기로 했다. 아이템마다 강화 항목이 n개 있으면,
이 중에서 랜덤으로 웨이브 종료시 몇 개가 구매할 수 있도록 뜬다. 여느 로그라이크 게임에서 그러하듯 랜덤 상점 기능인 것이다. 단 여기서는 아이템이 아닌 강화를 구매한다.
따라서 강화에는 좋고 비싼 강화, 싸고 그저 그런 강화도 있으니 밸런스 부담도 줄어들고, 구현 부담도 줄어들 것 같다.
돌아가기만 하면 된다는 생각으로 무작정 코드를 쳤더니 엄청 꼬이고 디버깅도 어려워져서 기록해둔다.
public int Gem{get; private set;} = 0; // 현재 게임 보석
public struct reinforce
{
public int[,] needGem;
public string[,] reinforceContent;
}
////////////////////////아이템 개수에 따라 수정/////////////////////////////
public bool[] itemChecker = new bool[5];
public reinforce[] reinforceArry = new reinforce[5]; //기타 강화 정보 표시용
public int[,] reinforceChecker{get; private set;} = new int[5,3]; //강화 단계 저장(아이템 넘버, 강화 테크) 배열
/////////////////////////////////////////////////////////////////////////
public bool isGameover { get; private set; } // 게임 오버 상태
private void Awake() {
// 씬에 싱글톤 오브젝트가 된 다른 GameManager 오브젝트가 있다면
if (instance != this)
{
// 자신을 파괴
Destroy(gameObject);
}
}
private void Start() {
//구조체의 배열들 초기화
for(int i=0 ; i < reinforceArry.Length; i++)
{
reinforceArry[i].needGem = new int[3,5];
reinforceArry[i].reinforceContent = new string[3,5];
}
//아이템 0번
reinforceArry[0].needGem[0,0] = 300;
reinforceArry[0].needGem[0,1] = 500;
reinforceArry[0].needGem[0,2] = 900;
reinforceArry[0].needGem[0,3] = 1500;
reinforceArry[0].needGem[0,4] = 2400;
reinforceArry[0].needGem[1,0] = 300;
reinforceArry[0].needGem[2,0] = 300;
reinforceArry[0].reinforceContent[0,0] = "Increase damage";
reinforceArry[0].reinforceContent[1,0] = "Increase speed";
reinforceArry[0].reinforceContent[2,0] = "Add sword";
//아이템 1번
reinforceArry[1].needGem[0,0] =300;
reinforceArry[1].needGem[1,0] =300;
reinforceArry[1].needGem[2,0] =300;
reinforceArry[1].reinforceContent[0,0] = "a";
reinforceArry[1].reinforceContent[1,0] = "b";
reinforceArry[1].reinforceContent[2,0] = "c";
//아이템 2번
reinforceArry[2].needGem[0,0] =300;
reinforceArry[2].needGem[1,0] =300;
reinforceArry[2].needGem[2,0] =300;
reinforceArry[2].reinforceContent[0,0] = "a";
reinforceArry[2].reinforceContent[1,0] = "b";
reinforceArry[2].reinforceContent[2,0] = "c";
//아이템 3번
reinforceArry[3].needGem[0,0] =300;
reinforceArry[3].needGem[1,0] =300;
reinforceArry[3].needGem[2,0] =300;
reinforceArry[3].reinforceContent[0,0] = "a";
reinforceArry[3].reinforceContent[1,0] = "b";
reinforceArry[3].reinforceContent[2,0] = "c";
//아이템 4번
reinforceArry[4].needGem[0,0] =300;
reinforceArry[4].needGem[1,0] =300;
reinforceArry[4].needGem[2,0] =300;
reinforceArry[4].reinforceContent[0,0] = "a";
reinforceArry[4].reinforceContent[1,0] = "b";
reinforceArry[4].reinforceContent[2,0] = "c";
for(int i = 0; i < itemChecker.Length; i++)
{
itemChecker[i] = false;
}
for(int i =0; i < 5; i++)/////////////////수정필요///////////////////
{
for(int k = 0; k < 3 ; k++)
reinforceChecker[i,k] = 0; //강화 단계 초기화.
}
구조체 배열을 만들고 (각 구조체는 아이템 하나를 의미) 각 강화 항목에 필요한 재화, 설명을 2차원 배열로 담는다.
강화 단계만 있는게 아니라 강화 종류가 3가지이므로 2차원 배열로 [강화 종류 3가지, 강화 단계 ] 이렇게 만들어야했다.
강화를 어디까지 했는지 기록하기 위해서 강화 단계를 저장하는 변수는 구조체와 별개로, 역시 2차원 배열로 만들었다.
[아이템 넘버(구조체 배열의 인덱스), 강화 테크] = 강화 단계 -> 이런 식으로 해서 모든 아이템의 강화 종류(세가지)에 대한 강화 단계를 저장 할 수 있었다.
public void Reinforce(int num)
{
IItem item = itemList[ITEM].GetComponent<IItem>();
switch(num)
{ //아이템은 정해졌고(몇 번 아이템으로 정해진건지 알려줘야함)
// 아이템의 강화가 선택되는 상황
case 0 : //Done 버튼
Time.timeScale =1;
reinforceSelect_r.SetActive(false);
break;
case 1 : //0번 테크가 선택된 상황
//GEM이 충분하다면
if(GameManager.instance.Gem >= GameManager.instance.reinforceArry[ITEM].needGem[0,GameManager.instance.reinforceChecker[ITEM,0]] )
{
GameManager.instance.MinusGem(GameManager.instance.reinforceArry[ITEM].needGem[0,GameManager.instance.reinforceChecker[ITEM,0]]);
GameManager.instance.reinforceChecker[ITEM,0] ++; //강화 횟수 증가(+1)
item.Reinforce(0); //ITEM번 아이템의 0번 테크 강화 호출
Debug.Log("강화완료");
}
else
Debug.Log("Not Enough Gem");
break;
이건 UI와 연결하여 아이템 강화에 대한 정보를 표시하는 부분인데, 애초에 저장 방식이 난잡하다보니
불러오는 과정에서도 복잡해진 것 같다.
'Unity' 카테고리의 다른 글
[Unity] 오브젝트 풀링시 총알이 자꾸 사라지는 문제 (0) | 2022.05.17 |
---|---|
[Unity] 오브젝트 풀링 + 가장 가까운 적 방향으로 공격 (0) | 2022.04.22 |
[Unity] 화염 방사 아이템 (0) | 2022.04.12 |
[Unity] 퍼블릭(public) 선언시 주의할 점 (0) | 2022.04.07 |
[Unity] 가장 가까운 적에게 투사체 발사 (0) | 2022.03.27 |