167 lines
5.9 KiB
C#
167 lines
5.9 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Streamingle.Contents.BossRaid
|
|
{
|
|
/// <summary>
|
|
/// 유저 HP바. 머리 위 월드스페이스 캔버스로 표시됩니다.
|
|
/// </summary>
|
|
public class PlayerHPBar : MonoBehaviour
|
|
{
|
|
#region Fields
|
|
|
|
[Header("설정")]
|
|
[SerializeField] private Vector3 offset = new Vector3(0f, 0.3f, 0f);
|
|
[SerializeField] private float barWidth = 1.2f;
|
|
[SerializeField] private float barHeight = 0.12f;
|
|
[SerializeField] private float smoothSpeed = 8f;
|
|
|
|
[Header("색상")]
|
|
[SerializeField] private Color hpColor = new Color(0.2f, 0.85f, 0.3f);
|
|
[SerializeField] private Color hpColorLow = new Color(0.95f, 0.2f, 0.15f);
|
|
[SerializeField] private Color bgColor = new Color(0.1f, 0.1f, 0.1f, 0.85f);
|
|
[SerializeField] private Color frameColor = new Color(0.3f, 0.3f, 0.35f);
|
|
|
|
private Canvas _canvas;
|
|
private Image _hpFill;
|
|
private RectTransform _fillRect;
|
|
private Transform _followTarget;
|
|
private float _targetRatio = 1f;
|
|
private float _displayRatio = 1f;
|
|
private bool _isVisible;
|
|
private Font _font;
|
|
private Text _nameText;
|
|
|
|
#endregion
|
|
|
|
#region Unity Messages
|
|
|
|
private void LateUpdate()
|
|
{
|
|
if (!_isVisible || _followTarget == null) return;
|
|
|
|
// 머리 위 따라다님
|
|
transform.position = _followTarget.position + offset;
|
|
|
|
// 카메라를 향하도록
|
|
if (Camera.main != null)
|
|
_canvas.transform.rotation = Camera.main.transform.rotation;
|
|
|
|
// 부드러운 HP 감소
|
|
_displayRatio = Mathf.Lerp(_displayRatio, _targetRatio, Time.deltaTime * smoothSpeed);
|
|
_fillRect.anchorMax = new Vector2(Mathf.Clamp01(_displayRatio), 1f);
|
|
_hpFill.color = _displayRatio > 0.3f ? hpColor : hpColorLow;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public Methods
|
|
|
|
public void Initialize(Transform headTarget, string playerName = "", Vector3? customOffset = null)
|
|
{
|
|
_font = BossRaidFontLoader.Load();
|
|
_followTarget = headTarget;
|
|
if (customOffset.HasValue)
|
|
offset = customOffset.Value;
|
|
CreateUI();
|
|
_isVisible = true;
|
|
|
|
if (_nameText != null && !string.IsNullOrEmpty(playerName))
|
|
_nameText.text = playerName;
|
|
}
|
|
|
|
public void SetHP(float ratio)
|
|
{
|
|
_targetRatio = Mathf.Clamp01(ratio);
|
|
}
|
|
|
|
public void Show()
|
|
{
|
|
_isVisible = true;
|
|
if (_canvas != null) _canvas.gameObject.SetActive(true);
|
|
}
|
|
|
|
public void Hide()
|
|
{
|
|
_isVisible = false;
|
|
if (_canvas != null) _canvas.gameObject.SetActive(false);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private Methods
|
|
|
|
private void CreateUI()
|
|
{
|
|
var canvasObj = new GameObject("PlayerHPBar_Canvas");
|
|
canvasObj.transform.SetParent(transform);
|
|
canvasObj.transform.localPosition = Vector3.zero;
|
|
_canvas = canvasObj.AddComponent<Canvas>();
|
|
_canvas.renderMode = RenderMode.WorldSpace;
|
|
_canvas.sortingOrder = 90;
|
|
|
|
var rt = canvasObj.GetComponent<RectTransform>();
|
|
rt.sizeDelta = new Vector2(barWidth, barHeight + 0.15f);
|
|
rt.localScale = Vector3.one;
|
|
|
|
// 프레임
|
|
var frameObj = new GameObject("Frame");
|
|
frameObj.transform.SetParent(canvasObj.transform, false);
|
|
var frameRect = frameObj.AddComponent<RectTransform>();
|
|
frameRect.anchorMin = new Vector2(0f, 0f);
|
|
frameRect.anchorMax = new Vector2(1f, 0.7f);
|
|
frameRect.offsetMin = Vector2.zero;
|
|
frameRect.offsetMax = Vector2.zero;
|
|
var frameImg = frameObj.AddComponent<Image>();
|
|
frameImg.color = frameColor;
|
|
frameImg.raycastTarget = false;
|
|
|
|
// 배경
|
|
var bgObj = new GameObject("BG");
|
|
bgObj.transform.SetParent(frameObj.transform, false);
|
|
var bgRect = bgObj.AddComponent<RectTransform>();
|
|
bgRect.anchorMin = Vector2.zero;
|
|
bgRect.anchorMax = Vector2.one;
|
|
bgRect.offsetMin = new Vector2(0.01f, 0.01f);
|
|
bgRect.offsetMax = new Vector2(-0.01f, -0.01f);
|
|
var bgImg = bgObj.AddComponent<Image>();
|
|
bgImg.color = bgColor;
|
|
bgImg.raycastTarget = false;
|
|
|
|
// HP Fill
|
|
var fillObj = new GameObject("Fill");
|
|
fillObj.transform.SetParent(bgObj.transform, false);
|
|
_fillRect = fillObj.AddComponent<RectTransform>();
|
|
_fillRect.anchorMin = Vector2.zero;
|
|
_fillRect.anchorMax = Vector2.one;
|
|
_fillRect.offsetMin = Vector2.zero;
|
|
_fillRect.offsetMax = Vector2.zero;
|
|
_hpFill = fillObj.AddComponent<Image>();
|
|
_hpFill.color = hpColor;
|
|
_hpFill.raycastTarget = false;
|
|
|
|
// 이름 텍스트 (바 위)
|
|
var nameObj = new GameObject("Name");
|
|
nameObj.transform.SetParent(canvasObj.transform, false);
|
|
var nameRect = nameObj.AddComponent<RectTransform>();
|
|
nameRect.anchorMin = new Vector2(0f, 0.7f);
|
|
nameRect.anchorMax = Vector2.one;
|
|
nameRect.offsetMin = Vector2.zero;
|
|
nameRect.offsetMax = Vector2.zero;
|
|
_nameText = nameObj.AddComponent<Text>();
|
|
_nameText.text = "";
|
|
_nameText.fontSize = 3;
|
|
_nameText.color = Color.white;
|
|
_nameText.alignment = TextAnchor.MiddleCenter;
|
|
_nameText.raycastTarget = false;
|
|
if (_font != null) _nameText.font = _font;
|
|
|
|
var outline = nameObj.AddComponent<Outline>();
|
|
outline.effectColor = Color.black;
|
|
outline.effectDistance = new Vector2(0.3f, -0.3f);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|