mirror of
https://udrimavric.com/MAVRIC/Stratasys-450mc-VR.git
synced 2025-01-23 15:48:33 -05:00
289 lines
8.6 KiB
C#
289 lines
8.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.XR.Interaction.Toolkit;
|
|
|
|
namespace UnityEngine.XR.Content.Walkthrough
|
|
{
|
|
/// <summary>
|
|
/// Contains information needed to process one step of a walkthrough.
|
|
/// </summary>
|
|
public class WalkthroughStep : MonoBehaviour
|
|
{
|
|
/// Local method use only -- created here to reduce garbage collection. Collections must be cleared before use
|
|
static readonly List<WalkthroughTrigger> s_TriggersToRemove = new List<WalkthroughTrigger>();
|
|
|
|
[SerializeField]
|
|
[Tooltip("Camera target to reposition user.")]
|
|
GameObject m_CameraTarget;
|
|
|
|
[SerializeField]
|
|
[Tooltip("The Teleportation Provider used to reposition the user. Usually a component on the XR Origin.")]
|
|
TeleportationProvider m_TeleportationProvider;
|
|
|
|
[SerializeField]
|
|
[Tooltip("Optional audio source for voiceover")]
|
|
AudioSource m_AudioSource;
|
|
|
|
[SerializeField]
|
|
[Tooltip("Objects to enable when this step is active.")]
|
|
List<GameObject> m_Visuals = new List<GameObject>();
|
|
|
|
#pragma warning disable 649
|
|
[SerializeField]
|
|
[Tooltip("Actions to call when the step starts.")]
|
|
UnityEvent m_OnStepBegin;
|
|
|
|
[SerializeField]
|
|
[Tooltip("Actions to call when the step completes.")]
|
|
UnityEvent m_OnStepComplete;
|
|
|
|
[SerializeField]
|
|
[Tooltip("The purpose of this step.")]
|
|
string m_Description;
|
|
#pragma warning restore 649
|
|
|
|
[SerializeField]
|
|
[Tooltip("If true, this step cannot be skipped until completed at least once.")]
|
|
bool m_BlockUntilComplete;
|
|
|
|
[SerializeField]
|
|
[Tooltip("If true, this step will automatically progress when complete - unless explicitly skipped to.")]
|
|
bool m_AutoProgressOnComplete = true;
|
|
|
|
bool m_Started;
|
|
bool m_AutoProgressEnabled = true;
|
|
bool m_StepInvoked;
|
|
|
|
Action<bool> m_OnComplete;
|
|
GameObject m_Waypoint;
|
|
GameObject m_Link;
|
|
|
|
List<WalkthroughTrigger> m_Triggers = new List<WalkthroughTrigger>();
|
|
List<WalkthroughTrigger> m_RemainingTriggers = new List<WalkthroughTrigger>();
|
|
|
|
/// <summary>
|
|
/// The purpose of this step. Appends a (Complete) if complete and normally has triggers.
|
|
/// </summary>
|
|
public string description => $"{m_Description}{(completed && m_Triggers.Count > 0 ? " (Complete)" : "") }";
|
|
|
|
|
|
public GameObject waypoint
|
|
{
|
|
get => m_Waypoint;
|
|
set => m_Waypoint = value;
|
|
}
|
|
|
|
public GameObject link
|
|
{
|
|
get => m_Link;
|
|
set => m_Link = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ensures the step visuals are hidden until active and that all triggers are accounted for
|
|
/// </summary>
|
|
public void Initialize()
|
|
{
|
|
if (!m_Started)
|
|
SetVisualsState(false);
|
|
|
|
GetComponents(m_Triggers);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if this step does not currently have any triggers remaining to fire
|
|
/// </summary>
|
|
public bool canProgress => (!m_BlockUntilComplete || (m_RemainingTriggers.Count == 0));
|
|
|
|
/// <summary>
|
|
/// Returns true if this step does not block, or has been completed at least once.
|
|
/// </summary>
|
|
public bool canSkip => (!m_BlockUntilComplete || completed);
|
|
|
|
/// <summary>
|
|
/// True if this step's triggers have been activated at least once
|
|
/// </summary>
|
|
public bool completed { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Makes this step and its triggers the active focus of a walkthrough
|
|
/// </summary>
|
|
/// <param name="onComplete">Callback to fire when this step's triggers are complete</param>
|
|
/// <param name="allowAutoProgress">If this step is allow to auto-progress during this activation</param>
|
|
public void StartStep(Action<bool> onComplete, bool allowAutoProgress = true)
|
|
{
|
|
if (m_Started)
|
|
return;
|
|
|
|
// Autoprogression is enabled only if the step AND walkthrough allow it
|
|
m_AutoProgressEnabled = allowAutoProgress && m_AutoProgressOnComplete;
|
|
|
|
SetVisualsState(true);
|
|
SetAudioSource(true);
|
|
if (m_Waypoint != null)
|
|
{
|
|
m_Waypoint.SetActive(false);
|
|
}
|
|
|
|
if (m_CameraTarget != null && m_TeleportationProvider != null)
|
|
{
|
|
SetCameraPosition();
|
|
}
|
|
|
|
m_OnComplete = onComplete;
|
|
|
|
m_Started = true;
|
|
|
|
if (m_Triggers.Count == 0 && m_AutoProgressEnabled)
|
|
{
|
|
CompleteStep();
|
|
return;
|
|
}
|
|
|
|
foreach (var currentTrigger in m_Triggers)
|
|
{
|
|
if (currentTrigger.ResetTrigger())
|
|
m_RemainingTriggers.Add(currentTrigger);
|
|
}
|
|
|
|
if (m_RemainingTriggers.Count == 0)
|
|
{
|
|
CompleteStep();
|
|
return;
|
|
}
|
|
|
|
if (m_RemainingTriggers.Count > 0)
|
|
m_AutoProgressEnabled = m_AutoProgressOnComplete;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ends this step being the focus of the current walkthrough
|
|
/// </summary>
|
|
public void CancelStep()
|
|
{
|
|
SetVisualsState(false);
|
|
SetAudioSource(false);
|
|
if (m_Waypoint != null)
|
|
{
|
|
m_Waypoint.SetActive(true);
|
|
}
|
|
|
|
if (!m_Started)
|
|
return;
|
|
|
|
m_OnComplete = null;
|
|
m_Started = false;
|
|
|
|
m_RemainingTriggers.Clear();
|
|
}
|
|
|
|
void CompleteStep()
|
|
{
|
|
if (!m_Started)
|
|
return;
|
|
|
|
completed = true;
|
|
|
|
m_OnComplete?.Invoke(m_AutoProgressEnabled);
|
|
m_OnComplete = null;
|
|
m_Started = false;
|
|
|
|
// We disable visuals if the the next step is being activated
|
|
if (m_AutoProgressEnabled)
|
|
{
|
|
SetVisualsState(false);
|
|
SetAudioSource(false);
|
|
if (m_Waypoint != null)
|
|
{
|
|
m_Waypoint.SetActive(true);
|
|
}
|
|
}
|
|
|
|
m_RemainingTriggers.Clear();
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
// If this step is running, check remaining triggers. Any triggers that are now met get removed.
|
|
// If there are no triggers left, then the step is complete.
|
|
if (!m_Started)
|
|
return;
|
|
|
|
if (m_RemainingTriggers.Count == 0)
|
|
return;
|
|
|
|
s_TriggersToRemove.Clear();
|
|
foreach (var currentTrigger in m_RemainingTriggers)
|
|
{
|
|
if (currentTrigger.Check())
|
|
s_TriggersToRemove.Add(currentTrigger);
|
|
}
|
|
|
|
foreach (var toRemove in s_TriggersToRemove)
|
|
{
|
|
m_RemainingTriggers.Remove(toRemove);
|
|
}
|
|
s_TriggersToRemove.Clear();
|
|
|
|
if (m_RemainingTriggers.Count == 0)
|
|
{
|
|
CompleteStep();
|
|
return;
|
|
}
|
|
}
|
|
|
|
void SetVisualsState(bool enabled)
|
|
{
|
|
if (m_Visuals != null)
|
|
{
|
|
foreach (var currentVisual in m_Visuals)
|
|
{
|
|
if (currentVisual != null)
|
|
currentVisual.SetActive(enabled);
|
|
}
|
|
}
|
|
|
|
if (m_StepInvoked == enabled)
|
|
return;
|
|
|
|
m_StepInvoked = enabled;
|
|
|
|
if (enabled && m_OnStepBegin != null)
|
|
m_OnStepBegin.Invoke();
|
|
|
|
if (!enabled && m_OnStepComplete != null)
|
|
m_OnStepComplete.Invoke();
|
|
}
|
|
|
|
void SetAudioSource(bool enabled)
|
|
{
|
|
if (m_AudioSource != null)
|
|
{
|
|
if (enabled)
|
|
{
|
|
m_AudioSource.Play();
|
|
}
|
|
else
|
|
{
|
|
m_AudioSource.Stop();
|
|
}
|
|
}
|
|
}
|
|
|
|
void SetCameraPosition()
|
|
{
|
|
TeleportRequest request = new TeleportRequest()
|
|
{
|
|
requestTime = Time.time,
|
|
matchOrientation = MatchOrientation.TargetUpAndForward,
|
|
|
|
destinationPosition = m_CameraTarget.transform.position,
|
|
destinationRotation = m_CameraTarget.transform.rotation
|
|
};
|
|
|
|
m_TeleportationProvider.QueueTeleportRequest(request);
|
|
}
|
|
}
|
|
}
|