Version 2024.03


GameDriver provides a new way to simulate XR inputs to projects that use both the legacy Input system (Unreal 4.27) and the Enhanced Input system (Unreal 5.1 and above).

The GameDriver tests can be executed as if a physical device were present, allowing for automated test execution independent of the physical device. Simulated devices are created by the GameDriver agent, which processes input commands passed into the project using the GameDriver API client.

Simulated Device Creation

The GameDriver Agent allows you to add simulated devices for testing interactions and inputs without the need to plug in a physical device during automated testing. CreateInputDevice call is used to create a generic device.

// Legacy Input
api.CreateInputDevice("OculusTouch", ""); 

// Enhanced Input (using mapping contexts)
api.CreateInputDevice("OculusTouch", "IMC_Menu,IMC_Weapon_Right,IMC_Hands");

Supported Commands

The GameDriver API supports the following commands for use with the Unreal Engine:

  • KeyPress - Controller button presses.
  • FloatInputEvent - Controller thumbstick axis input (x/y axes separately) in Legacy Input.
  • Vector2InputEvent - Controller thumbstick axis input in Enhanced Input. 
  • Vector3InputEvent - HMD/Controller position.
  • QuaternionInputEvent - HMD/Controller rotation.

Details on the use of these commands can be found in the API reference

Testing the Virtual Reality template project

Open Unreal Editor and select the Virtual Reality template project.  

Add the GameDriver plugin to the project and create an NUnit Test project as outlined in the documentation here.

Now let us write a simple test to grab the gun and shoot a cube.

public void GrabGunAndShootSmallCube()
    Vector3 playerStartPos, gunOriginalPos, pos;
    string smallCube1HPath = "//GrabActor_StaticMesh_Physics6";
    playerStartPos = new Vector3(20, 0, 110);

    // Save the Original gun position to check later
    gunOriginalPos = api.GetObjectPosition("//Pistol_00");
    // Move the player to the starting position.
    MoveObjectToPosition("//VRPawn_C_0", playerStartPos);
    // Move the right controller close to the Gun.
    pos = MoveObjectCloseToObjectOnAxes("//VRPawn_C_0/fn:component('MotionControllerRight')", "//Pistol_00", new Vector3(-1, 1, 2));
    // Hold down the grip button of the controller to grab the gun.
    //api.KeyPress(new KeyCode[] { KeyCode.OculusTouch_Right_Grip_Click }, 0); //key down
    api.KeyPress(new KeyCode[] { KeyCode.OculusTouch_Right_Grip_Axis }, 0); //key down
    //Move the controller to the right of the small cube
    pos = MoveObjectCloseToObjectOnAxes("//VRPawn_C_0/fn:component('MotionControllerRight')", smallCube1HPath, new Vector3(0, 50, 15));
    // look at cube
    Vector3 newRot = api.FindLookAtRotation("//VRPawn_C_0/fn:component('MotionControllerRight')", smallCube1HPath);
    //Controller forward is gun up, so need to add 90 to yaw (pitch,yaw,roll)
    newRot = new Vector3(newRot.x, newRot.y + 90, newRot.z);
    api.SetObjectRotation("//VRPawn_C_0/fn:component('MotionControllerRight')", newRot);
    //Pull gun trigger 
    //api.KeyPress(new KeyCode[] { KeyCode.OculusTouch_Right_Trigger_Click}, 25);
    api.KeyPress(new KeyCode[] { KeyCode.OculusTouch_Right_Trigger_Axis }, 25);
    //Release gun
    //api.KeyPress(new KeyCode[] { KeyCode.OculusTouch_Right_Grip_Click }, 0);//key up
    api.KeyPress(new KeyCode[] { KeyCode.OculusTouch_Right_Grip_Axis }, 0);//key up

#region HelperFunctions
Vector3 MoveObjectToPosition(string hPath, Vector3 position)
    if (hPath.Contains("fn:component("))
        api.CallMethod(hPath, "K2_SetWorldLocation", new object[] { position, false, true });
        api.CallMethod<bool>(hPath, "K2_SetActorLocation", new object[] { position });

    return api.GetObjectPosition(hPath);

Vector3 MoveObjectCloseToObjectOnAxes(string hPath, string toObjHpath,Vector3 distFromObjectOnAxes)
    Vector3 toObjPos = api.GetObjectPosition(toObjHpath);

    return MoveObjectToPosition(hPath, new Vector3(toObjPos.x + distFromObjectOnAxes.x, toObjPos.y + distFromObjectOnAxes.y, toObjPos.z + distFromObjectOnAxes.z));


Note: Only Oculus devices are fully certified as of this release. Other devices may work but are untested.