trò chơi game bóng rổ full code
2 * UniMove API - A Unity plugin for the PlayStation Move motion controller
3 * Copyright (C) 2012, 2013, Copenhagen Game Collective (http://www.cphgc.org)
4 * Patrick Jarnfelt
5 * Douglas Wilson (http://www.doougle.net)
6 *
7 *
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 **/
32
33 /**
34 * IMPORTANT NOTES!
35 *
36 * -- This API has been compiled for Mac OSX (10.7 and later) specifically.
37 *
38 * -- This API assumes that the controller has already been paired and connected by Bluetooth beforehand.
39 * To pair a controller(s), use the Pairing Utility provided by the PS Move API http://thp.io/2010/psmove/.
40 * To connect a controller by Bluetooth, just press the PS button after pairing it.
41 * You can also use the controllers by USB, but with limited functionality (see below).
42 *
43 * -- Features include:
44 *
45 * - Setting the RGB LED color and rumble intensity (USB and Bluetooth)
46 * - Read the status of the digital buttons (Bluetooth only)
47 * - Read the status of the analog trigger (Bluetooth only)
48 * - Read values for the internal sensors (Bluetooth only):
49 * - accelorometer
50 * - gyroscope
51 * - magnetometer
52 * - temperature
53 * - battery level
54 *
55 * Please see the README for more information!
56 **/
57
58 using System;
59 using UnityEngine;
60 using System.Runtime.InteropServices;
61
62 #region enums and structs
63
64 /// <summary>
65 /// The Move controller can be connected by USB and/or Bluetooth.
66 /// </summary>
67 public enum PSMoveConnectionType
68 {
69 Bluetooth,
70 USB,
71 Unknown,
72 };
73
74 // Not entirely sure why some of these buttons (R3/L3) are exposed...
75 public enum PSMoveButton
76 {
77 L2 = 1 << 0x00,
78 R2 = 1 << 0x01,
79 L1 = 1 << 0x02,
80 R1 = 1 << 0x03,
81 Triangle = 1 << 0x04,
82 Circle = 1 << 0x05,
83 Cross = 1 << 0x06,
84 Square = 1 << 0x07,
85 Select = 1 << 0x08,
86 L3 = 1 << 0x09,
87 R3 = 1 << 0x0A,
88 Start = 1 << 0x0B,
89 Up = 1 << 0x0C,
90 Right = 1 << 0x0D,
91 Down = 1 << 0x0E,
92 Left = 1 << 0x0F,
93 PS = 1 << 0x10,
94 Move = 1 << 0x13,
95 Trigger = 1 << 0x14, /* We can use this value with IsButtonDown() (or the events) to get
96 * a binary yes/no answer about if the trigger button is down at all.
97 * For the full integer/analog value of the trigger, see the corresponding property below.
98 */
99 };
100
101 // Used by psmove_get_battery().
102 public enum PSMove_Battery_Level {
103 Batt_MIN = 0x00, /*!< Battery is almost empty (< 20%) */
104 Batt_20Percent = 0x01, /*!< Battery has at least 20% remaining */
105 Batt_40Percent = 0x02, /*!< Battery has at least 40% remaining */
106 Batt_60Percent = 0x03, /*!< Battery has at least 60% remaining */
107 Batt_80Percent = 0x04, /*!< Battery has at least 80% remaining */
108 Batt_MAX = 0x05, /*!< Battery is fully charged (not on charger) */
109 Batt_CHARGING = 0xEE, /*!< Battery is currently being charged */
110 Batt_CHARGING_DONE = 0xEF, /*!< Battery is fully charged (on charger) */
111 };
112
113 public enum PSMove_Frame {
114 Frame_FirstHalf = 0, /*!< The older frame */
115 Frame_SecondHalf, /*!< The most recent frame */
116 };
117
118 public class UniMoveButtonEventArgs : EventArgs
119 {
120 public readonly PSMoveButton button;
121
122 public UniMoveButtonEventArgs(PSMoveButton button)
123 {
124 this.button = button;
125 }
126 }
127
128 #endregion
129
130 public class UniMoveController : MonoBehaviour
131 {
132 #region private instance variables
133
134 /// <summary>
135 /// The handle for this controller. This pointer is what the psmove library uses for reading data via the hid library.
136 /// </summary>
137 private IntPtr handle;
138 private bool disconnected = false;
139
140 private float timeElapsed = 0.0f;
141 private float updateRate = 0.05f; // The default update rate is 50 milliseconds
142
143 private static float MIN_UPDATE_RATE = 0.02f; // You probably don't want to update the controller more frequently than every 20 milliseconds
144
145 private float trigger = 0f;
146 private uint currentButtons = 0;
147 private uint prevButtons = 0;
148
149 private Vector3 rawAccel = Vector3.down;
150 private Vector3 accel = Vector3.down;
151 private Vector3 magnet = Vector3.zero;
152 private Vector3 rawGyro = Vector3.zero;
153 private Vector3 gyro = Vector3.zero;
154
155 // TODO: These values still need to be implemented, so we don't expose them publicly
156 private PSMove_Battery_Level battery = PSMove_Battery_Level.Batt_20Percent;
157 private float temperature = 0f;
158
159 /// <summary>
160 /// Event fired when the controller disconnects unexpectedly (i.e. on going out of range).
161 /// </summary>
162 public event EventHandler OnControllerDisconnected;
163
164 #endregion
165 /// <summary>
166 /// Returns whether the connecting succeeded or not.
167 ///
168 /// NOTE! This function does NOT pair the controller by Bluetooth.
169 /// If the controller is not already paired, it can only be connected by USB.
170 /// See README for more information.
171 /// </summary>
172 public bool Init(int index)
173 {
174 handle = psmove_connect_by_id(index);
175
176 // Error check the result!
177 if (handle == IntPtr.Zero) return false;
178
179 // Make sure the connection is actually sending data. If not, this is probably a controller
180 // you need to remove manually from the OSX Bluetooth Control Panel, then re-connect.
181 return (psmove_update_leds(handle) != 0);
182 }
183
184 /// <summary>
185 /// Static function that returns the number of *all* controller connections.
186 /// This count will tally both USB and Bluetooth connections.
187 /// Note that one physical controller, then, might register multiple connections.
188 /// To discern between different connection types, see the ConnectionType property below.
189 /// </summary>
190 public static int GetNumConnected()
191 {
192 return psmove_count_connected();
193 }
194
195 /// <summary>
196 /// The amount of time, in seconds, between update calls.
197 /// The faster this rate, the more responsive the controllers will be.
198 /// However, update too fast and your computer won't be able to keep up (see below).
199 /// You almost certainly don't want to make this faster than 20 milliseconds (0.02f).
200 ///
201 /// NOTE! We find that slower/older computers can have trouble keeping up with a fast update rate,
202 /// especially the more controllers that are connected. See the README for more information.
203 /// </summary>
204 public float UpdateRate
205 {
206 get { return this.updateRate; }
207 set { updateRate = Math.Max(value, MIN_UPDATE_RATE); } // Clamp negative values up to 0
208 }
209
210 void Update()
211 {
212 if (disconnected) return;
213
214 // we want to update the previous buttons outside the update restriction so,
215 // we only get one button event pr. unity update frame
216 prevButtons = currentButtons;
217
218 timeElapsed += Time.deltaTime;
219
220
221 // Here we manually enforce updates only every updateRate amount of time
222 // The reason we don't just do this in FixedUpdate is so the main program's FixedUpdate rate
223 // can be set independently of the controllers' update rate.
224
225 if (timeElapsed < updateRate) return;
226 else timeElapsed = 0.0f;
227
228 uint buttons = 0;
229
230 // NOTE! There is potentially data waiting in queue.
231 // We need to poll *all* of it by calling psmove_poll() until the queue is empty. Otherwise, data might begin to build up.
232 while (psmove_poll(handle) > 0)
233 {
234 // We are interested in every button press between the last update and this one:
235 buttons = buttons | psmove_get_buttons(handle);
236
237 // The events are not really working from the PS Move Api. So we do our own with the prevButtons
238 //psmove_get_button_events(handle, ref pressed, ref released);
239 }
240 currentButtons = buttons;
241
242
243 // For acceleration, gyroscope, and magnetometer values, we look at only the last value in the queue.
244 // We could in theory average all the acceleration (and other) values in the queue for a "smoothing" effect, but we've chosen not to.
245 ProcessData();
246
247 // Send a report to the controller to update the LEDs and rumble.
248 if (psmove_update_leds(handle) == 0)
249 {
250 // If it returns zero, the controller must have disconnected (i.e. out of battery or out of range),
251 // so we should fire off any events and disconnect it.
252 OnControllerDisconnected(this, new EventArgs());
253 Disconnect();
254 }
255 }
256
257 void OnApplicationQuit()
258 {
259 Disconnect();
260 }
261
262 /// <summary>
263 /// Returns true if "button" is currently down.
264 /// </summary
265 public bool GetButton(PSMoveButton b)
266 {
267 if (disconnected) return false;
268
269 return ((currentButtons & (uint)b) != 0);
270 }
271
272 /// <summary>
273 /// Returns true if "button" is pressed down this instant.
274 /// </summary
275 public bool GetButtonDown(PSMoveButton b)
276 {
277 if (disconnected) return false;
278 return ((prevButtons & (uint)b) == 0) && ((currentButtons & (uint)b) != 0);
279 }
280
281 /// <summary>
282 /// Returns true if "button" is released this instant.
283 /// </summary
284 public bool GetButtonUp(PSMoveButton b)
285 {
286 if (disconnected) return false;
287
288 return ((prevButtons & (uint)b) != 0) && ((currentButtons & (uint)b) == 0);
289 }
290 /// <summary>
291 /// Disconnect the controller
292 /// </summary>
293
294 public void Disconnect()
295 {
296 disconnected = true;
297 SetLED(0,0,0);
298 SetRumble(0);
299 psmove_disconnect(handle);
300 }
301
302 /// <summary>
303 /// Whether or not the controller has been disconnected
304 /// </summary
305 public bool Disconnected
306 {
307 get { return disconnected; }
308 }
309
310 /// <summary>
311 /// Sets the amount of rumble
312 /// </summary>
313 /// <param name="rumble">the rumble amount (0-1)</param>
314 public void SetRumble(float rumble)
315 {
316 if (disconnected) return;
317
318 // Clamp value between 0 and 1:
319 byte rumbleByte = (byte) (Math.Min(Math.Max(rumble, 0f), 1f) * 255);
320
321 psmove_set_rumble(handle, (char)rumbleByte);
322 }
323
324 /// <summary>
325 /// Sets the LED color
326 /// </summary>
327 /// <param name="color">Unity's Color type</param>
328 public void SetLED(Color color)
329 {
330 if (disconnected) return;
331
332 psmove_set_leds(handle, (char)(color.r * 255), (char)(color.g * 255), (char)(color.b * 255));
333 }
334
335 /// <summary>
336 /// Sets the LED color
337 /// </summary>
338 /// <param name="r">Red value of the LED color (0-255)</param>
339 /// <param name="g">Green value of the LED color (0-255)</param>
340 /// <param name="b">Blue value of the LED color (0-255)</param>
341 public void SetLED(byte r, byte g, byte b)
342 {
343 if (disconnected) return;
344
345 psmove_set_leds(handle, (char)r, (char)g, (char)b);
346 }
347
348 /// <summary>
349 /// Value of the analog trigger button (between 0 and 1)
350 /// </summary
351 public float Trigger
352 {
353 get { return trigger; }
354 }
355
356 /// <summary>
357 /// The 3-axis acceleration values.
358 /// </summary>
359 public Vector3 RawAcceleration
360 {
361 get { return rawAccel; }
362 }
363
364 /// <summary>
365 /// The 3-axis acceleration values, roughly scaled between -3g to 3g (where 1g is Earth's gravity).
366 /// </summary>
367 public Vector3 Acceleration
368 {
369 get { return accel; }
370 }
371
372 /// <summary>
373 /// The raw values of the 3-axis gyroscope.
374 /// </summary>
375 public Vector3 RawGyroscope
376 {
377 get { return rawGyro; }
378 }
379 /// <summary>
380 /// The raw values of the 3-axis gyroscope.
381 /// </summary>
382 public Vector3 Gyro
383 {
384 get { return gyro; }
385 }
386
387 /// <summary>
388 /// The raw values of the 3-axis magnetometer.
389 /// To be honest, we don't fully understand what the magnetometer does.
390 /// The C API on which this code is based warns that this isn't fully tested.
391 /// </summary>
392 public Vector3 Magnetometer
393 {
394 get { return magnet; }
395 }
396
397 /// <summary>
398 /// The battery level
399 /// </summary>
400 public PSMove_Battery_Level Battery
401 {
402 get { return battery; }
403 }
404
405 /// <summary>
406 /// The temperature in Celcius
407 /// </summary>
408 public float Temperature
409 {
410 get { return temperature; }
411 }
412
413 /* TODO: These two values still need to be implemented, so we don't expose them publicly... yet!
414
415 public float Battery
416 {
417 get { return this.battery; }
418 }
419
420 public float Temperature
421 {
422 get { return this.temperature; }
423 }
424 */
425
426 public PSMoveConnectionType ConnectionType
427 {
428 get { return psmove_connection_type(handle); }
429 }
430
431 #region private methods
432
433 /// <summary>
434 /// Process all the raw data on the Playstation Move controller
435 /// </summary>
436 private void ProcessData()
437 {
438 trigger = ((int)psmove_get_trigger(handle)) / 255f;
439
440 int x = 0, y = 0, z = 0;
441
442 psmove_get_accelerometer(handle, ref x, ref y, ref z);
443
444 rawAccel.x = x;
445 rawAccel.y = y;
446 rawAccel.z = z;
447
448
449 float ax = 0, ay = 0, az = 0;
450 psmove_get_accelerometer_frame(handle, PSMove_Frame.Frame_SecondHalf, ref ax, ref ay, ref az);
451
452 accel.x = ax;
453 accel.y = ay;
454 accel.z = az;
455
456 psmove_get_gyroscope(handle, ref x, ref y, ref z );
457
458 rawGyro.x = x;
459 rawGyro.y = y;
460 rawGyro.z = z;
461
462
463 float gx = 0, gy = 0, gz = 0;
464 psmove_get_gyroscope_frame(handle, PSMove_Frame.Frame_SecondHalf, ref gx, ref gy, ref gz);
465
466 gyro.x = gx;
467 gyro.y = gy;
468 gyro.z = gz;
469
470
471
472 psmove_get_magnetometer(handle, ref x, ref y, ref z );
473
474 // TODO: Should these values be converted into a more human-understandable range?
475 magnet.x = x;
476 magnet.y = y;
477 magnet.z = z;
478
479 battery = psmove_get_battery(handle);
480
481 temperature = psmove_get_temperature(handle);
482
483 }
484 #endregion
485
486
487 #region importfunctions
488
489 /* The following functions are bindings to Thomas Perl's C API for the PlayStation Move (http://thp.io/2010/psmove/)
490 * See README for more details.
491 *
492 * NOTE! We have included bindings for the psmove_pair() function, even though we don't use it here
493 * See README and Pairing Utility code for more about pairing.
494 *
495 * TODO: Expose hooks to psmove_get_btaddr() and psmove_set_btadd()
496 * These functions are already called by psmove_pair(), so unless you need to do something special, you won't need them.
497 */
498
499 [DllImport("libpsmoveapi")]
500 private static extern int psmove_count_connected();
501
502 [DllImport("libpsmoveapi")]
503 private static extern IntPtr psmove_connect();
504
505 [DllImport("libpsmoveapi")]
506 private static extern IntPtr psmove_connect_by_id(int id);
507
508 [DllImport("libpsmoveapi")]
509 private static extern int psmove_pair(IntPtr move);
510
511 [DllImport("libpsmoveapi")]
512 private static extern PSMoveConnectionType psmove_connection_type(IntPtr move);
513
514 [DllImport("libpsmoveapi")]
515 private static extern int psmove_has_calibration(IntPtr move);
516
517 [DllImport("libpsmoveapi")]
518 private static extern void psmove_set_leds(IntPtr move, char r, char g, char b);
519
520 [DllImport("libpsmoveapi")]
521 private static extern int psmove_update_leds(IntPtr move);
522
523 [DllImport("libpsmoveapi")]
524 private static extern void psmove_set_rumble(IntPtr move, char rumble);
525
526 [DllImport("libpsmoveapi")]
527 private static extern uint psmove_poll(IntPtr move);
528
529 [DllImport("libpsmoveapi")]
530 private static extern uint psmove_get_buttons(IntPtr move);
531
532 [DllImport("libpsmoveapi")]
533 private static extern uint psmove_get_button_events(IntPtr move, ref uint pressed, ref uint released);
534
535 [DllImport("libpsmoveapi")]
536 private static extern char psmove_get_trigger(IntPtr move);
537
538 [DllImport("libpsmoveapi")]
539 private static extern float psmove_get_temperature(IntPtr move);
540
541 [DllImport("libpsmoveapi")]
542 private static extern PSMove_Battery_Level psmove_get_battery(IntPtr move);
543
544 [DllImport("libpsmoveapi")]
545 private static extern void psmove_get_accelerometer(IntPtr move, ref int ax, ref int ay, ref int az);
546
547 [DllImport("libpsmoveapi")]
548 private static extern void psmove_get_accelerometer_frame(IntPtr move,PSMove_Frame frame, ref float ax, ref float ay, ref float az);
549
550 [DllImport("libpsmoveapi")]
551 private static extern void psmove_get_gyroscope(IntPtr move, ref int gx, ref int gy, ref int gz);
552
553 [DllImport("libpsmoveapi")]
554 private static extern void psmove_get_gyroscope_frame(IntPtr move,PSMove_Frame frame, ref float gx, ref float gy, ref float gz);
555
556 [DllImport("libpsmoveapi")]
557 private static extern void psmove_get_magnetometer(IntPtr move, ref int mx, ref int my, ref int mz);
558
559 [DllImport("libpsmoveapi")]
560 private static extern void psmove_disconnect(IntPtr move);
561
562 #endregion
563 }
* Copyright (C) 2012, 2013, Copenhagen Game Collective (http:www.cphgc.org)
* Douglas Wilson (http:www.doougle.net)
* To pair a controller(s), use the Pairing Utility provided by the PS Move API http:thp.io2010psmove.
The Move controller can be connected by USB andor Bluetooth.
Not entirely sure why some of these buttons (R3L3) are exposed...
Used by psmove_get_battery().
The handle for this controller. This pointer is what the psmove library uses for reading data via the hid library.
private float updateRate = 0.05f; The default update rate is 50 milliseconds
private static float MIN_UPDATE_RATE = 0.02f; You probably don't want to update the controller more frequently than every 20 milliseconds
TODO: These values still need to be implemented, so we don't expose them publicly
Event fired when the controller disconnects unexpectedly (i.e. on going out of range).
Returns whether the connecting succeeded or not.
NOTE! This function does NOT pair the controller by Bluetooth.
If the controller is not already paired, it can only be connected by USB.
See README for more information.
Error check the result!
Make sure the connection is actually sending data. If not, this is probably a controller
you need to remove manually from the OSX Bluetooth Control Panel, then re-connect.
Static function that returns the number of *all* controller connections.
This count will tally both USB and Bluetooth connections.
Note that one physical controller, then, might register multiple connections.
To discern between different connection types, see the ConnectionType property below.
The amount of time, in seconds, between update calls.
The faster this rate, the more responsive the controllers will be.
However, update too fast and your computer won't be able to keep up (see below).
You almost certainly don't want to make this faster than 20 milliseconds (0.02f).
NOTE! We find that slowerolder computers can have trouble keeping up with a fast update rate,
especially the more controllers that are connected. See the README for more information.
set { updateRate = Math.Max(value, MIN_UPDATE_RATE); } Clamp negative values up to 0
we want to update the previous buttons outside the update restriction so,
we only get one button event pr. unity update frame
Here we manually enforce updates only every updateRate amount of time
The reason we don't just do this in FixedUpdate is so the main program's FixedUpdate rate
can be set independently of the controllers' update rate.
NOTE! There is potentially data waiting in queue.
We need to poll *all* of it by calling psmove_poll() until the queue is empty. Otherwise, data might begin to build up.
We are interested in every button press between the last update and this one:
The events are not really working from the PS Move Api. So we do our own with the prevButtons
psmove_get_button_events(handle, ref pressed, ref released);
For acceleration, gyroscope, and magnetometer values, we look at only the last value in the queue.
We could in theory average all the acceleration (and other) values in the queue for a "smoothing" effect, but we've chosen not to.
Send a report to the controller to update the LEDs and rumble.
If it returns zero, the controller must have disconnected (i.e. out of battery or out of range),
so we should fire off any events and disconnect it.
Returns true if "button" is currently down.
Returns true if "button" is pressed down this instant. Returns true if "button" is released this instant. Disconnect the controller Whether or not the controller has been disconnected Sets the amount of rumble the rumble amount (0-1) Clamp value between 0 and 1: Sets the LED color Unity's Color type Sets the LED color Red value of the LED color (0-255) Green value of the LED color (0-255) Blue value of the LED color (0-255) Value of the analog trigger button (between 0 and 1) The 3-axis acceleration values. The 3-axis acceleration values, roughly scaled between -3g to 3g (where 1g is Earth's gravity). The raw values of the 3-axis gyroscope. The raw values of the 3-axis gyroscope. The raw values of the 3-axis magnetometer. To be honest, we don't fully understand what the magnetometer does. The C API on which this code is based warns that this isn't fully tested. The battery level The temperature in Celcius Process all the raw data on the Playstation Move controller TODO: Should these values be converted into a more human-understandable range? * The following functions are bindings to Thomas Perl's C API for the PlayStation Move (http:thp.io2010psmove)