171 lines
5.8 KiB
C#
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
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
}
|