{"name":"switchMove","operator":null,"title":"switchMove","type":"command","url":"https://community.bistudio.com/wiki/switchMove","revid":378292,"updated":"2026-04-01T13:01:19Z","groups":["Animations"],"status":"ok","replaced_by":[],"games":[{"game":"ofp","name":"Operation Flashpoint","version":"1.00"},{"game":"ofpe","name":"Operation Flashpoint: Elite","version":"1.00"},{"game":"arma1","name":"Armed Assault","version":"1.00"},{"game":"arma2","name":"Arma 2","version":"1.00"},{"game":"arma2oa","name":"Arma 2: Operation Arrowhead","version":"1.50"},{"game":"tkoh","name":"Take On Helicopters","version":"1.00"},{"game":"arma3","name":"Arma 3","version":"0.50"}],"since":{"game":"ofp","name":"Operation Flashpoint","version":"1.00"},"arma3_since":"0.50","branch":null,"locality":{"argument":"local","effect":"global","server_exec":false},"exec":null,"description":"Immediately applies given animation to the unit. For a smooth transition from the current animation (by connecting animations successively, e.g `CurrentAnim -> Intermediate1 -> Intermediate2 -> TargetAnim`), use playMove or playMoveNow.\n\n> [!NOTE]\n> see Category:Moves for respective games animations.\n\nThis command first resets the unit's animation states (including aiming state, gesture state, etc.) then puts the unit in the first frame of the animation (therefore showing no transition).\nIf an invalid animation is provided, the unit's animations will be reset but no new animation will be played (see #Example 3).\n\n> [!NOTE]\n> It is a good practice to always use playMoveNow after switchMove to make sure the animation plays correctly when using the first syntax:\n>\n> ```sqf\n> _unit switchMove \"myMove\";\n> _unit playMoveNow \"myMove\";\n> ```\n>\n> The alternative syntax does this automatically.","syntaxes":[{"syntax":"person switchMove moveName","since":null,"effect":null,"exec":null,"params":[{"name":"person","type":"Object","optional":false,"default":null,"description":"unit","types":["Object"],"since":null,"text":"person: Object - unit"},{"name":"moveName","type":"String","optional":false,"default":null,"description":"animation state (see animationState)","types":["String"],"since":null,"text":"moveName: String - animation state (see animationState)"}],"returns":{"type":"Nothing","types":["Nothing"],"description":null,"text":"Nothing"},"form":"binary","operator":null,"left":{"text":"person","types":["Object"]},"right":{"text":"moveName","types":["String"]}},{"syntax":"person switchMove [moveName, time, blendFactor, resetAim]","since":"arma3 2.18","effect":null,"exec":null,"params":[{"name":"person","type":"Object","optional":false,"default":null,"description":"unit","types":["Object"],"since":null,"text":"person: Object - unit"},{"name":"moveName","type":"String","optional":false,"default":null,"description":"entry from `\"CfgMovesMaleSdr\" >> \"states\"` or `\"CfgGesturesMale\" >> \"states\"`","types":["String"],"since":null,"text":"moveName: String - entry from `\"CfgMovesMaleSdr\" >> \"states\"` or `\"CfgGesturesMale\" >> \"states\"`"},{"name":"time","type":"Number","optional":true,"default":"0","description":"normalized time, in range 0..1, where 0 = beginning of the animation, and 1 = end of the animation","types":["Number"],"since":null,"text":"time: Number - (Optional, default 0) normalized time, in range 0..1, where 0 = beginning of the animation, and 1 = end of the animation"},{"name":"blendFactor","type":"Number","optional":true,"default":"1","description":"how much to blend the current animation with the new animation, in range 0..1, where 0 = current animation, and 1 = new animation. When 1 is used, the switching is instant (not smooth), similar to the first syntax.","types":["Number"],"since":null,"text":"blendFactor: Number - (Optional, default 1) how much to blend the current animation with the new animation, in range 0..1, where 0 = current animation, and 1 = new animation. When 1 is used, the switching is instant (not smooth), similar to the first syntax."},{"name":"resetAim","type":"Boolean","optional":true,"default":"true","description":"whether the aim/head direction should be reset after switching","types":["Boolean"],"since":null,"text":"resetAim: Boolean - (Optional, default true) whether the aim/head direction should be reset after switching"}],"returns":{"type":"Nothing","types":["Nothing"],"description":null,"text":"Nothing"},"form":"binary","operator":null,"left":{"text":"person","types":["Object"]},"right":{"text":"[moveName, time, blendFactor, resetAim]","types":["Array"]}}],"examples":[{"text":"Prone:\n\n```sqf\nplayer switchMove \"AmovPpneMstpSrasWrflDnon\";\n```","code":["player switchMove \"AmovPpneMstpSrasWrflDnon\";"]},{"text":"Sit player immediately and globally:\n\n```sqf\n[player, \"AmovPsitMstpSlowWrflDnon\"] remoteExec [\"switchMove\"];\n```","code":["[player, \"AmovPsitMstpSlowWrflDnon\"] remoteExec [\"switchMove\"];"]},{"text":"Resets unit's animation:\n\n```sqf\n_unit switchMove \"\";\n```","code":["_unit switchMove \"\";"]},{"text":"```sqf\n// Create a dummy agent that copies your moves\nai1 = createAgent [typeOf player, getPosATL player, [], 0, \"NONE\"];\nai1 disableAI \"ALL\";\nonEachFrame\n{\n    ai1 setAnimSpeedCoef getAnimSpeedCoef player;\n    ai1 setVectorDir vectorDir player;\n    private _m = animationState player;\n    private _g = gestureState player;\n    private _i = getUnitMovesInfo player;\n    private _a = getUnitMovesInfo ai1;\n    \n    if (animationState ai1 != _m || abs(_i#1 - _a#1) > 0.1) then\n    {\n        ai1 switchMove [_m, _i#0, _i#3, false];\n    };\n\n    if ((gestureState ai1 != _g || abs(_i#6 - _a#6) > 0.1) && (_g != \"<none>\" && _g find \"_player\" < 0)) then\n    {\n        ai1 switchGesture [_g, _i#5, _i#8, false];\n    };\n}\n```","code":["// Create a dummy agent that copies your moves\nai1 = createAgent [typeOf player, getPosATL player, [], 0, \"NONE\"];\nai1 disableAI \"ALL\";\nonEachFrame\n{\n\tai1 setAnimSpeedCoef getAnimSpeedCoef player;\n\tai1 setVectorDir vectorDir player;\n\tprivate _m = animationState player;\n\tprivate _g = gestureState player;\n\tprivate _i = getUnitMovesInfo player;\n\tprivate _a = getUnitMovesInfo ai1;\n\t\n\tif (animationState ai1 != _m || abs(_i#1 - _a#1) > 0.1) then\n\t{\n\t\tai1 switchMove [_m, _i#0, _i#3, false];\n\t};\n\n\tif ((gestureState ai1 != _g || abs(_i#6 - _a#6) > 0.1) && (_g != \"<none>\" && _g find \"_player\" < 0)) then\n\t{\n\t\tai1 switchGesture [_g, _i#5, _i#8, false];\n\t};\n}"]}],"multiplayer":"This command has a global effect when executed locally to the unit and will synchronise properly for JIP.\nIn this case the animation on the executing machine is immediate while on remote machines it will be transitional.\nIn order for the animation to change immediately on every PC in multiplayer, use global remote execution (see #Example 2).\nWhen the argument is remote, the animation change on the executing PC is only temporary.","problems":null,"aliases":[],"see_also":["switchGesture","playMove","playMoveNow","switchAction","playAction","playActionNow","animationState","getUnitMovesInfo"],"notes":[{"user":"Hurricane","date":"2007-03-25T23:48:00Z","text":"In some cases the movement won't stay. I.e. AI hostages that put their hands behind their heads (_hostage switchMove \"AmovPercMstpSsurWnonDnon\") won't hold their hands up, unless you first use disableAI \"autoTarget\" on them. They mostly put their hands down because they 'noticed' unknown objects."},{"user":"Killswitch","date":"2008-08-03T22:43:00Z","text":"This command will not cause an AnimChanged or AnimDone event. However, playMove will."},{"user":"AgentRev","date":"2016-11-12T20:11:00Z","text":"When using this command on the player unit outside unscheduled UI contexts, it will cause a minor camera glitch for a single frame.\n\nFor example,  Draw3D and KeyDown are UI contexts and so are not affected by the glitch, but EachFrame and scheduled scripts are not UI contexts and are affected by the glitch."},{"user":"Leopard20","date":"2021-08-08T15:59:00Z","text":"If the animation you're trying to use with this command has no connection/interpolation to the unit's base animation (usually \"AmovPercMstpSrasWrflDnon\"), the move might not play using switchMove alone. In such cases you have to do this:\n\n```sqf\n_unit switchMove _move; _unit playMoveNow _move;\n```\n\nThis must run in **unscheduled environment** (see isNil)\n\nAlternatively, just use the second syntax:\n\n```sqf\n_unit switchMove [_move];\n```"},{"user":"Leopard20","date":"2025-11-04T09:44:03Z","text":"You can loop an animation using a function like this (it's recommended to do `ai disableAI \"ANIM\"` first)\n\n```sqf\n// TAG_fnc_loopAnim\nparams [\"_unit\", \"_anim\"];\n\n// remove old EH\n_unit removeEventHandler [\"AnimStateChanged\", _unit getVariable [\"TAG_AnimStateChangedEH\", -1]];\n\nprivate _EH = -1;\n// if anim is empty, just stop looping\nif (_anim != \"\") then\n{\n    _EH = _unit addEventHandler [\"AnimStateChanged\", {  \n        params [\"_unit\", \"_anim\"]; \n        private _loopedAnim = _unit getVariable [\"TAG_LoopedAnim\", \"\"];\n        if (alive _unit && _anim != _loopedAnim) then {\n            _unit switchMove [_loopedAnim, 0, 0, false];\n        };\n    }];\n};\n\n_unit setVariable [\"TAG_AnimStateChangedEH\", _EH];\n_unit setVariable [\"TAG_LoopedAnim\", _anim];\n\n// start the anim\n_unit switchMove [_anim, 0, 0, false];\n```\n\nThen use the above code in a function, either by defining it in the function library or by doing \n\n```sqf\nTAG_fnc_loopAnim = { above code }\n```\n\nHow to use the function:\n\n```sqf\n// start looping\n[testUnit, \"HubSittingChairUA_move1\"] call TAG_fnc_loopAnim;\n\n// stop looping\n[testUnit, \"\"] call TAG_fnc_loopAnim;\n```"}],"categories":["ArmA: Armed Assault: Scripting Commands","Arma 2: Operation Arrowhead: Scripting Commands","Arma 2: Scripting Commands","Arma 3: Scripting Commands","Command Group: Animations","Introduced with Operation Flashpoint version 1.00","Operation Flashpoint: Elite: Scripting Commands","Operation Flashpoint: New Scripting Commands","Operation Flashpoint: Scripting Commands","Scripting Commands","Scripting Commands: Global Effect","Take On Helicopters: Scripting Commands"]}