Jump to content
Sign in to follow this  
xxanimusxx

Some problems using attachTo and vectorUp

Recommended Posts

Hi there folks,

I've problems using the correct combination of attachTo and setVector-commands to accomplish a specific task. I've read some threads concerning similar problems, but couldn't find a solution to mine.

I'm writing a script for a mission of mine in which a heli squadron is spawned with the player as the squadron leader. The script expects the heli type and the number of AI helis to spawn.

Just for this case lets use "UH1Y" and 4 helis. The script spawns 5 helis, puts the player into the pilot seat of the main (or master) heli and arranges the four helis (with AI in them) in a V shape, with the main heli at the very front.

This is achieved using attachTo and varying offsets, which really works great so far.

Okay, now to my problem. Using attachTo really has it's downsides sometimes, like how all the helis will just pitch and bank in the same plane like the main heli - it looks just strange.

What I wanted to do is give the slave helis their own pitch and bank individually using the pitch and bank values from the main heli. And thus my martyrdom began....

First I tried this:

slave setVectorUp (vectorUp master);

(These commands are being executed for every heli in the squadron and in a while-loop, but it's easier to understand if I just show the code-line which actually should set their pitch/bank.)

Using the code above, I got really weird results. If I pitch to like 40°, the slaves would pitch to almost 60° and the discrepancy kept increasing for greater pitch values. Upon combining pitch and bank (flying a curve) they started to overturn themselfs and couldn't get into their original position.

Facing any other direction except North with the main heli had the effect that the slaves did nothing O_O They just got into their original position and changed their pitch/bank not until I faced north again.

Using

slave setVectorDirAndUp [vectorDir master, vectorUp master];

had the similar effect, but now they rotated around their own Z-axis everytime I did (not surprising tho, using the same direction vector and stuff..).

After I read some threads about how everything gets relative when using attachTo, I tried this:

slave setVectorDirAndUp [[0.001, 1, 0.001], vectorUp master];

And had the first success! Now the pitch is correctly set by all slaves, regardless of the direction I look to.

But the problem with the bank still prevails - the bank is only set when the main heli is facing north and I get really weird effects when I bank - like overturning slaves.

So what is the correct approach here? How do I set the pitch and bank of the slaves using the ones from the main heli?

This would be quite easy I guess if it wasn't for the fact that attachTo is used...

I uploaded a picture showing you another, simple formation with the first code from above. Like I said the pitch is no problem anymore, but the bank still is.

http://i41.tinypic.com/doq791.jpg (227 kB)

Share this post


Link to post
Share on other sites

I believe you can do advanced AI stuff with formations using FSM files, but I don't know anything about them. That's generally where people go when they want to make alterations to AI behavior.

Do you know that there are BIS functions to set and retrieve pitch and bank information. BIS_fnc_setpitchbank, BIS_fnc_getpitchbank? Remember with Vectors in Arma there's a rule, you must always set VectorDir before VectorUp.By the sounds of things, the pitchbank functions will solve your problem.

If I were doing what you wanted to do and the AI wasn't doing the job, I wouldn't use attachTo. I'd basically just hack together a delay where each wingman was copying my VectorDir\VectorUp from about 1 second ago.

The flow would be something like this

1) Fill an array with about 60 frames of Position and Vector data. (1 second @ 60FPS)

2) Send that to the left and right wingman, while filling up a new array.

3) The left and right helis will have their Ai disabled, and you'll simply setVectorDirAndUp for each, copying your players movements.

4) The left and right wingmen will then send that array to the next level down in the V

It sounds complicated, but it would actually be quite simple. For more advanced stuff you could probably use a boids algorithm.

http://www.kfish.org/boids/pseudocode.html

Share this post


Link to post
Share on other sites

The flow would be something like this

1) Fill an array with about 60 frames of Position and Vector data. (1 second @ 60FPS)

2) Send that to the left and right wingman, while filling up a new array.

3) The left and right helis will have their Ai disabled, and you'll simply setVectorDirAndUp for each, copying your players movements.

4) The left and right wingmen will then send that array to the next level down in the V

What happens when you drop below 60fps, though? Wouldn't this cause a cumulative error?

---------- Post added at 14:37 ---------- Previous post was at 14:34 ----------

I've never heard of this - wow! Off to play in the editor...

Share this post


Link to post
Share on other sites
What happens when you drop below 60fps, though? Wouldn't this cause a cumulative error?

Yeah probably, 60FPS was just an arbitrary number. If you look at the code for BIS_fnc_unitplay they get around this problem using setvelocitytransformation in a clever way by interpolating based on the frame rate you're getting.

Share this post


Link to post
Share on other sites

Well, I had a ton of fun playing around with this today. I managed to get to the point where I have a second helo flying formation, maintaining altitude, heading, pitch, bank, and yaw. It would be relatively easy to add more aircraft, and even create more complex formations.

Issues:

