231 lines
7.3 KiB
C#
231 lines
7.3 KiB
C#
using Core;
|
|
using Core.Lifecycle;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Minigames.Airplane.UI
|
|
{
|
|
/// <summary>
|
|
/// Displays target information: icon and distance remaining to target.
|
|
/// Updates in real-time as the airplane moves.
|
|
/// </summary>
|
|
public class TargetDisplayUI : ManagedBehaviour
|
|
{
|
|
#region Inspector References
|
|
|
|
[Header("UI Elements")]
|
|
[Tooltip("Image to display target icon")]
|
|
[SerializeField] private Image targetIcon;
|
|
|
|
[Tooltip("Text to display distance remaining")]
|
|
[SerializeField] private TextMeshProUGUI distanceText;
|
|
|
|
[Header("Display Settings")]
|
|
[Tooltip("Format string for distance display (e.g., '{0:F1}m')")]
|
|
[SerializeField] private string distanceFormat = "{0:F1}m";
|
|
|
|
[Tooltip("Update distance every N frames (0 = every frame)")]
|
|
[SerializeField] private int updateInterval = 5;
|
|
|
|
[Header("Debug")]
|
|
[SerializeField] private bool showDebugLogs;
|
|
|
|
#endregion
|
|
|
|
#region State
|
|
|
|
private Transform _planeTransform;
|
|
private Transform _launchPointTransform;
|
|
private Vector3 _targetPosition;
|
|
private bool _isActive;
|
|
private int _frameCounter;
|
|
|
|
#endregion
|
|
|
|
#region Lifecycle
|
|
|
|
internal override void OnManagedAwake()
|
|
{
|
|
base.OnManagedAwake();
|
|
|
|
// Hide by default
|
|
Hide();
|
|
|
|
// Validate references
|
|
if (targetIcon == null)
|
|
{
|
|
Logging.Warning("[TargetDisplayUI] Target icon image not assigned!");
|
|
}
|
|
|
|
if (distanceText == null)
|
|
{
|
|
Logging.Warning("[TargetDisplayUI] Distance text not assigned!");
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
// Only update if active and we have at least one transform to calculate from
|
|
if (!_isActive) return;
|
|
if (_planeTransform == null && _launchPointTransform == null) return;
|
|
|
|
// Update distance at specified interval
|
|
_frameCounter++;
|
|
if (updateInterval == 0 || _frameCounter >= updateInterval)
|
|
{
|
|
_frameCounter = 0;
|
|
UpdateDistance();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public API
|
|
|
|
/// <summary>
|
|
/// Setup the target display with icon and target position.
|
|
/// Activates tracking using launch point for distance calculation.
|
|
/// </summary>
|
|
/// <param name="targetSprite">Sprite to display as target icon</param>
|
|
/// <param name="targetPosition">World position of the target</param>
|
|
/// <param name="launchPoint">Launch point transform (used for distance when plane not available)</param>
|
|
public void Setup(Sprite targetSprite, Vector3 targetPosition, Transform launchPoint)
|
|
{
|
|
_targetPosition = targetPosition;
|
|
_launchPointTransform = launchPoint;
|
|
|
|
// Set icon
|
|
if (targetIcon != null && targetSprite != null)
|
|
{
|
|
targetIcon.sprite = targetSprite;
|
|
targetIcon.enabled = true;
|
|
}
|
|
|
|
// Activate tracking so distance updates even before plane spawns
|
|
_isActive = true;
|
|
_frameCounter = 0;
|
|
|
|
// Update distance immediately using launch point
|
|
UpdateDistance();
|
|
|
|
if (showDebugLogs)
|
|
{
|
|
Logging.Debug($"[TargetDisplayUI] Setup with target at {targetPosition}, launch point at {launchPoint?.position ?? Vector3.zero}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Start tracking the airplane and updating distance.
|
|
/// Switches distance calculation from launch point to airplane position.
|
|
/// Note: Does not automatically show UI - call Show() separately.
|
|
/// </summary>
|
|
/// <param name="planeTransform">Transform of the airplane to track</param>
|
|
public void StartTracking(Transform planeTransform)
|
|
{
|
|
_planeTransform = planeTransform;
|
|
_isActive = true;
|
|
_frameCounter = 0;
|
|
|
|
// Update distance immediately if visible (now using plane position)
|
|
if (gameObject.activeSelf)
|
|
{
|
|
UpdateDistance();
|
|
}
|
|
|
|
if (showDebugLogs)
|
|
{
|
|
Logging.Debug("[TargetDisplayUI] Started tracking airplane");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stop tracking the airplane.
|
|
/// Reverts to using launch point for distance calculation if available.
|
|
/// Note: Does not automatically hide UI - call Hide() separately.
|
|
/// </summary>
|
|
public void StopTracking()
|
|
{
|
|
_planeTransform = null;
|
|
// Keep _isActive true so we can show distance from launch point
|
|
// Will be set false when Hide() is called
|
|
|
|
// Update immediately to show launch point distance again
|
|
if (_launchPointTransform != null && gameObject.activeSelf)
|
|
{
|
|
UpdateDistance();
|
|
}
|
|
|
|
if (showDebugLogs)
|
|
{
|
|
Logging.Debug("[TargetDisplayUI] Stopped tracking airplane, reverted to launch point");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Show the UI.
|
|
/// </summary>
|
|
public void Show()
|
|
{
|
|
gameObject.SetActive(true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Hide the UI and deactivate tracking.
|
|
/// </summary>
|
|
public void Hide()
|
|
{
|
|
_isActive = false;
|
|
gameObject.SetActive(false);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Internal
|
|
|
|
/// <summary>
|
|
/// Update the distance text based on current plane position.
|
|
/// Uses launch point if plane isn't available yet.
|
|
/// </summary>
|
|
private void UpdateDistance()
|
|
{
|
|
if (distanceText == null) return;
|
|
|
|
// Use plane position if available, otherwise use launch point
|
|
Vector3 currentPosition;
|
|
if (_planeTransform != null)
|
|
{
|
|
currentPosition = _planeTransform.position;
|
|
}
|
|
else if (_launchPointTransform != null)
|
|
{
|
|
currentPosition = _launchPointTransform.position;
|
|
}
|
|
else
|
|
{
|
|
// No reference available
|
|
return;
|
|
}
|
|
|
|
// Calculate horizontal distance (X-axis only for side-scroller)
|
|
float distance = Mathf.Abs(_targetPosition.x - currentPosition.x);
|
|
|
|
// Update text
|
|
distanceText.text = string.Format(distanceFormat, distance);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update distance and ensure UI is shown.
|
|
/// Call when showing UI to refresh distance display.
|
|
/// </summary>
|
|
public void UpdateAndShow()
|
|
{
|
|
UpdateDistance();
|
|
Show();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
|