|
|
(36 intermediate revisions by 3 users not shown) |
Line 1: |
Line 1: |
| [[Category:Arma 3: Editing]] | | {{TOC|side}} |
| [[Category:Arma 3: Tutorials]]
| | Animals in {{arma3}} roam freely according to their [[FSM]]; they autonomously walk, stop, eat, flee etc. |
| | In order to control them fully you will need to override their default behaviour and manually guide them, all with a bit of scripting. |
|
| |
|
| {{note|'''Please note, this feature is WIP and works only in Development Build 1.55.133700 and later!'''}}
| |
| ----
| |
|
| |
|
| == Introduction == | | == Animal Creation == |
|
| |
|
| Current system of animal behaviour is that animals are randomly idling / moving around when spawned. This is caused by changes on engine side to save some performance. However, many people from community want to be able to control animals via script in some reasonable manner. So I started to work on some tweaks of animal animation configs which will offer this possibility to them. This page is overview of this feature and tutorial, how this behaviour can be achieved.
| | Animal classnames can be found on the [[Arma 3: CfgVehicles Animals]] page. |
|
| |
|
| At the moment, the tweaks are made for dog animation config only, because dog has the most variable movement possibilities and is mostly requested by community. Don't worry, other animals will be tweaked as well.
| | === createAgent Command === |
|
| |
|
| == Basics ==
| | Spawning animals ''via'' [[createAgent]] is the best way how to have control over them in your mission.<br> |
| | An '''agent''' is a "light AI" that doesn't have all the abilities/intelligence of a "normal" AI unit created ''via'' [[createUnit]]; |
| | therefore, they '''cannot''' be controlled via commands such as [[doMove]] and [[doStop]]. However, low-level commands such as [[moveTo]] or [[setDestination]] will work. |
|
| |
|
| Animals can be spawned via multiple ways. Here I will explain you which ways will work with my recent tweaks, which partly and which not.
| | For a basic example see [[#Example script|Example script]]. |
|
| |
|
| === Module Animals from Sites category === | | <div class="float-right">[[File:arma3 animals module in menu.png|thumb|175px|Animals Module location]]</div> |
| | === Animals Module === |
|
| |
|
| Probably the easiest way how to spawn animals. Just insert the module in editor, set the desired parameters and you have animals in your mission. Unfortunately, animals spawned this way '''can't be controlled via script''' in any way and will only randomly move around depending on the area you set.
| | The Animals module can be found in [[:Category:Eden Editor|Eden Editor]] in the Modules page ({{Controls|F5}}), under the Sites category. |
|
| |
|
| === Spawn via createAgent command ===
| | Insert the module in editor, set the desired parameters and you have animals in your mission.<br> |
| | Spawned animals will be for mission decoration purpose instead of heavily-scripted behaviour. |
|
| |
|
| Spawning animals via scripting command createAgent is another way how to have animals in your mission. And yes, animals created this way can be controled in some limited way. As the animal AI is controlled by AIAgent, it won't be able to be controlled via commands such as doMove and doStop and will roam randomly around. '''But agents can be controlled via moveTo command'''. And you can also determine, in which state (like move, stop, etc.) the animal will move.
| |
|
| |
|
| '''Example:''' <syntaxhighlight lang="cpp">_dog = createAgent ["Fin_random_F", getPos player, [], 5, "CAN_COLLIDE"];</syntaxhighlight> | | == Disable animal's scripted behaviour == |
|
| |
|
| === Spawn via createUnit command ===
| | You can disable [[BIS_fnc_animalBehaviour|animal's scripted behaviour]] using the following: |
| | <sqf>_animal setVariable ["BIS_fnc_animalBehaviour_disable", true];</sqf> |
|
| |
|
| Another way to spawn animal is using createUnit command. This is probably most interesting for you, modders and mission creators. In this mode the AI is handled differently than agent so the animal won't randomly change directions and will face same direction in which it has been spawned. But the cool point is, you can command the animal via doMove and doStop commands, so you will be able to control it in any way you want (creating waypoints, following the player, etc.)
| |
|
| |
|
| '''Example''':
| | == Animations == |
| <syntaxhighlight lang="cpp">_grp = createGroup CIVILIAN;
| |
| _dog = _grp createUnit ["Fin_random_F", getPos player, [], 5, "CAN_COLLIDE"];</syntaxhighlight>
| |
|
| |
|
| Additionaly the animal can be groupped with player and thus will be able to obey some basic commands like Move via command menu.
| | Animations can be played using [[playMove]], [[playMoveNow]] or [[switchMove]]. Their names are quite self-explanatory. |
| | {{Feature|important|Animals will remain in the same animation cycle until manually changed!}} |
|
| |
|
| '''Example:''' <syntaxhighlight lang="cpp">_dog = group player createUnit ["Fin_random_F", getPos player, [], 5, "CAN_COLLIDE"];</syntaxhighlight>
| | === Dog === |
|
| |
|
| == Usage == | | <sqf> |
| | _dog playMove "Dog_Stop"; |
| | _dog playMove "Dog_Sit"; |
| | _dog playMove "Dog_Walk"; |
| | _dog playMove "Dog_Run"; |
| | _dog playMove "Dog_Sprint"; |
| | _dog playMove "Dog_Idle_Stop"; // wandering, default behaviour |
| | </sqf> |
| | <spoiler text="Show all dog animations"> |
| | {{Columns|4| |
| | * "Dog_Idle_Stop" |
| | * "Dog_Idle_Walk" |
| | * "Dog_Die" |
| | * "Dog_Run" |
| | * "Dog_Sprint" |
| | * "Dog_Sit" |
| | * "Dog_Stop" |
| | * "Dog_Idle_01" |
| | * "Dog_Idle_02" |
| | * "Dog_Idle_03" |
| | * "Dog_Idle_04" |
| | * "Dog_Idle_05" |
| | * "Dog_Idle_06" |
| | * "Dog_Idle_07" |
| | * "Dog_Idle_08" |
| | * "Dog_Idle_09" |
| | * "Dog_Idle_10" |
| | * "Dog_Idle_Sit01" |
| | * "Dog_Idle_Sit02" |
| | * "Dog_Idle_Sit03" |
| | * "Dog_Idle_Sit04" |
| | * "Dog_Idle_Sit05" |
| | * "Dog_Idle_Sit06" |
| | * "Dog_Idle_Sit07" |
| | * "Dog_Idle_Sit08" |
| | * "Dog_Idle_Bark" |
| | * "Dog_Idle_Growl" |
| | * "Dog_Idle_Walk" |
| | * "Dog_Idle_Run" |
| | * "Dog_Idle_Sprint" |
| | * "Dog_TurnL" |
| | * "Dog_TurnR" |
| | }} |
| | </spoiler> |
|
| |
|
| It is very simple. All you need is playMove or switchMove commands and knowledge of available animation states, which override the default animal behaviour (see [[#Currently available animals|list of currently available animals]]). When you will do that, remember, the animal will remain in that state until you change it via script. And also keep in mind, that the animal '''agent''' (spawned via createAgent command) will be affected by FSM if you won't disbale it via [[BIS_fnc_animalBehaviour|BIS_fnc_animalBehaviour_disable]] variable!
| | === Sheep === |
|
| |
|
| === Example mission for VR map ===
| | <sqf> |
| | _sheep playMove "Sheep_Stop"; |
| | _sheep playMove "Sheep_Walk"; |
| | _sheep playMove "Sheep_Run"; |
| | _sheep playMove "Sheep_Idle_Stop"; // wandering, default behaviour |
| | </sqf> |
|
| |
|
| You can try this mission - simply create mission for VR map, copy and paste / create following two files and preview in editor. All dog actions are controllable via action menu. See [https://www.youtube.com/watch?v=0X8oumNj9kc this video] captured from this example mission.
| | === Goat === |
|
| |
|
| '''mission.sqm'''
| | <sqf> |
| <syntaxhighlight lang="cpp">version=12; | | _goat playMove "Goat_Stop"; |
| class Mission
| | _goat playMove "Goat_Walk"; |
| {
| | _goat playMove "Goat_Run"; |
| addOns[]=
| | _goat playMove "Goat_Idle_Stop"; // wandering, default behaviour |
| {
| | </sqf> |
| "a3_characters_f",
| | |
| "map_vr",
| | === Rabbit === |
| "A3_Characters_F_Civil"
| |
| };
| |
| addOnsAuto[]=
| |
| {
| |
| "A3_Characters_F_Civil",
| |
| "a3_characters_f",
| |
| "map_vr"
| |
| };
| |
| randomSeed=9626175;
| |
| class Intel
| |
| {
| |
| timeOfChanges=1800.0002;
| |
| startWeather=0;
| |
| startWind=0.1;
| |
| startWaves=0.1;
| |
| forecastWeather=0;
| |
| forecastWind=0.1;
| |
| forecastWaves=0.1;
| |
| forecastLightnings=0.1;
| |
| year=2035;
| |
| day=28;
| |
| hour=13;
| |
| minute=37;
| |
| startFogDecay=1;
| |
| forecastFogDecay=1;
| |
| };
| |
| class Groups
| |
| {
| |
| items=1;
| |
| class Item0
| |
| {
| |
| side="CIV";
| |
| class Vehicles
| |
| {
| |
| items=1;
| |
| class Item0
| |
| {
| |
| position[]={150,5,150};
| |
| id=0;
| |
| side="CIV";
| |
| vehicle="C_man_1";
| |
| player="PLAYER COMMANDER";
| |
| leader=1;
| |
| skill=0.60000002;
| |
| };
| |
| };
| |
| };
| |
| };
| |
| class Markers
| |
| {
| |
| items=4;
| |
| class Item0
| |
| {
| |
| position[]={100,5,200};
| |
| name="BURK_mrk1";
| |
| text="Marker 1";
| |
| type="hd_destroy";
| |
| colorName="ColorBlack";
| |
| };
| |
| class Item1
| |
| {
| |
| position[]={200,5,200};
| |
| name="BURK_mrk2";
| |
| text="Marker 2";
| |
| type="hd_destroy";
| |
| colorName="ColorBlack";
| |
| };
| |
| class Item2
| |
| {
| |
| position[]={200,5,100};
| |
| name="BURK_mrk3";
| |
| text="Marker 3";
| |
| type="hd_destroy";
| |
| colorName="ColorBlack";
| |
| };
| |
| class Item3
| |
| {
| |
| position[]={100,5,100};
| |
| name="BURK_mrk4";
| |
| text="Marker 4";
| |
| type="hd_destroy";
| |
| colorName="ColorBlack";
| |
| };
| |
| };
| |
| };
| |
| class Intro
| |
| {
| |
| addOns[]=
| |
| {
| |
| "map_vr"
| |
| };
| |
| addOnsAuto[]=
| |
| {
| |
| "map_vr"
| |
| };
| |
| randomSeed=15868174;
| |
| class Intel
| |
| {
| |
| timeOfChanges=1800.0002;
| |
| startWeather=0;
| |
| startWind=0.1;
| |
| startWaves=0.1;
| |
| forecastWeather=0;
| |
| forecastWind=0.1;
| |
| forecastWaves=0.1;
| |
| forecastLightnings=0.1;
| |
| year=2035;
| |
| day=28;
| |
| hour=13;
| |
| minute=37;
| |
| startFogDecay=0.0049999999;
| |
| forecastFogDecay=0.0049999999;
| |
| };
| |
| };
| |
| class OutroWin
| |
| {
| |
| addOns[]=
| |
| {
| |
| "map_vr"
| |
| };
| |
| addOnsAuto[]=
| |
| {
| |
| "map_vr"
| |
| };
| |
| randomSeed=5156929;
| |
| class Intel
| |
| {
| |
| timeOfChanges=1800.0002;
| |
| startWeather=0;
| |
| startWind=0.1;
| |
| startWaves=0.1;
| |
| forecastWeather=0;
| |
| forecastWind=0.1;
| |
| forecastWaves=0.1;
| |
| forecastLightnings=0.1;
| |
| year=2035;
| |
| day=28;
| |
| hour=13;
| |
| minute=37;
| |
| startFogDecay=0.0049999999;
| |
| forecastFogDecay=0.0049999999;
| |
| };
| |
| };
| |
| class OutroLoose
| |
| {
| |
| addOns[]=
| |
| {
| |
| "map_vr"
| |
| };
| |
| addOnsAuto[]=
| |
| {
| |
| "map_vr"
| |
| };
| |
| randomSeed=12604209;
| |
| class Intel
| |
| {
| |
| timeOfChanges=1800.0002;
| |
| startWeather=0;
| |
| startWind=0.1;
| |
| startWaves=0.1;
| |
| forecastWeather=0;
| |
| forecastWind=0.1;
| |
| forecastWaves=0.1;
| |
| forecastLightnings=0.1;
| |
| year=2035;
| |
| day=28;
| |
| hour=13;
| |
| minute=37;
| |
| startFogDecay=0.0049999999;
| |
| forecastFogDecay=0.0049999999;
| |
| };
| |
| };
| |
| </syntaxhighlight>
| |
|
| |
|
| '''init.sqf'''
| | <sqf> |
| <syntaxhighlight lang="cpp">waitUntil {!isNil "BIS_fnc_init"};
| | _rabbit playMove "Rabbit_Stop"; |
| waitUntil {time > 0.1};
| | _rabbit playMove "Rabbit_Hop"; |
| | _rabbit playMove "Rabbit_Idle_Stop"; // wandering, default behaviour |
| | </sqf> |
|
| |
|
| // Draw icons in 3D on marker positions
| | === Cockerel === |
| addMissionEventHandler ["Draw3D", {
| |
| drawIcon3D ["", [1, 1, 1, 0.75], [100, 200, 5], 0, 0, 0, "Marker 1", 1, 0.05, "PuristaMedium"];
| |
| }];
| |
|
| |
|
| addMissionEventHandler ["Draw3D", {
| | <sqf> |
| drawIcon3D ["", [1, 1, 1, 0.75], [200, 200, 5], 0, 0, 0, "Marker 2", 1, 0.05, "PuristaMedium"];
| | _cock playMove "Cock_Stop"; |
| }];
| | _cock playMove "Cock_Walk"; |
| | _cock playMove "Cock_Run"; |
| | _cock playMove "Cock_Idle_Stop"; // wandering, default behaviour |
| | </sqf> |
|
| |
|
| addMissionEventHandler ["Draw3D", {
| | === Hen === |
| drawIcon3D ["", [1, 1, 1, 0.75], [200, 100, 5], 0, 0, 0, "Marker 3", 1, 0.05, "PuristaMedium"];
| |
| }];
| |
|
| |
|
| addMissionEventHandler ["Draw3D", {
| | <sqf> |
| drawIcon3D ["", [1, 1, 1, 0.75], [100, 100, 5], 0, 0, 0, "Marker 4", 1, 0.05, "PuristaMedium"];
| | _hen playMove "Hen_Stop"; |
| }];
| | _hen playMove "Hen_Walk"; |
| | _hen playMove "Hen_Idle_Stop"; // wandering, default behaviour |
| | </sqf> |
|
| |
|
| // 3rd person view
| | === Snake === |
| player switchCamera "External";
| |
|
| |
|
| // Dog group and follow setup
| | <sqf> |
| createCenter CIVILIAN;
| | _snake playMove "Snakes_Stop"; |
| BURK_grp = createGroup CIVILIAN;
| | _snake playMove "Snakes_Move"; |
| BURK_dogFollowing = false;
| | _snake playMove "Snakes_Idle_Stop"; // wandering, default behaviour |
| | </sqf> |
|
| |
|
| // Spawn dog
| |
| BURK_dog = BURK_grp createUnit ["Fin_random_F", getPos player, [], 5, "CAN_COLLIDE"];
| |
|
| |
|
| // Following player fnc
| | == Examples == |
| BURK_dogFollowPlayer = {
| |
| BURK_dogFollowing = true;
| |
|
| |
| 0 = [] spawn {
| |
| while {BURK_dogFollowing} do
| |
| {
| |
| if (alive BURK_dog) then
| |
| {
| |
| BURK_dog doMove getPos player;
| |
| sleep 1;
| |
| };
| |
| };
| |
| };
| |
| };
| |
|
| |
|
| // Stop following fnc
| | === Script === |
| BURK_dogStopFollowing = {
| |
| BURK_dogFollowing = false;
| |
|
| |
|
| BURK_dog playMove "Dog_Idle_Stop";
| | Simple example for a dog to follow the player: |
| doStop BURK_dog;
| | <sqf> |
| };
| | // spawn dog |
| | _dog = createAgent ["Fin_random_F", getPosATL player, [], 5, "NONE"]; |
|
| |
|
| // Follow defined path fnc | | // disable animal behaviour |
| BURK_dogFollowPath = {
| | _dog setVariable ["BIS_fnc_animalBehaviour_disable", true]; |
| if (BURK_dogFollowing) then {
| |
| [] call BURK_dogStopFollowing;
| |
| };
| |
|
| |
| BURK_dog doMove getMarkerPos "BURK_mrk1";
| |
| waitUntil {(BURK_dog distance getMarkerPos "BURK_mrk1") < 1};
| |
|
| |
| BURK_dog doMove getMarkerPos "BURK_mrk2";
| |
| waitUntil {(BURK_dog distance getMarkerPos "BURK_mrk2") < 1};
| |
|
| |
| BURK_dog doMove getMarkerPos "BURK_mrk3";
| |
| waitUntil {(BURK_dog distance getMarkerPos "BURK_mrk3") < 1};
| |
|
| |
| BURK_dog doMove getMarkerPos "BURK_mrk4";
| |
| waitUntil {(BURK_dog distance getMarkerPos "BURK_mrk4") < 1};
| |
|
| |
| BURK_dog playMove "Dog_Idle_Stop";
| |
| doStop BURK_dog;
| |
| };
| |
|
| |
|
| // Actions for following | | // following loop |
| player addAction ["Dog: Start following player", {[] call BURK_dogFollowPlayer;}];
| | [_dog] spawn { |
| player addAction ["Dog: Stop following", {[] call BURK_dogStopFollowing;}];
| | params ["_dog"]; |
| player addAction ["Dog: Follow path (Markers 1 - 2 - 3 - 4)", {[] call BURK_dogFollowPath;}];
| |
|
| |
|
| // Actions for behaviour override | | // force dog to sprint |
| player addAction ["Dog: Default behaviour", {BURK_dog playMove "Dog_Idle_Stop";}];
| | _dog playMove "Dog_Sprint"; |
| player addAction ["Dog: Stop", {BURK_dog playMove "Dog_Stop";}];
| |
| player addAction ["Dog: Sit", {BURK_dog playMove "Dog_Sit";}];
| |
| player addAction ["Dog: Walk", {BURK_dog playMove "Dog_Walk";}];
| |
| player addAction ["Dog: Run", {BURK_dog playMove "Dog_Run";}];
| |
| player addAction ["Dog: Sprint", {BURK_dog playMove "Dog_Sprint";}];</syntaxhighlight>
| |
|
| |
|
| == Currently available animals ==
| | while { sleep 3; alive _dog } do |
| | { |
| | _dog moveTo getPosATL player; |
| | }; |
| | }; |
| | </sqf> |
|
| |
|
| === Dog === | | See in action: {{Link|https://www.youtube.com/watch?v{{=}}0X8oumNj9kc|YouTube}} |
|
| |
|
| Available states
| |
|
| |
|
| '''Stop:''' <syntaxhighlight lang="cpp">_dog playMove "Dog_Stop";</syntaxhighlight>
| | {{GameCategory|arma3|Editing}} |
| '''Sit:''' <syntaxhighlight lang="cpp">_dog playMove "Dog_Sit";</syntaxhighlight>
| | {{GameCategory|arma3|Tutorials}} |
| '''Walk:''' <syntaxhighlight lang="cpp">_dog playMove "Dog_Walk";</syntaxhighlight>
| |
| '''Run:''' <syntaxhighlight lang="cpp">_dog playMove "Dog_Run";</syntaxhighlight>
| |
| '''Sprint:''' <syntaxhighlight lang="cpp">_dog playMove "Dog_Sprint";</syntaxhighlight>
| |
| '''Back to default behaviour:''' <syntaxhighlight lang="cpp">_dog playMove "Dog_Idle_Stop";</syntaxhighlight>
| |