2025-10-14 15:53:58 +02:00
|
|
|
|
using Core;
|
|
|
|
|
|
using UnityEngine;
|
2025-10-10 14:31:51 +02:00
|
|
|
|
using UnityEngine.EventSystems;
|
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
using Input;
|
2025-12-18 10:52:12 +01:00
|
|
|
|
using UnityEngine.Serialization;
|
|
|
|
|
|
using Utils.UI;
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
|
|
|
|
|
namespace Minigames.DivingForPictures.PictureCamera
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Attached to the viewfinder UI prefab. Handles tap detection and other viewfinder-specific operations.
|
2025-12-18 10:52:12 +01:00
|
|
|
|
/// Also exposes screenshot-related references for the diving minigame.
|
2025-10-10 14:31:51 +02:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class Viewfinder : MonoBehaviour, ITouchInputConsumer
|
|
|
|
|
|
{
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private Image[] viewfinderImages; // Array of Image components to tint based on proximity
|
|
|
|
|
|
|
2025-12-18 10:52:12 +01:00
|
|
|
|
[Header("Screenshot Components")]
|
|
|
|
|
|
[FormerlySerializedAs("_captureArea")]
|
|
|
|
|
|
[SerializeField] private RectTransform captureArea;
|
|
|
|
|
|
[FormerlySerializedAs("_flyawayAnimation")]
|
|
|
|
|
|
[SerializeField] private ScreenshotFlyawayAnimation flyawayAnimation;
|
|
|
|
|
|
|
|
|
|
|
|
[Header("UI Elements to Hide During Screenshot")]
|
|
|
|
|
|
[Tooltip("UI elements (like frame, crosshairs) that should be hidden during screenshot capture")]
|
|
|
|
|
|
[SerializeField] private GameObject[] uiElementsToHideDuringCapture;
|
|
|
|
|
|
|
2025-10-10 14:31:51 +02:00
|
|
|
|
// Events
|
|
|
|
|
|
public event System.Action OnViewfinderTapped;
|
2025-10-14 07:09:16 +00:00
|
|
|
|
public event System.Action OnViewfinderHoldStarted;
|
|
|
|
|
|
public event System.Action OnViewfinderHoldEnded;
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
|
|
|
|
|
// State
|
|
|
|
|
|
private bool isActive = true;
|
|
|
|
|
|
private RectTransform _rectTransform;
|
|
|
|
|
|
private CameraViewfinderManager _viewfinderManager;
|
|
|
|
|
|
|
2025-12-18 10:52:12 +01:00
|
|
|
|
// Public properties for screenshot system
|
|
|
|
|
|
public RectTransform CaptureArea
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (captureArea == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
captureArea = GetComponent<RectTransform>();
|
|
|
|
|
|
}
|
|
|
|
|
|
return captureArea;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ScreenshotFlyawayAnimation FlyawayAnimation => flyawayAnimation;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// UI elements to hide during screenshot capture (frame, crosshairs, etc.)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public GameObject[] UIElementsToHideDuringCapture => uiElementsToHideDuringCapture;
|
|
|
|
|
|
|
2025-10-10 14:31:51 +02:00
|
|
|
|
private void Awake()
|
|
|
|
|
|
{
|
|
|
|
|
|
_rectTransform = GetComponent<RectTransform>();
|
2025-12-18 10:52:12 +01:00
|
|
|
|
|
|
|
|
|
|
// Auto-assign capture area to self if not set
|
|
|
|
|
|
if (captureArea == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
captureArea = GetComponent<RectTransform>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Auto-find flyaway animation in children
|
|
|
|
|
|
if (flyawayAnimation == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
flyawayAnimation = GetComponentInChildren<ScreenshotFlyawayAnimation>(includeInactive: true);
|
|
|
|
|
|
}
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Initializes the viewfinder with a reference to its manager
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="manager">Reference to the CameraViewfinderManager</param>
|
|
|
|
|
|
public void Initialize(CameraViewfinderManager manager)
|
|
|
|
|
|
{
|
|
|
|
|
|
_viewfinderManager = manager;
|
|
|
|
|
|
|
|
|
|
|
|
if (_viewfinderManager != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_viewfinderManager.OnProximityUpdated += UpdateProximityColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnDisable()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Unsubscribe from events when disabled
|
|
|
|
|
|
if (_viewfinderManager != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_viewfinderManager.OnProximityUpdated -= UpdateProximityColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Updates the color of all viewfinder images based on proximity value
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="proximity">Proximity value between 0 and 1 (0=far, 1=close)</param>
|
|
|
|
|
|
private void UpdateProximityColor(float proximity)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Lerp between green (close) and red (far)
|
|
|
|
|
|
Color tintColor = Color.Lerp(Color.red, Color.green, proximity);
|
|
|
|
|
|
|
|
|
|
|
|
// Apply the color to all referenced image components
|
|
|
|
|
|
if (viewfinderImages != null && viewfinderImages.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (Image image in viewfinderImages)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (image != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
image.color = tintColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Enable or disable input reception
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void SetActive(bool active)
|
|
|
|
|
|
{
|
|
|
|
|
|
isActive = active;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region ITouchInputConsumer Implementation
|
|
|
|
|
|
|
|
|
|
|
|
public void SetupInputOverride()
|
|
|
|
|
|
{
|
|
|
|
|
|
InputManager.Instance.RegisterOverrideConsumer(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void RemoveInputOverride()
|
|
|
|
|
|
{
|
|
|
|
|
|
InputManager.Instance.UnregisterOverrideConsumer(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void OnTap(Vector2 position)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isActive)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Fire the tap event that PhotoSequenceController will listen to
|
|
|
|
|
|
OnViewfinderTapped?.Invoke();
|
2025-10-14 15:53:58 +02:00
|
|
|
|
Logging.Debug($"[MDPI] Viewfinder OnTap: {position}");
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-14 07:09:16 +00:00
|
|
|
|
public void OnHoldStart(Vector2 position)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isActive)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Fire the hold start event
|
|
|
|
|
|
OnViewfinderHoldStarted?.Invoke();
|
2025-10-14 15:53:58 +02:00
|
|
|
|
Logging.Debug($"[MDPI] Viewfinder OnHoldStart: {position}");
|
2025-10-14 07:09:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void OnHoldMove(Vector2 position)
|
|
|
|
|
|
{
|
|
|
|
|
|
// We can use this for any continuous effects during hold if needed in the future
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void OnHoldEnd(Vector2 position)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isActive)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Fire the hold end event
|
|
|
|
|
|
OnViewfinderHoldEnded?.Invoke();
|
2025-10-14 15:53:58 +02:00
|
|
|
|
Logging.Debug($"[MDPI] Viewfinder OnHoldEnd: {position}");
|
2025-10-14 07:09:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Check if a point is within the viewfinder's bounds
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool ContainsPoint(Vector2 screenPoint)
|
|
|
|
|
|
{
|
|
|
|
|
|
return RectTransformUtility.RectangleContainsScreenPoint(_rectTransform, screenPoint);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|