Files
beyond/Assets/Scripts/Tutorial/BaseStepController.cs
2024-11-20 15:21:28 +01:00

278 lines
10 KiB
C#

using Sirenix.OdinInspector;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace Beyond
{
public class BaseStepController : MonoBehaviour
{
public bool dontMeetConditionByDefault = false;
public float delayToStart = 0f;
public float initialTimeScale = 0f, normalTimeScale = 1f;
public float freezedTimeDuration = 1f;
public float delayAfterCompletingRequirements = 0f;
public GameObject stepPanel, additionalStepPanel;
private List<TMP_Text> stepPanelTexts = new List<TMP_Text>(), additionalStePanelTexts = new List<TMP_Text>();
public CanvasGroup canvasGroup;
public float additionalStepPanelDuration = 0f;
[FoldoutGroup("Buttons&Objects Lists")]
public List<GameObject> gameObjectsToEnable, gameObjectsToDisable, gameObjectsToEnableOnEnd, gameObjectsToDisableOnEnd;
// Nowa lista obiektów do włączenia na końcu kroku
[FoldoutGroup("Buttons&Objects Lists")]
public List<GameObject> objectsToEnableOnEnd;
[SerializeField]
private float fadeDuration = 0.0f;
//to replace buttonToDisable on numerous steps
[FoldoutGroup("Buttons&Objects Lists")]
public List<Button> buttonsToDisableDuringStep, buttonsToDisableOnStart, buttonsToEnableOnStart, buttonsToDisableOnEnd, buttonsToEnableOnEnd;
public List<GameObject> imagesToPulse;
// Dodanie zmiennych dla pulsowania
public float pulseSpeed = 5f; // Prędkość pulsowania
public Color pulseColor = Color.white; // Kolor pulsowania
[Range(1.0f, 1.5f)] public float scaleAmount = 1.05f; // Maksymalna wartość skalowania
public event Action OnCompletedStart, OnCompleted, OnEvaluationStart, OnStarted, OnAdditionalStepPanelEnabled;
public event Action OnEnableObjectsAtEnd;
// Dodanie tradycyjnych eventów Unity
public UnityEvent onStepStart;
public UnityEvent onStepEnd;
public delegate bool evaluate();
public evaluate ConditionsAreMet;
private void Awake()
{
if (stepPanel)
stepPanelTexts = stepPanel.GetComponentsInChildren<TMP_Text>().ToList();
if (additionalStepPanel)
{
additionalStePanelTexts = additionalStepPanel.GetComponentsInChildren<TMP_Text>().ToList();
}
OnEnableObjectsAtEnd += EnableObjectsAtEnd;
if (canvasGroup)
canvasGroup.alpha = 0f;
if (dontMeetConditionByDefault)
ConditionsAreMet = () => {return false;};
}
private void OnDestroy()
{
OnEnableObjectsAtEnd -= EnableObjectsAtEnd;
}
public void StartStep()
{
StartCoroutine(StartStepCoroutine());
}
private IEnumerator StartStepCoroutine()
{
OnStarted?.Invoke();
SetObjectsStatesOnStart();
if (delayToStart > 0)
yield return new WaitForSecondsRealtime(delayToStart);
onStepStart?.Invoke(); // Wywołanie UnityEvent na początku kroku
imagesToPulse.ForEach(go => PulseImage(go, true));
if (stepPanel)
StartCoroutine(FadePanelIn(stepPanel));
TimeController.Instance.SetTimeScale(initialTimeScale);
if (freezedTimeDuration > 0)
yield return new WaitForSecondsRealtime(freezedTimeDuration);
TimeController.Instance.SetTimeScale(normalTimeScale);
EvaluateStep();
}
private void SetObjectsStatesOnStart()
{
gameObjectsToEnable.ForEach(obj => obj.SetActive(true));
gameObjectsToDisable.ForEach(obj => obj.SetActive(false));
buttonsToDisableDuringStep.ForEach(button => button.enabled = false);
buttonsToDisableOnStart.ForEach(button => button.enabled = false);
buttonsToEnableOnStart.ForEach(button => button.enabled = true);
}
private void PulseImage(GameObject image, bool b)
{
if (b)
{
var pulse = image.GetComponentsInChildren<ImagePulser>();
if (pulse == null || pulse.Length == 0)
{
var imgs = image.GetComponentsInChildren<Image>();
foreach (var img in imgs)
{
var pulser = img.gameObject.AddComponent<ImagePulser>();
pulser.speed = pulseSpeed; // Ustawienie prędkości pulsowania
pulser.pulseColor = pulseColor; // Ustawienie koloru pulsowania
pulser.scaleAmount = scaleAmount; // Ustawienie wartości skalowania
pulser.StartPulsing();
}
}
else
{
foreach (var p in pulse)
{
p.enabled = true;
p.speed = pulseSpeed; // Ustawienie prędkości pulsowania
p.pulseColor = pulseColor; // Ustawienie koloru pulsowania
p.scaleAmount = scaleAmount; // Ustawienie wartości skalowania
p.StartPulsing();
}
}
}
else
{
var pulses = image.GetComponentsInChildren<ImagePulser>();
if (pulses != null)
{
foreach (var p in pulses)
p.StopPulsing(); // Zatrzymanie pulsowania
}
}
}
private IEnumerator FadePanelIn(GameObject panel)
{
panel.SetActive(true);
float currentDuration = 0;
while (currentDuration < fadeDuration)
{
yield return new WaitForSecondsRealtime(Time.unscaledDeltaTime);
canvasGroup.alpha = currentDuration / fadeDuration;
currentDuration += Time.unscaledDeltaTime;
}
canvasGroup.alpha = 1f;
}
private IEnumerator FadePanelOut(GameObject panel)
{
float currentDuration = 0;
while (currentDuration < fadeDuration)
{
yield return new WaitForSecondsRealtime(Time.unscaledDeltaTime);
canvasGroup.alpha = (fadeDuration - currentDuration) / fadeDuration;
currentDuration += Time.unscaledDeltaTime;
}
canvasGroup.alpha = 0f;
panel.SetActive(false);
}
public void EvaluateStep()
{
StartCoroutine(EvaluateStepCoroutine());
}
private IEnumerator EvaluateStepCoroutine()
{
OnEvaluationStart?.Invoke();
yield return StartCoroutine(WaitForCompletionOfConditionsCoroutine());
OnCompletedStart?.Invoke();
if (delayAfterCompletingRequirements > 0)
yield return new WaitForSecondsRealtime(delayAfterCompletingRequirements);
CompleteStep();
}
private IEnumerator WaitForCompletionOfConditionsCoroutine()
{
if (ConditionsAreMet == null)
{
yield return null;
}
else
{
yield return new WaitUntil(() => ConditionsAreMet());
}
}
public void CompleteStep()
{
if (stepPanel)
StartCoroutine(FadePanelOut(stepPanel));
StartCoroutine(FinishStep());
}
private IEnumerator FinishStep()
{
if (additionalStepPanel)
{
OnAdditionalStepPanelEnabled?.Invoke();
//yield return new WaitForSecondsRealtime(0f);
if (additionalStepPanel)
StartCoroutine(FadePanelIn(additionalStepPanel));
if (additionalStepPanelDuration > 0)
yield return new WaitForSecondsRealtime(additionalStepPanelDuration);
if (additionalStepPanel)
StartCoroutine(FadePanelOut(additionalStepPanel));
}
//yield return new WaitForSecondsRealtime(1f);
OnEnableObjectsAtEnd?.Invoke();
SetObjectsStatesOnFinish();
onStepEnd?.Invoke(); // Wywołanie UnityEvent na końcu kroku
OnCompleted?.Invoke();
}
private void SetObjectsStatesOnFinish()
{
gameObjectsToEnable.ForEach(obj => obj.SetActive(true));
buttonsToDisableDuringStep.ForEach(button => button.enabled = true);
buttonsToDisableOnEnd.ForEach(button => button.enabled = false);
buttonsToEnableOnEnd.ForEach(button => button.enabled = true);
imagesToPulse.ForEach(image => PulseImage(image, false));
// Aktywowanie obiektów z listy objectsToEnableOnEnd
objectsToEnableOnEnd.ForEach(obj => obj.SetActive(true));
foreach (var g in gameObjectsToEnableOnEnd)
{
if (g) g.SetActive(true);
}
foreach (var g in gameObjectsToDisableOnEnd)
{
if (g) g.SetActive(false);
}
}
private void EnableObjectsAtEnd()
{
gameObjectsToEnable.ForEach(obj => obj.SetActive(true));
}
public void ForceStepFinished()
{
SkipStep();
onStepEnd?.Invoke(); // Wywołanie UnityEvent na końcu kroku
OnCompleted?.Invoke();
}
public void SkipStep()
{
gameObjectsToEnable.ForEach(obj => obj.SetActive(true));
gameObjectsToDisable.ForEach(obj => obj.SetActive(false));
SetObjectsStatesOnFinish();
if (stepPanel)
stepPanel.SetActive(false);
if (additionalStepPanel)
{
additionalStepPanel.SetActive(false);
}
StopAllCoroutines();
TimeController.Instance.SetTimeScale(1f);
}
}
}