Home   Help Search Login Register  

Author Topic: Controlling a large number of AI  (Read 2465 times)

0 Members and 1 Guest are viewing this topic.

Offline ZapBrannigan

  • Members
  • *
Controlling a large number of AI
« on: 10 Oct 2011, 06:45:34 »
Hi,

I need a large number of AI to move in lines along a very precise path. Normally when its just 1 AI I will record the cords of points along the path i want them to take then guide them through the points.  Just for 1 AI guy it takes an hour or so to get it right.  But now i have a large number of AI.  more than 20.  If i get points for each of them it will take weeks to get it right.  

I was wondering if there was any way I could be the player and run the path, and then have the game automatically record the points along the path and then put them into a script that will make an AI soldier follow them.

thanks
« Last Edit: 10 Oct 2011, 06:48:55 by ZapBrannigan »

Offline F2kSel

  • Members
  • *
Re: Controlling a large number of AI
« Reply #1 on: 11 Oct 2011, 17:29:47 »
It is possible to use unitcapture to record the path of the player however it will only playback correctly for vehicles mostly aircraft.  A soldier would have no animations.

You could make a recording by using a radio trigger or action menu to store the players current X,Y position into an array and then convert that array to a series of waypoints but it will never be 100% accurate.






Offline ZapBrannigan

  • Members
  • *
Re: Controlling a large number of AI
« Reply #2 on: 11 Oct 2011, 19:36:36 »
but that only works in OA right?

Offline F2kSel

  • Members
  • *
Re: Controlling a large number of AI
« Reply #3 on: 11 Oct 2011, 21:27:17 »
I think your right unitcapture is only OA so your stuck with the second method.

If you want to try it it would go like this.

Place your player on the map and in his init put
Code: [Select]
store = [];what = player addaction ["Store", "Store.sqf"];
save as Store.sqf
Code: [Select]
while {true} do {

waituntil {(speed player != 0)};// wait until player is moving
store = store + [getpos player];// store player pos it store arrray

copyToClipboard (str store);// copy the array to the clip board so you can paste it later
sleep 1; // deleay to reduce the amount of data

hint format ["%1",store];// will display the x,y,z to the screen
};


To Play back the waypoints  and set up a second unit as player and leave the original unit in position and change it's init line to
Code: [Select]
null=[this]  execvm "play.sqf";
You will need to paste the data from your clipboard and past it directly into the playback =  line  it should look like this but with  more data points.

_playback = [[3552.26,3605.09,0.00143814],[3575.24,3606.41,0.00143814]];

save as play.sqf
Code: [Select]
_playback =   // copy the data from clipboard to this position
_unit = _this select 0;
_countwaypoints = count _playback;

while {count _playback > 0} do {
_WP = group _unit addWaypoint [_playback select 0, 0];
_WP SetWaypointType "MOVE";

_playback  set [0,-1];
_playback = _playback - [-1] ;
sleep 0.1;
};

The second script creates multiple waypoints using the data captured in Store, the usefulness  could be extended I guess by adding more data to capture such as speed , behaviour direction ect.

Offline ZapBrannigan

  • Members
  • *
Re: Controlling a large number of AI
« Reply #4 on: 12 Oct 2011, 05:45:18 »
thanks for your reply


It works but there's a problem, a pause between each waypoint, so he runs then stops then runs then stops, I want him to run through the points without stopping.

A second problem is, he wont go to the waypoints if there are enemies or he is being shot at
Is there a way to do this without using waypoints?

I want something that will force him to go wherever i want.   I was using animation loops and a script that found the direction to the target and then setdir'd him to face it and play the run animation.   SO how could i use that to make him go to the points.   So if i use this script below.  How could i make _tgt be each recorded point to go to.





#loop

? (((GetPos _Tgt select 1) - (GetPos _Unit select 1)) > 0): _Ang = ATan (((GetPos _Tgt select 0) - (GetPos _Unit select 0)) / ((GetPos _Tgt select 1) - (GetPos _Unit select 1)))
? (((GetPos _Tgt select 1) - (GetPos _Unit select 1)) < 0): _Ang = ATan (((GetPos _Tgt select 0) - (GetPos _Unit select 0)) / ((GetPos _Tgt select 1) - (GetPos _Unit select 1))) + 180
? _Ang < 0: _Ang = _Ang + 360

_unit setdir _ang
_unit playmove "AmovPercMevaSrasWrflDf"

~.2
goto "loop"
« Last Edit: 12 Oct 2011, 06:00:15 by ZapBrannigan »

Offline F2kSel

  • Members
  • *
Re: Controlling a large number of AI
« Reply #5 on: 12 Oct 2011, 09:47:45 »
That has always been a problem with waypoints they seem to have to evaluate at the direction at each waypoint.

I see what your doing in your code, it should be possible and I think there is a function that returns the direction of an unit relative to target so you would need to update the direction.




 

