IMHOTEP Framework
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Pages
SteamVR_Teleporter.cs
1 using UnityEngine;
2 using System.Collections;
3 
4 public class SteamVR_Teleporter : MonoBehaviour
5 {
6  public enum TeleportType
7  {
8  TeleportTypeUseTerrain,
9  TeleportTypeUseCollider,
10  TeleportTypeUseZeroY
11  }
12 
13  public bool teleportOnClick = false;
14  public TeleportType teleportType = TeleportType.TeleportTypeUseZeroY;
15 
16  Transform reference
17  {
18  get
19  {
20  var top = SteamVR_Render.Top();
21  return (top != null) ? top.origin : null;
22  }
23  }
24 
25  void Start()
26  {
27  var trackedController = GetComponent<SteamVR_TrackedController>();
28  if (trackedController == null)
29  {
30  trackedController = gameObject.AddComponent<SteamVR_TrackedController>();
31  }
32 
33  trackedController.TriggerClicked += new ClickedEventHandler(DoClick);
34 
35  if (teleportType == TeleportType.TeleportTypeUseTerrain)
36  {
37  // Start the player at the level of the terrain
38  var t = reference;
39  if (t != null)
40  t.position = new Vector3(t.position.x, Terrain.activeTerrain.SampleHeight(t.position), t.position.z);
41  }
42  }
43 
44  void DoClick(object sender, ClickedEventArgs e)
45  {
46  if (teleportOnClick)
47  {
48  // First get the current Transform of the the reference space (i.e. the Play Area, e.g. CameraRig prefab)
49  var t = reference;
50  if (t == null)
51  return;
52 
53  // Get the current Y position of the reference space
54  float refY = t.position.y;
55 
56  // Create a plane at the Y position of the Play Area
57  // Then create a Ray from the origin of the controller in the direction that the controller is pointing
58  Plane plane = new Plane(Vector3.up, -refY);
59  Ray ray = new Ray(this.transform.position, transform.forward);
60 
61  // Set defaults
62  bool hasGroundTarget = false;
63  float dist = 0f;
64  if (teleportType == TeleportType.TeleportTypeUseTerrain) // If we picked to use the terrain
65  {
66  RaycastHit hitInfo;
67  TerrainCollider tc = Terrain.activeTerrain.GetComponent<TerrainCollider>();
68  hasGroundTarget = tc.Raycast(ray, out hitInfo, 1000f);
69  dist = hitInfo.distance;
70  }
71  else if (teleportType == TeleportType.TeleportTypeUseCollider) // If we picked to use the collider
72  {
73  RaycastHit hitInfo;
74  hasGroundTarget = Physics.Raycast(ray, out hitInfo);
75  dist = hitInfo.distance;
76  }
77  else // If we're just staying flat on the current Y axis
78  {
79  // Intersect a ray with the plane that was created earlier
80  // and output the distance along the ray that it intersects
81  hasGroundTarget = plane.Raycast(ray, out dist);
82  }
83 
84  if (hasGroundTarget)
85  {
86  // Get the current Camera (head) position on the ground relative to the world
87  Vector3 headPosOnGround = new Vector3(SteamVR_Render.Top().head.position.x, refY, SteamVR_Render.Top().head.position.z);
88 
89  // We need to translate the reference space along the same vector
90  // that is between the head's position on the ground and the intersection point on the ground
91  // i.e. intersectionPoint - headPosOnGround = translateVector
92  // currentReferencePosition + translateVector = finalPosition
93  t.position = t.position + (ray.origin + (ray.direction * dist)) - headPosOnGround;
94  }
95  }
96  }
97 }
98