Fix (or a workaround) to characters teleporting inside/through colliders when leaving a sub (see #552). Gaps do a raycast out from the sub to see if there are obstacles outside, and if so, ragdolls place a collider at the corresponding position inside the sub. The collider is simply a straight axis-aligned line atm, so it doesn't work accurately with sloped ice/submarine walls, but does prevent the ragdoll from ending up inside the obstacles. TODO: use a few edges to approximate the shape of the obstacles more closely?

This commit is contained in:
Joonas Rikkonen
2018-08-02 16:48:51 +03:00
parent 708f72c883
commit 9099b191d0
4 changed files with 146 additions and 15 deletions
@@ -75,6 +75,7 @@ namespace Barotrauma
private static Vector2 lastPickedPosition;
private static float lastPickedFraction;
private static Vector2 lastPickedNormal;
private Md5Hash hash;
@@ -120,6 +121,11 @@ namespace Barotrauma
get { return lastPickedFraction; }
}
public static Vector2 LastPickedNormal
{
get { return lastPickedNormal; }
}
public bool Loading
{
get;
@@ -593,6 +599,7 @@ namespace Barotrauma
}
float closestFraction = 1.0f;
Vector2 closestNormal = Vector2.Zero;
Body closestBody = null;
GameMain.World.RayCast((fixture, point, normal, fraction) =>
{
@@ -616,6 +623,7 @@ namespace Barotrauma
if (fraction < closestFraction)
{
closestFraction = fraction;
closestNormal = normal;
if (fixture.Body != null) closestBody = fixture.Body;
}
return fraction;
@@ -624,6 +632,7 @@ namespace Barotrauma
lastPickedPosition = rayStart + (rayEnd - rayStart) * closestFraction;
lastPickedFraction = closestFraction;
lastPickedNormal = closestNormal;
return closestBody;
}
@@ -636,6 +645,7 @@ namespace Barotrauma
{
Body closestBody = null;
float closestFraction = 1.0f;
Vector2 closestNormal = Vector2.Zero;
if (Vector2.Distance(rayStart, rayEnd) < 0.01f)
{
@@ -664,6 +674,7 @@ namespace Barotrauma
{
closestBody = fixture.Body;
closestFraction = fraction;
closestNormal = normal;
}
return closestFraction;
}
@@ -672,6 +683,7 @@ namespace Barotrauma
lastPickedPosition = rayStart + (rayEnd - rayStart) * closestFraction;
lastPickedFraction = closestFraction;
lastPickedNormal = closestNormal;
return closestBody;
}