|
4 | 4 | using UnityEngine;
|
5 | 5 |
|
6 | 6 | public class FreeFlightController : MonoBehaviour {
|
7 |
| - [Tooltip("Enable/disable rotation control. For use in Unity editor only.")] |
8 |
| - public bool rotationEnabled = true; |
9 |
| - |
10 |
| - [Tooltip("Enable/disable translation control. For use in Unity editor only.")] |
11 |
| - public bool translationEnabled = true; |
12 |
| - |
13 |
| - [Tooltip("Speed of rotation in degrees/seconds.")] |
14 |
| - public float rotationSpeed = 90; |
15 |
| - |
16 |
| - [Tooltip("Speed of translation in meters/seconds.")] |
17 |
| - public float translationSpeed = 7; |
18 |
| - |
19 |
| - [Tooltip("Minimum distance the mouse must move to start registering movement.")] |
20 |
| - public float rotationDeadDistance = 0.001f; |
21 |
| - |
22 |
| - [Tooltip("Keys to move forward.")] |
23 |
| - public List<KeyCode> moveForwardKeys = |
24 |
| - new List<KeyCode> { KeyCode.W, KeyCode.UpArrow }; |
25 |
| - |
26 |
| - [Tooltip("Keys to move backward.")] |
27 |
| - public List<KeyCode> moveBackwardKeys = |
28 |
| - new List<KeyCode> { KeyCode.S, KeyCode.DownArrow }; |
29 |
| - |
30 |
| - [Tooltip("Keys to stride to the right.")] |
31 |
| - public List<KeyCode> strideRightKeys = |
32 |
| - new List<KeyCode> { KeyCode.D, KeyCode.RightArrow }; |
33 |
| - |
34 |
| - [Tooltip("Keys to stride to the left.")] |
35 |
| - public List<KeyCode> strideLeftKeys = |
36 |
| - new List<KeyCode> { KeyCode.A, KeyCode.LeftArrow }; |
37 |
| - |
38 |
| - [Tooltip("Keys to move upward.")] |
39 |
| - public List<KeyCode> moveUpwardKeys = new List<KeyCode> { KeyCode.R }; |
40 |
| - |
41 |
| - [Tooltip("Keys to move downward.")] |
42 |
| - public List<KeyCode> moveDownwardKeys = new List<KeyCode> { KeyCode.F }; |
43 |
| - |
44 |
| - private WebVRManager webVRManager; |
45 |
| - private WebVRDisplayCapabilities capabilities; |
46 |
| - |
47 |
| - bool inDesktopLike { |
48 |
| - get { |
49 |
| - return capabilities.hasExternalDisplay; |
50 |
| - } |
51 |
| - } |
52 |
| - |
53 |
| - Vector3 mouseMovement = Vector3.zero; |
54 |
| - |
55 |
| - Vector3 lastMousePosition; |
56 |
| - |
57 |
| - void Awake() |
58 |
| - { |
59 |
| - webVRManager = WebVRManager.Instance; |
60 |
| - } |
61 |
| - |
62 |
| - void Start() |
63 |
| - { |
64 |
| - WebVRManager.OnVRChange += onVRChange; |
65 |
| - WebVRManager.OnVRCapabilitiesUpdate += onVRCapabilitiesUpdate; |
66 |
| - } |
67 |
| - |
68 |
| - private void onVRChange() |
69 |
| - { |
70 |
| - if (webVRManager.vrState == WebVRState.ENABLED) |
71 |
| - { |
72 |
| - DisableEverything(); |
73 |
| - } |
74 |
| - else |
75 |
| - { |
76 |
| - EnableAccordingToPlatform(); |
77 |
| - } |
78 |
| - } |
79 |
| - |
80 |
| - private void onVRCapabilitiesUpdate(WebVRDisplayCapabilities vrCapabilities) |
81 |
| - { |
82 |
| - capabilities = vrCapabilities; |
83 |
| - EnableAccordingToPlatform(); |
84 |
| - } |
85 |
| - |
86 |
| - void Update() { |
87 |
| - if (translationEnabled) { |
88 |
| - Translate(); |
89 |
| - } |
90 |
| - if (rotationEnabled) { |
91 |
| - Rotate(); |
92 |
| - } |
93 |
| - } |
94 |
| - |
95 |
| - void DisableEverything() { |
96 |
| - translationEnabled = false; |
97 |
| - rotationEnabled = false; |
98 |
| - } |
99 |
| - |
100 |
| - /// Enables rotation and translation control for desktop environments. |
101 |
| - /// For mobile environments, it enables rotation or translation according to |
102 |
| - /// the device capabilities. |
103 |
| - void EnableAccordingToPlatform() { |
104 |
| - rotationEnabled = inDesktopLike || !capabilities.hasOrientation; |
105 |
| - translationEnabled = inDesktopLike || !capabilities.hasPosition; |
106 |
| - } |
107 |
| - |
108 |
| - void Translate() { |
109 |
| - transform.Translate( |
110 |
| - SideMovement(), |
111 |
| - ElevationMovement(), |
112 |
| - ForwardMovement() |
113 |
| - ); |
114 |
| - } |
115 |
| - |
116 |
| - void Rotate() { |
117 |
| - RegisterMouseMovement(); |
118 |
| - transform.Rotate(Vector3.up, YawMovement(), Space.World); |
119 |
| - transform.Rotate(Vector3.right, -PitchMovement(), Space.Self); |
120 |
| - } |
121 |
| - |
122 |
| - float SideMovement() { |
123 |
| - return TranslationPerFrame(DirectionFromKeys( |
124 |
| - strideRightKeys, |
125 |
| - strideLeftKeys |
126 |
| - )); |
127 |
| - } |
128 |
| - |
129 |
| - float ElevationMovement() { |
130 |
| - return TranslationPerFrame(DirectionFromKeys( |
131 |
| - moveUpwardKeys, |
132 |
| - moveDownwardKeys |
133 |
| - )); |
134 |
| - } |
135 |
| - |
136 |
| - float ForwardMovement() { |
137 |
| - return TranslationPerFrame(DirectionFromKeys( |
138 |
| - moveForwardKeys, |
139 |
| - moveBackwardKeys |
140 |
| - )); |
141 |
| - } |
142 |
| - |
143 |
| - float TranslationPerFrame(float direction) { |
144 |
| - return direction * translationSpeed * Time.deltaTime; |
145 |
| - } |
146 |
| - |
147 |
| - float DirectionFromKeys(List<KeyCode> positive, List<KeyCode> negative) { |
148 |
| - if (AnyKeyIsPressed(positive)) { |
149 |
| - return 1; |
150 |
| - } |
151 |
| - if (AnyKeyIsPressed(negative)) { |
152 |
| - return -1; |
153 |
| - } |
154 |
| - return 0; |
155 |
| - } |
156 |
| - |
157 |
| - bool AnyKeyIsPressed(List<KeyCode> keys) { |
158 |
| - return keys.FindAll(k => Input.GetKey(k)).Count > 0; |
159 |
| - } |
160 |
| - |
161 |
| - void RegisterMouseMovement() { |
162 |
| - bool mouseStoppedDragging = Input.GetMouseButtonUp(0); |
163 |
| - bool mouseIsDragging = Input.GetMouseButton(0); |
164 |
| - |
165 |
| - if (mouseStoppedDragging) { |
166 |
| - mouseMovement.Set(0, 0, 0); |
167 |
| - } |
168 |
| - else if (mouseIsDragging) { |
169 |
| - mouseMovement = Input.mousePosition - lastMousePosition; |
170 |
| - } |
171 |
| - |
172 |
| - lastMousePosition = Input.mousePosition; |
173 |
| - } |
174 |
| - |
175 |
| - float YawMovement() { |
176 |
| - return RotationPerFrame( |
177 |
| - DirectionFromMovement(mouseMovement.x, rotationDeadDistance)); |
178 |
| - } |
179 |
| - |
180 |
| - float PitchMovement() { |
181 |
| - return RotationPerFrame( |
182 |
| - DirectionFromMovement(mouseMovement.y, rotationDeadDistance)); |
183 |
| - } |
184 |
| - |
185 |
| - float RotationPerFrame(float direction) { |
186 |
| - return direction * rotationSpeed * Time.deltaTime; |
187 |
| - } |
188 |
| - |
189 |
| - float DirectionFromMovement(float number, float threshold=0.001f) { |
190 |
| - if (number > threshold) { |
191 |
| - return 1; |
192 |
| - } |
193 |
| - if (number < -threshold) { |
194 |
| - return -1; |
195 |
| - } |
196 |
| - return 0; |
197 |
| - } |
| 7 | + [Tooltip("Enable/disable rotation control. For use in Unity editor only.")] |
| 8 | + public bool rotationEnabled = true; |
| 9 | + |
| 10 | + [Tooltip("Enable/disable translation control. For use in Unity editor only.")] |
| 11 | + public bool translationEnabled = true; |
| 12 | + |
| 13 | + private WebVRManager webVRManager; |
| 14 | + private WebVRDisplayCapabilities capabilities; |
| 15 | + |
| 16 | + [Tooltip("Mouse sensitivity")] |
| 17 | + public float mouseSensitivity = 1f; |
| 18 | + |
| 19 | + [Tooltip("Straffe Speed")] |
| 20 | + public float straffeSpeed = 5f; |
| 21 | + |
| 22 | + private float minimumX = -360f; |
| 23 | + private float maximumX = 360f; |
| 24 | + |
| 25 | + private float minimumY = -90f; |
| 26 | + private float maximumY = 90f; |
| 27 | + |
| 28 | + private float rotationX = 0f; |
| 29 | + private float rotationY = 0f; |
| 30 | + |
| 31 | + Quaternion originalRotation; |
| 32 | + |
| 33 | + bool inDesktopLike { |
| 34 | + get { |
| 35 | + return capabilities.hasExternalDisplay; |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + void Awake() |
| 40 | + { |
| 41 | + webVRManager = WebVRManager.Instance; |
| 42 | + } |
| 43 | + |
| 44 | + void Start() |
| 45 | + { |
| 46 | + WebVRManager.OnVRChange += onVRChange; |
| 47 | + WebVRManager.OnVRCapabilitiesUpdate += onVRCapabilitiesUpdate; |
| 48 | + originalRotation = transform.localRotation; |
| 49 | + } |
| 50 | + |
| 51 | + private void onVRChange() |
| 52 | + { |
| 53 | + if (webVRManager.vrState == WebVRState.ENABLED) |
| 54 | + { |
| 55 | + DisableEverything(); |
| 56 | + } |
| 57 | + else |
| 58 | + { |
| 59 | + EnableAccordingToPlatform(); |
| 60 | + } |
| 61 | + } |
| 62 | + |
| 63 | + private void onVRCapabilitiesUpdate(WebVRDisplayCapabilities vrCapabilities) |
| 64 | + { |
| 65 | + capabilities = vrCapabilities; |
| 66 | + EnableAccordingToPlatform(); |
| 67 | + } |
| 68 | + |
| 69 | + void Update() { |
| 70 | + if (translationEnabled) |
| 71 | + { |
| 72 | + float x = Input.GetAxis("Horizontal") * Time.deltaTime * straffeSpeed; |
| 73 | + float z = Input.GetAxis("Vertical") * Time.deltaTime * straffeSpeed; |
| 74 | + |
| 75 | + transform.Translate(x, 0, z); |
| 76 | + } |
| 77 | + |
| 78 | + if (rotationEnabled && Input.GetMouseButton(0)) |
| 79 | + { |
| 80 | + |
| 81 | + rotationX += Input.GetAxis ("Mouse X") * mouseSensitivity; |
| 82 | + rotationY += Input.GetAxis ("Mouse Y") * mouseSensitivity; |
| 83 | + |
| 84 | + rotationX = ClampAngle (rotationX, minimumX, maximumX); |
| 85 | + rotationY = ClampAngle (rotationY, minimumY, maximumY); |
| 86 | + |
| 87 | + Quaternion xQuaternion = Quaternion.AngleAxis (rotationX, Vector3.up); |
| 88 | + Quaternion yQuaternion = Quaternion.AngleAxis (rotationY, Vector3.left); |
| 89 | + |
| 90 | + transform.localRotation = originalRotation * xQuaternion * yQuaternion; |
| 91 | + } |
| 92 | + } |
| 93 | + |
| 94 | + void DisableEverything() |
| 95 | + { |
| 96 | + translationEnabled = false; |
| 97 | + rotationEnabled = false; |
| 98 | + } |
| 99 | + |
| 100 | + /// Enables rotation and translation control for desktop environments. |
| 101 | + /// For mobile environments, it enables rotation or translation according to |
| 102 | + /// the device capabilities. |
| 103 | + void EnableAccordingToPlatform() |
| 104 | + { |
| 105 | + rotationEnabled = inDesktopLike || !capabilities.hasOrientation; |
| 106 | + translationEnabled = inDesktopLike || !capabilities.hasPosition; |
| 107 | + } |
| 108 | + |
| 109 | + public static float ClampAngle (float angle, float min, float max) |
| 110 | + { |
| 111 | + if (angle < -360f) |
| 112 | + angle += 360f; |
| 113 | + if (angle > 360f) |
| 114 | + angle -= 360f; |
| 115 | + return Mathf.Clamp (angle, min, max); |
| 116 | + } |
198 | 117 | }
|
0 commit comments