first commit
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
using System.Collections.Generic;
|
||||
using OTG.Lab06.Abilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace OTG.Lab06.UI
|
||||
{
|
||||
public sealed class AbilityBarUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private AbilityManager abilityManager;
|
||||
[SerializeField] private AbilitySlotUI slotPrefab;
|
||||
[SerializeField] private Transform slotRoot;
|
||||
[SerializeField] private TooltipUI tooltip;
|
||||
|
||||
private readonly List<AbilitySlotUI> slots = new List<AbilitySlotUI>();
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (abilityManager != null)
|
||||
{
|
||||
abilityManager.AbilitiesChanged += RebuildOrRefresh;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (abilityManager != null)
|
||||
{
|
||||
abilityManager.AbilitiesChanged -= RebuildOrRefresh;
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (abilityManager != null)
|
||||
{
|
||||
RebuildOrRefresh(abilityManager.Abilities);
|
||||
}
|
||||
}
|
||||
|
||||
public void Bind(AbilityManager manager, AbilitySlotUI prefab, Transform root, TooltipUI tooltipUI)
|
||||
{
|
||||
if (abilityManager != null)
|
||||
{
|
||||
abilityManager.AbilitiesChanged -= RebuildOrRefresh;
|
||||
}
|
||||
|
||||
abilityManager = manager;
|
||||
slotPrefab = prefab;
|
||||
slotRoot = root;
|
||||
tooltip = tooltipUI;
|
||||
|
||||
if (isActiveAndEnabled && abilityManager != null)
|
||||
{
|
||||
abilityManager.AbilitiesChanged += RebuildOrRefresh;
|
||||
RebuildOrRefresh(abilityManager.Abilities);
|
||||
}
|
||||
}
|
||||
|
||||
private void RebuildOrRefresh(IReadOnlyList<AbilityRuntime> abilities)
|
||||
{
|
||||
if (slotPrefab == null || slotRoot == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (slots.Count < abilities.Count)
|
||||
{
|
||||
AbilitySlotUI slot = Instantiate(slotPrefab, slotRoot);
|
||||
slots.Add(slot);
|
||||
}
|
||||
|
||||
for (int i = 0; i < slots.Count; i++)
|
||||
{
|
||||
bool active = i < abilities.Count;
|
||||
slots[i].gameObject.SetActive(active);
|
||||
if (active)
|
||||
{
|
||||
slots[i].Bind(abilities[i], i, tooltip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1b8660e98f014b3880af4c5b70f2dc6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,103 @@
|
||||
using OTG.Lab06.Abilities;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace OTG.Lab06.UI
|
||||
{
|
||||
public sealed class AbilitySlotUI : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
|
||||
{
|
||||
[SerializeField] private Image icon;
|
||||
[SerializeField] private Image cooldownOverlay;
|
||||
[SerializeField] private Text hotkeyLabel;
|
||||
[SerializeField] private Text nameLabel;
|
||||
[SerializeField] private Text manaLabel;
|
||||
[SerializeField] private Text cooldownLabel;
|
||||
|
||||
private AbilityRuntime runtime;
|
||||
private TooltipUI tooltip;
|
||||
|
||||
public void Bind(AbilityRuntime abilityRuntime, int index, TooltipUI tooltipUI)
|
||||
{
|
||||
runtime = abilityRuntime;
|
||||
tooltip = tooltipUI;
|
||||
|
||||
if (icon != null)
|
||||
{
|
||||
icon.sprite = runtime.Data.icon;
|
||||
icon.color = runtime.Data.icon == null ? new Color(0.35f, 0.35f, 0.35f, 1f) : Color.white;
|
||||
}
|
||||
|
||||
if (hotkeyLabel != null)
|
||||
{
|
||||
hotkeyLabel.text = (index + 1).ToString();
|
||||
}
|
||||
|
||||
if (manaLabel != null)
|
||||
{
|
||||
manaLabel.text = Mathf.RoundToInt(runtime.Data.manaCost).ToString();
|
||||
}
|
||||
|
||||
if (nameLabel != null)
|
||||
{
|
||||
nameLabel.text = GetShortName(runtime.Data.abilityName);
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private static string GetShortName(string abilityName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(abilityName))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return abilityName.Length <= 9 ? abilityName : abilityName.Substring(0, 9);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
if (runtime == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (cooldownOverlay != null)
|
||||
{
|
||||
cooldownOverlay.fillAmount = runtime.CooldownNormalized;
|
||||
}
|
||||
|
||||
if (cooldownLabel != null)
|
||||
{
|
||||
bool show = runtime.CooldownRemaining > 0.05f;
|
||||
cooldownLabel.gameObject.SetActive(show);
|
||||
if (show)
|
||||
{
|
||||
cooldownLabel.text = runtime.CooldownRemaining.ToString("0.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPointerEnter(PointerEventData eventData)
|
||||
{
|
||||
if (tooltip != null && runtime != null)
|
||||
{
|
||||
tooltip.Show(runtime.Data, transform as RectTransform);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPointerExit(PointerEventData eventData)
|
||||
{
|
||||
if (tooltip != null)
|
||||
{
|
||||
tooltip.Hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d80b838b44dd63b8a83685aa2df02f15
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,89 @@
|
||||
using OTG.Lab06.Characters;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace OTG.Lab06.UI
|
||||
{
|
||||
public sealed class ResourceBarUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private PlayerStats playerStats;
|
||||
[SerializeField] private Image fill;
|
||||
[SerializeField] private Text valueLabel;
|
||||
[SerializeField] private bool useMana;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
Subscribe();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Unsubscribe();
|
||||
}
|
||||
|
||||
public void Bind(PlayerStats stats, bool mana)
|
||||
{
|
||||
Unsubscribe();
|
||||
playerStats = stats;
|
||||
useMana = mana;
|
||||
Subscribe();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void Subscribe()
|
||||
{
|
||||
if (playerStats == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (useMana)
|
||||
{
|
||||
playerStats.ManaChanged += OnChanged;
|
||||
}
|
||||
else
|
||||
{
|
||||
playerStats.HealthChanged += OnChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private void Unsubscribe()
|
||||
{
|
||||
if (playerStats == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
playerStats.ManaChanged -= OnChanged;
|
||||
playerStats.HealthChanged -= OnChanged;
|
||||
}
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
if (playerStats == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OnChanged(useMana ? playerStats.Mana : playerStats.Health, useMana ? playerStats.MaxMana : playerStats.MaxHealth);
|
||||
}
|
||||
|
||||
private void OnChanged(float current, float max)
|
||||
{
|
||||
float normalized = max <= 0f ? 0f : Mathf.Clamp01(current / max);
|
||||
if (fill != null)
|
||||
{
|
||||
fill.type = Image.Type.Filled;
|
||||
fill.fillMethod = Image.FillMethod.Horizontal;
|
||||
fill.fillOrigin = (int)Image.OriginHorizontal.Left;
|
||||
fill.fillAmount = normalized;
|
||||
}
|
||||
|
||||
if (valueLabel != null)
|
||||
{
|
||||
valueLabel.text = $"{Mathf.RoundToInt(current)} / {Mathf.RoundToInt(max)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b1633c268542d115823df8771e20b9b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
using OTG.Lab06.Abilities;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace OTG.Lab06.UI
|
||||
{
|
||||
public sealed class TooltipUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Text titleLabel;
|
||||
[SerializeField] private Text descriptionLabel;
|
||||
[SerializeField] private Text statsLabel;
|
||||
|
||||
private RectTransform rectTransform;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
rectTransform = transform as RectTransform;
|
||||
Hide();
|
||||
}
|
||||
|
||||
public void Show(AbilityData data, RectTransform anchor)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (rectTransform == null)
|
||||
{
|
||||
rectTransform = transform as RectTransform;
|
||||
}
|
||||
|
||||
titleLabel.text = data.abilityName;
|
||||
descriptionLabel.text = data.description;
|
||||
statsLabel.text = $"Damage: {Mathf.RoundToInt(data.damage)}\nMana: {Mathf.RoundToInt(data.manaCost)}\nCooldown: {data.cooldown:0.#}s";
|
||||
gameObject.SetActive(true);
|
||||
|
||||
if (rectTransform != null && anchor != null)
|
||||
{
|
||||
rectTransform.position = anchor.position + new Vector3(0f, 142f, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13ea93e0504244d82b04abc14e512442
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user