체력게이지#1

CJB_ny·2022년 1월 1일
0

Mini_MMO_RPG

목록 보기
8/16

이번시간에는 실제로 때리면 체력이 닳도록 구현을 해볼 것이다.

칠때마다 체력 게이지가 줄어드는 그런 작업을 해보도록 할 것이다.

이때까지는 그냥 2D UI들만 붙였었는데

처음으로 3D UI를 붙여서 작업을 해볼 것이다.

1.3D UI구현

지금까지 우리가 배운 것들로는 3D UI를 구현하기가 애매하다.

우리가 배운것은 2D UI인데 2D UI를 사용한다라는 것은

오브젝트 대가리위에 고정적인 크기의 UI를 입힌다는 말이 되는데

이게 조금 문제가 되는 것이 뭐냐하면은

어떤 오브젝트가 Player랑 멀리 있다, 만약 점점 멀어지면은

그 멀어지는 오브젝트는 점점 작게 보여지게 될 것이다.

이런식으로

그런데 대가리위에 있는 UI가 고정크기로 있게되면은 굉장히 어색하게 보여질 것이다.

경우에 따라서는 와우같은것은 엄청 멀리있는 오브젝트(몬스터)도 볼 수 있는데

캐릭터는 엄청 작은데 체력 UI가 존나게 크면은 병신처럼 보일 것이다.

1.UI의 종류

  • 고정적 크기의 UI(우리가 만든 아이템창 -> 게임세상과는 거의 별개이다)

  • 인게임에 배치할 체력게이지 오브젝트와 같이 원근 표시가 적용이 되가지고 멀리가면 작아지고 가까이 가면 커지는 작업을 할 필요가있는 UI

그래서 3D게임을 만들다보면 world space안에서 배치하게되는 UI도 은근히 많이 사용하게 된다.

2.구현할것 && 구현예시 (롤)

예를 들어 롤같은 경우 클릭을 했을 때 나타는 표시나

도움핑같은 경우

이런 도움핑의 경우 이런 깃발이 뜨는데

이런것들도 당연히 인게임에다가 해당 도움핑을 찍은 부분에다가 UI역할을 하는 오브젝트를 배치를 해가지고 보이게 하는 부분이다.

다양한 방법으로 응용이 가능하다.

그래서 오늘은 처음으로 월드 스페이스에 붙이는 그런 UI를 만들어 보도록 하자.

3.UI make

에셋을 다운받지는 않고 유니티에서 제공하는 UI로 일단 make해보자.

우클릭후 UI -> Slider로 만들어주면

이렇게 존나게 큰 UI바 하나가 생성이 되는데

world space에서는 이렇게

뜬다.

얘는 사실 2D UI니까 고정적인 크리고 이렇게 뜬다.

그래서 우리가 여기에서 해야 될것은 뭐냐

기존에 우리가 UI를 만들 때 보면은

canvas가보면은 이렇게 기본적으로

Render Mode가 Screen Space - Overlay를 사용을 하고 있었다.

이것은 한마디로 게임세상을 다 그린다음에 마지막으로

이런식으로 탁! 붙여 주겠다 그런 말이다.

그런데 우리가 할것은 이 3D세상에 이녀석을 실제로 배치를 시키는 것이다.

그래서 이 녀석의 옵션을 world space로 바꾸도록 하자.


이렇게!

그러면 이제 이녀석도 world space에 붙여주었기때문에 월드에서도 보일 수 있도록

카메라를 붙여 주어야한다.

우리의 이 Main Camera를 붙여주면 될 것이다.


이렇게

이것은 나중에 코드로 자동으로 매핑을 할 수 있도록 작업을 할 것이다.

그래서 지금 canvas의 크기가 어마어마하게 크기 때문에 크기를 조절을 해볼 것이다.

아까 위에위에 사진처럼 DemoScene이 좆만하게 보이는것 처럼 ㅈㄴ 크다.

그래서 이런 World UI를 만들때는 1/100의 크기로 줄이면 대충 맞는거 같더라~


그래서 크기를 이런식으로 0.01로 바꿔치기를 해주도록 하자.

이렇게 작아졌다..

그다음에 position이 굉장히 엉뚱한 위치로 가있는데 조절을 좀 하자.

이렇게 조절을 해줌


그래서 이런식으로 위치를 대충 옮겨주면은 그럴싸한 모습으로 바뀐다.

이제 이상태에서 작업을 해볼 것이다.

3. UI 작업

그래서 이제 여기서 잠깐 수정할 것이 뭐가 있을까 생각을 해보면은

이 UI의 색상을 빨간색으로 바꿔보도록 하자.

그래서 이 Slider를 이리저리 살펴보면은


이런식으로 되어있는데

뭐가 뭔지 잘 모르니까 하나씩 껏다 켜보면된다.

하나하씩 뭐 껏다 켜보았다.

background는 말그대로


UI의 background역할을 하는거같다.

Handle을 보면은

