지금까지 작업했던 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;
    }
}

+ Recent posts