체력게이지#2

CJB_ny·2022년 1월 3일
0

Mini_MMO_RPG

목록 보기
9/16
post-thumbnail

저번시간에 하던

두번째

UI를 Player에 고정시켜놓고 회전도 고정시키기를 구현을 해볼 것이다.

그래서 이것을 어떻게 처리를 할지 굉장히 고민인데


이런식으로 시야가 바뀌면 돌아가는데

카메라가 바라보는 방향대로 똑같이 맞춰 주면은


이런식으로

2D UI를 보는 느낌을 받을 것이다.

그래서 이것을 어떻게 할지 좀 햇갈리기는 하는데

가장 직관적인 방법으로 해결을 해보도록 하자.

1. BillBoard


transform.LookAt이라는 애가 있어는데

누구누구를 처다봐라 라는 애다.


그래서 Camera.main을 바라보는데 transform을 바라보라고 해주면 될 것이다.


지금 붙어서 메인 카메라를 봐라봐서 회전은 하지 않는데

HPBar가 거꾸로 붙어 져 버렸다.

왜그런지 살펴보자면은


유니티에서 지금 HPBar의 좌표를 보면 이렇게

x축 이 오른쪽으로 가있는데

우리는 여기서 이렇게 바라보니까 거꾸로 보이는 상황이 되는 것이다.

메인카메라에서 봤을때(혹은 월드 스페이스의 좌표는 왼쪽이 x축임)

그래서 우리가 반대로 보이게 되는데

이것을 카메라가 바라보는 방향대로 보이게 하는 것을 굉장히 간단하게 처리를 할 수가 있는데

이것이 무엇이냐 하면은

transform의 rotation을 카메라의 로테이션과 똑같이 맞추어 주면된다.


메인 카메라가 바라보고 있는 방향이(Camera.main.trasnform.rotation)

너가 바라보고 있는 방향이여야 한다.

이말이다.


이렇게 하면 이제 정상적으로 잘 처리가 되는 것을 볼 수 가 있다.

그래서 이것이

플레이어가 어떤 방향을 처다보든

HPBar가 그 방향으로 회전을 하는 것이 아니라 무조건 카메랑 똑같은

회전 값을 가지도록 셋팅을 해두었기 때문에

이런식으로 부드럽게 자연 스럽게 보이고 있는 중이다.

그리고 이것이 BillBoard의 개념이다.

항상 UI가 카메라를 처다보도록 강제로 하는 것이다.

어쨋든 이렇게해서 Hpbar까지 구현하는 것을 완성을 하였다.

그리고 일단 크기가 너무 크니까 크기도 수정을 조금 해주도록 하자.

2. 체력 게이지 구현

그다음에 이제 체력게이지 바가 늘어났다가 줄어드는 것을 연동을 해보도록하자.

그래서 Hp가 줄어드는 것을 구현을 하기위해서 일단

3D_UI 프리팹으로 가보면은



일단은 HPBar라는 오브젝트에 접근을 해가지고


여기 있는 Slider 컴포넌트를 추출 해낸 다음에

Value를 줄였다가 늘렸다가 하면 된다는 것을 알 수 있다.

그래서 일단 코드로 돌아가서 함수를 하나 만들어 주도록 하자.


이렇게 새로 하나 파주고

이함수 안에서 value의 값을 0~1사이의 값으로 설정을 해주도록 접근을 하면 될 것이다.

