Skip to content

Commit

Permalink
feat: new teleport property implementation (#91)
Browse files Browse the repository at this point in the history
fix: interaction assets were relocated
  • Loading branch information
Gustavo Quiroz committed Mar 22, 2021
1 parent 17492a5 commit 9736451
Show file tree
Hide file tree
Showing 30 changed files with 460 additions and 1,093 deletions.
106 changes: 106 additions & 0 deletions Editor/Properties/TeleportationPropertyEditor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using System;
using UnityEditor;
using UnityEngine;
using Innoactive.Creator.Core.Properties;
using UnityEngine.UIElements;
using UnityEngine.XR.Interaction.Toolkit;

namespace Innoactive.CreatorEditor.XRInteraction
{
/// <summary>
/// Custom inspector for <see cref="TeleportationProperty"/>, adding a button to automatically configure <see cref="Innoactive.Creator.XRInteraction.TeleportationAnchor"/>s.
/// </summary>
[CustomEditor(typeof(TeleportationProperty)), CanEditMultipleObjects]
internal class TeleportationPropertyEditor : Editor
{
private const string AnchorPrefabName = "Anchor";
private const string ReticlePrefab = "TeleportReticle";
private const string TeleportLayerName = "XR Teleport";
private LayerMask teleportLayer;
private bool isSetup;

private void OnEnable()
{
TeleportationProperty teleportationProperty = target as TeleportationProperty;
TeleportationAnchor teleportAnchor = teleportationProperty.GetComponent<TeleportationAnchor>();

if (teleportationProperty.transform.childCount != 0 && teleportAnchor.teleportAnchorTransform.name == AnchorPrefabName)
{
isSetup = true;
}
}

public override void OnInspectorGUI()
{
base.OnInspectorGUI();
EditorGUILayout.Space();

ShowConfigurationButton();
}

private void ShowConfigurationButton()
{
if (isSetup == false && GUILayout.Button("Set Default Teleportation Anchor"))
{
foreach (UnityEngine.Object targetObject in serializedObject.targetObjects)
{
if (targetObject is TeleportationProperty teleportationAnchor)
{
ConfigureDefaultTeleportationAnchor(teleportationAnchor);
}
}
}
}

private void ConfigureDefaultTeleportationAnchor(TeleportationProperty teleportationAnchor)
{
teleportLayer = LayerMask.NameToLayer(TeleportLayerName);

try
{
GameObject anchorPrefab = CreateVisualEffect(teleportationAnchor);
ConfigureTeleportationAnchor(teleportationAnchor, anchorPrefab.transform);
ConfigureCollider(teleportationAnchor);

isSetup = true;
}
catch (Exception e)
{
Debug.LogError($"There was an exception of type '{e.GetType()}' when trying to setup {name} as default Teleportation Anchor\n{e.Message}", teleportationAnchor.gameObject);
}
}

private GameObject CreateVisualEffect(TeleportationProperty teleportationAnchor)
{
Transform anchorTransform = teleportationAnchor.transform;

GameObject anchorPrefab = Instantiate(Resources.Load<GameObject>(AnchorPrefabName));
anchorPrefab.name = anchorPrefab.name.Remove(AnchorPrefabName.Length);

anchorPrefab.transform.SetPositionAndRotation((anchorTransform.position + (Vector3.up * 0.01f)), anchorTransform.rotation);
anchorPrefab.transform.SetParent(anchorTransform);

teleportationAnchor.gameObject.layer = teleportLayer;

return anchorPrefab;
}

private void ConfigureTeleportationAnchor(TeleportationProperty teleportationAnchor, Transform prefabTransform)
{
TeleportationAnchor teleportAnchor = teleportationAnchor.GetComponent<TeleportationAnchor>();

teleportAnchor.teleportAnchorTransform = prefabTransform;
teleportAnchor.interactionLayerMask = 1 << teleportLayer;
teleportAnchor.customReticle = Resources.Load<GameObject>(ReticlePrefab);
teleportAnchor.matchOrientation = MatchOrientation.TargetUpAndForward;
}

private void ConfigureCollider(TeleportationProperty teleportationAnchor)
{
BoxCollider propertyCollider = teleportationAnchor.GetComponent<BoxCollider>();

propertyCollider.center = new Vector3(0f, 0.02f, 0f);
propertyCollider.size = new Vector3(1f, 0.01f, 1f);
}
}
}
3 changes: 3 additions & 0 deletions Editor/Properties/TeleportationPropertyEditor.cs.meta

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

111 changes: 111 additions & 0 deletions Runtime/Properties/TeleportationProperty.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using System;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
using Innoactive.Creator.BasicInteraction.Properties;

namespace Innoactive.Creator.Core.Properties
{
/// <summary>
/// XR implementation of <see cref="ITeleportationProperty"/>.
/// </summary>
/// <remarks>
/// This implementation is based on 'TeleportationAnchor'.
/// </remarks>
[RequireComponent(typeof(TeleportationAnchor), typeof(BoxCollider))]
public class TeleportationProperty : LockableProperty, ITeleportationProperty
{
/// <inheritdoc />
public event EventHandler<EventArgs> Teleported;

/// <inheritdoc />
public bool WasUsedToTeleport => wasUsedToTeleport;

private TeleportationAnchor teleportationInteractable;
private Renderer[] renderers;
private bool wasUsedToTeleport;

protected void Awake()
{
renderers = GetComponentsInChildren<Renderer>();
teleportationInteractable = GetComponent<TeleportationAnchor>();
}

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

switch (teleportationInteractable.teleportTrigger)
{
case BaseTeleportationInteractable.TeleportTrigger.OnActivated:
teleportationInteractable.activated.AddListener(args =>
{
EmitTeleported();
});
break;
case BaseTeleportationInteractable.TeleportTrigger.OnDeactivated:
teleportationInteractable.deactivated.AddListener(args =>
{
EmitTeleported();
});
break;
case BaseTeleportationInteractable.TeleportTrigger.OnSelectEntered:
teleportationInteractable.selectEntered.AddListener(args =>
{
EmitTeleported();
});
break;
case BaseTeleportationInteractable.TeleportTrigger.OnSelectExited:
teleportationInteractable.selectExited.AddListener(args =>
{
EmitTeleported();
});
break;
}
}

/// <inheritdoc />
public void Initialize()
{
wasUsedToTeleport = false;
}

/// <inheritdoc />
public void FastForwardTeleport()
{
TeleportRequest teleportRequest = new TeleportRequest
{
requestTime = Time.time,
matchOrientation = teleportationInteractable.matchOrientation,
destinationPosition = teleportationInteractable.teleportAnchorTransform.position,
destinationRotation = teleportationInteractable.teleportAnchorTransform.rotation
};

teleportationInteractable.teleportationProvider.QueueTeleportRequest(teleportRequest);
}

/// <inheritdoc />
protected override void InternalSetLocked(bool lockState)
{
foreach (Collider collider in teleportationInteractable.colliders)
{
collider.enabled = !lockState;
}

teleportationInteractable.enabled = !lockState;

if (renderers != null)
{
foreach (Renderer anchorRenderer in renderers)
{
anchorRenderer.enabled = !lockState;
}
}
}

protected void EmitTeleported()
{
wasUsedToTeleport = true;
Teleported?.Invoke(this, EventArgs.Empty);
}
}
}
3 changes: 3 additions & 0 deletions Runtime/Properties/TeleportationProperty.cs.meta

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

8 changes: 0 additions & 8 deletions Runtime/Static Assets.meta

This file was deleted.

8 changes: 0 additions & 8 deletions Runtime/Static Assets/Materials.meta

This file was deleted.

77 changes: 0 additions & 77 deletions Runtime/Static Assets/Materials/ControllerMaterial.mat

This file was deleted.

8 changes: 0 additions & 8 deletions Runtime/Static Assets/Materials/ControllerMaterial.mat.meta

This file was deleted.

Loading

0 comments on commit 9736451

Please sign in to comment.