GazeProject/Assets/EYE ADVANCED/Scripts/SpherePatternUnlock.cs
2025-05-15 15:19:18 +02:00

254 lines
7.0 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpherePatternUnlock : MonoBehaviour
{
[System.Serializable]
public class SphereKey
{
public GameObject sphere;
public bool isCorrect;
public Material defaultMaterial;
public Material selectedMaterial;
public Material correctMaterial;
public Material incorrectMaterial;
[HideInInspector] public bool isSelected = false;
}
[SerializeField] private SphereKey[] sphereKeys;
[SerializeField] private int requiredCorrectSelections = 3;
[SerializeField] private bool randomizeCorrectPattern = true;
[SerializeField] private float resetDelay = 2f;
[Header("Light Control")]
[SerializeField] private Light lightToControl;
[SerializeField] private bool startLightEnabled = false;
[Header("Audio Feedback")]
[SerializeField] private AudioSource audioSource;
[SerializeField] private AudioClip correctSound;
[SerializeField] private AudioClip incorrectSound;
[SerializeField] private AudioClip successSound;
private int correctSelections = 0;
private int totalSelections = 0;
private bool isUnlocked = false;
private Coroutine resetCoroutine;
private void Start()
{
InitializeSpheres();
// Set initial light state
if (lightToControl != null)
{
lightToControl.enabled = startLightEnabled;
}
}
private void InitializeSpheres()
{
if (randomizeCorrectPattern)
{
SetRandomCorrectPattern();
}
// Initialize all spheres with default material
foreach (SphereKey key in sphereKeys)
{
if (key.sphere != null)
{
MeshRenderer renderer = key.sphere.GetComponent<MeshRenderer>();
if (renderer != null && key.defaultMaterial != null)
{
renderer.material = key.defaultMaterial;
}
// Add click handler to each sphere
SphereClickHandler clickHandler = key.sphere.GetComponent<SphereClickHandler>();
if (clickHandler == null)
{
clickHandler = key.sphere.AddComponent<SphereClickHandler>();
}
clickHandler.patternUnlock = this;
clickHandler.sphereKey = key;
}
}
correctSelections = 0;
totalSelections = 0;
isUnlocked = false;
}
private void SetRandomCorrectPattern()
{
// Reset all to incorrect
foreach (SphereKey key in sphereKeys)
{
key.isCorrect = false;
}
// Randomly select correct spheres
List<int> indices = new List<int>();
for (int i = 0; i < sphereKeys.Length; i++)
{
indices.Add(i);
}
// Shuffle indices
for (int i = 0; i < indices.Count; i++)
{
int temp = indices[i];
int randomIndex = Random.Range(i, indices.Count);
indices[i] = indices[randomIndex];
indices[randomIndex] = temp;
}
// Set first N as correct
for (int i = 0; i < Mathf.Min(requiredCorrectSelections, indices.Count); i++)
{
sphereKeys[indices[i]].isCorrect = true;
Debug.Log($"Sphere {indices[i]} is correct");
}
}
public void OnSphereClicked(SphereKey key)
{
if (isUnlocked || key.isSelected)
return;
MeshRenderer renderer = key.sphere.GetComponent<MeshRenderer>();
if (renderer == null)
return;
key.isSelected = true;
totalSelections++;
if (key.isCorrect)
{
// Handle correct selection
correctSelections++;
renderer.material = key.correctMaterial;
if (audioSource != null && correctSound != null)
audioSource.PlayOneShot(correctSound);
// Check if pattern is complete
if (correctSelections >= requiredCorrectSelections)
{
OnPatternCompleted(true);
}
}
else
{
// Handle incorrect selection
renderer.material = key.incorrectMaterial;
if (audioSource != null && incorrectSound != null)
audioSource.PlayOneShot(incorrectSound);
// Auto-reset after delay
if (resetCoroutine != null)
StopCoroutine(resetCoroutine);
resetCoroutine = StartCoroutine(ResetAfterDelay(resetDelay));
}
// Check if all selections are used up
if (totalSelections >= requiredCorrectSelections)
{
// Check if successful
bool success = (correctSelections >= requiredCorrectSelections);
if (!success)
{
OnPatternCompleted(false);
}
}
}
private void OnPatternCompleted(bool success)
{
if (isUnlocked)
return;
if (success)
{
isUnlocked = true;
Debug.Log("🎉 Pattern unlocked successfully!");
// Turn on the light
if (lightToControl != null)
{
lightToControl.enabled = true;
}
if (audioSource != null && successSound != null)
audioSource.PlayOneShot(successSound);
}
else
{
Debug.Log("❌ Incorrect pattern!");
// Auto-reset after delay
if (resetCoroutine != null)
StopCoroutine(resetCoroutine);
resetCoroutine = StartCoroutine(ResetAfterDelay(resetDelay));
}
}
private IEnumerator ResetAfterDelay(float delay)
{
yield return new WaitForSeconds(delay);
ResetPattern();
}
public void ResetPattern()
{
foreach (SphereKey key in sphereKeys)
{
key.isSelected = false;
MeshRenderer renderer = key.sphere.GetComponent<MeshRenderer>();
if (renderer != null && key.defaultMaterial != null)
{
renderer.material = key.defaultMaterial;
}
}
if (randomizeCorrectPattern && !isUnlocked)
{
SetRandomCorrectPattern();
}
correctSelections = 0;
totalSelections = 0;
}
public void ResetCompletely()
{
if (lightToControl != null)
{
lightToControl.enabled = startLightEnabled;
}
isUnlocked = false;
ResetPattern();
}
}
// Helper component for click detection
public class SphereClickHandler : MonoBehaviour
{
[HideInInspector] public SpherePatternUnlock patternUnlock;
[HideInInspector] public SpherePatternUnlock.SphereKey sphereKey;
private void OnMouseDown()
{
if (patternUnlock != null && sphereKey != null)
{
patternUnlock.OnSphereClicked(sphereKey);
}
}
}