이런식으로 양옆으로 스크롤 하는 것인데

원래 Slider가 저 동그라미를 양옆으로 스크롤 하는 역할이라서 그런것이다.

그런데 우리는 그냥 체력게이지를 만드는 것이기 때문에 없애도 됨.


그래서 Fill의 색상을 대충 이정도로 바꿔주도록 하자.

그래서 Fill이 뭔가 채우는 역할을 할거같다라는 생각이 들고

FillArea도 채우는 범위를 지정하는거 같다라는 생각이 든다.

그래서 다시 Slider로 와가지고

이런식으로 Value를 늘렸다가 줄였다가 해보면은

이런식으로 FillArea가 늘어났다가 줄어들었다가 막 한다.

그런데 문제점이

Value가 0일때 빨간부분이 다 사라지지 않고 조금 남아있고

그리고 Value를 끝까지(1까지) 다채워도

이렇게 공백이 남아있으니까

이부분을 수정을 해보도록 하자.

이게 왜그런지 2D모드로 봐가지고 분석을 해보도록하자

신기하다(오른쪽 위에 2D버튼 누르면된다)


FillArea눌러보면은 이런식으로 핀이 잡혀 있는 것을 볼 수 있는데

anchor가 어떻게 잡혀있는지를 유심히 살펴보도록 하자.


Fill부분의 anchor가 전체 범위를 커버를 해야지만 다 채워 질거같다라는 생각이 드네용~


FillArea에 오른쪽에 Rect Transform 이라고 수치들이 있는데

Left, Right의 수치를 0, 0으로 하게되면 꽉 찬다.

그리고 마찬가지로 Fill도 가보면은


이런게 뭔가 삐져나온 부분이 있는데

그래서 Fill

Rect Transform을 이런식으로 조절을 해주면은

Slider의 Value = 0 일때

Slider Value = 1 일때

이런식으로 꽉꽉 채워진다!

그러면 이제 이것을 우리의 HP바로 사용을 하면 될것이다.

그래서 canvas이름을 바꿔주고

이제 실제로 우리가 필요한 것은


이 Slider만 매핑을 해서 사용을 하면 된다.

그래서 Slider만 매핑을 해서 Value라는 애만 건드리면 되니까

그래서 Slider -> rename -> HPBar

변경해주도록 하고 나머지는 UI의 색상과 관련이 있으니까 그대로 놔두도록 하자.

4. 3D UI 프리팹 && 코드 매핑

그래서 이제 이것을 다 만들었으면

우리가 늘 하던대로 prefab으로 만들어야 하는데

그래서 우리가 만든 Prefab폴더로 가보면은

이렇게 있는데

지금 Hp Ui는 카메라도 아니고

이거 3개중에 해당하는 것이 없다.

그래서 이런 3D UI를 관리를 해줄 수 있는 폴더를 하나 새로 파주도록 하자.

이름은 그냥

내가 원하는 이름의 폴더로 만들고

UI_HPBar를 안에 넣어 주도록 하자.

그리고 마찬가지로 UI를 만들자 마자

매핑되는 코드도 만들어 주어야 한다.

이녀석도 마찬가지로 3D_UI로 폴더를 파주고

그리고 만든 폴더 안에 스크립트파일을 UI 프리팹과 이름이 같게

똑같이 만들어 주자.


일단 UI_HPBar는 씬이랑 팝업은 아니니까

UI_Base를 상속받도록 해주자.

빨간 줄이 뜨는데 추상 클래스를 구현을 해주도록 하자.

저안을 나중에 구현을 해주면 될거같고

UI_HPBar안에 매핑을 해주도록하자.


enum을 줘가지고 HPBar라는 애들 만들어 줬었다.

enum안에있는 HPBar는 게임안에 Slider를 뽑아와야 한다.

뭐 어쨋든 GameObject로 접근을 하면 되는 부분이다.


바인드를 해주는데 타입은<> GameObject이고 typeof(GameObjects)를 넣어주자.

그다음에 해줄것을 곰곰히 생각을 해보면은...

일단 UIManager로 가가지고

우리가

이런식으로 하나씩 하나씩 막 만들어 줬었는데

새로운 식구가 왔으니까 여기에다가 코드를 추가를 해주도록 하자.

나중에 코드로 동적으로 붙이고싶을 상황이 생길 수도 있으니까

이녀석을 똑같이 복사를 해준다음에

똑같이 일단 만들어 주고

나는 이렇게 Make3D_UI로 하였다.


그래서

if(string.IsNullOrEmpty(name))
name = typeof(T).Name;

GameObject go = Managers.Resource.Instantiate 까지는 똑같은데

UI/3D_UI/{name} 이런식으로 맞추어 주었다.

그래서 이까지는 똑같고 이담에 해야하는 것은


Prefab에 UI_HPBar를 보면은 오른쪽에 Canvas를 보면 World Space로 해야하고

Event Camera를 Main Camera로 붙여줬어야 했다.

