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);
}
}