Skip to content

Commit

Permalink
Teleport Mode for Teleport System (#726)
Browse files Browse the repository at this point in the history
* Add .vsconfig to gitignore

* Introduce teleport mode

* Clean up provider when switching back to default mode
  • Loading branch information
FejZa committed Dec 19, 2020
1 parent b706686 commit fcc4048
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 9 deletions.
17 changes: 15 additions & 2 deletions Editor/Profiles/MixedRealityTeleportSystemProfileInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,42 @@
using UnityEditor;
using XRTK.Definitions.TeleportSystem;
using XRTK.Services;
using XRTK.Services.Teleportation;

namespace XRTK.Editor.Profiles
{
[CustomEditor(typeof(MixedRealityTeleportSystemProfile))]
public class MixedRealityTeleportSystemProfileInspector : MixedRealityServiceProfileInspector
{
private SerializedProperty teleportMode;
private SerializedProperty teleportProvider;

protected override void OnEnable()
{
base.OnEnable();

teleportMode = serializedObject.FindProperty(nameof(teleportMode));
teleportProvider = serializedObject.FindProperty(nameof(teleportProvider));
}

public override void OnInspectorGUI()
{
RenderHeader("The teleport system profile defines default behaviour for the teleport system.");
RenderHeader("The teleport system profile defines behaviour for the teleport system.");

serializedObject.Update();
EditorGUI.BeginChangeCheck();

EditorGUILayout.PropertyField(teleportProvider);
EditorGUILayout.PropertyField(teleportMode);

var activeTeleportMode = (TeleportMode)teleportMode.intValue;
switch (activeTeleportMode)
{
case TeleportMode.Provider:
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(teleportProvider);
EditorGUI.indentLevel--;
break;
}

serializedObject.ApplyModifiedProperties();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,29 @@
using XRTK.Definitions.Utilities;
using XRTK.Interfaces.TeleportSystem;
using XRTK.Interfaces.TeleportSystem.Handlers;
using XRTK.Services.Teleportation;

namespace XRTK.Definitions.TeleportSystem
{
/// <summary>
/// Configuration profile for the <see cref="Services.Teleportation.MixedRealityTeleportSystem"/>.
/// Configuration profile for the <see cref="MixedRealityTeleportSystem"/>.
/// </summary>
[CreateAssetMenu(menuName = "Mixed Reality Toolkit/Teleport System Profile", fileName = "MixedRealityTeleportSystemProfile", order = (int)CreateProfileMenuItemIndices.Input)]
public class MixedRealityTeleportSystemProfile : BaseMixedRealityServiceProfile<IMixedRealityTeleportDataProvider>
{
[SerializeField]
[Tooltip("The teleportation mode to use.")]
private TeleportMode teleportMode = TeleportMode.Default;

/// <summary>
/// The teleportation mode to use.
/// </summary>
public TeleportMode TeleportMode
{
get => teleportMode;
internal set => teleportMode = value;
}

[SerializeField]
[Tooltip("The concrete teleport provider to use for teleportation.")]
[Implements(typeof(IMixedRealityTeleportProvider), TypeGrouping.ByNamespaceFlat)]
Expand Down
74 changes: 68 additions & 6 deletions Runtime/Services/TeleportSystem/MixedRealityTeleportSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,21 @@ public class MixedRealityTeleportSystem : BaseEventSystem, IMixedRealityTeleport
public MixedRealityTeleportSystem(MixedRealityTeleportSystemProfile profile)
: base(profile)
{
if (profile.TeleportProvider?.Type == null)
teleportMode = profile.TeleportMode;
if (teleportMode == TeleportMode.Provider)
{
throw new Exception($"The {nameof(MixedRealityTeleportSystemProfile)} is missing the required {teleportProvider}!");
}
if (profile.TeleportProvider?.Type == null)
{
throw new Exception($"The {nameof(MixedRealityTeleportSystemProfile)} is configured for " +
$"{TeleportMode.Provider} but is missing the required {teleportProvider}!");
}

teleportProvider = profile.TeleportProvider;
teleportProvider = profile.TeleportProvider;
}
}

private readonly SystemType teleportProvider;
private readonly TeleportMode teleportMode;

private TeleportEventData teleportEventData;
private bool isTeleporting = false;
Expand All @@ -54,7 +60,26 @@ public override void Initialize()
teleportEventData = new TeleportEventData(EventSystem.current);
}

CameraCache.Main.gameObject.EnsureComponent(teleportProvider.Type);
switch (teleportMode)
{
case TeleportMode.Default:
var component = CameraCache.Main.GetComponent<IMixedRealityTeleportProvider>() as Component;
if (!component.IsNull())
{
if (Application.isPlaying)
{
Object.Destroy(component);
}
else
{
Object.DestroyImmediate(component);
}
}
break;
case TeleportMode.Provider:
CameraCache.Main.gameObject.EnsureComponent(teleportProvider.Type);
break;
}
}

/// <inheritdoc />
Expand All @@ -65,7 +90,6 @@ public override void Disable()
if (!Application.isPlaying)
{
var component = CameraCache.Main.GetComponent<IMixedRealityTeleportProvider>() as Component;

if (!component.IsNull())
{
Object.DestroyImmediate(component);
Expand Down Expand Up @@ -151,6 +175,13 @@ public void RaiseTeleportStarted(IMixedRealityPointer pointer, IMixedRealityTele

// Pass handler
HandleEvent(teleportEventData, OnTeleportStartedHandler);

// In default teleportation mode we do not expect any provider
// to handle teleportation, instead we simply perform an instant teleport.
if (teleportMode == TeleportMode.Default)
{
PerformDefaultTeleport(teleportEventData);
}
}

private static readonly ExecuteEvents.EventFunction<IMixedRealityTeleportHandler> OnTeleportCompletedHandler =
Expand Down Expand Up @@ -198,5 +229,36 @@ public void RaiseTeleportCanceled(IMixedRealityPointer pointer, IMixedRealityTel
}

#endregion IMixedRealityTeleportSystem Implementation

private void PerformDefaultTeleport(TeleportEventData eventData)
{
var cameraTransform = MixedRealityToolkit.CameraSystem != null ?
MixedRealityToolkit.CameraSystem.MainCameraRig.CameraTransform :
CameraCache.Main.transform;
var teleportTransform = cameraTransform.parent;
Debug.Assert(teleportTransform != null,
$"{nameof(TeleportMode.Default)} requires that the camera be parented under another object!");

var targetRotation = Vector3.zero;
var targetPosition = eventData.Pointer.Result.EndPoint;
targetRotation.y = eventData.Pointer.PointerOrientation;

if (eventData.HotSpot != null)
{
targetPosition = eventData.HotSpot.Position;
if (eventData.HotSpot.OverrideTargetOrientation)
{
targetRotation.y = eventData.HotSpot.TargetOrientation;
}
}

var height = targetPosition.y;
targetPosition -= cameraTransform.position - teleportTransform.position;
targetPosition.y = height;
teleportTransform.position = targetPosition;
teleportTransform.RotateAround(cameraTransform.position, Vector3.up, targetRotation.y - cameraTransform.eulerAngles.y);

RaiseTeleportComplete(eventData.Pointer, eventData.HotSpot);
}
}
}
23 changes: 23 additions & 0 deletions Runtime/Services/TeleportSystem/TeleportMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) XRTK. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

namespace XRTK.Services.Teleportation
{
/// <summary>
/// Supported teleport modes in the <see cref="MixedRealityTeleportSystem"/> implementation.
/// </summary>
public enum TeleportMode
{
/// <summary>
/// <see cref="Default"/> will instantly teleport the player
/// to the selected location and does not require any additional setup.
/// </summary>
Default = 0,
/// <summary>
/// <see cref="Provider"/> mode lets <see cref="Interfaces.TeleportSystem.Handlers.IMixedRealityTeleportProvider"/>'s
/// handle teleportation. This mode requires <see cref="Definitions.TeleportSystem.MixedRealityTeleportSystemProfile.TeleportProvider"/>
/// to be configured with a concrete <see cref="Interfaces.TeleportSystem.Handlers.IMixedRealityTeleportProvider"/> implementation.
/// </summary>
Provider
}
}
11 changes: 11 additions & 0 deletions Runtime/Services/TeleportSystem/TeleportMode.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit fcc4048

Please sign in to comment.