먼저 이 녀석으로 GetObject((int)GameObjects.HPBar

GameObjects를 뱉어 주고

GetComponent < Slider >().value = ratio;
이렇게 접근을 해서 value에다가 ratio를 넣어 주면 된다.


요렇게

그런데 지금 빨간 줄이 뜨는 것은

using UnityEngine.UI; 위에 추가 해주면 된다.

그래서 이제 SetHpRatio를 만들었으니까 Update를 할 때마다

이녀석이 들고있는 몬스터나 플레이어의 채력과 최대 채력을 뽑아 와가지고

그것의 비율을 SetHpRatio에 계속 넣어주면 될 것이다.


이런식으로 넣어주면 될 것인데

체력 정보는 _stat에서 관리를 하고 있었다.


그래서 위에서 한번만 불러와가지고

init을 할때

부모에 접근을 해서 Stat이라는 컴포넌트를 추출을 하도록 하자.


PlayerStat도 Stat을 상속을 받았으니까

_stat = transform.parent.GetComponent < Stat >();
이녀석을 이용해서 추출을 하면은

PlayerStat도 잘 뽑아 오게 될 것이다.

그래서 일단

이렇게만 만들어 주어도 되고

그래서 이제 결국 우리가 넣어주고 싶은 ratio


ratio는 이렇게 넣어주도록 하자.

뭐 물론 MaxHp가 0이라면 크래쉬가 나겠지만 그 문제는 그때가서 해결을 하면 될 것이다.

그래서 일단 이렇게 하면되는데

사실 여기 문제가 하나 더 있다.

지금 보면

_stat.Hp도 int형이고 _stat.MaxHp도 int형이다.

정수랑 정수를 나누면 무조건 정수로 뱉어 주는데

그렇다는 것은

예를 들어 _stat.Hp 가 50이고 _stat.MaxHp가 100이라면

수학적으로는 0.5인데 정수 나누기 정수라 ratio에는 .5라는 소수점을 버려서

0이라는 값이 들어가게 될 것이다.

그래서 이런식으로 하면 안되고 둘중 하나를 float로 캐스팅을 해주어야만


float랑 int랑 나누면 결과를 소수로 복원을 해주기 때문에

ratio값이 제대로 들어간다.

일단 이까지는 됬고


init을 어떻게 구현을 했는지 기억이 안나니까

UI_Base로 가서 어떻게 구현을 했는지 함 보자.


UI_Base에서는 init을 만들어주고 Start를 넣어주지는 않았다.

그러니까 사실은 매번 Start를 넣어주는게 귀찮으면

우리가 이전 시간에 해보았던것 처럼

이런식으로 init을 넣어주면은

밖에서는(UI_Base를 상속받는 애들은)

굳이 Start함수에 init을 넣어 놓지 않더라도


이녀석들이 자동으로 호출이 된다.(지난 시간에 했던거)

그런데 사실 이것이 조금 더 편한거 같기는 하다.

대신 UI_Base를 바꾸었으면

UI_Base상속받는 애들중에서

Strat함수에안에 init호출한것을 다 없애 주어야 한다.

(Start함수를 삭제함) -> init을 통해서만 만들어 줘야 한다.


이것도 삭제


UI_Base에 있는 Start를 통해서 init을 만들어 줄꺼니까

UI_HPBar도 Start가 없어도

init이 실행이 될 것이다.

그래서 실행이 되면


Stat _stat; 선언한것을 통해서

_stat = transform.parent.GetComponent< Stat >();가져 온다..

그래서 Update를 할때마다

체력과 최대 체력을 가져와서


ratio에 이렇게 저장을 하고 있을 것이다.

그래서 이까지 잘되는지 유니티로 가서 테스트를 해보도록 하자.


일단은 풀Hp인데 유니티짱의 체력을 강제로 줄여 보도록 하자.


지금Hp가 100이니까 50으로 변경을 하면은



이렇게 절반이 줄어 들었다.

그래서 이녀석이 정상적으로 작동이 되는 것은 확인을 하였다.

3. 몬스터 수정

그래서 이제 몬스터 한테도 우리가 만들어준 HPBar를 붙여 줘야 하는데

우리가 지금은 MonsterControler는 만든 상태가 아니니까

얘를 그냥 수동으로 만들어서 붙여 주도록 하자.


UI_HPBar를 드래그 드롭 해가지고

Knight에다가 붙여 주도록하자.


그래서 이렇게 들어 왔는데

이녀석을 프리팹으로 저장을 해주어도 되고

임시로 일단 놔두었다가 MonsterContoller가 들어오면 날리도록 하자.

플레이와 똑같이

Event 카메라를 메인 카메라로 설정해주자(드래그 드롭)


그리고 지금 우리가 UI_HPBar에다가 컴포넌트(코드)를 안 붙여 주었는데

그러니까 동적으로 생성하면(코드로)

우리가 아가 Make3D_UI에서

(이부분에서)


이녀석들을 자동으로 붙여 줬는데

지금은 그 케이스가 아니니까


이 스크립트 파일을 강제로 붙여 주도록 하자.

그러면 프리팹에 붙여 주었으니까

Knight의 컴포넌트에도

이렇게 HPBar에 잘 붙어서 Knight도 똑같이 잘 작동을 할 것이다.

그래서 테스트를 해보면

잘 된다.

(지금 3D_UI에서 HPBar는 없애고 Knight의 컴포넌트에다가 UI_HPBar를 붙여 주었다.)


현재 잘 작동 하고있다.

4. 공격시 Hp감소 구현

공격을 했을 때 Hp가 줄어들도록 하는 것을 구현 해보도록 하자.

PlayerController에서


OnHitEvent부분에서 구현을 해야 할거같다.

여기다가 뭔가 이제 때리는 것을 넣어 주면 될거같다.

여기서 이제 아무것도 안하고 Idle로 가거나 SKill로 가거나 했었다.

여기서 만약

_lockTarget이 있었다고 하면은


여기다가 이제 뭔가를 채워 주면 될거같다.

그런데

지금 PlayerController에서

때렸을 때 직접 상대방의 체력을 깍는 것이 맞는지는 의문이기는 하다.

강사님도 처음에 MMO_RPG같은 것을 만들때 체력을 깍는 부분이나 전투 하는 부분에서는 누가 관리를 하여야 할지 굉장히 고민이였다고 한다.

내가 상대방의 체력을 깍는 것이니까 내가 상대방의 체력을 빼와가지고

깍고 돌려보내는 것이 맞는지

아니면은

상대방한테 내가 공격한다는 데미지를 넣어주고

몬스터가 내부에서 체력을 깍는 것을 실행하는 것이 맞는지

아니면 아싸리

제 3자인 BattleManager같은 녀석한테 처리하도록 맡기는 것이 맞는지

여러가지 방법 중에서 고민을 했는데

결론부터 얘기를 하자면은 상대방한테 데미지를 넣어 줘서 상대방이 처리하도록 하는 부분이 훨씬 더 좋다.

왜냐하면은 나중에 일반적인 RPG게임을 생각을 하면은

무적이라는 상태도 있을 것이고

상대방이 들고있는 스탯이나 버프에 따라가지고

그 데미지 받는 것이 달라질 수 있기 때문에

굳이 내가 상대방의 것을 일일히 꺼내오기 보다는

상대방이 알아서 함수내에서 처리하도록 하는 것이 좋은거같다.

그것은 일단 나중에 MonsterController가 생기면 그때가서 넣어주도록 하고

여기서는 일단 상대방것을 꺼내와서 OnHitEvent에서 처리하는 방식으로 하도록 하자.


상대방의 GetComponent를 뽑아 올것인데


이렇게 targetStat에 _lockTarget의 Stat을 뽑아오고

나의 Stat은 무엇이냐?

Stat myStat = transform.GetComponent();이렇게 뽑아 올 것이고

참고로 현재 PlayerController니까

이렇게 PlayerStat 으로 가져와도 아무 상관없다.

왜냐하면 PlayerController는 Player한테 붙는 거니까

반드시 이 PlayerStat이 있다고 가정을 해도 무방할 것이다.


이렇게

그리고 데미지 같은 경우에는 어떻게 만들것인가??

int damage = myStat.Attack - targetStat.Defense;
일단 나의 공격력에서 target의 방어력 만큼 빼준 만큼으로 만들어 주도록 하자.

하지만 myStat.Attack - targetStat.Defense; 이녀석이 음수가 되면은 안된다.

음수가 되면은 오히려 때릴 때마다 체력이 올라가는 힐이되는 그런식이 될 테니까

이 녀석을 0보다는 크도록 만들어 주도록 하자.


이렇게 해주는데

혹시라도 myStat.Attack - targetStat.Defense가 음수로 떨어지더라도 0으로 설정이 된다.


그리고 target의 Hp는 이렇게 "데미지 만큼 줄여주세요"가 되는 것이다.

그르면 만약에 OnHitEvent에서 target의 Hp를 깍았는데

이것을 UI에 접근을 해서 Update를 해야 할까요???

-> 정답은 "꼭 그렇지는 않다!"이다.

정확히 말하면 그럴 필요가 없다.

=> 왜??

왜냐하면 우리 UI를 처리 하는 부분은

UI_HPBar라는 부분이

자기가.. 자기가 추가한 주인님을 찾아가지고

Update를 이런식으로 매 프레임마다 해주고 있다.

여기

SetHpRatio를 계속 돌리고 있으니까

우리가 외부에서 _stat.Hp를 건들여 주면은 다음틱에 그것을 인지를 해가지고


SetHpRaio함수에서 이런식으로 알아서 UI를 갱신을 해준다.

그리고 이것을 유니티로 돌아가서 테스트를 해보면은


이런식으로 ㅈㄴ 때릴때마다 5라는 데미지가 들어가면서 UI에서 Update를 하여 Hp를 깍아주고 있는 모오습이다!

그런데 지금 UI에서 때려서 체력이 깍이는 모습이 뭔가 한박자 씩 늦게 깍이는 모습인데

이것은

우리가 애니매이션 이벤트를 발생시키는 부분이 늦게 발생하도록 만들어서 그런거 같다.

그래서 이부분만 조금더 이쁘고 자연스럽게 동작하게 하기 위해서는


Knight2 -> Attack_1 로 가서

OnHitEvent를 발생시키는 부분을 조금 앞당겨서 해놓도록 하고

Apply를 해주도록 하자.

그냥 적절한 시간대를 잡아서 OnHitEvent를 불러오면 될거같다.


그러면 이제 이렇게 내려 칠때마다 체력이 깍이는 것을 볼 수 있다.

-끝-

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글