Unity - HPBarUI 구현하기

김도현·2023년 12월 14일
0

TIL

목록 보기
75/76

Enemy의 hp 구현하기

Enemy에서는 플레이어가 일정거리 가까이 왔을 때 UI Manager에 자신의 정보를 전달하여 Enemy에게서 UI가 들어갈 위치(Enemy의 위치), 최대 HP, 변화된 HP등을 전달받아서 HPBarUI로서 기능을 수행한다.

구현 코드

HPBarMain.cs

using System;
using UnityEngine;
using UnityEngine.Pool;

public class HPBarMain : MonoBehaviour
{
    [SerializeField] private int poolMaxCount = 30;
    [Range(0f, 30f)][SerializeField] private float extraHeight;
    private UI_Manager uiManager;
    private GameObject hpBarUIPrefab;
    private BossHPBar bossHPBar;
    private IObjectPool<EnemyHPBar> objectPool_EnemyHPBar;

    private void Awake()
    {
        uiManager = UI_Manager.Instance;
        objectPool_EnemyHPBar = new ObjectPool<EnemyHPBar>(CreateEnemyHPBar, OnGetEnemyHPBar, OnReleaseEnemyHPBar, OnDestroyEnemyHPBar, maxSize: poolMaxCount);
        hpBarUIPrefab = Resources.Load<GameObject>("Prefabs/UI/EnemyHPBar/UI_EnemyHPBar");
    }

    private void Start()
    {
        uiManager.enemyHPBarUITurnOnEvent += SetEnemyHpBarByType;
        bossHPBar = uiManager.BossHPBarUI.GetComponent<BossHPBar>();
    }

    private void SetEnemyHpBarByType(Enemy enemy)
    {
        if (enemy.Data.ID > 100)
        {
            EnemyHPBar hpBar = objectPool_EnemyHPBar.Get();
            hpBar.SetEnemyHPBar(enemy, extraHeight);
        }
        else
        {
            bossHPBar.SetEnemyHPBar(enemy);
        }
    }

    //Objectpool
    private EnemyHPBar CreateEnemyHPBar()
    {
        EnemyHPBar hPBar = Instantiate(hpBarUIPrefab, transform).GetComponent<EnemyHPBar>();
        hPBar.SetManagedPool(objectPool_EnemyHPBar);
        return hPBar;
    }

    private void OnGetEnemyHPBar(EnemyHPBar hPBar)
    {
        hPBar.gameObject.SetActive(true);
    }
    private void OnReleaseEnemyHPBar(EnemyHPBar hPBar)
    {
        hPBar.gameObject.SetActive(false);
    }

    private void OnDestroyEnemyHPBar(EnemyHPBar hPBar)
    {
        Destroy(hPBar.gameObject);
    }
    //---------
}

BossHPBar.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BossHPBar : MonoBehaviour
{
    private Enemy enemy;
    [SerializeField] private UIBarScript uiBarScript;

    public void SetEnemyHPBar(Enemy newEnemy)
    {
        enemy = newEnemy;
        uiBarScript.UpdateValue(newEnemy.StateMachine.HP, newEnemy.Data.MaxHP);
        Activate();
        enemy.StateMachine.HpUpdated += uiBarScript.UpdateValue;
        enemy.StateMachine.ReleaseMonsterUI += OnRelease;
    }

    private void OnRelease()
    {
        enemy.StateMachine.HpUpdated -= uiBarScript.UpdateValue;
        enemy.StateMachine.ReleaseMonsterUI -= OnRelease;
        enemy = null;
        Deactivate();
    }

    private void Activate()
    {
        gameObject.SetActive(true);
    }

    private void Deactivate()
    {
        gameObject.SetActive(false);
    }
}

EnemyHPBar.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;

public class EnemyHPBar : MonoBehaviour
{
    private Enemy enemy;
    private Camera mainCamera;
    private UIBarScript uiBarScript;
    private Transform uiBarScriptTransform;
    private Transform mainCameraTransform;
    private Vector3 thisPos;
    private IObjectPool<EnemyHPBar> managedPool;

    public bool Test;
    private void Awake()
    {
        uiBarScript = GetComponentInChildren<UIBarScript>();
        uiBarScriptTransform = uiBarScript.transform;
        mainCamera = Camera.main;
        mainCameraTransform = mainCamera.transform;
        thisPos = Vector3.zero;
    }

    public void SetManagedPool(IObjectPool<EnemyHPBar> pool)
    {
        managedPool = pool;
    }

    public void SetEnemyHPBar(Enemy newEnemy, float extraHeight)
    {
        enemy = newEnemy;
        transform.parent = newEnemy.transform;
        uiBarScript.UpdateValue(newEnemy.StateMachine.HP, newEnemy.Data.MaxHP);
        
        newEnemy.StateMachine.HpUpdated += uiBarScript.UpdateValue;
        newEnemy.StateMachine.ReleaseMonsterUI += OnRelease;
        SetUIPosition(newEnemy.transform, newEnemy.Agent.height, extraHeight);
        StartCoroutine(SetUIRotion());
    }

    private void SetUIPosition(Transform enemyTransform, float enemyHeight, float extraHeight)
    {
        thisPos.Set(0, enemyHeight + extraHeight, 0);
        transform.localPosition = thisPos;
    }

    private IEnumerator SetUIRotion()
    {
        while (true)
        {
            uiBarScript.transform.rotation = Quaternion.LookRotation(uiBarScript.transform.position - mainCamera.transform.position);
            yield return null;
        }
    }

    private void OnRelease()
    {
        enemy.StateMachine.HpUpdated -= uiBarScript.UpdateValue;
        enemy.StateMachine.ReleaseMonsterUI -= OnRelease;
        enemy = null;
        thisPos = Vector3.zero;
        StopCoroutine(SetUIRotion());
        managedPool.Release(this);
    }
}

0개의 댓글