197 lines
7.0 KiB
C#
197 lines
7.0 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
using TriInspector;
|
|
|
|
namespace R0bbie.Timeline
|
|
{
|
|
/// <summary>
|
|
/// Toggle between step option based on what external TimelineTrigger is received
|
|
/// </summary>
|
|
[AddComponentMenu("Timeline/StepSwitches/External Trigger (Step Switch)")]
|
|
public class ExternalTriggerStepSwitch : StepSwitch
|
|
{
|
|
enum IfStepAlreadyPlayedAction
|
|
{
|
|
PlayAgain,
|
|
DoNothing,
|
|
SkipSwitch
|
|
}
|
|
|
|
[System.Serializable]
|
|
struct TriggerSwitch
|
|
{
|
|
[SerializeField] public TimelineTrigger trigger;
|
|
[SerializeField] public Step stepOption;
|
|
[SerializeField] public IfStepAlreadyPlayedAction ifStepPrevPlayed;
|
|
}
|
|
|
|
[Title("Switch Options")]
|
|
[SerializeField] List<TriggerSwitch> triggerSwitches = new List<TriggerSwitch>();
|
|
|
|
[Title("Adjust Trigger Behaviour")]
|
|
[SerializeField, Tooltip("If a trigger attached to this switch was triggered previously, set the corresponding step option as active immediately, rather than waiting for a live trigger.")] private bool switchImmediatelyIfPrevTriggered;
|
|
|
|
[ShowIf(nameof(switchImmediatelyIfPrevTriggered))]
|
|
[SerializeField, Tooltip("If no triggers attached to this switch have been triggered previously, just skip this switch altogether.")] private bool skipImmediatelyIfNotPrevTriggered;
|
|
|
|
|
|
/// <summary>
|
|
/// Initialise the StepSwitch by Timeline
|
|
/// </summary>
|
|
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 (TriggerSwitch triggerSwitch in triggerSwitches)
|
|
{
|
|
triggerSwitch.stepOption.Init(attachedStepTimeline, this);
|
|
}
|
|
|
|
init = true;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Initialise the StepSwitch by StepController
|
|
/// </summary>
|
|
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 (TriggerSwitch triggerSwitch in triggerSwitches)
|
|
{
|
|
triggerSwitch.stepOption.Init(attachedController, this);
|
|
}
|
|
|
|
init = true;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Play this StepSwitch, in turn playing whichever step its conditions point to
|
|
/// </summary>
|
|
public override void Play()
|
|
{
|
|
Debug.Log(name + " - Started");
|
|
|
|
isActive = true;
|
|
|
|
activeMode = Mode.WaitingForEvent;
|
|
|
|
// Option to play a child option immediately if the paired trigger was triggered previously
|
|
if (switchImmediatelyIfPrevTriggered)
|
|
{
|
|
// Loop through all triggers and check if any were triggered before
|
|
foreach (TriggerSwitch triggerSwitch in triggerSwitches)
|
|
{
|
|
// If so we've got our step option to play
|
|
if (triggerSwitch.trigger.triggered)
|
|
{
|
|
activeStepOption = triggerSwitch.stepOption;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If no triggers were previously triggered, option to just skip over this switch altogether, and inform the timeline to play the next step
|
|
if (skipImmediatelyIfNotPrevTriggered)
|
|
{
|
|
SkipSwitch();
|
|
return;
|
|
}
|
|
|
|
// If active step is now setup, play it!
|
|
if (activeStepOption)
|
|
{
|
|
activeMode = Mode.PlayingChildStep;
|
|
activeStepOption.Play();
|
|
}
|
|
}
|
|
|
|
// Listen for triggers..
|
|
foreach (TriggerSwitch triggerSwitch in triggerSwitches)
|
|
{
|
|
triggerSwitch.trigger.onTrigger.AddListener(TriggerContinue);
|
|
}
|
|
|
|
// If we've got here then we want to wait for an external trigger to send instruction to this switch..
|
|
}
|
|
|
|
|
|
void SkipSwitch()
|
|
{
|
|
activeMode = Mode.Inactive;
|
|
Continue();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Trigger command received from external TimelineTrigger
|
|
/// </summary>
|
|
public override void TriggerContinue(TimelineTrigger _trigger)
|
|
{
|
|
if (!isActive || activeMode != Mode.WaitingForEvent)
|
|
return;
|
|
|
|
// Remove listeners
|
|
foreach (TriggerSwitch triggerSwitch in triggerSwitches)
|
|
{
|
|
triggerSwitch.trigger.onTrigger.RemoveListener(TriggerContinue);
|
|
}
|
|
|
|
// Find this trigger in the list, and set the corresponding child step as active
|
|
int switchIndexInList = triggerSwitches.FindIndex(x => x.trigger == _trigger);
|
|
|
|
// If this trigger wasn't found in the list, we can't play any child step. Don't do anything
|
|
if (switchIndexInList == -1)
|
|
{
|
|
Debug.LogWarning("ExternalTriggerStepSwitch received a command from a trigger not in the switch list, can't do anything.");
|
|
return;
|
|
}
|
|
|
|
// With the trigger found in the list, set active step option to corresponding step
|
|
activeStepOption = triggerSwitches[switchIndexInList].stepOption;
|
|
|
|
// Check if step was previously played, and if we want to execute any custom action here if so
|
|
if (activeStepOption.wasCompleted)
|
|
{
|
|
if (triggerSwitches[switchIndexInList].ifStepPrevPlayed == IfStepAlreadyPlayedAction.DoNothing)
|
|
{
|
|
activeStepOption = null;
|
|
return;
|
|
}
|
|
else if (triggerSwitches[switchIndexInList].ifStepPrevPlayed == IfStepAlreadyPlayedAction.SkipSwitch)
|
|
{
|
|
SkipSwitch();
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Target step option to play is now definitely set..
|
|
|
|
// Play the selected option, unless it's null (in which case just play next step in timeline)
|
|
if (activeStepOption)
|
|
{
|
|
activeMode = Mode.PlayingChildStep;
|
|
activeStepOption.Play();
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("The option selected by the step switch was null, so just proceeding to next step in timeline.");
|
|
SkipSwitch();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
} |