{"name":"Camera Tutorial","title":"Camera Tutorial","type":"topic","url":"https://community.bistudio.com/wiki/Camera_Tutorial","revid":370868,"updated":"2025-02-21T10:43:59Z","aliases":[],"markdown":"### Basics\n\nA cinematic camera is what is commonly known as a \"cutscene\"; the player's input are dismissed and events happen during the video.\nA camera is **local** to the computer where the script has been called; one player could see a cutscene but still get killed by another player that didn't trigger the video.\n\n### How to\n\nThe list of all camera commands can be found in the Camera command group category.\n\n> [!IMPORTANT]\n> The \"Prepare\" version of camera commands has been introduced with Armed Assault. Using this set of commands helps the engine preloading the camera's (future) field of view (see also preloadCamera).\n> **Operation Flashpoint** only features the \"Set\" version of camera commands; use them instead (e.g camPreparePos becomes camSetPos, camCommitPrepared becomes camCommit, etc).\n> Only camCommitted is common to both syntaxes.\n\n#### Create the camera\n\n```sqf\nprivate _camera = \"camera\" camCreate getPosATL player;\n```\n\n#### Enter the camera\n\n```sqf\n_camera cameraEffect [\"internal\", \"back\"];\n```\n\n#### Select a target\n\n##### Object target\n\n```sqf\n_camera camPrepareTarget player; // a camera will automatically target the human target's face\n```\n\n##### Position target\n\n```sqf\n_camera camPrepareTarget getPosATL player;\n```\n\n#### Place the camera\n\n##### World position\n\n```sqf\n_camera camPreparePos (player getRelPos [5, 0]);\n```\n\n##### Relative position\n\n```sqf\n_camera camCommitPrepared 0; // required to apply the prepared target first - otherwise a long trip from [0,0,0] is to follow\n_camera camPrepareRelPos [0,5,0];\n```\n\n#### Apply camera's Field of View\n\n```sqf\n_camera camPrepareFOV 0.5; // standard FOV is 0.7; lesser (e.g 0.5) is zoomed in, greater (e.g 0.9) is zoomed out\n```\n\n#### Apply all the changes\n\n##### Immediately or with transition\n\n```sqf\n_camera camCommitPrepared 0; // 0 for immediate change, value in seconds for transition\n```\n\n##### With a loading timeout\n\n```sqf\n_camera camPreload 3;    // since Armed Assault - instantly moves the camera once preload or timeout is done.\n                        // tells the game to preload the future field of view. 3 here is a timeout, 0 for infinite timeout\n```\n\n#### Check that the commit happened\n\n```sqf\ncamCommitted _camera; // for camCommit/camCommitPrepared usage\n```\n\n```sqf\ncamPreloaded _camera; // for camPreload usage\n```\n\n#### Leave the camera\n\n```sqf\n_camera cameraEffect [\"terminate\", \"back\"];\n```\n\n#### Delete the camera\n\n```sqf\ncamDestroy _camera;\n```\n\n### Specific cases\n\n- A camera of bird type (seagull or crowe) **cannot** be controlled via \"Prepare\" commands - only camSet* ones.\n- A camera of bird type is **always** committed (camCommitted will always return true) even if it is still moving toward its destination.\n\n### Full example\n\n| SQF Syntax | SQS Syntax |\n|---|---|\n| ```sqf<br>private _camera = \"camera\" camCreate [0, 0, 0];<br>_camera camPrepareTarget player;<br>_camera camCommitPrepared 0; // needed for relative position<br>_camera camPrepareRelPos [0, -5, 10];<br>_camera cameraEffect [\"internal\", \"back\"];<br>_camera camCommitPrepared 0;<br>waitUntil { camCommitted _camera };<br>_camera camPrepareRelPos [90, 25, 8];<br>_camera camCommitPrepared 5;<br>waitUntil { camCommitted _camera };<br>_camera camPrepareRelPos [-90, -5, 5];<br>_camera camCommitPrepared 3;<br>waitUntil { camCommitted _camera };<br>sleep 3;<br>_camera cameraEffect [\"terminate\", \"back\"];<br>camDestroy _camera;<br>``` | ```sqs<br>_camera = \"camera\" camCreate [0, 0, 0]<br>_camera camSetTarget player<br>_camera camSetRelPos [0, -5, 10]<br>_camera cameraEffect [\"internal\", \"back\"]<br>_camera camCommit 0<br>@camCommitted _camera<br>_camera camSetRelPos [90, 25, 8]<br>_camera camCommit 5<br>@camCommitted _camera<br>_camera camSetRelPos [-90, -5, 5]<br>_camera camCommit 3<br>@camCommitted _camera<br>~3<br>_camera cameraEffect [\"terminate\", \"back\"]<br>camDestroy _camera<br>``` |\n\n### Picture-in-Picture\n\n#### Create Source\n\nThe Picture-in-Picture (PiP) RTT (or R2T, Render to Texture) source can be defined at the Enter the camera step; instead of\n\n```sqf\n_camera cameraEffect [\"internal\", \"back\"];\n```\n\nuse the following to create a PiP source - multiple sources can be\n\n```sqf\n_camera cameraEffect [\"internal\", \"back\", \"rttName\"];\n```\n\n#### Configure PiP Effects\n\nA camera effect is set using setPiPEffect as such:\n\n```sqf\n\"rttName\" setPiPEffect [2]; // sets thermal imaging\n```\n\nOnce all the configuration is done, the PiP texture can be accessed by referencing its name \"rttName\". For example:\n\n```sqf\nif (!isPiPEnabled) exitWith { systemChat \"PiP is not enabled in video options\"; };\n\nwith uiNamespace do // or use disableSerialization\n{\n    private _ctrl = findDisplay 46 createDisplay \"RscDisplayEmpty\" ctrlCreate [\"RscPicture\", -1];\n    _ctrl ctrlSetPosition [safeZoneW * 0.75, safeZoneY, safeZoneW * 0.25, safeZoneH * 0.25];\n    _ctrl ctrlSetText \"#(argb,512,512,1)r2t(rttName,1.0)\";\n    _ctrl ctrlCommit 0;\n};\n```\n\nIn order to stop the camera from \"broadcasting\", use\n\n```sqf\n_camera cameraEffect [\"terminate\", \"back\", \"rttName\"];    // terminates \"rttName\" r2t source\n_camera cameraEffect [\"terminate\", \"back\"];                // terminates all r2t source\n```\n\nThe camera still exists until destroyed with camDestroy.\n\n### See also\n\n- Camera.sqs\n- Arma 3: Splendid Camera / BIS_fnc_camera\n- Command Group: Camera Control\n- BIS_fnc_PIP","sections":[{"heading":"Basics","level":3,"markdown":"A cinematic camera is what is commonly known as a \"cutscene\"; the player's input are dismissed and events happen during the video.\nA camera is **local** to the computer where the script has been called; one player could see a cutscene but still get killed by another player that didn't trigger the video."},{"heading":"How to","level":3,"markdown":"The list of all camera commands can be found in the Camera command group category.\n\n> [!IMPORTANT]\n> The \"Prepare\" version of camera commands has been introduced with Armed Assault. Using this set of commands helps the engine preloading the camera's (future) field of view (see also preloadCamera).\n> **Operation Flashpoint** only features the \"Set\" version of camera commands; use them instead (e.g camPreparePos becomes camSetPos, camCommitPrepared becomes camCommit, etc).\n> Only camCommitted is common to both syntaxes."},{"heading":"Create the camera","level":4,"markdown":"```sqf\nprivate _camera = \"camera\" camCreate getPosATL player;\n```"},{"heading":"Enter the camera","level":4,"markdown":"```sqf\n_camera cameraEffect [\"internal\", \"back\"];\n```"},{"heading":"Select a target","level":4,"markdown":""},{"heading":"Object target","level":5,"markdown":"```sqf\n_camera camPrepareTarget player; // a camera will automatically target the human target's face\n```"},{"heading":"Position target","level":5,"markdown":"```sqf\n_camera camPrepareTarget getPosATL player;\n```"},{"heading":"Place the camera","level":4,"markdown":""},{"heading":"World position","level":5,"markdown":"```sqf\n_camera camPreparePos (player getRelPos [5, 0]);\n```"},{"heading":"Relative position","level":5,"markdown":"```sqf\n_camera camCommitPrepared 0; // required to apply the prepared target first - otherwise a long trip from [0,0,0] is to follow\n_camera camPrepareRelPos [0,5,0];\n```"},{"heading":"Apply camera's Field of View","level":4,"markdown":"```sqf\n_camera camPrepareFOV 0.5; // standard FOV is 0.7; lesser (e.g 0.5) is zoomed in, greater (e.g 0.9) is zoomed out\n```"},{"heading":"Apply all the changes","level":4,"markdown":""},{"heading":"Immediately or with transition","level":5,"markdown":"```sqf\n_camera camCommitPrepared 0; // 0 for immediate change, value in seconds for transition\n```"},{"heading":"With a loading timeout","level":5,"markdown":"```sqf\n_camera camPreload 3;    // since Armed Assault - instantly moves the camera once preload or timeout is done.\n                        // tells the game to preload the future field of view. 3 here is a timeout, 0 for infinite timeout\n```"},{"heading":"Check that the commit happened","level":4,"markdown":"```sqf\ncamCommitted _camera; // for camCommit/camCommitPrepared usage\n```\n\n```sqf\ncamPreloaded _camera; // for camPreload usage\n```"},{"heading":"Leave the camera","level":4,"markdown":"```sqf\n_camera cameraEffect [\"terminate\", \"back\"];\n```"},{"heading":"Delete the camera","level":4,"markdown":"```sqf\ncamDestroy _camera;\n```"},{"heading":"Specific cases","level":3,"markdown":"- A camera of bird type (seagull or crowe) **cannot** be controlled via \"Prepare\" commands - only camSet* ones.\n- A camera of bird type is **always** committed (camCommitted will always return true) even if it is still moving toward its destination."},{"heading":"Full example","level":3,"markdown":"| SQF Syntax | SQS Syntax |\n|---|---|\n| ```sqf<br>private _camera = \"camera\" camCreate [0, 0, 0];<br>_camera camPrepareTarget player;<br>_camera camCommitPrepared 0; // needed for relative position<br>_camera camPrepareRelPos [0, -5, 10];<br>_camera cameraEffect [\"internal\", \"back\"];<br>_camera camCommitPrepared 0;<br>waitUntil { camCommitted _camera };<br>_camera camPrepareRelPos [90, 25, 8];<br>_camera camCommitPrepared 5;<br>waitUntil { camCommitted _camera };<br>_camera camPrepareRelPos [-90, -5, 5];<br>_camera camCommitPrepared 3;<br>waitUntil { camCommitted _camera };<br>sleep 3;<br>_camera cameraEffect [\"terminate\", \"back\"];<br>camDestroy _camera;<br>``` | ```sqs<br>_camera = \"camera\" camCreate [0, 0, 0]<br>_camera camSetTarget player<br>_camera camSetRelPos [0, -5, 10]<br>_camera cameraEffect [\"internal\", \"back\"]<br>_camera camCommit 0<br>@camCommitted _camera<br>_camera camSetRelPos [90, 25, 8]<br>_camera camCommit 5<br>@camCommitted _camera<br>_camera camSetRelPos [-90, -5, 5]<br>_camera camCommit 3<br>@camCommitted _camera<br>~3<br>_camera cameraEffect [\"terminate\", \"back\"]<br>camDestroy _camera<br>``` |"},{"heading":"Picture-in-Picture","level":3,"markdown":""},{"heading":"Create Source","level":4,"markdown":"The Picture-in-Picture (PiP) RTT (or R2T, Render to Texture) source can be defined at the Enter the camera step; instead of\n\n```sqf\n_camera cameraEffect [\"internal\", \"back\"];\n```\n\nuse the following to create a PiP source - multiple sources can be\n\n```sqf\n_camera cameraEffect [\"internal\", \"back\", \"rttName\"];\n```"},{"heading":"Configure PiP Effects","level":4,"markdown":"A camera effect is set using setPiPEffect as such:\n\n```sqf\n\"rttName\" setPiPEffect [2]; // sets thermal imaging\n```\n\nOnce all the configuration is done, the PiP texture can be accessed by referencing its name \"rttName\". For example:\n\n```sqf\nif (!isPiPEnabled) exitWith { systemChat \"PiP is not enabled in video options\"; };\n\nwith uiNamespace do // or use disableSerialization\n{\n    private _ctrl = findDisplay 46 createDisplay \"RscDisplayEmpty\" ctrlCreate [\"RscPicture\", -1];\n    _ctrl ctrlSetPosition [safeZoneW * 0.75, safeZoneY, safeZoneW * 0.25, safeZoneH * 0.25];\n    _ctrl ctrlSetText \"#(argb,512,512,1)r2t(rttName,1.0)\";\n    _ctrl ctrlCommit 0;\n};\n```\n\nIn order to stop the camera from \"broadcasting\", use\n\n```sqf\n_camera cameraEffect [\"terminate\", \"back\", \"rttName\"];    // terminates \"rttName\" r2t source\n_camera cameraEffect [\"terminate\", \"back\"];                // terminates all r2t source\n```\n\nThe camera still exists until destroyed with camDestroy."},{"heading":"See also","level":3,"markdown":"- Camera.sqs\n- Arma 3: Splendid Camera / BIS_fnc_camera\n- Command Group: Camera Control\n- BIS_fnc_PIP"}],"categories":["Arma Scripting Tutorials"],"groups":["Scripting"]}