This repository was archived by the owner on Dec 5, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathTeleportationHandler.cs
115 lines (100 loc) · 3.96 KB
/
TeleportationHandler.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using Assets.Gamelogic.Global;
using Assets.Gamelogic.Utils;
using Improbable;
using Improbable.General;
using Improbable.Player;
using Improbable.Unity.Common.Core.Math;
using Improbable.Unity.Visualizer;
using UnityEngine;
namespace Assets.Gamelogic.Player
{
public class TeleportationHandler : MonoBehaviour
{
[Require]
private Position.Writer PositionWriter;
[Require]
private VRPeripheralOffsets.Reader VROffsetsReader;
private GameObject teleportTargeter;
private GameObject targetingController;
private bool teleportTargetingActive;
[SerializeField]
private GameObject TeleportTargeterModel;
[SerializeField]
private SteamVR_TrackedController LeftController;
[SerializeField]
private SteamVR_TrackedController RightController;
void OnEnable()
{
LeftController.PadClicked += ActivateTeleportTargeter;
RightController.PadClicked += ActivateTeleportTargeter;
LeftController.PadUnclicked += AttemptToTeleport;
RightController.PadUnclicked += AttemptToTeleport;
}
private void ActivateTeleportTargeter(object sender, ClickedEventArgs e)
{
if (!teleportTargetingActive) // other pad already teleport targeting
{
CreateTeleportTargeterInstance();
teleportTargetingActive = true;
}
SetTargetingController(e.controllerIndex);
}
private void SetTargetingController(uint controllerIndex)
{
if (controllerIndex == LeftController.controllerIndex)
{
targetingController = LeftController.gameObject;
}
else
{
targetingController = RightController.gameObject;
}
}
private void AttemptToTeleport(object sender, ClickedEventArgs e)
{
if (!teleportTargetingActive)
{
return;
}
// The player position represents the position of the Vive play area. We need to take into account
// the position of the head relative to the play area so that the teleport feels intuitive.
var headGroundOffset = VROffsetsReader.Data.head.position.ToUnityVector();
headGroundOffset.y = 0;
var targetTeleportPosition = teleportTargeter.transform.position - headGroundOffset;
DeactivateTeleportTargeting();
UpdatePlayerPosition(targetTeleportPosition);
}
private void DeactivateTeleportTargeting()
{
teleportTargetingActive = false;
Destroy(teleportTargeter);
}
private void UpdatePlayerPosition(Vector3 targetTeleportPosition)
{
transform.position = targetTeleportPosition;
PositionWriter.Send(new Position.Update().SetCoords(targetTeleportPosition.ToCoordinates()));
}
private void CreateTeleportTargeterInstance()
{
teleportTargeter = Instantiate(TeleportTargeterModel);
teleportTargeter.transform.localScale = new Vector3(SimulationSettings.TeleportTargeterDiameter, 1f, SimulationSettings.TeleportTargeterDiameter);
}
private void Update()
{
if (teleportTargetingActive)
{
UpdateTeleportTargetPosition();
}
}
private void UpdateTeleportTargetPosition()
{
Ray controllerRay = new Ray(targetingController.transform.position, -targetingController.transform.up);
var terrainLayerMask = 1 << LayerMask.NameToLayer(SimulationSettings.TerrainLayerName);
RaycastHit hit;
if (Physics.Raycast(controllerRay, out hit, SimulationSettings.MaxTeleportDistance, terrainLayerMask))
{
teleportTargeter.transform.position = hit.point + new Vector3(0.0f, 0.1f, 0.0f);
}
}
}
}