Jump to content
johnnyboy

Detect unit clipped under building or rock

Recommended Posts

I'm currently dealing with large Prairie Fire craters, which are technically building objects.  Sometimes when entering a crater, a unit clips or "ghosts" under the crater (building), instead of walking up slope and down into crater.

 

How can I detect this condition?  I want to teleport him back up to be on top of crater if this occurs.

 

Forums have been rather dead lately, I hope there is a smart guy out there that can help!  🙂

Share this post


Link to post
Share on other sites

Hey j-buddy, I've run into this exact same problem.  I think I handled it like this:

 

Check his getPosASL (or perhaps a bit lower) to his eyepos (which is also ASL) for object(s) via lineIntersectsSurfaces or similar.  If you get a hit, pop him up above.

 

You probably want to check on every frame.  One side effect is, you might end up with dudes up on top of objects where it doesn't make much sense for them to be.  Like up on a roof with no access, etc.  If you're only doing this for crater entry/exit, you'll probably be ok.  If you want, I can post some relevant code over PM.

  • Thanks 1

Share this post


Link to post
Share on other sites

What MadRussian said you could use https://community.bistudio.com/wiki/lineIntersectsSurfaces. Here is a example i got from a mod called: Anti Wall Glitch Fix by Nerexis
Check for is unit gliching:
 

if (NER_antiWallGlitch_checkHead) then {
	_obstacles = lineIntersectsSurfaces [
		[(eyePos _unit select 0) + (eyeDirection _unit select 0)*NER_antiWallGlitch_distance_head, (eyePos _unit select 1) + (eyeDirection _unit select 1)*NER_antiWallGlitch_distance_head, (eyePos _unit select 2) + (eyeDirection _unit select 2)*NER_antiWallGlitch_distance_head],
		eyePos _unit,
		_unit,
		objNull,
		false,
		NER_antiWallGlitch_checkMaxResultsCount,
		NER_antiWallGlitch_checkGeom,
		NER_antiWallGlitch_checkGeom,
		true
	];
	_isGlitching = count _obstacles > 0;
};

And here is a teleport fnc that will teleport unit if he is glitching:

params["_unit"];
private _force = NER_antiWallGlitch_punishByTeleport_strength;
private _oppositeVelocity = vectorNormalized ( (velocity _unit) vectorMultiply -1);
private _oppositeVelocityWithForce = _oppositeVelocity vectorMultiply _force;

_unit setPos ((getPos _unit) vectorAdd _oppositeVelocityWithForce);

 

  • Like 1

Share this post


Link to post
Share on other sites
37 minutes ago, johnnyboy said:

Forums have been rather dead lately, I hope there is a smart guy out there that can help!  🙂

Well this quote didn't age well, lol!  I got two great responses within minutes of asking!  This forum still rocks!

  • Like 2

Share this post


Link to post
Share on other sites

Well, this is a recurring issue (a sea serpent as we say in French).
As open discussion, I'm on a test. Scripting a scenario for Gabreta (CSLA), I remarked multiple AIs stuck inside houses or even rocks, and no way for further move (ordered by leader).
 

Spoiler

 

With this additional very bad trip, about leader orders on AIs:
https://feedback.bistudio.com/T161166

https://www.youtube.com/watch?v=jgcMEkcOPKo

 

 

So, 2 things, not really related:
- units stuck at spawn:  "just" need a right placement along with obstacles/houses/trees, depending on type of (infantry or vehicle or plane or ship),

- units stuck during a move order, waypoint.... to destination

 

Here is my WIP test:
 

["stuckUnits","onEachFrame",{  
  if (diag_frameno mod 60 isEqualTo 0) then {  // That's my 2 cent contrib for dampening a code without necessity to run every frame! Cherry on the cake, the code occurrence is f(FPS)
    {
      if (speed _x isEqualTo 0  && {expectedDestination _x#1 in ["DoNotPlan"]} && {expectedDestination _x#0 distance2D _x > 3} && {lifeState _x in ["HEALTHY","INJURED"] && isNull objectParent _x}) then {  
        if (_x getVariable ["presPos",FALSE]) then {
          _x setVariable ["presPos",FALSE];
          private _surfaces = lineIntersectsSurfaces [getPosASL _x vectorAdd [0,0,50], getPosASL _x,_x,objNull,TRUE,1,"GEOM","VIEW",TRUE];
          if ( _surfaces isNotEqualTo [] && {!(_surfaces #0#3 in nearestTerrainObjects [_x,["TREE"],20])}) then {

////////////// debug occurrence
_mk = createMarker [str random 1,ASLToAGL _surfaces #0#0];
_mk setMarkerType "hd_objective";
_mk setMarkerText format ["%1 is stuck",_x];
hint "marker Stuck created";
systemChat format ["unit %1 is stuck!",_x];
/////////////

            _x setPosASL (_surfaces #0#0);   // move the unit on top of the obstacle (could be move it somewhere safe, as well)
          };
        } else {
          _x setVariable ["presPos",TRUE]
        };
      };
    } forEach (units player - [player]);   // at this level, concern AIs in player group only
  };  
}] call BIS_fnc_addStackedEventHandler;

 

The first condition:

(speed _x isEqualTo 0  && {expectedDestination _x#1 in ["DoNotPlan"]} && {expectedDestination _x#0 distance2D _x > 3} && {lifeState _x != "incapacitated" && isNull objectParent _x})

That's the core of the problem: When can we say a unit is stuck?

  • speed 0 is not so often, sometimes unit "stutters" on place. On the other end, this is a reliable point.
  • expectedDestination is a jungle of possibilities, along with move ordered or not, destination reached or not, possible path or not, deputy leader or not!... Difficult to choose but I remarked a "DoNotPlan" return when unit fails to reach the position, or arrives at the destination. So the distance from unit to destination is decisive (may be).
  • lifeState must be filtered also, as dead, dead-respawned, incapacitated are always "DoNotPlan" and not at destination (which can shift for [0,0,0]!)
  • units in vehicle are also wrongly detected as stuck with this condition

 

The second (if then else) condition, around _x getVariable ["presPos",FALSE] is a switch for running the code at second occurrence when 1st condition met (condition is lasting 2 loops)

The third condition : _surfaces isNotEqualTo [] && {!(_surfaces #0#3 in nearestTerrainObjects [_x,["TREE"],20])})  is for ceiling detection (rocks, houses) but tree branches.

Well, I hope someone could help improving that. I tried to find a getter for AI's situation when yelling "No, sir" or "Negative", or... other warnings.

 

Spoiler

 

I also tried to use the new & promising event handlers on group:
group player addEventHandler ["commandChanged",{
    params ["_grp","_newCmd"];
    if (_newCmd in ["MOVE","JOIN"]) then {
       .....
    };
}];

but these EHs don't return selected units, just the group.

 


Have fun!

 

  • Thanks 1

Share this post


Link to post
Share on other sites
34 minutes ago, pierremgi said:

Well, this is a recurring issue (a sea serpent as we say in French).

I'd say you are quite the serpent slayer Pierre!  Thanks much for the above.  

  • Like 1

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

×