As you know, when you use UAV, you can open terminal and have video from gunner and pilot camera streamed directly to it. Unfortunately this is hardcoded engine functionality and there is no direct way of tapping into these video feeds. Fortunately there is a way to simulate this using available SQF commands and config params. I am going to show how to “hack” UAV gunner camera and stream it to a texture surface so that it will show what UAV gunner sees.


The idea is simple, create render surface, create instance of a camera and assign it to created render surface, attach camera to the UAV gunner camera position, make it point where gunner camera is pointing. Everything is pretty straight forward apart from getting gunner camera direction. For this we need to look in config of the particular UAV to find gunner camera memory points. For the quadrotor UAV they are:

  • uavCameraGunnerPos = “PiP0_pos”;
  • uavCameraGunnerDir = “PiP0_dir”;

uavCameraGunnerPos is position of the camera lens in model coordinates. It will be good for attaching custom camera to it. uavCameraGunnerDir is also position, contrary to the name. One might expect directional vector, but it is actually position, so in order to find directional vector, you need to calculate it from uavCameraGunnerPos and uavCameraGunnerDir. Luckily there is a command for it, vectorFromTo. To get the actual coordinates you need selectionPosition command. So the vectorDir of the gunner camera can be calculated like this:

_start = uav selectionPosition "PiP0_pos"; _end = uav selectionPosition "PiP0_dir"; _vDir = _start vectorFromTo _end;

This is how this vectorDir would look like when calculated:


But having just vectorDir is not enough and for complete camera orientation we need vectorUp as well, which can be found as vectorCrossProduct between vectorDir and a side vector, which is perpendicular to vectorDir:

_vSide = [-(_vDir select 1), _vDir select 0, 0]; _vUp = _vDir vectorCrossProduct _vSide;

The direction of the attached camera will need to be adjusted every frame as attached objects do not change direction automatically. The whole code should now look like this:

/* create render surface */ _bb = "Land_Billboard_F" createVehicle position player; _bb setObjectTexture [0, "#(argb,512,512,1)r2t(uavrtt,1)"]; /* create uav and make it fly */ uav = createVehicle ["B_UAV_01_F", _bb modelToWorld [0,100,100], [], 0, "FLY"]; createVehicleCrew uav; uav lockCameraTo [_bb, [0]]; uav flyInHeight 100; /* add loiter waypoint */ _wp = group uav addWaypoint [position _bb, 0]; _wp setWaypointType "LOITER"; _wp setWaypointLoiterType "CIRCLE_L"; _wp setWaypointLoiterRadius 100; /* create camera and stream to render surface */ cam = "camera" camCreate [0,0,0]; cam cameraEffect ["Internal", "Back", "uavrtt"]; /* attach cam to gunner cam position */ cam attachTo [uav, [0,0,0], "PiP0_pos"]; /* make it zoom in a little */ cam camSetFov 0.1; /* switch cam to thermal */ "uavrtt" setPiPEffect [2]; /* adjust cam orientation */ addMissionEventHandler ["Draw3D", { _dir = (uav selectionPosition "PiP0_pos") vectorFromTo (uav selectionPosition "PiP0_dir"); cam setVectorDirAndUp [ _dir, _dir vectorCrossProduct [-(_dir select 1), _dir select 0, 0] ]; }];


An experiment I did earlier with Greyhawk UAV:

EDIT: fixed small typo _uav -> uav