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

200 lines
6.2 KiB
C#

using Sirenix.OdinInspector;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace Beyond
{
public class TutorialController : MonoBehaviour
{
public bool played = false;
public GameObject stepPanel;
public List<BaseStepController> steps;
public CanvasGroup tutorialButtonsCanva;
private float fadeDuration = 0.4f, frameDuration = 0.02f;
public List<GameObject> tutorialButtons;
//colliders and stuff
[SerializeField]
private List<GameObject> objectsToEnableOnlyDuringTutorial;
private BaseStepController currentStep;
public int skipSteps = 0;
public float delayToStart = 4f;
// Start is called before the first frame update
public UnityEvent OnTutorialEnded;
private bool finished = false;
private void Start()
{
if (tutorialButtons != null )
tutorialButtons.ForEach(button => button.SetActive(false));
if (tutorialButtonsCanva != null)
{
tutorialButtonsCanva.interactable = false;
tutorialButtonsCanva.blocksRaycasts = false;
}
}
[Button]
public void StartTutorial()
{
StartCoroutine(StartTutorialCoroutine());
}
private IEnumerator StartTutorialCoroutine()
{
//could check based on something different
yield return new WaitForEndOfFrame();
if (played)
{
SkipTutorial();
yield break;
}
played = true;
if (objectsToEnableOnlyDuringTutorial.Count > 0)
{
objectsToEnableOnlyDuringTutorial.ForEach(obj => obj.SetActive(true));
}
yield return new WaitForSecondsRealtime(delayToStart);
EnableTutorialButtons();
// tutorialButtons.ForEach(button => button.SetActive(true));
for (int i = 0; i < skipSteps; i++)
{
steps[i].ForceStepFinished();
}
for (int i = skipSteps; i < steps.Count; i++)
{
if (i != steps.Count - 1)
{
steps[i].OnCompleted += steps[i + 1].StartStep; //this does not require an additional variable
}
else
{
steps[i].OnCompleted += () =>
{
FinishTutorial();
};
}
int locali = i;
steps[i].OnStarted += () => //this does
{
Debug.Log("TutorialController.Step.OnStarted "+locali);
currentStep = steps[locali];
};
}
steps[skipSteps].StartStep();
}
[Button]
public void SkipTutorial()
{
if (!currentStep)
{
return;
}
int id = steps.FindIndex(step => step == currentStep);
for (int i = id; i < steps.Count; i++)
{
steps[i].ForceStepFinished();
}
FinishTutorial();
}
public void EnableTutorialButtons()
{
StartCoroutine(FadeInTutorialButtons());
}
private IEnumerator FadeInTutorialButtons()
{
tutorialButtons.ForEach(button => button.SetActive(true));
float currentDuration = 0;
while (currentDuration < fadeDuration)
{
yield return new WaitForSecondsRealtime(Time.unscaledDeltaTime);
tutorialButtonsCanva.alpha = currentDuration / fadeDuration;
currentDuration += Time.unscaledDeltaTime;
// texts.ForEach(text => text.alpha = currentDuration / fadeDuration);
}
tutorialButtonsCanva.alpha = 1f;
tutorialButtonsCanva.interactable = true;
tutorialButtonsCanva.blocksRaycasts = true;
}
private void FinishTutorial()
{
if (finished)
{
return;
}
finished = true;
played = true;
StopAllCoroutines();
DisableTutorialButtons();
objectsToEnableOnlyDuringTutorial.ForEach(obj => obj.SetActive(false));
OnTutorialEnded?.Invoke();
}
public void DisableTutorialButtons()
{
StartCoroutine(FadeOutTutorialButtons());
// tutorialButtons.ForEach(button => button.SetActive(false));
}
private IEnumerator FadeOutTutorialButtons()
{
float currentDuration = 0;
while (currentDuration < fadeDuration)
{
yield return new WaitForSecondsRealtime(Time.unscaledDeltaTime);
tutorialButtonsCanva.alpha = (fadeDuration - currentDuration) / fadeDuration;
currentDuration += Time.unscaledDeltaTime;
// texts.ForEach(text => text.alpha = (fadeDuration - currentDuration) / fadeDuration);
}
tutorialButtonsCanva.alpha = 0f;
tutorialButtonsCanva.interactable = false;
tutorialButtonsCanva.blocksRaycasts = false;
tutorialButtons.ForEach(button => button.SetActive(false));
}
[Button]
public void SkipTutorialStep()
{
try {
Debug.Log("skipped");
currentStep.ForceStepFinished();
}
catch (Exception e)
{
Debug.LogError("Exception in TutorialController.SkupTutorialStep, gameObject: "+gameObject.name+" "+e.ToString());
}
}
public int GetCurrentStepIndex()
{
return steps.FindIndex(item => item == currentStep);
}
public void SkipTutorialStepsTo(int stepIndex)
{
int index = GetCurrentStepIndex();
while (index != stepIndex)
{
steps[index].ForceStepFinished();
index++;
}
}
}
}