Jump to content
Sign in to follow this  
Horner

How to determine if one unit is behind another unit.

Recommended Posts

So, I'd like to be able to find out if a certain unit is behind another unit, I've got it kind of figured but I have no way to determine for sure. Here's some pseudocode for it.


_unit = (nearestObjects [getPos player, ["Man"], 5]) select 0;
_isBehind = false;

// Player is facing 360 degrees
_dir = getDir player;

// Player is directly behind, should return 195
_dirTo = [player, _unit] call BIS_fnc_dirTo;

// Calculate

Basically, with dirTo I'd like to calculate a certain field of degrees. Basically directly behind the player would be 180 degrees right? So I would like to check if a player is in a field + 20 from 180 or - 20 from 180. But with degress not always being in the 0-360 degree field (sometimes you have -30 or 780 or numbers like that). This may or may not be a shitty explanation, but if you can help it's much appreciated :)

Share this post


Link to post
Share on other sites

Different approach, but maybe result you were after...

_obj1    = _this select 0;
_obj2    = _this select 1;

_ang = ((getPos _obj2 select 0)-(getPos _obj1 select 0)) atan2 ((getPos _obj2 select 1)-(getPos _obj1 select 1));
_dif = (_ang - getDir _obj1);
if (_dif < 0) then {_dif = 360 + _dif;};
if (_dif > 180) then {_dif = _dif - 360;};
if ((abs(_dif) > 160) && (abs(_dif) < 200))  then
{
  _isBehind = true;
}
else
{
  _isBehind = false;
};

not tested

Share this post


Link to post
Share on other sites

I found a way to do it. Here it is for those who want it.

The main function that determines the bool value of whether or not one unit is behind the other.

private["_unit1","_unit2","_pos1","_pos2","_dir","_dirTo","_isBehind","_ret","_startDir","_dirs"];

_unit1 = _this select 0;
_unit2 = _this select 1;
_pos1 = getPos _unit1;
_pos2 = getPos _unit2;

_dir = getDir _unit1;
_dirTo = ((_pos2 select 0) - (_pos1 select 0)) atan2 ((_pos2 select 1) - (_pos1 select 1));

_dir = [_dir] call hrn_fnc_correctDir;
_dirTo = [_dirTo] call hrn_fnc_correctDir;

_isBehind = false;

// player groupChat (str _dir);
// player groupChat (str _dirTo);

_startDir = round ([_dir - 160] call hrn_fnc_correctDir);
_dirs = [];

for [{_i = 0},{_i < 40},{_i = _i + 1}] do
{
_dirs = _dirs + [[(_startDir - _i)] call hrn_fnc_correctDir];
};

if ((round _dirTo) in _dirs) then
{
_isBehind = true;
};

_ret = _isBehind;
_ret

And here is the function that corrects the degree values to be between 0-360.

private["_dir","_ret"];

_dir = _this select 0;

if (_dir < 0) then
{
while {_dir < 0} do
{
	_dir = _dir + 360;
};
};

if (_dir > 360) then
{
while {_dir > 360} do
{
	_dir = _dir - 360;
};
};

_ret = _dir;
_ret

Also, I'm not sure if your method would work, as abs just takes the negative value and turns it into a positive, so if you have -160 in your function it will turn it into 160 degress, where it should be 200 degrees :)

Edited by Horner

Share this post


Link to post
Share on other sites

Maybe I'm just posting more nonsense, but couldn't you just use the bi function?

_InFront = [Me,You,0] Call [url="http://www.ofpec.com/COMREF/index.php?action=read&id=231#isinfrontof"]BIS_Fnc_IsInFrontOf[/url];
If (_InFront) Then {Hint "He's in front"} Else { Hint "He's in back"};

If not, then maybe you can look and see how they did it, and maybe tweak some values to make it essentially "IsInBackOf"?

Edited by Iceman77

Share this post


Link to post
Share on other sites

One of functions, that I give you for EFL does that too. Very similar to panther42's method, but with one difference. Works fine.

WhereIs

If you want this function in EFL, then note one change there. Fix was needed, as for some reason where this works:

if (_angle < 0) then {_angle = _angle + 360};
if (_axis < 0) then {_axis = _axis + 360};

This doesn't:

	{
if (_x < 0) then {_x = _x + 360}
}
foreach [_angle,_axis];

Some array or foreach'es _x thing perhaps.

Share this post


Link to post
Share on other sites

@Iceman, I like to avoid using BIS functions as much as possible, just because of the requirement of the functions logic. I don't know how many times I've written like 300 lines of code for a mission and sat there for HOURS trying to figure out why it's not working just to realize it's because I don't have a functions logic...

@Ryd

Still working on adding your huge list of functions into Ext Fnc Lib, I'll see which one would be better to use. Thanks :)

Share this post


Link to post
Share on other sites
... sat there for HOURS trying to figure out why it's not working just to realize it's because I don't have a functions logic...

Haha, yeah I know what you mean.

Share this post


Link to post
Share on other sites

@Horner omg that comment just makes me want to pull my hair... so frustrating when I do that.

Share this post


Link to post
Share on other sites

Spawn the module in init.sqf?

_funchq = createCenter sideLogic;
_group = createGroup sideLogic;
_fmodle = (_group) createunit ["FunctionsManager",position player,[],0,"NONE"];

As long as you have the check at the top of the scripts that need it - shouldn't be a problem?

waitUntil {!isNil "bis_fnc_init"};

Edited by Mattar_Tharkari

Share this post


Link to post
Share on other sites

It's also a matter of learning how to do things myself instead of relying on BIS functions, :p

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  

×