Sony PlayStation Move
Visit Sony PlayStation Move - v2.0 for latest version.
Get new version from Unity Asset Store.
What is the PlayStation Move?
PlayStation Move(PS Move) is a motion-sensing game controller platform for the PlayStation 3 (PS3) video game console by Sony Computer Entertainment. Based on the popular game play style of Nintendo's Wii console, PlayStation Move uses the PlayStation Eye camera to track the wand's position, and inertial sensors in the wand to detect its motion.
Installing the Move.me SDK
In order to use PS Move for development, you need to install Move.me SDK on PlayStation3. Move.me SDK is supported by Sony, and can be accessed by PlayStation Network. Currently, Move.me SDK is already installed on PS3 of ETC. Follow this link. to learn more about Move.me SDK.
Launch Move.me Server
NOTE: Before running your PS Move world, you MUST run Move.me on PS3.
- Connect PlayStation Eye camera and PS Move to PS3 and make sure PS3 is connected to internet.
- Launch Move.me under the GAME section.
- Once the instruction of Move.me finishes, press any button on Move controller to enter.
- If you see IP address and port on the upper left corner, Move.me is ready.
- Do NOT press PS button on the Move controller when you are running your world, Move.me will not work in the menu mode.
Calibration, Track and Reset
- Calibration and Track - Press MOVE button, and the ball will flash and then glow. Stand still until the ball glows, otherwise calibration will fail. After calibration, you can see a sword in Move.me SDK for the first Move. For other Moves, you can see virtual Move controllers.
- Reset - Press SELLECT button to reset.
Integrating with Unity
To use PS Move in Unity is easy. All you need to do is to import the PSMoveWrapper package, which includes 4 scripts (PSMoveWrapper.cs, PSMoveClient.cs, PSMoveExample.cs and PSEyeImageDisplay.cs) and a PSMoveBasicScene.
Move.me server on PS3 will detect Move controller and send its data to PSMoveWrapper via UDP. You can also use PSMoveWrapper to send request to Move.me server via TCP to control Move controller (rumbling or changing color, for instance).
- Please change the Fixed Timestep (Edit->Project Settings->Time) to 0.008 and put your controlling code in FixedUpdate (refer to PSMoveExample)
- Turn OFF the Windows Firewall if your build version cannot get data from PS3.
- Please make sure your Move controller is charged.
- For new Move controller, please connect to PS3 by USB cable and press PS button to pair.
Bringing the Move.me SDK in to Unity
Install the Unity Package
The pre-built Unity package includes all of the scripts required to start running your world. To install, simply import the package, and you all of the required assets will appear in your project.
The following items are included within the package:
- PSMoveBasicScene - This scene shows you what data you can get from and send to PS Move, and how to build an avatar for the Move controller in your world. Use this to get a feel for what the PS Move is capable of. It also shows you how to prepare your GameObjects
- PSMoveClient - This is the script that act as a bridge between unity and Move.me server on PS3. It handles all the data receiving and request sending. Normally you don't need to access to this script.
- PSMoveWrapper - This is the script that pulls out most of the features from the Move.me and brings them for use within Unity. It also contains most of the update logic required for using the PS Move. You need to attach this script to a GameObject, and access its fields and methods to use PS Move's features. However, if you are switching scenes, it will persist because of the DontDestroyOnLoad call in this script, so you don't need to attach it to another GameObject in each scene.
- PSMoveExample - This is the script that shows the basic use of PSMoveWrapper in the PSMoveBasicScene.
- PSEyeImageDisplay - This is the script that shows how to display camera image.
Using the Scripts
After importing the asset package, you have the PSMoveBasicScene to test and get familiar with the PSMoveWrapper. You can use this as your base scene, or you can drag the appropriate GameObjects into a new one.
As previously mentioned, you need to attach PSMoveWrapper on one of your GameObjects in the scene, like the "PSController" in PSMoveBasicScene. If you want to use PSMoveExample, drag the GameObject with PSMoveWrapper to the psMoveWrapper slot of the script.
Here is a list of illustration for the fields and methods you may need to access in PSMoveWrapper and PSMoveExample.
Most of the fields in PSMoveWrapper are of an array type. The Move.me SDK currently can support up to 4 Move controllers and up to 7 Navigation controllers. Thus each array Move fields has 4 elements, representing Move controller No.0 - No.3, and each array for Navigation fields has 7 elements, representing Navigation controller No.0 - No.6. For example, access position to get the postion of the ball of the first Move controller, and access valueNavAnalogX to get the x value of analog of the first Navigation controller. Also most fields are to provide information and should be read-only. The PSMoveWrapper set these fields public to make them visible in Unity editor, but DO NOT MODIFY THEM MANUALLY UNLESS IT IS SPECIFIED MODIFIABLE.
fields for Move controller
- position - a Vector3 represents the postion of the ball.
- velocity - a Vector3 represents the velocity of the ball.
- acceleration - a Vector3 represents the acceleration of the ball.
- orientation - a Vector3 represents the orientation of the wand in Eular angles.
- qOrientation - a Quaternion represents the orientation of the wand in Quaternion.
- angularVelocity - a Vector3 represents the angular velocity of the wand.
- angularAcceleration - a Vector3 represents the angular acceleration of the wand.
- handlePosition - a Vector3 represents the position of the handle.
- handleVelocity - a Vector3 represents the velocity of the handle.
- handleAcceleration - a Vector3 represents the acceleration of the handle.
- isButtonSquare - a bool represents whether the button SQUARE is pressed.
- isButtonCross - a bool represents whether the button CROSS is pressed.
- isButtonCircle - a bool represents whether the button CIRCLE is pressed.
- isButtonTriangle - a bool represents whether the button TRIANGLE is pressed.
- isButtonMove - a bool represents whether the button MOVE is pressed.
- isButtonStart - a bool represents whether the button START is pressed.
- isButtonSelect - a bool represents whether the button SELECT is pressed.
- valueT - a int represents the scale of button TRIGGER, range from 0 to 255. 0 means fully released and 255 means fully pressed.
- thresholdT - a int represents whether the button TRIGGER can be treated as "pressed". It changes the status of button TRIGGER from a range of int to a bool. For now it is used only in methods "WasPressed" and "WasReleased". The default value is 250. This field is modifiable.
- sphereColor - a Color represents the light color of the ball of Move controller.
- isTracking - a bool represents whether the PS Eye camera is tracking the ball of Move controller.
- trackingHue - a int represents the hue that PS Eye camera is tracking for Move controller, range from 0 to 359. You can call "GetHueFromColor" to calculate the hue from a certain color.
- rumbleLevel - a int represents the rumble scale for Move controller, range from 0 to 19. This field should read-only. If you want to set rumble level, call "SetRumble" fucntion.
- spherePixelPosition - a Vector2 represents the pixel position of the ball of move controller on camera image.
- spherePixelRadius - a float represents the pixel radius of the ball of move controller on camera image.
- sphereProjectionPosition - a Vector2 represents the normalized position of the ball of move controller on camera image.
- sphereDistance - a float represents the actual distance of move controller to the origin of the camera (in meters/Unity units).
- sphereVisible - a bool represents whether the camera can see the ball of move controller;
- sphereRadiusValid - a bool represents whether sphereRadius/sphereDistance of this frame is valid;
fields for Navigation controller
- isNavUp - a bool represents whether the navigation button UP is pressed.
- isNavDown - a bool represents whether the navigation button DOWN is pressed.
- isNavLeft - a bool represents whether the navigation button LEFT is pressed.
- isNavRight - a bool represents whether the navigation button RIGHT is pressed.
- isNavButtonCross - a bool represents whether the navigation button CROSS is pressed.
- isNavButtonCircle - a bool represents whether the navigation button CIRCLE is pressed.
- isNavButtonL1 - a bool represents whether the navigation button L1 is pressed.
- isNavButtonL3 - a bool represents whether the navigation button L3 (the analog) is pressed.
- valueNavAnalogX - a int represents the x scale of navigation analog, range from -128 to 127.
- valueNavAnalogY - a int represents the y scale of navigation analog, range from -128 to 127.
- valueNavL2 - a int represents the scale of navigation button L2, range from 0 to 255. 0 means fully released and 255 means fully pressed.
- thresholdNavL2 - a int represents whether the navigation button L2 can be treated as "pressed". It changes the status of button L2 from a range of int to a bool. For now it is used only in methods "WasPressed" and "WasReleased". The default value is 250. This field is modifiable.
fields for system
- moveConnected - a bool represents whether a single Move controller is connected and calibrated. NOTE: IN PSMOVEWRAPPER, WE SAY A MOVE CONTROLLER IS CONNECTED AFTER IT IS SUCCESSFULLY CALIBRATED.
- navConnected - a bool represents whether a single Navigation controller is connected.
- moveCount - a int represents how many Move controllers are connected and calibrated.
- navCount - a int represents how many Navigation controllers are connected.
- state - a PSMoveSharp.PSMoveSharpState represents the complete state information of Move.me Server and all Move controllers. Use it when you need additional information which is not provided by PSMoveWrapper.
- cameraFrameState - a PSMoveSharp.PSMoveSharpCameraFrameState represents the complete state information of PS Eye camera. Use it when you need additional information which is not provided by PSMoveWrapper.
- isConnected - a bool represents whether the PSMoveWrapper is connected to the Move.me server on PS3.
- isCameraResume - a bool represents whether to receive the camera image stream.
- ipAddress - a string represents the IP address of PS3. You can see the IP address after you launch Move.me server on PS3. It is used for connection if the IP is fixed. The default value is "188.8.131.52". This field is modifiable.
- port - a int represents the port of PS3. You can see the port after you launch the Move.me server on PS3. It is used for connection and it is always fixed. The default value is 7899. This field is modifiable.
- isFixedIP - a bool represents whether the IP address of PS3 is fixed. If it is false, PSMoveWrapper will try to read the first line from an "IPAddress.txt" file under the same path as the .exe file, and to update the ipAddress, if fails, it won't change its value. Since we have 2 PS3 in ETC, so LEAVE IT UNCHECKED and use text file for IP address. This field is modifiable.
- enableDefaultInGameCalibrate - a bool represents whether you can calibrate and reset by pressing MOVE button and RESET button via PSMoveWrapper. This field is modifiable.
- onlineMode - a bool represents whether the wrapper should connect to PS3. If it is false, the Connect function will NOT connect to PS3 even it is called. This prevents possible interference with other games testing on Move.me. It is also suggested to use this value to determine whether to activate your hot keys/simulator.
IMPORTANT: The default value of onlineMode is true, remember to UNCHECK when testing upstairs, and CHECK when testing in platform room or doing final build.
Notes for connection:
- The field ipAddress and port will only affect if you call method Connect() to build a connection. You can always customize your connection by calling Connect(string ipAddress, int port).
- The field isFixedIP is used for when IP address is not fixed (when PS3 is moved to another network), and you do not want to make another scene to input the dynamic IP address. Uncheck this field before building exe file. And before running, simply create an "IPAddress.txt", input the IP address and save the file. PSMoveWrapper will automatically update the field "ipAddress" and allow your program running with a different IP address.
- void Connect() - the same as "Connect(ipAdress, port)".
- void Connect(string ipAddress, int port) - connect to Move.me server.
- void Disconnect() - the same as "Disconnect(true)". Pause camera stream, reset all move controllers and disconnect to Move.me server.
- void Disconnect(bool isCleanUp) - isCleanUp whether to clean up stuff before disconnection. If you just want to disconnect to Move.me server, call "Disconnect(false)". NOT RECOMMENDED.
- void CameraFrameResume() - the same as "CameraFrameResume(8)".
- void CameraFrameResume(int sliceNum) - sliceNum the number of slices for sending camera image, range from 1 to 8. Resume camera stream and set slice num. Camera stream is initially paused, you need to call CameraFrameResume() to get camera image.
- void SetCameraFrameSlices(int sliceNum) - sliceNum the number of slices for sending camera image, range from 1 to 8.. Set slice num.
- void CameraFramePause() - Pause camera image stream.
- void Calibrate(int num) - num Move controller number. Calibrate the Move controller. The ball will NOT glow after calibration. You need to call any one of the "SetColor" methods to make it glow, and the "Track" methods to track.
- void TrackAll() - Set all Move controllers with default color and track with corresponding hue. Use this method when you do not care about the color of all Move controllers.
- void AutoTrack(int num) - num Move controller number. Let PS3 pick color and track the selected Move controller. Use this method when you do not care about the color of the ball.
- void SetColor(int num, Color color) - num Move controller number. color the color to set. Set the color of Move controller's ball. The PS Eye camera will NOT automatically track after calling SetColor(). If you change the color of a tracking Move controller, the tracking will be lost. You need to call any one of the "Track" methods to track. The minimum step for color is 0.2f for any RGB value, the alpha value is not used.
- void SetTrackingHue(int num, int hue) - num Move controller number. hue the hue to track. Set the tracking hue of Move controller. The hue should fit the ball's color to enable tracking.
- void SetColorAndTrack(int num, Color color) - num Move controller number. color the color to set and to track. The combination of "SetColor" and "SetTrackingHue".
- void CalibrateAndTrack(int num) - the same as "CalibrateAndTrack(num, 0.8f)"
- void CalibrateAndTrack(int num, Color color) - the same as "CalibrateAndTrack(num, color, 0.8f)"
- void CalibrateAndTrack(int num, float time) - num Move controller number. time delay time for tracking after calibration. The combination of "Calibrate" and "AutoTrack". Since calibration take time, tracking should be delayed a certain amount of seconds. 0.8f seems appropriate after some tests.
- void CalibrateAndTrack(int num, Color color, float time) - num Move controller number. color the color to set and to track. time delay time for tracking after calibration. The combination of "Calibrate" and "SetColorAndTrack".
- void ResetAll() - Reset the Move controllers.
- void Reset(int num) - num Move controller number. Reset the Move controller. The ball will not glow and it need to re-calibrate.
- void SetRumble(int num, int level) - num Move controller number. level the scale of rumble, range from 0 - 19. To set the rumble of Move controller. 0 is not rumble, 19 is maximum rumble.
- Color32 GetCameraImage() - Returns the complete camera image, null if not connected or camera stream is paused. The image should be 640x480, please check the length before using it. Also I know it is a weird issue, but after Move.me started, please calibrate at least once to make sure the image stream working smoothly. Once you have done this, it will work fine.
- bool WasPressed(int num, string button) - num Move controller number or Navigation controller number. button a string represents the name of buttons; you can use constant strings defined in PSMoveWrapper. Returns whether a button was pressed after your last call. If you call it in every update loop, it will only return true once you pressed a button, and return false while you are holding it.
- bool WasReleased(int num, string button) - num Move controller number or Navigation controller number. button a string represents the name of buttons; you can use constant strings defined in PSMoveWrapper. Returns whether a button was released after your last call. If you call it in every update loop, it will only return true once you released a button, and return false while its status remains.
Example: WasPressed(0, PSMoveWrapper.SQUARE) is to detect square button of No.0 Move controller.
Example: WasReleased(0, PSMoveWrapper.NAV_UP) is to detect up button of No.0 Navigation controller.
The difference of isButton fields, WasPressed and WasReleased is shown in the following figure.
- int GetHueFromColor(Color color) - color the target color. Returns the hue of the color.
- psMoveWrapper - a PSMoveWrapper. The PSMoveWrapper you used in the scene.
- gem - a GameObject act as the avatar for the ball of Move controller in the scene.
- handle - a GameObject act as the avatar for the handle of Move controller in the scene.
- isMirror - a bool determine whether the avatar for Move controller in the scene is its mirror image. The default value is TRUE.
- zOffset - a float represents the start z position in the scene. This variable is used only when isMirror == FALSE. You can imagine that the PS Eye camera's Z postion in the scene is zOffset. The default value is 20.
This script shows you how to get camera image. To display, just drag the script to an gameObject with renderer (Cube or Plane for instance).
PS Move vs. Wii Remote
PS Move and Wii Remote are using the similar concept of motion control. Here is a discussion of features of these two controllers.
For a basic Wii Remote, the only data we can get is acceleration. If we have an IR bar, we can get orientation and rotation. But an important limit is the camera of Wii Remote must see the IR light to ensure the orientation, which set a limit of your gesture design if it is based on orientation. With Wii Motion Plus, we can get more data, and this part will be updated after Wii Motion Plus page being made.
For PS Move, as mentioned before, we can get much more data. The most important feature is its position in 3D space, which allows you to do much more precise controlling. Since tracking camera is separated instead of building in the Move controller as Wii Remote, gestures are largely enriched as long as it is within the scope of the PS Eye camera. However, the limit becomes that all your activity must be seen by the PS Eye camera. So consider this problem if your player need to be on different spots on the stage, or need to face the screen some time and face the audience some time. Another feature is the ball must glow to make the tracking system work. This can be a useful and creative part of your world, but it can also be annoying if you prefer completely darkness during the performance.
Another "big" difference is about the acceleration. The acceleration data of Wii Remote is totally local, which means that if you are doing exactly the same gesture while facing different directions, the acceleration sequence will always be the same. However, the acceleration data of the Move controller is relative to the PS Eye camera, so it is consistent with the position data. Thus the direction your player is facing does matters if you are doing gesture recognition using acceleration data.
Extensive Functions of Move.me SDK
The PSMoveWrapper covers most features of PS Move that are usually used in game development. However there are still some status information provided by Move.me server that are not included in this version. You can actually access to these data by directly accessing PSMoveClient, or editing the PSMoveWrapper. Some may be considered to be added in if there is a request.
- Fix bug: now program will be auto disconnected from Move.me when stop playing in Unity.
- Hide all variables in PSMoveWrapper that is not supposed to be modified from inspector.
- Change isFixedIP to false as default value.
- Add onlineMode variable in PSMoveWrapper.
- Add information for navigation controller.
- Change the function structure of "WasPressed" and "WasReleased".
- Add information display for navigation controller in PSMoveExample.cs.
- Special thanks to Girish Balakrishnan for helping me add and test all the new features.
- Add camera image stream data and image display script.
- Add image position of move controller (in pixels) and relevant data.
- Change the default calibration button back to Move button, to match Move.me.
- Change the default calibration, it will keep the color when re-calibrating.
- Add variable enableDefaultInGameCalibrate to turn on/off default in-game calibration.
- Change the Disconnect function. It will now automatically pause camera image stream and reset all move controllers. For the original function, you should call Disconnect(false).
- Change the Rumble function to private; add a new SetRumble function that change rumble scale to 0-19 and avoid sending request to PS3 if setting the same rumble scale.
- Remove Program.cs, the PSMoveClient instance is now in PSMoveWrapper.cs.
If you have any question or if you are interested in further development, please contact [Xun Zhang].