player collision fixes
This commit is contained in:
@@ -1,17 +1,15 @@
|
||||
{
|
||||
"ID": "af2e52554f7faed7b4937181dd22d166",
|
||||
"TypeName": "FlaxEditor.Content.Settings.BuildSettings",
|
||||
"EngineBuild": 6222,
|
||||
"EngineBuild": 6224,
|
||||
"Data": {
|
||||
"MaxAssetsPerPackage": 4096,
|
||||
"MaxPackageSizeMB": 1024,
|
||||
"ContentKey": 0,
|
||||
"ForDistribution": false,
|
||||
"SkipPackaging": false,
|
||||
"AdditionalAssets": [
|
||||
"54a1ff4a42af9f018234f7b39b1366b3",
|
||||
"1ef4565844a4b36cdfda54b51f338c77"
|
||||
],
|
||||
"AdditionalAssets": [],
|
||||
"AdditionalAssetFolders": [],
|
||||
"ShadersNoOptimize": false,
|
||||
"ShadersGenerateDebugData": false,
|
||||
"Presets": [
|
||||
@@ -22,7 +20,10 @@
|
||||
"Name": "Win64",
|
||||
"Output": "Output\\Windows",
|
||||
"Platform": 2,
|
||||
"Mode": 1
|
||||
"Mode": 1,
|
||||
"CustomDefines": null,
|
||||
"PreBuildAction": null,
|
||||
"PostBuildAction": null
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -33,7 +34,10 @@
|
||||
"Name": "Win64",
|
||||
"Output": "Output\\WindowsRelease",
|
||||
"Platform": 2,
|
||||
"Mode": 2
|
||||
"Mode": 2,
|
||||
"CustomDefines": null,
|
||||
"PreBuildAction": null,
|
||||
"PostBuildAction": null
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -39,7 +39,8 @@ namespace Game
|
||||
|
||||
private InputEvent onExit = new InputEvent("Exit");
|
||||
|
||||
private const float collisionMargin = 0.031f * 1.666f;
|
||||
// FIXME, should be much smaller but needed to avoid issues with box collider edges against brush edges diagonally
|
||||
private const float collisionMargin = 0.031f * 1.666f * 1.85f;
|
||||
private const float slopeNormal = 0.7f;
|
||||
|
||||
private Actor rootActor;
|
||||
@@ -102,16 +103,8 @@ namespace Game
|
||||
viewRoll = initialEulerAngles.Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sweeps the player rigidbody in world and returns geometry which was hit during the trace.
|
||||
/// </summary>
|
||||
/// <param name="start">Start position</param>
|
||||
/// <param name="end">End position</param>
|
||||
/// <returns></returns>
|
||||
private TraceInfo TracePlayer(Vector3 start, Vector3 end)
|
||||
private bool SweepPlayerCollider(Vector3 start, Vector3 end, out RayCastHit[] hits)
|
||||
{
|
||||
TraceInfo traceInfo = new TraceInfo();
|
||||
|
||||
Vector3 delta = end - start;
|
||||
float maxDistance = delta.Length;
|
||||
Vector3 direction = delta.Normalized;
|
||||
@@ -126,7 +119,7 @@ namespace Game
|
||||
colliderActor = capsuleCollider;
|
||||
collided = Physics.CapsuleCastAll(start,
|
||||
capsuleCollider.Radius, capsuleCollider.Height,
|
||||
direction, out traceInfo.hitInfos, capsuleCollider.Orientation, maxDistance,
|
||||
direction, out hits, capsuleCollider.Orientation, maxDistance,
|
||||
uint.MaxValue,
|
||||
false);
|
||||
}
|
||||
@@ -135,7 +128,7 @@ namespace Game
|
||||
colliderActor = meshCollider;
|
||||
collided = Physics.ConvexCastAll(start,
|
||||
meshCollider.CollisionData, meshCollider.Scale,
|
||||
direction, out traceInfo.hitInfos, meshCollider.Orientation, maxDistance,
|
||||
direction, out hits, meshCollider.Orientation, maxDistance,
|
||||
uint.MaxValue,
|
||||
false);
|
||||
}
|
||||
@@ -144,10 +137,91 @@ namespace Game
|
||||
colliderActor = boxCollider;
|
||||
collided = Physics.BoxCastAll(start,
|
||||
boxCollider.OrientedBox.Extents,
|
||||
direction, out traceInfo.hitInfos, boxCollider.Orientation, maxDistance, uint.MaxValue,
|
||||
direction, out hits, boxCollider.Orientation, maxDistance,
|
||||
uint.MaxValue,
|
||||
false);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Player does not have a collider");
|
||||
}
|
||||
|
||||
return collided;
|
||||
}
|
||||
|
||||
private bool SweepPlayerCollider(Vector3 position, out PhysicsColliderActor[] colliders)
|
||||
{
|
||||
bool collided = false;
|
||||
var capsuleCollider = Actor.GetChild<CapsuleCollider>();
|
||||
var boxCollider = Actor.GetChild<BoxCollider>();
|
||||
var meshCollider = Actor.GetChild<MeshCollider>();
|
||||
PhysicsColliderActor colliderActor = null;
|
||||
if (capsuleCollider && capsuleCollider.IsActive)
|
||||
{
|
||||
colliderActor = capsuleCollider;
|
||||
collided = Physics.OverlapCapsule(position,
|
||||
capsuleCollider.Radius, capsuleCollider.Height,
|
||||
out colliders, capsuleCollider.Orientation,
|
||||
uint.MaxValue,
|
||||
false);
|
||||
}
|
||||
else if (meshCollider && meshCollider.IsActive)
|
||||
{
|
||||
colliderActor = meshCollider;
|
||||
collided = Physics.OverlapConvex(position,
|
||||
meshCollider.CollisionData, meshCollider.Scale,
|
||||
out colliders, meshCollider.Orientation,
|
||||
uint.MaxValue,
|
||||
false);
|
||||
}
|
||||
else if (boxCollider && boxCollider.IsActive)
|
||||
{
|
||||
colliderActor = boxCollider;
|
||||
collided = Physics.OverlapBox(position,
|
||||
boxCollider.OrientedBox.Extents,
|
||||
out colliders, boxCollider.Orientation,
|
||||
uint.MaxValue,
|
||||
false);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Player does not have a collider");
|
||||
}
|
||||
|
||||
if (collided)
|
||||
{
|
||||
List<PhysicsColliderActor> collidersFiltered = new List<PhysicsColliderActor>();
|
||||
foreach (var collider in colliders)
|
||||
{
|
||||
if (collider.Parent == Actor)
|
||||
continue;
|
||||
|
||||
collidersFiltered.Add(collider);
|
||||
}
|
||||
|
||||
colliders = collidersFiltered.ToArray();
|
||||
if (colliders.Length == 0)
|
||||
collided = false;
|
||||
}
|
||||
|
||||
return collided;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sweeps the player rigidbody in world and returns geometry which was hit during the trace.
|
||||
/// </summary>
|
||||
/// <param name="start">Start position</param>
|
||||
/// <param name="end">End position</param>
|
||||
/// <returns></returns>
|
||||
private TraceInfo TracePlayer(Vector3 start, Vector3 end)
|
||||
{
|
||||
TraceInfo traceInfo = new TraceInfo();
|
||||
|
||||
Vector3 delta = end - start;
|
||||
float maxDistance = delta.Length;
|
||||
Vector3 direction = delta.Normalized;
|
||||
|
||||
bool collided = SweepPlayerCollider(start, end, out traceInfo.hitInfos);
|
||||
if (collided)
|
||||
{
|
||||
List<RayCastHit> hitInfosFiltered = new List<RayCastHit>();
|
||||
@@ -155,7 +229,9 @@ namespace Game
|
||||
closest.Distance = float.MaxValue;
|
||||
foreach (var hitInfo in traceInfo.hitInfos)
|
||||
{
|
||||
if (hitInfo.Collider == colliderActor)
|
||||
//if (hitInfo.Collider == colliderActor)
|
||||
// continue;
|
||||
if (hitInfo.Collider.Parent == Actor)
|
||||
continue;
|
||||
|
||||
hitInfosFiltered.Add(hitInfo);
|
||||
@@ -164,8 +240,27 @@ namespace Game
|
||||
closest = hitInfo;
|
||||
}
|
||||
|
||||
if (hitInfosFiltered.Count == 0)
|
||||
if (hitInfosFiltered.Count == 0 /*|| closest.Distance == float.MaxValue*/)
|
||||
collided = false; // self-collision?
|
||||
/*else if (closest.Distance == float.MaxValue)
|
||||
{
|
||||
bool startSolid = SweepPlayerCollider(start, out PhysicsColliderActor[] colliders);
|
||||
if (startSolid)
|
||||
{
|
||||
traceInfo.hitInfos = hitInfosFiltered.ToArray();
|
||||
|
||||
traceInfo.fraction = 0f;
|
||||
traceInfo.hitNormal = Vector3.Zero;
|
||||
traceInfo.hitPosition = start;
|
||||
traceInfo.endPosition = start;
|
||||
traceInfo.startSolid = true;
|
||||
|
||||
if (delta.Y >= 0f)
|
||||
Console.Print("ovr: " + colliders[0].Parent.Name);
|
||||
}
|
||||
else
|
||||
collided = false;
|
||||
}*/
|
||||
else //if (closest.Distance > 0f)
|
||||
{
|
||||
if (closest.Distance == float.MaxValue)
|
||||
@@ -186,6 +281,9 @@ namespace Game
|
||||
|
||||
if (traceInfo.fraction == 0f && maxDistance > 0f)
|
||||
traceInfo.startSolid = true;
|
||||
|
||||
//if (delta.Y >= 0f)
|
||||
// Console.Print("col: " + closest.Collider.Parent.Name + ", " + closest.Distance.ToString("G9"));
|
||||
}
|
||||
/*else
|
||||
{
|
||||
@@ -280,7 +378,7 @@ namespace Game
|
||||
else if (traceDown.fraction > 0f)
|
||||
position = traceDown.endPosition;
|
||||
|
||||
// add some margin from the ground in order to avoid getting stuck
|
||||
// add some margin from the ground in order to avoid getting stuck after stepping up
|
||||
if (traceDown.fraction < 1f)
|
||||
position.Y += collisionMargin;
|
||||
|
||||
@@ -289,7 +387,7 @@ namespace Game
|
||||
var d2 = -Vector3.Dot(Physics.Gravity.Normalized, originalPosition);
|
||||
if (d1 < d2)
|
||||
{
|
||||
Console.Print("no stepping 2, " + d1 + " < " + d2);
|
||||
//Console.Print("no stepping 2, " + d1 + " < " + d2);
|
||||
position = slidePosition;
|
||||
velocity = slideVelocity;
|
||||
return slideMoveHit;
|
||||
@@ -306,7 +404,7 @@ namespace Game
|
||||
//if ((stepPosition2 - originalPosition).Length < (slidePosition2 - originalPosition).Length)
|
||||
if ((slidePosition2 - originalPosition).Length >= (stepPosition2 - originalPosition).Length)
|
||||
{
|
||||
Console.Print("no stepping 3");
|
||||
//Console.Print("no stepping 3");
|
||||
position = slidePosition;
|
||||
velocity = slideVelocity;
|
||||
return slideMoveHit;
|
||||
@@ -425,6 +523,7 @@ namespace Game
|
||||
|
||||
// push off slightly away from the walls to not get stuck
|
||||
position += normalMargin.Normalized * collisionMargin;
|
||||
//Console.Print("pushin");
|
||||
|
||||
if (plane == hitNormals.Count)
|
||||
{
|
||||
@@ -537,12 +636,15 @@ namespace Game
|
||||
|
||||
// categorize position
|
||||
onGround = true;
|
||||
Vector3 groundDelta = Physics.Gravity.Normalized * (collisionMargin * 2);
|
||||
Vector3 groundDelta = Physics.Gravity.Normalized;//Physics.Gravity.Normalized * (collisionMargin * 2);
|
||||
//if (velocity.Y < 0f)
|
||||
// groundDelta = Physics.Gravity.Normalized * velocity.Y * Time.DeltaTime;
|
||||
TraceInfo traceGround = TracePlayer(position, position + groundDelta);
|
||||
|
||||
if (!traceGround.startSolid && traceGround.fraction < 1f &&
|
||||
-Vector3.Dot(Physics.Gravity.Normalized, traceGround.hitNormal) < slopeNormal)
|
||||
{
|
||||
//Console.Print("slope?");
|
||||
// slope
|
||||
// clip velocity
|
||||
Vector3 bounce = groundDelta;
|
||||
@@ -567,6 +669,7 @@ namespace Game
|
||||
else
|
||||
{
|
||||
onGround = !traceGround.startSolid;
|
||||
//Console.Print("issolid? :" + traceGround.startSolid);
|
||||
}
|
||||
|
||||
// TODO: snap to ground here
|
||||
|
||||
Reference in New Issue
Block a user