This is better suited to fixed-wing aircraft, as the behavior of the formation is closer to that of an aerobatics team. It is very unnatural for helos, particularly when making big movements, yawing in particular. Also, the other aircraft will not avoid terrain, so NOE flying is a bad idea. I'm sure these things can be ironed out, but there are only so many hours in the day. I also suspect it will require a bit of math. I was told there would be no math.

http://www.youtube.com/watch?v=maDTEcJNizc

=====

init.sqf:

getRelPos = compile preprocessfile "getRelPos.sqf";

getRelPos.sqf (by AliMag):

private ["_obj","_dis","_posX","_posY","_posZ","_dir","_pos"];

_obj = _this select 0;
_dis = _this select 1;
_dir = _this select 2;

_posX = getPos _obj select 0;
_posY = getPos _obj select 1;
_posZ = getPosASL _obj select 2;
_pos = [_posX + ((sin _dir) * _dis), _posY + ((cos _dir) * _dis),_posZ];
_pos

Place player helo, flying. Named "a1".

Place a small object (I used a baseball), hide it, name it "a2". This is the reference point for the formation.

Place wingman helo, flying, named "a3".

Call "formation.sqf" ( I used an invisible helo pad):

private ["_dir","_distance","_pos"];

while {true} do {

//place outer reference point for formation

_dir = (getDir a1) -90;
a2 setPosASL ([a1,100,_dir] call getRelPos);

//set formation

_distance = 25/(a1 distance a2);  //maintains constant distance, change "25" to whatever value desired
_pos = [getPosASL a1, getPosASL a2, velocity a1, velocity a2, vectorDir a1, vectorDir a2, vectorUp a1, vectorUp a2, _distance];
a3 setVelocityTransformation _pos;
};

Edited by Harzach

Share this post


Link to post
Share on other sites

All righty, here's another try, using seven F-35s in a wedge formation. Here you'll see that my code is inefficient, characterized by the stuttering of the "slave" planes.

http://youtu.be/8rjv36XIFuE

=====

formation.sqf:

private ["_time","_arr","_dir1","_dir2","_dir3","_port","_stbd","_aft"];

_port = [p2,p3];
_stbd = [p4,p5];
_aft = [p6,p7];

while {true} do {

//place outer reference point(s) for formation

_dir1 = (getDir p1) -135;
_dir2 = (getDir p1) +135;
_dir3 = (getDir p1) -180;

a1 setPosASL ([p1,500,_dir1] call getRelPos);
a2 setPosASL ([p1,500,_dir2] call getRelPos);
a3 setPosASL ([p1,500,_dir3] call getRelPos);

//set formation

for "_i" from 0 to 1 do {
_time = (_i+1)*.1; //intervals
_arr = [getPosASL p1, getPosASL a1, velocity p1, velocity a1, vectorDir p1, vectorDir a1, vectorUp p1, vectorUp a1, _time];
(_port select _i) setVelocityTransformation _arr;
};

for "_i" from 0 to 1 do {
_time = (_i+1)*.1;
_arr = [getPosASL p1, getPosASL a2, velocity p1, velocity a2, vectorDir p1, vectorDir a2, vectorUp p1, vectorUp a2, _time];
(_stbd select _i) setVelocityTransformation _arr;
};	

for "_i" from 0 to 1 do {
_time = (_i+1)*.1;
_arr = [getPosASL p1, getPosASL a3, velocity p1, velocity a3, vectorDir p1, vectorDir a3, vectorUp p1, vectorUp a3, _time];
(_aft select _i) setVelocityTransformation _arr;
};	
};

Edited by Harzach

Share this post


Link to post
Share on other sites

Sorry for the late response, I tried out several things and wanted to be sure before I post something.

Thanks to KK and Harzach, this was exactly the thing I was searching for. It has some demerits though, so I'd like to discuss this with you guys.

Is using setPosASL and/or (especially) setVelocityTransformation in a while-loop frequently without any delays more expensive then using an attachTo considering network load in a MP mission?

I'd have used setPosASL and simple angle calculations to perform similiar linear transformations like setVelocityTransformation does, but didn't even think about it because I've had performance issues some time ago.

But if setVelocityTransformation won't cause any major network problems, I'm willing to use it instead of attachTo.

I'd have hoped to be able to implement a slight delay before the vectorUP is applied to the helos in order to give them something like a reaction time so the animation won't look like completely scripted, how Harzach mentioned already.

But doing so leads to uncomely stutters while the helo is trying to align itself ... :S

Furthermore using attachTo disables damage handling somehow so the helos can crash against objects without taking damage - which is a good thing actually if you want to do some NOE flying but I found a way to avoid most of the damage by elevating the helos if the main helo is under a certain altitude.

Deactivating damage handling for the helos won't work if they actually crash against objects, is there a way to prevent them blowing up nevertheless?

Last thing is: what does visiblePositionASL do in contrast to getPosASL? I get the same values using both of them, so is visiblePositionASL faster for some reason?

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×