그래서 이 작업(매핑을) 해보도록 하겠다.(코드로)


그래서 이렇게 GetComponent를 해주자(GetOrAddComponent를 하더라도 크게 상관은 없다)

그리고 renderMode, MainCamera 둘다

이렇게 설정을 해주면된다.


그리고 GetOrAddComponent로 뱉어주면 똑같이 작동할 것이다.

그래서

이 Make3D_UI를 사용하는 것은

뭔가 프리팹에는 안 붙어 있는데

동적으로 WorldSpace에 3D UI를 붙여 주고 싶을 때를 대비해서 만들어 준 것이다.

자 그럼 그렇다는 것은 PlayerController에 가서 사용이 가능한지 테스트를 해보자.


Start에서 Managers에 접근을 해서 UI -> Make3D_UI에 <UI_HPBar> 를 만들어 주는데

그다음에 그냥 만들어 주는 것이 아니라

"나한테 붙여줘!!"라고

이렇게 trasnform을 건내주면은

나한테 붙어서 HPBar가 만들어 질거라는 생각이 드네요~

일단 여기까지만하고 뭐 처리한것은 없지만 어떻게 뜰지 확인하러 유니티에서 테스트를 해보도록 하자.


그럼일단 이렇게 뜨는데...ㅋㅋ

Player가 회전하며 움직일때 마다 같이 회전을 한다.

그럼 이 UI가 왜 회전을 하는지 궁금하죠?

사실은 어찌보면 굉장히 당연한 일 이기도 하다!!


게임을 실행하면 이렇게 UnityChan 산하에 HPBar가 생성이 되는데

유니티짱 산하에 들어가있다는 말은

유니티짱이 회전을 할때마다 Child니까 같이 회전이 되는 식이다.

그래서 이것을 어떤 식으로든 머리위에 고정 시키는 방법이 필요하다.

5. 구현해야 할것

1.결국에는 HPBar의 위치도 고정을 시켜야 하고,
2.Rotation도 고정을 시켜야 한다는 말인데

일단은 하나씩 해보도록 하자.

먼저 Player의 머리 위에 고정시키는 작업부터 해보자.

그럼 이 작업은 어디서 하냐?

UI_HPBar로 가주자

여기서 작업을 해주도록 하자.

여기서 뭔가를 추가를 해주면 될 것이다.

Update를 하면서 Update를 할 때마다

내 부모님의 위치 에다가 (머리 쯤에다가)

위치를 하게끄름 강제로 셋팅을 해주면 되는데

일단 내 부모님의 위치를 뽑아 와야 할 것이다.


trasnform.parent;를 이용을 하면은 나의 부모님을 빼올 수 있다.

참고로 transform.parent로 뽑아오는 것이 어색하다면

앞에 gameObject를 붙여 주어도 크게 상관은 없다.



HPBar를 들고 있는 gameObject에 가서

그 아이의 transform을 뽑아 온다음에 parent를 뽑아 오겠다!

이런식으로 접근을 해도된다.

그래서 나의 위치는 어디냐 하면은

나의 위치 transform.position은 parent의 position의 조금 위에 위치를 하면 될 것이다.


나는 어떻게 했냐하면은

구글링으로

코드를 이렇게 짜니까

이렇게 고정이 되기는 하였다.

강의에서는 어떻게 하는지 보도록 하자.


이럴때 문제? 걱정스러운 부분이 무었이냐고하면은


오브젝트들 마다 y축 방향 높이 height 높이가 다 달라가지고

머리라는 위치가 조금씩 다 다를텐데

이것을 어떻게 처리를 할지 조금 고민이 되기는 한다.

이것을 조금 쉽게 처리를 하기 위해서

Collider의 크기만큼 올려주도록 하자.


Capsule Collider의 크기가 저런데

저 크기를 구해서 조금 위에다가 위치를 시켜주면 될거같다라는 생각이 든다.

일단은 "위"라는 "방향"은


Vector3.up으로 가져오면 되고

여기다가 뭔가 이제 크기를 입력을 해주어야 한다.


그래서 parent에 접근을 해서 GetComponent로 Collider를 빼오도록하자.

(없으면 크래쉬가 나겠지만 있다고 가정을 하고 진행을 하자.)


그래서 이렇게 Collider().bounds.size를 찍어보면

이녀석은 Vector3인데 점을(.)을 찍어보면은

x, y 가 있다.


높이는 y일거같으니까


이따구로 해주자

그래서 이렇게 맞춰 주면은

transform.position
나의 위치는

parent.position 나의 부모님 위치를 기준으로


Collider만큼 위로 올려가지고

transform.position(나를) 위치 시켜줘 라는 의미가 되니까

그래서 이제 position이 제대로 위치시켜지는지 확인을 해보자


위치는 아주 아주 잘 맞는데

회전할때 Player에 따라 회전하는 것이 문제가 된다.

다음 시간에 해결을 하자!

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

0개의 댓글