Chapter 13-7. 미니 RPG : 체력 게이지
카테고리: Unity Lesson 2
태그: Unity Game Engine
인프런에 있는 Rookiss님의 [C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진 강의를 듣고 정리한 필기입니다. 😀
🌜 강의 들으러 가기 Click
Chapter 13. 미니 RPG 만들기
🚀 체력 게이지 UI 만들기도
체력 게이지는 몬스터와 플레이어 위에 따라다녀야함. 그러니 원근법 적용이 되야 한다. 3D 오브젝트처럼! 👉 캔버스 렌더러 모드를 World Space로 바꿔준다.
UI_HPBar
캔버스- 👉 RenderMode는 WorldSpace. 이땐 이 캔버스를 찍을 카메라도 할당해주어야 하는데, RenderMode, Camera 둘 다 코드로 로드해줄 것이다.
HPBar
슬라이더
이제 캔버스는 게임 월드 기준 좌표를 가지므로 캔버스와 슬라이더의 위치와 크기를 잘 맞춰주고 최종적으로 UI_HPBar
캔버스를 프리팹으로 만들어준다. 게임이 시작되면 몬스터와 플레이어의 산하 자식으로 Instantiate 시켜주어 몬스터와 플레이어를 따라다니게 할 것이다.
🚀 공격시 체력 깎기
✈ 로드하기
📜UI_HPBar
public class UI_HPBar : UI_Base
{
enum GameObjects
{
HPBar
}
Stat _stat;
public override void Init()
{
Bind<GameObject>(typeof(GameObjects));
_stat = transform.parent.GetComponent<Stat>();
}
void Start()
{
Init();
}
- 이 스크립트는 📜UIManger의 MakeWorldSpace 함수를 통해
UP_HPBar
캔버스에 붙을 예정 - Bind를 통해
UP_HPBar
의 자식인HPBar
오브젝트(슬라이더)가 캐싱 된다. - 플레이어의 스탯을 슬라이더에 적용시킬 수 있도록 📜Stat 로딩
📜UIManager
public T MakeWorldSpace<T>(Transform parent = null, string name = null) where T : UI_Base
{
if (string.IsNullOrEmpty(name))
name = typeof(T).Name;
GameObject go = Managers.Resource.Instantiate($"UI/WorldSpace/{name}");
if (parent != null)
go.transform.SetParent(parent);
Canvas canvas = go.GetComponent<Canvas>();
canvas.renderMode = RenderMode.WorldSpace;
canvas.worldCamera = Camera.main;
return Util.GetOrAddComponent<T>(go);
}
- MakeWorldSpace
- 📂UI/WorldSpace 에 있는 캔버스 프리팹을 로드하여
parent
산하에 붙여주는 함수 - WorldSpace 모드의 캔버스만 붙일 것이다.
- 캔버스 설정
- 로드한 캔버스 프리팹의 렌더러 모드는 WorldSpace로, 카메라는 메인 카메라로 설정
go
에게T
를 붙인다.- 즉, 캔버스 프리팹에 원하는 스크립트를 붙일 것.
- 📂UI/WorldSpace 에 있는 캔버스 프리팹을 로드하여
📜PlayerController
void Start()
{
//...
Managers.UI.MakeWorldSpace<UI_HPBar>(transform);
}
transform
(플레이어 본인)의 자식으로 UI_HPBar
프리팹을 로드한다. 그리고 📜UI_HPBar 를 붙여준다.
게임이 시작되면 자동으로 이렇게 unityChan
에 스크립트가 붙고 저렇게 캔버스 설정도 완료될 것이다.
✈ 체력 게이지에 깎인 체력 반영한다 (+ 빌보드)
📜UI_HPBar
void Update()
{
Transform parent = transform.parent;
transform.position = parent.position + Vector3.up * (parent.GetComponent<Collider>().bounds.size.y);
transform.rotation = Camera.main.transform.rotation; // 빌보드
float ratio = _stat.Hp / (float)_stat.MaxHp;
SetHpRatio(ratio); // 슬라이더 값 매 프레임마다 갱신
}
public void SetHpRatio(float ratio)
{
GetObject((int)GameObjects.HPBar).GetComponent<Slider>().value = ratio;
}
parent
는 이 📜UI_HPBar가 붙는UI_HPBar
의 부모인 플레이어가 된다.transform
은UI_HPBar
UI_HPBar
의 위치는 부모인 플레이어의 머리 위에 있도록 플레이어의 Collider 경계의 상단에 위시치키도록 한다.UI_HPBar
는 회전하면 안된다.UI_HPBar
도 WorldSpace로서 3D 오브젝트 취급을 받는 캔버스이므로 플레이어의 머리 위에 있다보면 플레이어 따라 같이 회전할 수 있다. 따라서 카메라의 회전값과 동일하게 해주어 오로지 카메라만 고정적으로 바라보도록 계속해서 회전시켜야 한다. 즉, 부모인 플레이어의 회전값을 따라가는게 아니라, 카메라를 고정적으로 바라보도록 계속 회전시킴. 👉 이게 빌보드의 개념이다.빌보드
란 카메라가 어느 방향을 보고 있던간에 정면이 늘 카메라를 향하도록 하는 기능이다.transform.rotation = Camera.main.transform.rotation;
📜PlayerController
void OnHitEvent()
{
if (_lockTarget != null)
{
Stat targetStat = _lockTarget.GetComponent<Stat>();
PlayerStat myStat = gameObject.GetComponent<PlayerStat>();
int damage = Mathf.Max(0, myStat.Attack - targetStat.Defense); // 음수되면 0 이 되게끔
targetStat.Hp -= damage;
}
if (_stopSkill)
{
State = PlayerState.Idle;
}
else
{
State = PlayerState.Skill;
}
}
공격 애니메이션 때리는 타이밍에 OnHitEvent 이벤트가 발생하게 한다. 이 때 공격할 대상인 _lockTarget
오브젝트에서 📜Stat 을 가져와 상대방의 체력을 공격력만큼 깎는다.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기