지금까지 작업했던 UI를 Main씬을 저장하고 01.Scenes/Play 씬을 더블클릭해 연다.
Canvas를 하나 만들고 다음과 같이 설정한다.
Canvas를 선택하고 + 버튼을 클릭한 후 UI>Panel을 추가하다. "Panel-Hpbar"로 이름을 바꾼다. Panel의 이미지를 04.Image>Menu폴더의 Button-Tab으로 선택한다.
Panel아래 TextMeshPro를 추가하고 HP로 내용을 바꾼다.
Panel아래 Image를 추가하고 이름을 Image-Hpbar로 수정후 Source Image에 04.Images/Menu폴더에 있는 HpBar를 연결한다.Sprite로 변경후 연결해야한다.
Fill Amount의 슬라이드 바를 조정하면 좌우로 채워지는 걸 확인할 수 있다. TAG를 HP_BAR를 만들어 지정해준다.
PlayerCtrl 스크립트를 다음과 같이 수정한다.
UI에 접근하기 위해 using UnityEngine.UI;를 선언한다.
HP_BAR TAG를 이용해 오브젝트를 hpBar와 연결해준다. ?는 null이 아니면 뒤쪽 GetComponent()을 실행한다는 뜻이다.
hpBar= GameObject.FindGameObjectWithTag("HP_BAR")?.GetComponent<Image>();
트리거가 발생하면 HP를 10빼주고 HP바를 갱신할 DisplayHealth()를 실행한다.
void OnTriggerEnter(Collider coll) {
if(curHP >= 0.0f && coll.CompareTag("PUNCH")) {
curHP -= 10.0f;
DisplayHealth();
//Debug.Log($"Player hp = { curHP / initHP }");
if (curHP <= 0.0f) {
PlayerDie();
}
}
}
fillAmount의 값을 조정해 바의 상태를 갱신한다. 0~1f의값을 갖는다
void DisplayHealth() {
hpBar.fillAmount = curHP / initHP;
}
PlayerCtrl 전체코드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerCtrl : MonoBehaviour {
// Start is called before the first frame update
Transform tr;
private Animation anim;
private float moveSpeed = 10f; //이동속도
private float turnSpeed = 80f; //회전속도
private readonly float initHP = 100.0f; //초기 생명값
public float curHP; //현재생명값
public Image hpBar;
public delegate void PlayerDieHandler(); //델리게이트타입 선언
public static event PlayerDieHandler OnPlayerDie; //델리게이트 변수선언
public
IEnumerator Start() { //start()함수는 코루틴으로 실행할 수 있다.
//Hpbar연결
hpBar= GameObject.FindGameObjectWithTag("HP_BAR")?.GetComponent<Image>();
curHP = initHP;
DisplayHealth();
tr = GetComponent<Transform>();
anim = GetComponent<Animation>(); //추가된 코드
anim.Play("Idle");
turnSpeed = 0.0f; //프로그램 기동시 가비지 마우스값을 막기위해
yield return new WaitForSeconds(0.3f); //0.3초 기다린후
turnSpeed = 300f; //변수값을 설정
}
// Update is called once per frame
void Update() {
float h = Input.GetAxis("Horizontal"); //AD 입력 좌우
float v = Input.GetAxis("Vertical"); //WS 입력 전후
if (Mathf.Abs(h) > float.Epsilon || Mathf.Abs(v) > float.Epsilon) { //움직임이 없다면 불필요한 동작을 안한다.
Vector3 dir = Vector3.right * h + Vector3.forward * v;
tr.Translate(dir.normalized * moveSpeed * Time.deltaTime);
PlayerAnim(h, v);
}
float r = Input.GetAxis("Mouse X"); //마우스 x축 입력
tr.Rotate(Vector3.up * turnSpeed * Time.deltaTime * r);
}
void PlayerAnim(float h, float v) {
if (v >= 0.1f) { //앞으로 달림
anim.CrossFade("RunF",0.25f);
} else if(v <= -0.1f) { //뒤로 움직임
anim.CrossFade("RunB", 0.25f);
} else if(h >= 0.1f) { //오른쪽으로 움직임
anim.CrossFade("RunR", 0.25f);
} else if (h <= -0.1f) { //왼쪽으로 움직임
anim.CrossFade("RunL", 0.25f);
} else { //제자리대기
anim.CrossFade("Idle", 0.25f);
}
}
void OnTriggerEnter(Collider coll) {
if(curHP >= 0.0f && coll.CompareTag("PUNCH")) {
curHP -= 10.0f;
DisplayHealth();
//Debug.Log($"Player hp = { curHP / initHP }");
if (curHP <= 0.0f) {
PlayerDie();
}
}
}
void PlayerDie() {
//MONSTER 태그를 가진 모든 게임오브젝트를 찾아옴
/*
GameObject[] monsters = GameObject.FindGameObjectsWithTag("MONSTER");
foreach(GameObject monster in monsters) { //모든 오브젝트를 순차적으로 불러옴
monster.SendMessage("OnPlayerDie", SendMessageOptions.DontRequireReceiver);
}
*/
OnPlayerDie(); //주인공 사망 이벤트 호출(발생)
}
void DisplayHealth() {
hpBar.fillAmount = curHP / initHP;
}
}
'유니티게임강좌 > 유니티UI시스템' 카테고리의 다른 글
[UI시스템] TextMesh Pro (0) | 2023.03.16 |
---|---|
[UI시스템] Rect Transform 컴포넌트 (0) | 2023.03.10 |
[UI시스템] Canvas 객체 (0) | 2023.03.10 |
[UI시스템] 유니티 UI 구현 형태 (0) | 2023.03.10 |