diff --git a/Content/Settings/EngineSettings/BuildSettings.json b/Content/Settings/EngineSettings/BuildSettings.json index 8a0ab18..61e74b3 100644 --- a/Content/Settings/EngineSettings/BuildSettings.json +++ b/Content/Settings/EngineSettings/BuildSettings.json @@ -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 } ] } diff --git a/Source/Game/PlayerMovement.cs b/Source/Game/PlayerMovement.cs index 373f379..691edee 100644 --- a/Source/Game/PlayerMovement.cs +++ b/Source/Game/PlayerMovement.cs @@ -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; } - /// - /// Sweeps the player rigidbody in world and returns geometry which was hit during the trace. - /// - /// Start position - /// End position - /// - 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(); + var boxCollider = Actor.GetChild(); + var meshCollider = Actor.GetChild(); + 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 collidersFiltered = new List(); + foreach (var collider in colliders) + { + if (collider.Parent == Actor) + continue; + + collidersFiltered.Add(collider); + } + + colliders = collidersFiltered.ToArray(); + if (colliders.Length == 0) + collided = false; + } + + return collided; + } + + /// + /// Sweeps the player rigidbody in world and returns geometry which was hit during the trace. + /// + /// Start position + /// End position + /// + 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 hitInfosFiltered = new List(); @@ -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