1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using UnityEngine;
|
---|
4 | using VRTK;
|
---|
5 |
|
---|
6 | /**
|
---|
7 | * This class can be used to monitor the usage of an AR/VR which uses the VRTK framework. For this, it
|
---|
8 | * uses the full functionality of the base class by considering further relevant game objects from the
|
---|
9 | * VRTK framework and adding for them additional types of event handling.
|
---|
10 | */
|
---|
11 | public class AutoQUESTGenericMonitorUnityVRTK : AutoQUESTGenericMonitorUnity
|
---|
12 | {
|
---|
13 | /**
|
---|
14 | * Traverses a hierarchy of game objects and adds game objects relevant for event logging to the given list
|
---|
15 | */
|
---|
16 | override protected void addRelevantGameObjects(GameObject gameObject, LinkedList<UnityEngine.Object> currentRelevantGameObjects)
|
---|
17 | {
|
---|
18 | base.addRelevantGameObjects(gameObject, currentRelevantGameObjects);
|
---|
19 |
|
---|
20 | if (gameObject)
|
---|
21 | {
|
---|
22 | Component[] vrtkObjects = gameObject.GetComponentsInChildren(typeof(VRTK_InteractableObject));
|
---|
23 | foreach (Component relevantObject in vrtkObjects)
|
---|
24 | {
|
---|
25 | currentRelevantGameObjects.AddLast(relevantObject);
|
---|
26 | }
|
---|
27 |
|
---|
28 | Component[] vrtkControllers = gameObject.GetComponentsInChildren(typeof(VRTK_ControllerEvents));
|
---|
29 | foreach (Component relevantObject in vrtkControllers)
|
---|
30 | {
|
---|
31 | currentRelevantGameObjects.AddLast(relevantObject);
|
---|
32 | }
|
---|
33 | }
|
---|
34 | }
|
---|
35 |
|
---|
36 | /**
|
---|
37 | * registers event handling for the given relevant object
|
---|
38 | */
|
---|
39 | override protected void ensureEventHandling(UnityEngine.Object relevantObject)
|
---|
40 | {
|
---|
41 | if (relevantObject is VRTK_InteractableObject)
|
---|
42 | {
|
---|
43 | ensureEventHandling((VRTK_InteractableObject)relevantObject);
|
---|
44 | }
|
---|
45 | else if (relevantObject is VRTK_ControllerEvents)
|
---|
46 | {
|
---|
47 | ensureEventHandling((VRTK_ControllerEvents)relevantObject);
|
---|
48 | }
|
---|
49 | else
|
---|
50 | {
|
---|
51 | base.ensureEventHandling(relevantObject);
|
---|
52 | }
|
---|
53 | }
|
---|
54 |
|
---|
55 | /**
|
---|
56 | * registers event handling for the given relevant object
|
---|
57 | */
|
---|
58 | private void ensureEventHandling(VRTK_InteractableObject interactableObject)
|
---|
59 | {
|
---|
60 | VRTKListeners listeners = (VRTKListeners) getListeners(interactableObject.gameObject);
|
---|
61 |
|
---|
62 | InteractableObjectEventHandler listener = listeners.getCreateListener("objectTouched", interactableObject);
|
---|
63 | // remove the listener first to ensure, it is not registered twice
|
---|
64 | interactableObject.InteractableObjectTouched -= listener;
|
---|
65 | interactableObject.InteractableObjectTouched += listener;
|
---|
66 |
|
---|
67 | listener = listeners.getCreateListener("objectUntouched", interactableObject);
|
---|
68 | // remove the listener first to ensure, it is not registered twice
|
---|
69 | interactableObject.InteractableObjectUntouched -= listener;
|
---|
70 | interactableObject.InteractableObjectUntouched += listener;
|
---|
71 |
|
---|
72 | listener = listeners.getCreateListener("objectGrabbed", interactableObject);
|
---|
73 | // remove the listener first to ensure, it is not registered twice
|
---|
74 | interactableObject.InteractableObjectGrabbed -= listener;
|
---|
75 | interactableObject.InteractableObjectGrabbed += listener;
|
---|
76 |
|
---|
77 | listener = listeners.getCreateListener("objectUngrabbed", interactableObject);
|
---|
78 | // remove the listener first to ensure, it is not registered twice
|
---|
79 | interactableObject.InteractableObjectUngrabbed -= listener;
|
---|
80 | interactableObject.InteractableObjectUngrabbed += listener;
|
---|
81 |
|
---|
82 | listener = listeners.getCreateListener("objectUsed", interactableObject);
|
---|
83 | // remove the listener first to ensure, it is not registered twice
|
---|
84 | interactableObject.InteractableObjectUsed -= listener;
|
---|
85 | interactableObject.InteractableObjectUsed += listener;
|
---|
86 |
|
---|
87 | listener = listeners.getCreateListener("objectUnused", interactableObject);
|
---|
88 | // remove the listener first to ensure, it is not registered twice
|
---|
89 | interactableObject.InteractableObjectUnused -= listener;
|
---|
90 | interactableObject.InteractableObjectUnused += listener;
|
---|
91 | }
|
---|
92 |
|
---|
93 | /**
|
---|
94 | * registers event handling for the given relevant object
|
---|
95 | */
|
---|
96 | private void ensureEventHandling(VRTK_ControllerEvents controller)
|
---|
97 | {
|
---|
98 | VRTKListeners listeners = (VRTKListeners)getListeners(controller.gameObject);
|
---|
99 |
|
---|
100 | ControllerInteractionEventHandler listener = listeners.getCreateListener("triggerPressed", controller);
|
---|
101 | // remove the listener first to ensure, it is not registered twice
|
---|
102 | controller.TriggerPressed -= listener;
|
---|
103 | controller.TriggerPressed += listener;
|
---|
104 |
|
---|
105 | listener = listeners.getCreateListener("triggerReleased", controller);
|
---|
106 | // remove the listener first to ensure, it is not registered twice
|
---|
107 | controller.TriggerReleased -= listener;
|
---|
108 | controller.TriggerReleased += listener;
|
---|
109 |
|
---|
110 | listener = listeners.getCreateListener("triggerTouchStart", controller);
|
---|
111 | // remove the listener first to ensure, it is not registered twice
|
---|
112 | controller.TriggerTouchStart -= listener;
|
---|
113 | controller.TriggerTouchStart += listener;
|
---|
114 |
|
---|
115 | listener = listeners.getCreateListener("triggerTouchEnd", controller);
|
---|
116 | // remove the listener first to ensure, it is not registered twice
|
---|
117 | controller.TriggerTouchEnd -= listener;
|
---|
118 | controller.TriggerTouchEnd += listener;
|
---|
119 |
|
---|
120 |
|
---|
121 | listener = listeners.getCreateListener("triggerHairlineStart", controller);
|
---|
122 | // remove the listener first to ensure, it is not registered twice
|
---|
123 | controller.TriggerHairlineStart -= listener;
|
---|
124 | controller.TriggerHairlineStart += listener;
|
---|
125 |
|
---|
126 | listener = listeners.getCreateListener("triggerHairlineEnd", controller);
|
---|
127 | // remove the listener first to ensure, it is not registered twice
|
---|
128 | controller.TriggerHairlineEnd -= listener;
|
---|
129 | controller.TriggerHairlineEnd += listener;
|
---|
130 |
|
---|
131 |
|
---|
132 | listener = listeners.getCreateListener("triggerClicked", controller);
|
---|
133 | // remove the listener first to ensure, it is not registered twice
|
---|
134 | controller.TriggerClicked -= listener;
|
---|
135 | controller.TriggerClicked += listener;
|
---|
136 |
|
---|
137 | listener = listeners.getCreateListener("triggerUnclicked", controller);
|
---|
138 | // remove the listener first to ensure, it is not registered twice
|
---|
139 | controller.TriggerUnclicked -= listener;
|
---|
140 | controller.TriggerUnclicked += listener;
|
---|
141 |
|
---|
142 |
|
---|
143 | listener = listeners.getCreateListener("triggerAxisChanged", controller);
|
---|
144 | // remove the listener first to ensure, it is not registered twice
|
---|
145 | controller.TriggerAxisChanged -= listener;
|
---|
146 | controller.TriggerAxisChanged += listener;
|
---|
147 |
|
---|
148 |
|
---|
149 | listener = listeners.getCreateListener("gripPressed", controller);
|
---|
150 | // remove the listener first to ensure, it is not registered twice
|
---|
151 | controller.GripPressed -= listener;
|
---|
152 | controller.GripPressed += listener;
|
---|
153 |
|
---|
154 | listener = listeners.getCreateListener("gripReleased", controller);
|
---|
155 | // remove the listener first to ensure, it is not registered twice
|
---|
156 | controller.GripReleased -= listener;
|
---|
157 | controller.GripReleased += listener;
|
---|
158 |
|
---|
159 |
|
---|
160 | listener = listeners.getCreateListener("gripTouchStart", controller);
|
---|
161 | // remove the listener first to ensure, it is not registered twice
|
---|
162 | controller.GripTouchStart -= listener;
|
---|
163 | controller.GripTouchStart += listener;
|
---|
164 |
|
---|
165 | listener = listeners.getCreateListener("gripTouchEnd", controller);
|
---|
166 | // remove the listener first to ensure, it is not registered twice
|
---|
167 | controller.GripTouchEnd -= listener;
|
---|
168 | controller.GripTouchEnd += listener;
|
---|
169 |
|
---|
170 |
|
---|
171 | listener = listeners.getCreateListener("gripHairlineStart", controller);
|
---|
172 | // remove the listener first to ensure, it is not registered twice
|
---|
173 | controller.GripHairlineStart -= listener;
|
---|
174 | controller.GripHairlineStart += listener;
|
---|
175 |
|
---|
176 | listener = listeners.getCreateListener("gripHairlineEnd", controller);
|
---|
177 | // remove the listener first to ensure, it is not registered twice
|
---|
178 | controller.GripHairlineEnd -= listener;
|
---|
179 | controller.GripHairlineEnd += listener;
|
---|
180 |
|
---|
181 |
|
---|
182 | listener = listeners.getCreateListener("gripClicked", controller);
|
---|
183 | // remove the listener first to ensure, it is not registered twice
|
---|
184 | controller.GripClicked -= listener;
|
---|
185 | controller.GripClicked += listener;
|
---|
186 |
|
---|
187 | listener = listeners.getCreateListener("gripUnclicked", controller);
|
---|
188 | // remove the listener first to ensure, it is not registered twice
|
---|
189 | controller.GripUnclicked -= listener;
|
---|
190 | controller.GripUnclicked += listener;
|
---|
191 |
|
---|
192 |
|
---|
193 | listener = listeners.getCreateListener("gripAxisChanged", controller);
|
---|
194 | // remove the listener first to ensure, it is not registered twice
|
---|
195 | controller.GripAxisChanged -= listener;
|
---|
196 | controller.GripAxisChanged += listener;
|
---|
197 |
|
---|
198 |
|
---|
199 | listener = listeners.getCreateListener("touchpadPressed", controller);
|
---|
200 | // remove the listener first to ensure, it is not registered twice
|
---|
201 | controller.TouchpadPressed -= listener;
|
---|
202 | controller.TouchpadPressed += listener;
|
---|
203 |
|
---|
204 | listener = listeners.getCreateListener("touchpadReleased", controller);
|
---|
205 | // remove the listener first to ensure, it is not registered twice
|
---|
206 | controller.TouchpadReleased -= listener;
|
---|
207 | controller.TouchpadReleased += listener;
|
---|
208 |
|
---|
209 |
|
---|
210 | listener = listeners.getCreateListener("touchpadTouchStart", controller);
|
---|
211 | // remove the listener first to ensure, it is not registered twice
|
---|
212 | controller.TouchpadTouchStart -= listener;
|
---|
213 | controller.TouchpadTouchStart += listener;
|
---|
214 |
|
---|
215 | listener = listeners.getCreateListener("touchpadTouchEnd", controller);
|
---|
216 | // remove the listener first to ensure, it is not registered twice
|
---|
217 | controller.TouchpadTouchEnd -= listener;
|
---|
218 | controller.TouchpadTouchEnd += listener;
|
---|
219 |
|
---|
220 |
|
---|
221 | listener = listeners.getCreateListener("touchpadAxisChanged", controller);
|
---|
222 | // remove the listener first to ensure, it is not registered twice
|
---|
223 | controller.TouchpadAxisChanged -= listener;
|
---|
224 | controller.TouchpadAxisChanged += listener;
|
---|
225 |
|
---|
226 |
|
---|
227 | listener = listeners.getCreateListener("buttonOnePressed", controller);
|
---|
228 | // remove the listener first to ensure, it is not registered twice
|
---|
229 | controller.ButtonOnePressed -= listener;
|
---|
230 | controller.ButtonOnePressed += listener;
|
---|
231 |
|
---|
232 | listener = listeners.getCreateListener("buttonOneReleased", controller);
|
---|
233 | // remove the listener first to ensure, it is not registered twice
|
---|
234 | controller.ButtonOneReleased -= listener;
|
---|
235 | controller.ButtonOneReleased += listener;
|
---|
236 |
|
---|
237 |
|
---|
238 | listener = listeners.getCreateListener("buttonOneTouchStart", controller);
|
---|
239 | // remove the listener first to ensure, it is not registered twice
|
---|
240 | controller.ButtonOneTouchStart -= listener;
|
---|
241 | controller.ButtonOneTouchStart += listener;
|
---|
242 |
|
---|
243 | listener = listeners.getCreateListener("buttonOneTouchEnd", controller);
|
---|
244 | // remove the listener first to ensure, it is not registered twice
|
---|
245 | controller.ButtonOneTouchEnd -= listener;
|
---|
246 | controller.ButtonOneTouchEnd += listener;
|
---|
247 |
|
---|
248 |
|
---|
249 | listener = listeners.getCreateListener("buttonTwoPressed", controller);
|
---|
250 | // remove the listener first to ensure, it is not registered twice
|
---|
251 | controller.ButtonTwoPressed -= listener;
|
---|
252 | controller.ButtonTwoPressed += listener;
|
---|
253 |
|
---|
254 | listener = listeners.getCreateListener("buttonTwoReleased", controller);
|
---|
255 | // remove the listener first to ensure, it is not registered twice
|
---|
256 | controller.ButtonTwoReleased -= listener;
|
---|
257 | controller.ButtonTwoReleased += listener;
|
---|
258 |
|
---|
259 |
|
---|
260 | listener = listeners.getCreateListener("buttonTwoTouchStart", controller);
|
---|
261 | // remove the listener first to ensure, it is not registered twice
|
---|
262 | controller.ButtonTwoTouchStart -= listener;
|
---|
263 | controller.ButtonTwoTouchStart += listener;
|
---|
264 |
|
---|
265 | listener = listeners.getCreateListener("buttonTwoTouchEnd", controller);
|
---|
266 | // remove the listener first to ensure, it is not registered twice
|
---|
267 | controller.ButtonTwoTouchEnd -= listener;
|
---|
268 | controller.ButtonTwoTouchEnd += listener;
|
---|
269 |
|
---|
270 |
|
---|
271 | listener = listeners.getCreateListener("startMenuPressed", controller);
|
---|
272 | // remove the listener first to ensure, it is not registered twice
|
---|
273 | controller.StartMenuPressed -= listener;
|
---|
274 | controller.StartMenuPressed += listener;
|
---|
275 |
|
---|
276 | listener = listeners.getCreateListener("startMenuReleased", controller);
|
---|
277 | // remove the listener first to ensure, it is not registered twice
|
---|
278 | controller.StartMenuReleased -= listener;
|
---|
279 | controller.StartMenuReleased += listener;
|
---|
280 |
|
---|
281 |
|
---|
282 | listener = listeners.getCreateListener("controllerEnabled", controller);
|
---|
283 | // remove the listener first to ensure, it is not registered twice
|
---|
284 | controller.ControllerEnabled -= listener;
|
---|
285 | controller.ControllerEnabled += listener;
|
---|
286 |
|
---|
287 | listener = listeners.getCreateListener("controllerDisabled", controller);
|
---|
288 | // remove the listener first to ensure, it is not registered twice
|
---|
289 | controller.ControllerDisabled -= listener;
|
---|
290 | controller.ControllerDisabled += listener;
|
---|
291 |
|
---|
292 |
|
---|
293 | listener = listeners.getCreateListener("controllerIndexChanged", controller);
|
---|
294 | // remove the listener first to ensure, it is not registered twice
|
---|
295 | controller.ControllerIndexChanged -= listener;
|
---|
296 | controller.ControllerIndexChanged += listener;
|
---|
297 |
|
---|
298 | }
|
---|
299 |
|
---|
300 | /**
|
---|
301 | * creates a new listeners object supporting VRTK
|
---|
302 | */
|
---|
303 | override protected Listeners createListeners()
|
---|
304 | {
|
---|
305 | return new VRTKListeners(LogEvent);
|
---|
306 | }
|
---|
307 |
|
---|
308 | /**
|
---|
309 | * inner structure to use for storing listeners for scene objects
|
---|
310 | */
|
---|
311 | protected class VRTKListeners : AutoQUESTGenericMonitorUnity.Listeners
|
---|
312 | {
|
---|
313 | /**
|
---|
314 | * used to pass the event handling callback method
|
---|
315 | */
|
---|
316 | internal VRTKListeners(EventHandlingCallback callback) : base (callback)
|
---|
317 | {
|
---|
318 | // nothing to do
|
---|
319 | }
|
---|
320 |
|
---|
321 | /**
|
---|
322 | * returns a listener for the given event type and updates the internal timestamp. If there is no listener
|
---|
323 | * one will be created and registered.
|
---|
324 | */
|
---|
325 | internal InteractableObjectEventHandler getCreateListener(string eventType, VRTK_InteractableObject eventTarget)
|
---|
326 | {
|
---|
327 | InteractableObjectEventHandler listener = null;
|
---|
328 |
|
---|
329 | foreach (KeyValuePair<string, object> candidate in listeners)
|
---|
330 | {
|
---|
331 | if (candidate.Key == eventType)
|
---|
332 | {
|
---|
333 | listener = (InteractableObjectEventHandler)candidate.Value;
|
---|
334 | break;
|
---|
335 | }
|
---|
336 | }
|
---|
337 |
|
---|
338 | if (listener == null)
|
---|
339 | {
|
---|
340 | listener = delegate (object sender, InteractableObjectEventArgs e)
|
---|
341 | {
|
---|
342 | callback(eventType, eventTarget.gameObject, new KeyValuePair<string, string>("interactingObject", e.interactingObject.name));
|
---|
343 | };
|
---|
344 |
|
---|
345 | addListener(eventType, listener);
|
---|
346 | //Debug.Log("ensuring handling of event " + eventType + " for " + eventTarget);
|
---|
347 | }
|
---|
348 |
|
---|
349 | lastTouched = DateTime.UtcNow.Ticks;
|
---|
350 | return listener;
|
---|
351 | }
|
---|
352 |
|
---|
353 | /**
|
---|
354 | * returns a listener for the given event type and updates the internal timestamp. If there is no listener
|
---|
355 | * one will be created and registered.
|
---|
356 | */
|
---|
357 | internal ControllerInteractionEventHandler getCreateListener(string eventType, VRTK_ControllerEvents controller)
|
---|
358 | {
|
---|
359 | ControllerInteractionEventHandler listener = null;
|
---|
360 |
|
---|
361 | foreach (KeyValuePair<string, object> candidate in listeners)
|
---|
362 | {
|
---|
363 | if (candidate.Key == eventType)
|
---|
364 | {
|
---|
365 | listener = (ControllerInteractionEventHandler)candidate.Value;
|
---|
366 | break;
|
---|
367 | }
|
---|
368 | }
|
---|
369 |
|
---|
370 | if (listener == null)
|
---|
371 | {
|
---|
372 | listener = delegate (object sender, ControllerInteractionEventArgs e)
|
---|
373 | {
|
---|
374 | if (eventType.StartsWith("touchpad"))
|
---|
375 | {
|
---|
376 | Vector2 axis = e.touchpadAxis;
|
---|
377 | roundVector(ref axis);
|
---|
378 |
|
---|
379 | callback(eventType, controller.gameObject,
|
---|
380 | new KeyValuePair<string, string>("controller", controller.gameObject.name),
|
---|
381 | new KeyValuePair<string, string>("touchpadAngle", Math.Round(e.touchpadAngle, 2).ToString()),
|
---|
382 | new KeyValuePair<string, string>("touchpadAxis", "(" + axis.x + ", " + axis.y + ")"));
|
---|
383 | }
|
---|
384 | else if (eventType.StartsWith("trigger"))
|
---|
385 | {
|
---|
386 | callback(eventType, controller.gameObject,
|
---|
387 | new KeyValuePair<string, string>("controller", controller.gameObject.name),
|
---|
388 | new KeyValuePair<string, string>("buttonPressure", Math.Round(e.buttonPressure, 2).ToString()));
|
---|
389 | }
|
---|
390 | else
|
---|
391 | {
|
---|
392 | callback(eventType, controller.gameObject,
|
---|
393 | new KeyValuePair<string, string>("controller", controller.gameObject.name));
|
---|
394 | }
|
---|
395 | };
|
---|
396 |
|
---|
397 | addListener(eventType, listener);
|
---|
398 | //Debug.Log("ensuring handling of event " + eventType + " for " + eventTarget);
|
---|
399 | }
|
---|
400 |
|
---|
401 | lastTouched = DateTime.UtcNow.Ticks;
|
---|
402 | return listener;
|
---|
403 | }
|
---|
404 |
|
---|
405 | /**
|
---|
406 | * convenience method to round the values of a vector to two decimal positions
|
---|
407 | */
|
---|
408 | private void roundVector(ref Vector2 vector)
|
---|
409 | {
|
---|
410 | vector.x = (float)Math.Round(vector.x, 2);
|
---|
411 | vector.y = (float)Math.Round(vector.y, 2);
|
---|
412 | }
|
---|
413 | }
|
---|
414 |
|
---|
415 | }
|
---|