wildbill2016 1 Posted April 23, 2018 So in the initialization script I defined a unit group like this townenemy = ["wp1_enemy1","wp1_enemy2","wp1_enemy3","wp1_enemy4","wp1_enemy5","wp1_enemy6"]; and I want to use a trigger to disable their AI, when the player lefts the trigger. so I use the for each loop and the magic variable. But it always pops up a generic error.. { _x disableAI "TARGET"; } forEach _townenemy; { _x disableAI "TARGET"; } forEach townenemy; { _x disableAI "TARGET"; } forEach units townenemy; { _x disableAI "TARGET"; } forEach units _townenemy; None of the above works.. Is that I missed something? 1 Share this post Link to post Share on other sites
Grumpy Old Man 3540 Posted April 23, 2018 If in doubt, check the wiki. disableAI requires object as first and string as second parameter. You're passing a string as a first parameter, hence it doesn't work. I guess wp1_enemy1 etc. are the variable names of editor placed units? Just remove the quotation marks inside townenemy array then. Cheers 1 Share this post Link to post Share on other sites
Harzach 2507 Posted April 23, 2018 In addition, your second code is the correct one: { _x disableAI "TARGET"; } forEach townenemy; You wouldn't use _townenemy because that's a local variable that you have not defined. Also, units returns the members of a group, and so would only work if townenemy was defined as such. https://community.bistudio.com/wiki/Variables https://community.bistudio.com/wiki/units 2 Share this post Link to post Share on other sites
zonekiller 174 Posted April 23, 2018 Quote So in the initialization script I defined a unit group like this I guess wp1_enemy1 etc. are group names? so if townenemy is an array of group names and not unit names it would need to look like this as you will need to loop through all the units in each group as DisableAI only works with objects not groups Syntax: unitName disableAI section Parameters: unitName: Object - AI unit Just remove the quotation marks inside townenemy array then loop through each unit in each group. you could do something like this townenemy = [wp1_enemy1,wp1_enemy2,wp1_enemy3,wp1_enemy4,wp1_enemy5,wp1_enemy6]; { { _x disableAI "TARGET"; } forEach units _x; } forEach townenemy; // it will run the red code for all units in selected group (_x) before continuing on to the next loop in townenemy //(yes i know there are 2 _Xs that is because each _x is only local to whats between {} ) or for "_i" from 0 to ((count townenemy) - 1) do { { _x disableAI "TARGET"; } forEach units (townenemy select _i); }; or townenemy_units = []; // create an empty array {townenemy_units pushBack units _x } forEach townenemy; // add all the units from groups into one array { _x disableAI "TARGET"; } forEach townenemy_units; // run code on each unit Hope this helps 1 Share this post Link to post Share on other sites
Harzach 2507 Posted April 23, 2018 6 minutes ago, zonekiller said: I guess wp1_enemy1 etc. are group names? I read it as he was trying to create a group by placing units (wp1_enemy#) into an array (townenemy) , which of course will not work, but which was irrelevant to his process further down the line. I hadn't considered the possibility of the scenario you describe - lots of useful info in your post! Share this post Link to post Share on other sites
zonekiller 174 Posted April 23, 2018 Quote I read it as he was trying to create a group by placing units (wp1_enemy#) into an array (townenemy) that could be that case also then it would be townenemy = [wp1_enemy1,wp1_enemy2,wp1_enemy3,wp1_enemy4,wp1_enemy5,wp1_enemy6]; { _x disableAI "TARGET"; } forEach townenemy; Share this post Link to post Share on other sites
wildbill2016 1 Posted April 25, 2018 On 2018/4/22 at 10:53 PM, Grumpy Old Man said: If in doubt, check the wiki. disableAI requires object as first and string as second parameter. You're passing a string as a first parameter, hence it doesn't work. I guess wp1_enemy1 etc. are the variable names of editor placed units? Just remove the quotation marks inside townenemy array then. Cheers On 2018/4/22 at 11:01 PM, Harzach said: In addition, your second code is the correct one: { _x disableAI "TARGET"; } forEach townenemy; You wouldn't use _townenemy because that's a local variable that you have not defined. Also, units returns the members of a group, and so would only work if townenemy was defined as such. https://community.bistudio.com/wiki/Variables https://community.bistudio.com/wiki/units On 2018/4/23 at 5:10 PM, zonekiller said: I guess wp1_enemy1 etc. are group names? so if townenemy is an array of group names and not unit names it would need to look like this as you will need to loop through all the units in each group as DisableAI only works with objects not groups Syntax: unitName disableAI section Parameters: unitName: Object - AI unit Just remove the quotation marks inside townenemy array then loop through each unit in each group. you could do something like this townenemy = [wp1_enemy1,wp1_enemy2,wp1_enemy3,wp1_enemy4,wp1_enemy5,wp1_enemy6]; { { _x disableAI "TARGET"; } forEach units _x; } forEach townenemy; // it will run the red code for all units in selected group (_x) before continuing on to the next loop in townenemy //(yes i know there are 2 _Xs that is because each _x is only local to whats between {} ) or for "_i" from 0 to ((count townenemy) - 1) do { { _x disableAI "TARGET"; } forEach units (townenemy select _i); }; or townenemy_units = []; // create an empty array {townenemy_units pushBack units _x } forEach townenemy; // add all the units from groups into one array { _x disableAI "TARGET"; } forEach townenemy_units; // run code on each unit Hope this helps Hi guys, thanks again (And thanks for the additional info about the loop nesting). It's the double quotation marks.... And I define the group of townunits in another .sqf file. Maybe global variables should be defined in certain script like init.? When I define the array of units in another custom script and tried to access the array from another script, there is an undefined variable error. It is removed after I copy and paste the array definition to the disable AI execution script.. Share this post Link to post Share on other sites
Harzach 2507 Posted April 25, 2018 2 hours ago, wildbill2016 said: When I define the array of units in another custom script and tried to access the array from another script, there is an undefined variable error. It is removed after I copy and paste the array definition to the disable AI execution script.. Most likely, the variable is being defined after is is being called. Sometimes it's tricky to get things initialized at the right time, but this might help: https://community.bistudio.com/wiki/Initialization_Order Share this post Link to post Share on other sites
zonekiller 174 Posted April 26, 2018 A simple way to explain it is _townenemy would only be local to a script or within {some code}; townenemy is local to every script and can be changed by other scripts _townenemy = [wp1_enemy1,wp1_enemy2,wp1_enemy3,wp1_enemy4,wp1_enemy5,wp1_enemy6]; { _x disableAI "TARGET"; } forEach _townenemy; // would be local to the script that it is run on and cant be changed by other scripts also what you would have to be careful if your units die and are not respawned so if wp1_enemy1 died then that variable no longer exists and will give an error when referenced one way to get around this would be townenemy = ["wp1_enemy1","wp1_enemy2","wp1_enemy3","wp1_enemy4","wp1_enemy5","wp1_enemy6"]; // global string array can be read from all scripts if added to an init.sqf script in the script you wish to change the target setting _townenemy = []; // create an empty array {if !(isnil {call compile _x}) then {_townenemy pushBack _x }} forEach townenemy; // add all the alive units into a local array from the global array { _x disableAI "TARGET"; } forEach _townenemy; // would be local to the script that it is run on and cant be changed by other scripts //(call compile _x) converts a string back to an object, ie _object = call compile _string; // if !(isnil {call compile _x}) // checks if it is a variable that exists Share this post Link to post Share on other sites
Grumpy Old Man 3540 Posted April 26, 2018 2 hours ago, zonekiller said: {if !(isnil {call compile _x}) then {_townenemy pushBack _x }} forEach townenemy; // add all the alive units into a local array from the global array You're using 4 commands (isNil, call, compile, pushBack) in an if then statement inside a forEach loop, not the most practical way and takes quite some time to run. Assuming only the last one is alive the above can be condensed as follows: //original example: //init array once before performance test townenemy = ["wp1_enemy1","wp1_enemy2","wp1_enemy3","wp1_enemy4","wp1_enemy5","wp1_enemy6"]; //performance test {if !(isnil {call compile _x}) then {_townenemy pushBack _x }} forEach townenemy;//runs for 0.0137ms, if only wp1_enemy6 exists in mission //improved example: //init array once before performance test townenemy = [wp1_enemy1,wp1_enemy2,wp1_enemy3,wp1_enemy4,wp1_enemy5,wp1_enemy6];//use objects instead of strings //performance test _townenemy = townenemy select {alive _x};//runs for 0.004ms, if only wp1_enemy6 exists in mission You can use "alive" to check if something exists, it will return nothing if not alive or non existant and the select command acts accordingly. Improved example takes only 0.004ms, instead of 0.0137, which is a third of the runtime. Cheers 1 Share this post Link to post Share on other sites