Working? MVP of the minigame
This commit is contained in:
300
Assets/Scripts/Minigames/Airplane/UI/AirplaneAbilityButton.cs
Normal file
300
Assets/Scripts/Minigames/Airplane/UI/AirplaneAbilityButton.cs
Normal file
@@ -0,0 +1,300 @@
|
||||
using Core;
|
||||
using Input;
|
||||
using Minigames.Airplane.Abilities;
|
||||
using Minigames.Airplane.Core;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Minigames.Airplane.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// UI button for activating airplane special abilities.
|
||||
/// Handles input, visual feedback, and cooldown display.
|
||||
/// Implements ITouchInputConsumer to properly handle hold/release for Jet ability.
|
||||
/// </summary>
|
||||
public class AirplaneAbilityButton : MonoBehaviour, ITouchInputConsumer
|
||||
{
|
||||
#region Inspector References
|
||||
|
||||
[Header("UI Components")]
|
||||
[SerializeField] private Button button;
|
||||
[SerializeField] private Image abilityIcon;
|
||||
[SerializeField] private Image cooldownFill;
|
||||
[SerializeField] private TextMeshProUGUI cooldownText;
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] private bool showDebugLogs;
|
||||
|
||||
#endregion
|
||||
|
||||
#region State
|
||||
|
||||
private BaseAirplaneAbility currentAbility;
|
||||
private AirplaneController currentAirplane;
|
||||
private bool isHoldAbility; // Jet plane needs hold mechanic
|
||||
private bool isHolding; // Track if button is currently being held
|
||||
|
||||
#endregion
|
||||
|
||||
#region Lifecycle
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (button != null)
|
||||
{
|
||||
button.onClick.AddListener(OnButtonClick);
|
||||
}
|
||||
|
||||
// Hide by default
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (currentAbility == null) return;
|
||||
|
||||
// Update cooldown display
|
||||
if (currentAbility.IsOnCooldown)
|
||||
{
|
||||
// Fill starts at 1 and reduces to 0 over cooldown duration
|
||||
float fillAmount = currentAbility.CooldownRemaining / currentAbility.CooldownDuration;
|
||||
if (cooldownFill != null)
|
||||
{
|
||||
cooldownFill.fillAmount = fillAmount;
|
||||
}
|
||||
|
||||
// Show timer text
|
||||
if (cooldownText != null)
|
||||
{
|
||||
cooldownText.text = $"{currentAbility.CooldownRemaining:F1}s";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cooldown complete - fill at 0, no text
|
||||
if (cooldownFill != null)
|
||||
cooldownFill.fillAmount = 0f;
|
||||
|
||||
if (cooldownText != null)
|
||||
cooldownText.text = "";
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
// Unsubscribe from events
|
||||
if (currentAbility != null)
|
||||
{
|
||||
currentAbility.OnAbilityActivated -= HandleAbilityActivated;
|
||||
currentAbility.OnAbilityDeactivated -= HandleAbilityDeactivated;
|
||||
currentAbility.OnCooldownChanged -= HandleCooldownChanged;
|
||||
}
|
||||
|
||||
// Unregister from input system
|
||||
if (InputManager.Instance != null)
|
||||
{
|
||||
InputManager.Instance.UnregisterOverrideConsumer(this);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public API
|
||||
|
||||
/// <summary>
|
||||
/// Setup button with airplane and ability reference.
|
||||
/// </summary>
|
||||
public void Setup(AirplaneController airplane, BaseAirplaneAbility ability)
|
||||
{
|
||||
currentAirplane = airplane;
|
||||
currentAbility = ability;
|
||||
isHolding = false;
|
||||
|
||||
// Set icon and show immediately
|
||||
if (abilityIcon != null && ability != null)
|
||||
{
|
||||
abilityIcon.sprite = ability.AbilityIcon;
|
||||
abilityIcon.enabled = true;
|
||||
}
|
||||
|
||||
// Initialize cooldown display
|
||||
if (cooldownFill != null)
|
||||
{
|
||||
cooldownFill.fillAmount = 0f;
|
||||
}
|
||||
|
||||
if (cooldownText != null)
|
||||
{
|
||||
cooldownText.text = "";
|
||||
}
|
||||
|
||||
// Check if this is a hold ability (Jet)
|
||||
isHoldAbility = ability is JetAbility;
|
||||
|
||||
// Subscribe to ability events
|
||||
if (ability != null)
|
||||
{
|
||||
ability.OnAbilityActivated += HandleAbilityActivated;
|
||||
ability.OnAbilityDeactivated += HandleAbilityDeactivated;
|
||||
ability.OnCooldownChanged += HandleCooldownChanged;
|
||||
|
||||
if (showDebugLogs)
|
||||
{
|
||||
Logging.Debug($"[AirplaneAbilityButton] Subscribed to ability events for: {ability.AbilityName}");
|
||||
}
|
||||
}
|
||||
|
||||
// Show UI
|
||||
gameObject.SetActive(true);
|
||||
|
||||
if (showDebugLogs)
|
||||
{
|
||||
Logging.Debug($"[AirplaneAbilityButton] Setup complete with ability: {ability?.AbilityName ?? "None"}, Hold: {isHoldAbility}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hide and cleanup button.
|
||||
/// </summary>
|
||||
public void Hide()
|
||||
{
|
||||
if (currentAbility != null)
|
||||
{
|
||||
currentAbility.OnAbilityActivated -= HandleAbilityActivated;
|
||||
currentAbility.OnAbilityDeactivated -= HandleAbilityDeactivated;
|
||||
currentAbility.OnCooldownChanged -= HandleCooldownChanged;
|
||||
}
|
||||
|
||||
// Unregister from input system
|
||||
if (InputManager.Instance != null)
|
||||
{
|
||||
InputManager.Instance.UnregisterOverrideConsumer(this);
|
||||
}
|
||||
|
||||
currentAbility = null;
|
||||
currentAirplane = null;
|
||||
isHolding = false;
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Input Handling
|
||||
|
||||
private void OnButtonClick()
|
||||
{
|
||||
if (currentAirplane == null || currentAbility == null) return;
|
||||
if (!currentAbility.CanActivate) return;
|
||||
|
||||
// Activate ability
|
||||
currentAirplane.ActivateAbility();
|
||||
|
||||
// For hold abilities (Jet), mark as holding and register for input
|
||||
if (isHoldAbility)
|
||||
{
|
||||
isHolding = true;
|
||||
|
||||
// Register as override consumer to receive hold/release events
|
||||
if (InputManager.Instance != null)
|
||||
{
|
||||
InputManager.Instance.RegisterOverrideConsumer(this);
|
||||
}
|
||||
|
||||
if (showDebugLogs)
|
||||
{
|
||||
Logging.Debug("[AirplaneAbilityButton] Started holding ability, registered for input");
|
||||
}
|
||||
}
|
||||
|
||||
// For non-hold abilities (Bobbing, Drop), this is all we need
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
private void HandleAbilityActivated(BaseAirplaneAbility ability)
|
||||
{
|
||||
if (showDebugLogs)
|
||||
{
|
||||
Logging.Debug($"[AirplaneAbilityButton] Ability activated: {ability.AbilityName}");
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleAbilityDeactivated(BaseAirplaneAbility ability)
|
||||
{
|
||||
if (showDebugLogs)
|
||||
{
|
||||
Logging.Debug($"[AirplaneAbilityButton] Ability deactivated: {ability.AbilityName}");
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleCooldownChanged(float remaining, float total)
|
||||
{
|
||||
if (showDebugLogs)
|
||||
{
|
||||
Logging.Debug($"[AirplaneAbilityButton] OnCooldownChanged: remaining={remaining:F2}, total={total:F2}");
|
||||
}
|
||||
|
||||
// When cooldown starts (remaining == total), set fill to 1
|
||||
if (remaining >= total - 0.01f && cooldownFill != null)
|
||||
{
|
||||
cooldownFill.fillAmount = 1f;
|
||||
|
||||
if (showDebugLogs)
|
||||
{
|
||||
Logging.Debug($"[AirplaneAbilityButton] Cooldown started: {total}s, fill set to 1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ITouchInputConsumer Implementation
|
||||
|
||||
public void OnTap(Vector2 position)
|
||||
{
|
||||
// If Jet ability is active (holding), next tap anywhere deactivates it
|
||||
if (isHoldAbility && isHolding)
|
||||
{
|
||||
isHolding = false;
|
||||
currentAirplane?.DeactivateAbility();
|
||||
|
||||
// Unregister from input system after tap
|
||||
if (InputManager.Instance != null)
|
||||
{
|
||||
InputManager.Instance.UnregisterOverrideConsumer(this);
|
||||
}
|
||||
|
||||
if (showDebugLogs)
|
||||
{
|
||||
Logging.Debug("[AirplaneAbilityButton] Tap detected - deactivated Jet ability, unregistered");
|
||||
}
|
||||
}
|
||||
// Handle as button click for non-hold abilities
|
||||
else if (!isHoldAbility)
|
||||
{
|
||||
OnButtonClick();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnHoldStart(Vector2 position)
|
||||
{
|
||||
// Not used - button click handles activation, tap handles deactivation
|
||||
}
|
||||
|
||||
public void OnHoldMove(Vector2 position)
|
||||
{
|
||||
// Not used
|
||||
}
|
||||
|
||||
public void OnHoldEnd(Vector2 position)
|
||||
{
|
||||
// Not used - tap handles deactivation for Jet ability
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user