Using Phidgets in Unreal Development Kit
This tutorial will show you how to use Phidgets within UDK. Phidgets are low cost USB sensor and control units for the PC. They allow your game to control objects in the real world such as servo motors and LCD screens, and also allow the real world to control your game through sensors such as vibration sensors and Radio Fequency ID tags (RFID Tags). For a full list of the sensors see the phidgets website www.phidgets.com.
Phidgets can be easily used with a range of languages including C++. C# Flash, Flex, MATLAB and Java, have a look at the programming resources here.
Be warned. This tutorial is fairly detailed and only takes you through setting up one type of phidget, the 3-axis accelerometer. Although the code for most phidgets follows roughly the same pattern in terms of defining handlers, opening and closing, there are variations across the phidgets, so I’ve tried to explain the logic, rather than just tell you what to copy and past, as you will need to understand the logic of the API if you want to use other phidgets in UDK.
A Problem & Solution
The Phidget drivers do provide you with a DLL file (32bit and 64bit), created in standard C, which allows access to the phidgets from any language which can link to a C based DLL. UnrealScript provides the DLLBind command, which in theory should be able to link directly to this DLL and provide direct access to the phidgets from within UnrealScript. Unfortunately, I had all sorts of problems trying get this DLL to work with UnrealScript, so I decided to created my own DLL based on C++ which works fine in UnrealScript. This also gave me more control over how the phidgets communicate with UnrealScript. For example, RFID tags output their ID number as an array of bytes (unsigned chars) which are not as easy to remember so I find it easier to work with my own unique integers. I found it a lot easier to convert the array of bytes into integers within the DLL, rather than passing the byte data from the DLL to UnrealScript and then processing the byte data it in UnrealScript.
So, you could try using the phidget21.dll supplied with the phidget drivers, and DLLBind() within UnrealScript, but this tutorial will show you the DIY approach, which will give you more flexibility in the long run. I also learned a heck of a lot going through this process, which will hopefully save you a lot of time.
This tutorial will walk you through how to create your own C++ DLL for UnrealScript and how to access the phidgets from within UnrealScript.
You Will Need
- Latest phidget drivers from here: http://www.phidgets.com/drivers.php
- Make sure you download the correct version for your system (32bit or 64bit). If using the 64bit version, this also comes with 32bit versions of the phidget library, which you will need later. This tutorial will assume you are using the 64bit version.
- Visual Studio 2008 Professional (I am still using 2008 as I know it works, I’m sure the express edition will work as well).
- An accelerometer phidget (the phidget code follows a similar logic for many of the phidget’s, so you will be able to adjust the following tutorial for most phidget’s)
A – Phidget Setup
Download and install the latest drivers, link is provided above.
- Phidget21Manager.exe – This is the Phidget Control Panel application.
- Phidget21.h – This header file will provide your C or C++ application with phidget functionality.
- Phidget21.lib – Also required when we create the DLL project.
- Phidget21.dll – the standard C based DLL which I could not get working in UnrealScript. If you do get it working let me know!
That’s it for setting up the phidgets. The next step is creating a C++ DLL so we can.
B – Download the C/C++ Code
Go to the following link http://www.phidgets.com/programming_resources.php and from the C/C++ section download the “Code Sample”. You may also want to download the API Refence and the “Getting Started Guide”.
This will provide you with a series of .c files which we will copy and past into our new DLL.
C – Prepareing the C++ DLL
This part will assume you are using Visual Studio 2008 Professional, although I’m sure visual Studio Express will work as well.
In Visual Studio select FILE | NEW | PROJECT
Enter a name for the DLL, for example “UDKphidgets”. Then select a location to save the project. Click OK
- Click NEXT in the project wizard
- Select DLL in the APPLICATION TYPE
- Uncheck all the other options and click FINISH, as below
The new project will open up and you will have a project structure like this:
Next we need to add in the Phidget21.h which we looked at back in step A3, into our project, so we have access to all the phidget functionality. In Windows Explorer, navigate to C:\Program Files\Phidgets copy Phidget21.h then paste it into your project directory, in the same location as UDKphidgets.cpp.
This next step assumes you are using the 64bit version of the drivers. Navigate to C:\Program Files\Phidgets\x86 and copy phidget21.lib and paste this into your project directory, in the same location as UDKphidgets.cpp. Do not copy the version of this file which is in C:\Program Files\Phidgets, we need the x86 version.
In the Solution Explorer window in Visual Studio, expand the HEADER FILES folder to view the contents. Right click on the folder name and select ADD | EXISTING ITEM. Navigate to the project folder and select the Phidget21.h. Now right click on the REOURCE FILES folder and select Phidget21.lib. A custom build windows will appear, just click NO. Your project structure should look like this:
Now add a reference to this header file and another header. In UDKphidgets.cpp add the following lines if the are not already present: underneath:
To save a bit of typing use the std namespace. This will allow us to call functions in the std library without having to type std:: every time. It will also be more flexible if you decide to use other libraries inside the DLL. Read this if you are not familiar with namespaces. Add the following after the header files:
D – The Sample Code
First I would recommend reading through the Phdiget Programming Manual, especially the section on Phidget API Copncepts, page 8 to 10. I will not repeat that section here, so I will assume you have read it through and understand the main concepts behind opening and closing phidgets, as well as event handlers.Lets have a look at the sample code you download in step B1. This tutorial is based on the accelerometer phidget, so we will look at the example Accelerometer-simple.c
The main structure of the this code is:
- AttachHandler() – To react to the accelerometer being attached to the PC
- DetachHandler() – To react to the accelerometer being detached from the PC
- ErrorHandler() – To react to an error in the acceleromoeter
- accel_AccelChangeHandler() – To react to a change in the acceleromoter data which is greater than a specified threshold
- display_properties() – Prints the properties of the acceleromoeter to the command line
- accelerometer_simple() – This is the main code which opens, processes and closes the phidgetmain() – this is the main entry point for the DLL, we are not interested in this.
If you browse through the other samples you will see that the code follows a very similar structure in each example. We are going to copy this code into our DLL, and only make a few slight changes, so if you are trying this with another phidget, use the sample code for that phidget in your DLL.
First we need to define the event handlers, as above. In the sample file, the attach event handler looks like this:
In our DLL we need that function to look like this, exactly the same, but with the __stdcall convetion added and a accel_ prefix to the function name:
__stdcall ensures that the standard calling convention for the Microsoft Win32 API is used, without this convention, the DLL will not compile. See this artcile on calling conventions. The accel_ prefix just distinguishes this attach handler from other attach handlers for other phidgets if you add them later.
For each of the four event handlers in Accelerometer-simple.c, copy the function into your DLL, and add the __stdcall convention before the function name and the accel_ prefix to the function name.
Now copy the following variable from the sample file and place it after the namespace line:
Next copy and paste the display_properties() function into your code, place it after accel_AccelChangeHandler. No changes are required to this function. This will simply output properties to the command line from Unreal, so we can see that the phidget is working.
Our DLL is going to expose five functions to the outside world:
- Open the accelerometer
- Get data from the X axis of the accelerometer
- Get data from the Y axis of the accelerometer
- Get data from the Z axis of the accelerometer
- Close the Acceleromoeter
The functions to define the event handlers in step 3 above do not need to be exposed outside the DLL.
To start, we need to define the names of any external functions so UnrealScript will be able to hook into the DLL. Copy the following code into UDKphidgets.cpp after the declaration of the accelerometer handle:
First, create the open() function. Add the following code after the display_properties() function:
This method will be available from outside the DLL as we have defined it as an extern, in the previous step.
Copy all the code between the curly brackets in the open() method in the sample file, and paste it into the above empty method. We now need to make a few adjustments.
I removed the following lines, but you can keep them.
Remove the following. We do not want the player pressing a key in Unreal in order to get the accelerometer working. We will place the closing statements in their own method, so we can call a separate close event from within UnrealScript.
Add the accel_ prefix to event handlers within the new open() method, so
- AttachHandler becomes accel_AttachHandler
- DetachHandler becomes accel_DetachHandler
- ErrorHandler becomes accel_ErrorHandler
- AccelChangeHandler becomes accel_AccelChangeHandler
We will now create a method to read the acceleration data on the x axis of the acceleromoeter. Add the following code after the open() method:
The above code is using the CPhidgetAccelerometer_getAcceleration() method, this is not in the sample file, but more info on this and other methods for each specific phidget can be found in the documentation on the phidget’s website. The second parameter of this method is the axis number where:
0 = x axis
1 = y axis
2 = z axis
When called this method will return the current acceleration data on the x axis. This method will be available from outside the DLL as we have defined it as an extern, in the step 8 above.
Now copy and paste this code to create similar methods for the Y and Z axis. Remember to change the 2nd parameter of CPhidgetAccelerometer_getAcceleration() and use the same method names as declared in step 8 with the accel_ prefix. Also change the comment line which acts as a debug statement. You can remove this later.
Finally, compile the code and check for errors. If all is well, you will find the DLL in the debug folder in the project folder.
Over to UDK
Now that we have out DLL,we need to copy it across to UDK. Place the DLL in the following folder inside the UDK installation: \Binaries\Win32\UserCode
we need to setup Unreal Script to call these methods. In this example, we will control a rolling sphere with the accelerometer. I will assume you are using the Unreal Frontend application to compile and run your scripts.
I will assume you are familiar with setting up UnrealScript and a suitable IDE, as well as the language itself. I will assume you know how to do this and are ready to add the code into your own custom classes. Please make sure you understand the above tutorials, otherwise the following steps will just not work.
In your custom package in the Development\Src folder create a new .uc file called accel_KActorSphere.uc and add the following code into it, the comments in the code will explain whats happening:
Save the scripts and use the Unreal Frontend to compile and check for errors
Lets move over to the editor now. In the Unreal Editor add the sphere to the level by selecting the Generic Browser, then Actor Classes tab, select Actor | DynamicSMActor | KActor | KActorSpawnable | PhidgetKActorSphere. Then right click on the map somewhere and select Add PhidgetKActorSphere here.
Download my test sphere object in its own package here. Place this in the UDKGame\Content\TestPackages folder. Load up the Generic Browser and select the Content Browser Tab, navigate to the SH_Package | TestObjects package and select the SH_Mesh object in the Content Browser. This is the sphere which we willadd to the level and control with the accelerometer.
In the editor window, select the new sphere and press F4 to view the properties and expand DynamicSMActor | Static Mesh Component | Static Mesh Component | Static Mesh entry. Click the Use Selected Object in Content Browser icon . This will paste a link to the SH_Mesh sphere into this property. The sphere is ready to go !
Close the editor and use the Unreal Frontend to launch the game. You should see the sphere in the level, small rotations of the accelerometer will move the sphere.
If you are having problems, you can debug with the ‘log() statement in UnrealScript and with the printf() statement in the DLL. Both will output to the log window which you can switch on in the UnrealFrontend (the ‘Show Log’ option in the PC pane of the game tab.