Загрузка данных
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class FloatingBuildingUI : MonoBehaviour
{
[Header("Offset")]
public Vector3 worldOffset = new Vector3(0f, 3f, 0f);
[Header("Size")]
public Vector2 canvasSize = new Vector2(120f, 24f);
private BuildingInstance _building;
private Canvas _canvas;
private Image _fill;
private TextMeshProUGUI _label;
private Camera _cam;
void Start()
{
_building = GetComponent<BuildingInstance>();
if (_building == null)
{
Destroy(this);
return;
}
CreateUI();
_building.OnHealthChanged += Refresh;
_building.OnDied += HandleDeath;
Refresh(_building.CurrentHealth, _building.MaxHealth);
}
void CreateUI()
{
GameObject canvasGO = new GameObject("BuildingUI");
canvasGO.transform.SetParent(transform);
canvasGO.transform.localPosition = worldOffset;
canvasGO.transform.localRotation = Quaternion.identity;
_canvas = canvasGO.AddComponent<Canvas>();
_canvas.renderMode = RenderMode.WorldSpace;
_canvas.worldCamera = Camera.main;
CanvasScaler scaler = canvasGO.AddComponent<CanvasScaler>();
scaler.dynamicPixelsPerUnit = 20;
RectTransform canvasRT = canvasGO.GetComponent<RectTransform>();
canvasRT.sizeDelta = canvasSize;
canvasGO.transform.localScale = Vector3.one * 0.01f;
//---------------------------------------------------
// BG
//---------------------------------------------------
GameObject bgGO = new GameObject("BG");
bgGO.transform.SetParent(canvasGO.transform, false);
Image bg = bgGO.AddComponent<Image>();
bg.color = new Color(0, 0, 0, 0.75f);
RectTransform bgRT = bg.GetComponent<RectTransform>();
bgRT.anchorMin = Vector2.zero;
bgRT.anchorMax = Vector2.one;
bgRT.offsetMin = Vector2.zero;
bgRT.offsetMax = Vector2.zero;
//---------------------------------------------------
// Fill
//---------------------------------------------------
GameObject fillGO = new GameObject("Fill");
fillGO.transform.SetParent(bgGO.transform, false);
_fill = fillGO.AddComponent<Image>();
_fill.color = Color.green;
_fill.type = Image.Type.Filled;
_fill.fillMethod = Image.FillMethod.Horizontal;
_fill.fillOrigin = 0;
RectTransform fillRT = _fill.GetComponent<RectTransform>();
fillRT.anchorMin = Vector2.zero;
fillRT.anchorMax = Vector2.one;
fillRT.offsetMin = new Vector2(2, 2);
fillRT.offsetMax = new Vector2(-2, -2);
//---------------------------------------------------
// TEXT
//---------------------------------------------------
GameObject textGO = new GameObject("Text");
textGO.transform.SetParent(canvasGO.transform, false);
_label = textGO.AddComponent<TextMeshProUGUI>();
_label.fontSize = 14;
_label.alignment = TextAlignmentOptions.Center;
_label.color = Color.white;
RectTransform textRT = _label.GetComponent<RectTransform>();
textRT.anchorMin = Vector2.zero;
textRT.anchorMax = Vector2.one;
textRT.offsetMin = Vector2.zero;
textRT.offsetMax = Vector2.zero;
}
void Refresh(int current, int max)
{
if (_fill == null)
return;
float hp = max > 0 ? (float)current / max : 0f;
_fill.fillAmount = hp;
if (hp > 0.6f)
_fill.color = Color.green;
else if (hp > 0.3f)
_fill.color = Color.yellow;
else
_fill.color = Color.red;
if (_label != null)
_label.text = $"{current} / {max}";
}
void HandleDeath()
{
if (_canvas != null)
Destroy(_canvas.gameObject);
}
void LateUpdate()
{
if (_canvas == null)
return;
if (_cam == null)
_cam = Camera.main;
if (_cam == null)
return;
_canvas.transform.forward =
_canvas.transform.position - _cam.transform.position;
}
void OnDestroy()
{
if (_building != null)
{
_building.OnHealthChanged -= Refresh;
_building.OnDied -= HandleDeath;
}
}
}