2025-05-15 15:19:18 +02:00

264 lines
7.0 KiB
C#

using UnityEngine;
using System.Collections;
using Modularify.LoadingBars3D;
[RequireComponent(typeof(Collider))]
[RequireComponent(typeof(Rigidbody))]
public class EyeInteractable : MonoBehaviour
{
public bool IsHovered { get; private set; }
[Header("Mode")]
[Tooltip("If true, this object acts as an unlocker and skips progress bar logic.")]
[SerializeField] private bool isUnlocker = false;
[Header("Materials")]
[SerializeField] private Material OnHoverActiveMaterial;
[SerializeField] private Material OnHoverInactiveMaterial;
[Header("Sequence Setup")]
[SerializeField] private GameObject nextSegment;
[SerializeField] private GameObject segmentUnlock;
[Header("Progress Settings (for non-unlockers)")]
[SerializeField] private LoadingBarSegments progressBar;
[SerializeField] private int totalSegments = 5;
[SerializeField] private float segmentFillTime = 1f;
[Header("Unlocker Settings (if isUnlocker is true)")]
[SerializeField] private float unlockDelay = 2f;
private MeshRenderer meshRenderer;
public GameObject selectionRing;
private int currentFilledSegments = 0;
private Coroutine progressCoroutine;
private Coroutine resetCoroutine;
private Coroutine unlockCoroutine;
private bool isCompleted = false;
void Start()
{
meshRenderer = GetComponent<MeshRenderer>();
if (segmentUnlock != null)
segmentUnlock.SetActive(false);
if (selectionRing != null)
selectionRing.SetActive(false);
if (progressBar != null)
progressBar.SetPercentage(0);
if (nextSegment != null)
nextSegment.SetActive(false);
}
public void OnStartLooking()
{
if (isCompleted) return;
Debug.Log("Started looking at: " + gameObject.name);
IsHovered = true;
if (meshRenderer != null && OnHoverActiveMaterial != null)
meshRenderer.material = OnHoverActiveMaterial;
if (selectionRing != null)
selectionRing.SetActive(true);
if (segmentUnlock != null)
segmentUnlock.SetActive(true);
if (resetCoroutine != null)
{
StopCoroutine(resetCoroutine);
resetCoroutine = null;
}
if (isUnlocker)
{
if (unlockCoroutine == null)
unlockCoroutine = StartCoroutine(UnlockAfterDelay());
}
else
{
if (progressBar != null && progressCoroutine == null)
progressCoroutine = StartCoroutine(FillProgress());
}
}
public void OnStopLooking()
{
if (isCompleted) return;
Debug.Log("Stopped looking at: " + gameObject.name);
IsHovered = false;
if (meshRenderer != null && OnHoverInactiveMaterial != null)
meshRenderer.material = OnHoverInactiveMaterial;
if (selectionRing != null)
selectionRing.SetActive(false);
if (segmentUnlock != null && !isCompleted)
segmentUnlock.SetActive(false);
if (isUnlocker)
{
if (unlockCoroutine != null)
{
StopCoroutine(unlockCoroutine);
unlockCoroutine = null;
}
}
else
{
if (progressCoroutine != null)
{
StopCoroutine(progressCoroutine);
progressCoroutine = null;
}
if (currentFilledSegments > 0)
{
resetCoroutine = StartCoroutine(ResetAfterDelay());
}
}
}
private IEnumerator FillProgress()
{
while (currentFilledSegments < totalSegments)
{
if (!IsHovered)
{
progressCoroutine = null;
yield break;
}
currentFilledSegments++;
float percentage = (float)currentFilledSegments / totalSegments;
progressBar.SetPercentage(percentage);
Debug.Log($"{gameObject.name} progress: {currentFilledSegments}/{totalSegments}");
if (currentFilledSegments >= totalSegments)
{
CompleteSegment();
progressCoroutine = null;
yield break;
}
yield return new WaitForSeconds(segmentFillTime);
}
progressCoroutine = null;
}
private IEnumerator UnlockAfterDelay()
{
yield return new WaitForSeconds(unlockDelay);
Debug.Log("Unlocker activated: " + gameObject.name);
isCompleted = true;
if (nextSegment != null)
{
Debug.Log("Activating next segment: " + nextSegment.name);
nextSegment.SetActive(true);
}
// Optional: Reset unlocker after delay so it can be reused
yield return new WaitForSeconds(2.0f);
ResetInteractable();
}
private void CompleteSegment()
{
Debug.Log(gameObject.name + " COMPLETED!");
isCompleted = true;
progressBar.SetPercentage(1.0f);
if (segmentUnlock != null)
segmentUnlock.SetActive(true);
if (selectionRing != null)
selectionRing.SetActive(false);
StartCoroutine(ActivateNextSegmentAfterDelay());
}
private IEnumerator ActivateNextSegmentAfterDelay()
{
yield return new WaitForSeconds(1.0f);
if (nextSegment != null)
{
Debug.Log("Activating next segment: " + nextSegment.name);
nextSegment.SetActive(true);
}
else
{
Debug.Log("No next segment assigned to " + gameObject.name);
}
// Optional: Reset current segment after a delay so the whole thing can be repeated
yield return new WaitForSeconds(2.0f);
ResetInteractable();
}
private IEnumerator ResetAfterDelay()
{
yield return new WaitForSeconds(2.0f);
if (!IsHovered && !isCompleted)
{
Debug.Log("Resetting progress for " + gameObject.name);
currentFilledSegments = 0;
progressBar.SetPercentage(0);
}
resetCoroutine = null;
}
public void ResetInteractable()
{
isCompleted = false;
IsHovered = false;
currentFilledSegments = 0;
if (progressCoroutine != null)
{
StopCoroutine(progressCoroutine);
progressCoroutine = null;
}
if (resetCoroutine != null)
{
StopCoroutine(resetCoroutine);
resetCoroutine = null;
}
if (unlockCoroutine != null)
{
StopCoroutine(unlockCoroutine);
unlockCoroutine = null;
}
if (progressBar != null)
progressBar.SetPercentage(0);
if (segmentUnlock != null)
segmentUnlock.SetActive(false);
if (selectionRing != null)
selectionRing.SetActive(false);
if (nextSegment != null)
nextSegment.SetActive(false);
Debug.Log(gameObject.name + " has been reset.");
}
}