ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스파르타 심화주차 팀과제 / 계속 나오는 보스 만들기
    스파르타 게임 개발 2024. 6. 19. 22:35

    이번 팀과제에서는 우리팀의 컨셉을 이용한 클릭형 게임을 만들어 보기로 했다.

     

    우리가 보스고, 우리를 죽이면 사진을 얻어서 프로필사진을 바꿀 수 있게 된다. 뭔가 좀 더 스토리를 떠올리면 재밌을 것 같은데 일단은 여기까지,

    팀 컨셉

     

    보스는 죽으면 다른 보스가 나오고, 점점 체력이 많아진다. 

    보스들로 만들어질 기본프사들..,

     

    지금 생각 한 것은 보스는 맞으면 확률적으로 사진을 떨어뜨리고, 돈을 주고, 피격애니메이션, 효과음이 있고, 말풍선이 랜덤으로 나오게 할 생각이다. 그리고 죽게 되면 다음 보스가 스폰 되고, 사진도 뿌리고, 해서 결과적으로 우리 4명의 사진을 다 모으면 엔딩이다.

    보스 초기 구상안?이라고 해야 하나.

     

     

    일단 뭐부터 시작해야할지 생각이 길어질까봐 무작정 오브젝트들부터 만들었다.

    굉장히 간단하다.. ㅋㅋ 나중에 최대한 이것저것 붙여서 이쁘게 보이게 해야겠다.

     

    오브젝트를 만드는 데 Text가 나오질 않는 것이다. 그냥 Legacy 오류 때문이었는데, 이제 그냥 웬만하면 TMP 써야겠다..

    처음엔 사이즈 잘못 조절 해서인줄 알았는데 아무튼 아니였다. 

     

    하 그런데 역시 2D 뭔가 어렵다. 3D가 쉬운 것 같다 나는

     

    그리고 이제 스크립트 작업을 해주면 될 것 같다. 

     

    보스마다 다른 대사들, 다른 아이템들의 데이터를 갖고 있어야 하기에 나는 Scriptable Object를 사용 하기로 했다. 

    이 스크립터블 오브젝트로 보스가 갖고 있는 사진, 대사들 체력, 등등 기본 데이터를 관리 하게 할 생각이다. 

     

    보스는 총 4마리로 만들 생각이고, 4마리가 다 처치 된 다음에는 기본보스가 나오게 할 것이다. 

     

    그러니까 4마리 말고 보스를 더 만들고 싶다면, 오브젝트 하나 만들고 SO만 추가 시켜주면 되게끔 만들고 싶다. 

    만든 SO 코드

    이렇게 만들어봤는데 나중에 보스를 생성 할 때 게임매니저에 SO배열을 만들거다. 거기에 순서대로 배열을 집어넣고 생성 할 때 이 배열 순서로 보스를 생성 하게 하고, 만약 배열이 없다면 생각해둔 보스가 없는 것이니까 그냥 쭉 다른 능력치 적용 하게 해서 보스 만들게 할 생각이다. 한 번 해보자. 

     

    예) 보스 생성 if( SO[i] != null) bossStemina = SO[i].Stemina 

     

    else bossStemina = curBossStemina += 증가 될 능력치 

     

    이런 식으로 만들어 볼 생각이다. 

     

    일단 한 번 해보자. 

     

     

    ======

    문제 발생. 

    저렇게 스크립트를 작성 하고 SO를 등록 하려고 하였는데 에디터에서 수정이 제대로 되지 않는 것을 발견 했다. 

    Reward에 None이라고 돼 있는 모습, 원래는 클래스 안에 변수가 나와야함.

     

    코드를 다시 봐도 내가 생각한대로 되어야 하는데 되지 않길래 무엇인고 찾아봤는데 내가 Reward 클래스 위에 직렬화 해주는 것을 추가 해주지 않았다. 

     

    그래서 [System.Serializable] 코드를 추가 시켜줬다. 

     

    하지만 그럼에도 되질 않았다. 대체 왜 그런고, 나의 두뇌로는 작동이 돼야 했다. 

     

    그래서 튜터님께 여쭤봤는데 나는 Reward에 MonoBehaviour를 상속 받게 했다. 그래서 안 되는 것이였다. 

    [System.Serializable]은 클래스를 직렬화 해주는 것인데 이 MonoBehaviour는 직렬화가 안 되는 기능들도 있기에(클래스를 받아 올 때 private는 접근 할 수 없듯이) [System.Serializable]을 사용해도 나오지가 않는 것이었다. 

     

    그래서 MonoBehaviour를 상속 빼고 적용을 하니 정상적으로 작동이 되는 것을 확인 했다!

    히히 속이 시원하군

     

    내가 원하는 대로 만들어서 만족 한다 음.

     

    이제 이 SO를 활용해서 구현을 하자. 생각보다 이거 오래 걸려서 까먹었다 뭐 할려고 했지.

    아 보스를 만들게 해야 한다. 일단 SO들을 만들자

     

    이제 게임매니저나 보스를 생성 하는 곳에서 이 SO들을 등록을 해두고 보스가 죽으면 다시 보스를 생성을 하는데 생성 할 때 이 SO를 찾조하게 할 거다. 

     

    그리고 만약 없다면 기본값 해서 쭉 생성 되게 하면 될 것 같다. 그러면 보스를 생성 하는 걸 만들어 보자. 

     

    보스 생성하는 얘 - > 게임매니저 이런 느낌으로 해봐야 겠다. 

     

    일단 오브젝트와 스크립트를 만든다. 

     

     

    ================ 시간이 지나고 난 뒤 .., 

    원래 하면서 계속계속 추가 하려고 했지만 일이 좀 생겼어서 몰아적게 되었다. 

     

    나는 보스 구현을 이렇게 했다. 

     

    Boss라는 오브젝트는 SO를 받아와서 그 SO를 참고해 함수들을 호출 한다. 

    BossManager에서 Boss를 생성 하는데 갖고 있는 SO로 생성을 시킨다. (Manager는 SO를 배열로 갖고 있음)

     

    갖고 있는 SO배열이 내가 만들어둔 보스들로 생각 하면 된다. 

    지정해둔 보스는 4개

     

    보스가 다 잡히면 그냥 기본 도형 나오게 했다. 방치형게임은 멈추면 안 되기 때문이다.

     

    이렇게 SO를 늘리고, Boss 오브젝트는 하나만 만들었다. 

     

    나는 굳이 보스별 오브젝트를 만들 필요 없이, 체력이라는 변수가 0이 되면 체력변수와 이미지, 텍스트들을 담고 있는 SO를 바꿔버리면 된다고 생각 했기에 SO만 배열로 넣게 했다. 결론적으로 나중에 보스를 추가 하고 싶으면 SO만 추가 시키면 된다. 

    BossManager의 코드

     

    위 함수는 보스의 데이터를 바꾸는 함수로 만들어 봤고 함수이름에 대해서 고민을 많이 했다.

    Spawn이라는 단어를 쓸지...., Change라는 이름을 쓸지.., 함수이름과 기능은 같게 하라는 말이 있어서,, 고민을 좀 해보고 나는 눈에 보이는 것은 보스를 재생성 하는 것이기에 Spawn이라는 이름을 썻다. 

     

    나중에 그리고 코루틴을 적용해서 보스가 죽고 바로 생성 되지 않게 할 거다. 

     

    (위에 사진 중 curBoss는 Boss 클래스, CreateBoss는 Boss가 갖고 있는 필드를 매개변수로 받은 SO의 데이터들로 초기화 하는 함수다)

    CreatBoss가 호출 하는 함수.

     

    CreatBoss는 Boss의 필드들의 값을 바꾸게 하는 것이고 그러니까 SO를 바꾸게 했다. 그리고 BossDataEnter(함수명이 좀 이거 맞나? ㅋㅋ,,,,,) 를 호출 해서 보스의 스텟과 등등등을 다시 바꾸게 만들었다. 

     

    이렇게 스텟을 바꾸게 한 다음에 보스들에 여러 기능들을 호출 하는 형식으로 만들었다. 

    ex) 보스 말풍선 나오기, 보스 체력 닳게 하기, 보스 템 뿌리기, 보스 골드 주기, 등등등!

    이렇게 하면 현재 SO에 따라 각각 보스들이 갖고 있는 대사와 체력, 아이템이 뿌려지는 거다.

     

    그리고 나는 보스의 체력이 닳게 하는 부분을 어떻게 할까 고민을 한 적이 있었다. 

    무슨 고민이였냐면, 보스의 체력을 어디에 두어야 할까였다. 

     

    현재 구조상 SO를 변경 하는 건 BossManager에서 가능 했다. 그래서 체력을 갖고 있는 Boss에서 0이 되어도 SO를 바꾸지 못 하고 필드 값도 다시 바꿔주지 못 했다. 

     

    그래서 어떻게 할까 고민 해봤는데 처음에는 BossManager에 체력을 만들어서 그걸 함수 호출 될 때마다 바뀌게 할까 해봤지만 그것보단 더 나은 방법을 떠올렸다. 

    보스의 현재 체력을 리턴함.

     

    이런 식으로 보스의 체력이 깎이게 한 다음에 현재 보스의 체력을 리턴 하게 만들었다.

    그래서 0이 리턴 되면 보스가 재생성 되는 코드를 호출 하게끔 해봤다.

    이런 식으로, 난 매개변수 2번 받는 것을 깨닫기까지 꽤 오래 걸림.

     

    이렇게 해서 보스가 죽으면 보스를 생성 하는 코드를 다시 호출 하고, 만들어둔 보스가 다 죽으면 기본도형 그냥 나오게 해서 색깔만 바뀌게 했다. 체력은 그냥 2배로 늘려버리게 하고, 방치형은 멈추면 안 되니까..!

    보스 생성 하는 함수가 다름

     

    이 기능을 구현 할 때 어떻게든 함수 하나만 사용해서 보스 나오게 하고 싶었는데, 결론적으로는 그냥 함수 하나 더 만들었다.(ClearCreateBoss다) / 마지막으로 저장 된 Base스텟에 계속 *2배 한다. 

     

    그리고 이 기능을 구현 할 때 나는 오류사항을 겪었다. 사진의 if조건문을 보면 올바르게 돼 있는 것을 볼 수 있다. 

    하지만 나는 처음에 bossDataSOs.Length[i] != null 이라고 조건문을 달았는데 안 됐다. 왜 안 되는지 깨달을 수 없었다. 

     

    그러니까 배열이 없다면 기본도형이 나오는 함수를 호출 하게 하고 싶어서 배열[i] != null 이라는 코드를 사용 했는데 오류가 낫다. 

     

    오류가 난 이유는 어떻게 보면 맞다고 볼 수 있는데 저건 틀린 코드다. 그러니까 컴퓨터에게 묻는 질문 자체가 잘 못 됐다고 볼 수 있다. 나는 이 몇 번째 배열이 있냐? 그러니까 배열이 5개짜리이냐? 5번째 배열이 있냐 라고 묻고 싶었다. 

     

    하지만 저 코드는 5번째 배열의 값이 들어있냐? 라는 질문인것이다. 

    그림판 참조

     

    배열을 많이 사용 안 한 문제였고,, 굉장히 단순한 거여서 튜터님께 물어보고나서 부끄러웠다 ..ㅎㅎ;; 튜터님들은 어떻게 바로바로 아는지 ㅎㅎ..,

     

    그래서 위 사진처럼 배열의 갯수를 사용해서 호출이 되게끔 코드를 바꿨다.

     

    이거 말고도 여러가지 기능들을 다 만들어놨다. 말풍선 나오게 하는거, 체력 닳고 표시 하는 거, 골드랑 아이템들 반환 하는 거 등등 다 만들어놔서 이제 합치기만 하면 될 것 같다. 

     

    오늘 합치려고 했는데 지금 생각해보면 바쁘진 않았지만 오늘 하루 정신적으로 너무 바빠서 좀 늦은 것 같다. 하.. 최종팀 관련해서 스트레스가 좀 많다.. C조에 아는 사람도 없고,,, 인구수도 없고..., ㅜㅜ 나 원래 B조였는데..,

     

    그래도 오늘 코드를 작성 하면서 내가 정말 레벨업을 많이 한 것을 느꼈다. 

    내가 봐도 내가 이렇게 코드를 잘 작성 한다고? 느껴지는 게 많았다.., 후후 나 재능 많을지도? public은 다섯손가락도 안 된다!! SO빼고, 챌린저이신 팀원분도 코드 작성 잘한다고 한다 ㅎㅎㅎ. 하지만 후반으로 갈수록.., 디버그에 약해지는 나 자신.. 그래도 시간을 헛버리진 않은 것 같아서 다행이군..,

     

    코딩이란,, 코드 치는 시간보다 고민 하는 시간이 20배는 긴 것. 그래도 고민을 많이 하고 코드를 작성 하니 술술 적힌다.

    아무튼 이제 기본적인 거 만들었고 내일 팀원분들 작업과 합친 후에 여러가지 더 추가 하면 될 것 같다!

    테스트를 해보니 뭔가 좀 이상한..데 내일 확인 해야지 ^^..

     

    기능들 다 만들어뒀으니 이제 호출 할 곳들에 넣어주기만 하면 된다.. 금방 끝나겠는뎅?

Designed by Tistory.