Offline ZapBrannigan

  • Members
  • *
Re: Controlling a large number of AI
« Reply #6 on: 12 Oct 2011, 11:03:27 »
yeah it works, im just wondering how would i input the data i recorded using your thing. Into my animation loop with direction script

all i need to do is

1. take the first coordinate of the recorded data,  and name it _tgt

2. find the direction the unit should face to get to _tgt and setdir the unit to face that way. using this code here
Code: [Select]
? (((GetPos _Tgt select 1) - (GetPos _Unit select 1)) > 0): _Ang = ATan (((GetPos _Tgt select 0) - (GetPos _Unit select 0)) / ((GetPos _Tgt select 1) - (GetPos _Unit select 1)))
? (((GetPos _Tgt select 1) - (GetPos _Unit select 1)) < 0): _Ang = ATan (((GetPos _Tgt select 0) - (GetPos _Unit select 0)) / ((GetPos _Tgt select 1) - (GetPos _Unit select 1))) + 180
? _Ang < 0: _Ang = _Ang + 360

_unit setdir _ang

3.  create a loop that plays the running forward animation over and over until the unit arrives at the coordinate

4. takes the second coordinate and does the same thing. over and over until there are no more coordinates left.

Thanks a ton

« Last Edit: 12 Oct 2011, 11:05:32 by ZapBrannigan »

Offline F2kSel

  • Members
  • *
Re: Controlling a large number of AI
« Reply #7 on: 12 Oct 2011, 13:00:08 »
Yea as the data would be in an array you only need to point to that element or remove the completed element from the array and run again.

Perhaps something like this, I probably have the wrong syntax as I mostly use sqf and I can't test right now.



Code: [Select]
_Tgt = [];// your data would go here

while {count _Tgt > 0} do {

? (((GetPos _Tgt select 1) - (GetPos _Unit select 1)) > 0): _Ang = ATan (((GetPos _Tgt select 0) - (GetPos _Unit select 0)) / ((GetPos _Tgt select 1) - (GetPos _Unit select 1)))
? (((GetPos _Tgt select 1) - (GetPos _Unit select 1)) < 0): _Ang = ATan (((GetPos _Tgt select 0) - (GetPos _Unit select 0)) / ((GetPos _Tgt select 1) - (GetPos _Unit select 1))) + 180
? _Ang < 0: _Ang = _Ang + 360

_unit setdir _ang

 ? (_unit distance (_Tgt select 1) <1) :_Tgt  set [0,-1];_Tgt = _Tgt - [-1] ;// remove the element from the array
sleep 0.1;

}

I would expect an error to crop up at the last waypoint, but we could look at that later.
The other problem could be the distance, I'm not sure how close you can get a unit to walk.

This bit may be wrong  ? (_unit distance (_Tgt select 1) <1) :
« Last Edit: 12 Oct 2011, 13:16:22 by F2kSel »

Offline ZapBrannigan

  • Members
  • *
Re: Controlling a large number of AI
« Reply #8 on: 12 Oct 2011, 15:05:23 »
Yeah that's not working :/

How about this

Code: [Select]
_playback =  [[3521.44,3594.3,0.00143814],[3521.27,3594.32,0.00143814],[3521.01,3594.35,0.00143814]]
_unit = _this select 0
_targetcount = count _playback

_count = 1

#loop1
_Target = (_playback select _count)


#innerloop
? (_unit distance _Target)<1: goto "continue"


? (((GetPos _Target select 1) - (GetPos _unit select 1)) > 0): _direction = ATan (((GetPos _Target select 0) - (GetPos _unit select 0)) / ((GetPos _Target select 1) - (GetPos _unit select 1)))
? (((GetPos _Target select 1) - (GetPos _unit select 1)) < 0): _direction = ATan (((GetPos _Target select 0) - (GetPos _unit select 0)) / ((GetPos _Target select 1) - (GetPos _unit select 1))) + 180
? _direction < 0: _direction = _direction + 360
_unit setdir _direction
_unit playmove "AmovPercMevaSrasWrflDf"

~.2
goto "innerloop"

#continue
player setdamage 1
_count = (_count + 1)
?(_targetcount > _count) : exit
goto "loop1"




I tried it, the unit just runs straight ahead.  any ideas on what the problem is with this script?

Offline F2kSel

  • Members
  • *
Re: Controlling a large number of AI
« Reply #9 on: 12 Oct 2011, 15:35:53 »
I can't tell without testing.

 I've not done much with playmove animation, does it have to play out before it can change direction.

Try placing some hints in the script to see if the loops are running and the variables are returning the right numbers.

 

Offline ZapBrannigan

  • Members
  • *
Re: Controlling a large number of AI
« Reply #10 on: 12 Oct 2011, 17:00:51 »
I got it working, the problem was i used getpos _target select 1   when i should have used  _target select 1

Thank you for your help F2ksel