using System.Collections; using System.Collections.Generic; using TriInspector; using UnityEngine; namespace R0bbie.Timeline { /// /// Trigger the next step on the switch after a delay if the player doesn't realize the desired action /// [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 reminderSwitches = new List(); [SerializeField] bool keepTriggeringSteps; // Private Variables int stepIndex; /// /// Init switch by Timeline /// /// 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; } /// /// Init switch by StepController /// /// 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 } } } }