Tanoda
XRHeightOffset.cs
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) Ultraleap, Inc. 2011-2020. *
3 * *
4 * Use subject to the terms of the Apache License 2.0 available at *
5 * http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
6 * between Ultraleap and you, your company or other organization. *
7 ******************************************************************************/
8
9using UnityEngine;
11using UnityEngine.Serialization;
12
13namespace Leap.Unity {
14
15 [ExecuteInEditMode]
16 public class XRHeightOffset : MonoBehaviour {
17
18 #region Inspector
19
20 [Header("Room-scale Height Offset")]
21
22 [SerializeField]
23 [OnEditorChange("roomScaleHeightOffset")]
24 [Tooltip("This height offset allows you to place your Rig's base location at the "
25 + "approximate head position of your player during edit-time, while still "
26 + "providing correct cross-platform XR rig heights. If the tracking space "
27 + "type is detected as RoomScale, the Rig will be shifted DOWN by this height "
28 + "on Start, matching the expected floor height for, e.g., SteamVR, "
29 + "while the rig remains unchanged for Android VR and Oculus single-camera "
30 + "targets. "
31 + "Use the magenta gizmo as a reference; the circles represent where your "
32 + "floor will be in a Room-scale experience.")]
33 [MinValue(0f)]
34 private float _roomScaleHeightOffset = 1.6f; // average human height (or so)
35 private float _lastKnownHeightOffset = 0f;
36 public float roomScaleHeightOffset {
37 get { return _roomScaleHeightOffset; }
38 set {
39 _roomScaleHeightOffset = value;
40 this.transform.position += this.transform.up
41 * (_roomScaleHeightOffset - _lastKnownHeightOffset);
42 _lastKnownHeightOffset = value;
43 }
44 }
45
46 #region Auto Recenter
47 [Header("Auto Recenter")]
48
49 [FormerlySerializedAs("autoRecenterOnUserPresence")]
50 [Tooltip("If the detected XR device is present and supports userPresence, "
51 + "checking this option will detect when userPresence changes from false to "
52 + "true and call InputTracking.Recenter. Supported in 2017.2 and newer.")]
53 public bool recenterOnUserPresence = true;
54
55 [Tooltip("Calls InputTracking.Recenter on Start().")]
56 public bool recenterOnStart = true;
57
58 [Tooltip("If enabled, InputTracking.Recenter will be called when the assigned key is "
59 + "pressed.")]
60 public bool recenterOnKey = false;
61
62 [Tooltip("When this key is pressed, InputTracking.Recenter will be called.")]
63 public KeyCode recenterKey = KeyCode.R;
64
65 private bool _lastUserPresence;
66
67 #endregion
68
69 #region Runtime Height Adjustment
70
71 [Header("Runtime Height Adjustment")]
72
73 [Tooltip("If enabled, then you can use the chosen keys to step the player's height "
74 + "up and down at runtime.")]
75 public bool enableRuntimeAdjustment = true;
76
77 [DisableIf("enableRuntimeAdjustment", isEqualTo: false)]
78 [Tooltip("Press this key on the keyboard to adjust the height offset up by stepSize.")]
79 public KeyCode stepUpKey = KeyCode.UpArrow;
80
81 [DisableIf("enableRuntimeAdjustment", isEqualTo: false)]
82 [Tooltip("Press this key on the keyboard to adjust the height offset down by stepSize.")]
83 public KeyCode stepDownKey = KeyCode.DownArrow;
84
85 [DisableIf("enableRuntimeAdjustment", isEqualTo: false)]
86 public float stepSize = 0.1f;
87
88 #endregion
89
90 #endregion
91
92 #region Unity Events
93
94 private void Start() {
95 _lastKnownHeightOffset = _roomScaleHeightOffset;
96
97 if (XRSupportUtil.IsRoomScale()) {
98 this.transform.position -= this.transform.up * _roomScaleHeightOffset;
99 }
100
101 if (recenterOnStart) {
102 XRSupportUtil.Recenter();
103 }
104 }
105
106 private void Update() {
107 if (Application.isPlaying) {
108 var deviceIsPresent = XRSupportUtil.IsXRDevicePresent();
109 if (deviceIsPresent) {
110
112 if (Input.GetKeyDown(stepUpKey)) {
114 }
115
116 if (Input.GetKeyDown(stepDownKey)) {
118 }
119 }
120
121 if (recenterOnUserPresence && !XRSupportUtil.IsLargePlayspace()) {
122 var userPresence = XRSupportUtil.IsUserPresent();
123
124 if (_lastUserPresence != userPresence) {
125 if (userPresence) {
126 XRSupportUtil.Recenter();
127 }
128
129 _lastUserPresence = userPresence;
130 }
131 }
132
133 if (recenterOnKey && Input.GetKeyDown(recenterKey)) {
134 XRSupportUtil.Recenter();
135 }
136 }
137 }
138 }
139
140 #endregion
141
142 #region Gizmos
143
144 private void OnDrawGizmos() {
145 Gizmos.color = Color.Lerp(Color.magenta, Color.white, 0.3f).WithAlpha(0.5f);
146
147 var totalHeight = roomScaleHeightOffset;
148 var segmentsPerMeter = 32;
149 var numSegments = totalHeight * segmentsPerMeter;
150 var segmentLength = totalHeight / numSegments;
151 var rigPos = this.transform.position;
152 var down = this.transform.rotation * Vector3.down;
153
154 if (Application.isPlaying && XRSupportUtil.IsRoomScale()) {
155
156 var roomScaleGizmoOffset = Vector3.up * totalHeight;
157
158 rigPos += roomScaleGizmoOffset;
159 }
160
161 for (int i = 0; i < numSegments; i += 2) {
162 var segStart = rigPos + down * segmentLength * i;
163 var segEnd = rigPos + down * segmentLength * (i + 1);
164
165 Gizmos.DrawLine(segStart, segEnd);
166 }
167
168 var groundPos = rigPos + down * totalHeight;
169 drawCircle(groundPos, down, 0.01f);
170 Gizmos.color = Gizmos.color.WithAlpha(0.3f);
171 drawCircle(groundPos, down, 0.10f);
172 Gizmos.color = Gizmos.color.WithAlpha(0.2f);
173 drawCircle(groundPos, down, 0.20f);
174 }
175
176 private void drawCircle(Vector3 position, Vector3 normal, float radius) {
177 var r = normal.Perpendicular() * radius;
178 var q = Quaternion.AngleAxis(360f / 32, normal);
179 for (int i = 0; i < 32; i++) {
180 var tempR = q * r;
181 Gizmos.DrawLine(position + r, position + tempR);
182 r = tempR;
183 }
184 }
185
186 #endregion
187
188 }
189
190}
UnityEngine.Color Color
Definition: TestScript.cs:32