step-timeline/Scripts/StepSwitches/ReminderStepSwitch.cs

171 lines
5.8 KiB
C#

using System.Collections;
using System.Collections.Generic;
using TriInspector;
using UnityEngine;
namespace R0bbie.Timeline
{
/// <summary>
/// Trigger the next step on the switch after a delay if the player doesn't realize the desired action
/// </summary>
[AddComponentMenu("Timeline/StepSwitches/Reminder (Step Switch)")]
public class ReminderStepSwitch : StepSwitch
{
// Assign the step, and how long should the timeline wait before trigger the next step
[System.Serializable]
struct ReminderSwitch
{
[SerializeField] public Step stepOption;
[SerializeField] public float secondsToTrigger;
}
// Exposed Variables
[Title("Switch Options")]
[SerializeField] List<ReminderSwitch> reminderSwitches = new List<ReminderSwitch>();
[SerializeField] bool keepTriggeringSteps;
// Private Variables
int stepIndex;
/// <summary>
/// Init switch by Timeline
/// </summary>
/// <param name="_stepTimeline"></param>
public override void Init(StepTimeline _stepTimeline)
{
// Setup necessary refs such as parent timeline
attachedStepTimeline = _stepTimeline;
// Inactive by default
activeMode = Mode.Inactive;
// Init all step switch options
foreach (ReminderSwitch reminderSwitch in reminderSwitches)
{
reminderSwitch.stepOption.Init(attachedStepTimeline, this);
}
init = true;
}
/// <summary>
/// Init switch by StepController
/// </summary>
/// <param name="_controller"></param>
public override void Init(StepController _controller)
{
// Setup necessary refs such as parent controller
attachedController = _controller;
// Inactive by default
activeMode = Mode.Inactive;
// Init all step switch options
foreach (ReminderSwitch reminderSwitch in reminderSwitches)
{
reminderSwitch.stepOption.Init(attachedController, this);
}
init = true;
}
public override void Play()
{
Debug.Log(name + " - Started");
isActive = true;
waitingForExternalTrigger = true;
activeMode = Mode.WaitingForEvent;
// Trigger the first step
reminderSwitches[stepIndex].stepOption.Play();
// Start the coroutine in case the player doesn't press the button before the first reminder
StartCoroutine(TriggerReminder(reminderSwitches[stepIndex].secondsToTrigger));
}
IEnumerator TriggerReminder(float delayTime)
{
yield return new WaitForSeconds(delayTime);
// If by the time this part is triggered, the step has skipped through external Step Controller then avoid continue
if (wasSkipped || !isActive)
yield break;
// If the step haven't been completed yet, skip it and trigger the next reminder on the list
if (!wasCompleted)
{
reminderSwitches[stepIndex].stepOption.Skip();
}
}
public override void Continue()
{
// If the active step was skipped because of the delay, trigger the next one on the switch
if (reminderSwitches[stepIndex].stepOption.wasSkipped && !reminderSwitches[stepIndex].stepOption.wasCompleted)
{
stepIndex++;
// If we want to loop again through the steps
if (keepTriggeringSteps)
{
// Reset the index to 0
if (stepIndex >= reminderSwitches.Count)
stepIndex = 0;
}
// Play the next one if it's inside the length of the list
if (stepIndex < reminderSwitches.Count)
{
// Trigger the next step
reminderSwitches[stepIndex].stepOption.Play();
// If the actual step is not the last one, or we want to loop through all the steps, start the coroutine to trigger the reminder
if (stepIndex < reminderSwitches.Count - 1 || keepTriggeringSteps)
StartCoroutine(TriggerReminder(reminderSwitches[stepIndex].secondsToTrigger));
}
}
else // Triggered through the timeline trigger
{
// If the step switch was already completed and is called through the same timeline trigger twice, only register one
if (wasCompleted)
return;
Debug.Log(name + " - Completed");
// Complete the switch
isActive = false;
activeMode = Mode.Inactive;
wasCompleted = true;
// Tell the timeline to play the next step (or step group, or controller)
if (parentStepGroup)
{
parentStepGroup.Continue();
}
else
{
if (attachedStepTimeline != null)
attachedStepTimeline.PlayNextStep();
else
attachedController.StepCompleted();
}
// TODO Complete the current switch and steps inside
}
}
}
}