From 6a8d8a969b72954f712a34e6dcdffc3b27839593 Mon Sep 17 00:00:00 2001 From: GoaLitiuM Date: Fri, 30 Apr 2021 07:27:41 +0300 Subject: [PATCH] moving somewhat --- .../PhysicsMaterials/Physical Material 0.json | 10 +- .../PlayerPhysicsMaterial.json | 2 +- Content/Scenes/MainScene.scene | 16 +- Content/Settings/PhysicsSettings.json | 2 +- Content/Settings/TimeSettings.json | 2 +- Source/Game/PlayerMovement.cs | 722 +++++++++++++++--- 6 files changed, 618 insertions(+), 136 deletions(-) diff --git a/Content/PhysicsMaterials/Physical Material 0.json b/Content/PhysicsMaterials/Physical Material 0.json index 1732de5..6054dc0 100644 --- a/Content/PhysicsMaterials/Physical Material 0.json +++ b/Content/PhysicsMaterials/Physical Material 0.json @@ -1,13 +1,13 @@ { "ID": "d99b8b6f40198beea4703dadd642150e", "TypeName": "FlaxEngine.PhysicalMaterial", - "EngineBuild": 6216, + "EngineBuild": 6217, "Data": { "Friction": 0.0, "FrictionCombineMode": 2, - "OverrideFrictionCombineMode": true, - "Restitution": 0.0, - "RestitutionCombineMode": 1, - "OverrideRestitutionCombineMode": true + "OverrideFrictionCombineMode": false, + "Restitution": 1.0, + "RestitutionCombineMode": 3, + "OverrideRestitutionCombineMode": false } } \ No newline at end of file diff --git a/Content/PhysicsMaterials/PlayerPhysicsMaterial.json b/Content/PhysicsMaterials/PlayerPhysicsMaterial.json index b8f7499..7d260c1 100644 --- a/Content/PhysicsMaterials/PlayerPhysicsMaterial.json +++ b/Content/PhysicsMaterials/PlayerPhysicsMaterial.json @@ -1,7 +1,7 @@ { "ID": "ffe0e84c49607480f67a3994a7fe11a8", "TypeName": "FlaxEngine.PhysicalMaterial", - "EngineBuild": 6216, + "EngineBuild": 6217, "Data": { "Friction": 30.0, "FrictionCombineMode": 2, diff --git a/Content/Scenes/MainScene.scene b/Content/Scenes/MainScene.scene index 47529da..596ec5f 100644 --- a/Content/Scenes/MainScene.scene +++ b/Content/Scenes/MainScene.scene @@ -31,14 +31,15 @@ "Name": "PlayerPrefab", "Transform": { "Translation": { - "X": -913.1759033203125, - "Y": 207.86880493164063, - "Z": 433.89312744140627 + "X": -158.97650146484376, + "Y": -12.66842269897461, + "Z": 62.08625793457031 } }, "LinearDamping": 0.0, "AngularDamping": 0.0, "Constraints": 56, + "EnableSimulation": false, "IsKinematic": true, "EnableGravity": false }, @@ -83,7 +84,7 @@ }, "IsTrigger": true, "ContactOffset": 0.0, - "Material": "ffe0e84c49607480f67a3994a7fe11a8", + "Material": "d99b8b6f40198beea4703dadd642150e", "Radius": 16.0, "Height": 52.0 }, @@ -146,13 +147,13 @@ "Transform": { "Translation": { "X": 0.0, - "Y": 887.0, + "Y": 889.0, "Z": 0.0 } }, "Control": "FlaxEngine.GUI.Label", "Data": { - "Text": "FPS: 120\nrFPS: 120\nCon: NaNms\nDirectX11\nGC memory: 8.103872MB", + "Text": "FPS: 4\nrFPS: 120\nCon: NaNms\nDirectX11\nGC memory: 8.171392MB", "TextColor": { "R": 1.0, "G": 1.0, @@ -222,8 +223,7 @@ "A": 0.0 }, "Enabled": true, - "Visible": true, - "AutoFocus": false + "Visible": true } }, { diff --git a/Content/Settings/PhysicsSettings.json b/Content/Settings/PhysicsSettings.json index 459c603..861fe12 100644 --- a/Content/Settings/PhysicsSettings.json +++ b/Content/Settings/PhysicsSettings.json @@ -19,7 +19,7 @@ "EnableSubstepping": false, "SubstepDeltaTime": 0.008333334, "MaxSubsteps": 5, - "SupportCookingAtRuntime": false, + "SupportCookingAtRuntime": true, "LayerMasks": [ 4294967295, 4294967295, diff --git a/Content/Settings/TimeSettings.json b/Content/Settings/TimeSettings.json index 40d56f8..3a3636c 100644 --- a/Content/Settings/TimeSettings.json +++ b/Content/Settings/TimeSettings.json @@ -1,7 +1,7 @@ { "ID": "a55dc3c04da4ea3744b7f1994565beac", "TypeName": "FlaxEditor.Content.Settings.TimeSettings", - "EngineBuild": 6217, + "EngineBuild": 6218, "Data": { "UpdateFPS": 60.0, "PhysicsFPS": 60.0, diff --git a/Source/Game/PlayerMovement.cs b/Source/Game/PlayerMovement.cs index e9ce452..5fc0408 100644 --- a/Source/Game/PlayerMovement.cs +++ b/Source/Game/PlayerMovement.cs @@ -3,9 +3,27 @@ using FlaxEngine; using Cabrito; using System.Diagnostics; using System.Threading.Tasks; +using FlaxEditor.Utilities; namespace Game { + public struct TraceInfo + { + public RayCastHit[] hitInfos; + public bool startSolid; + + // closest hit + public float fraction; + public Vector3 endPosition; + public Vector3 hitNormal; + public Vector3 hitPosition; + + // furthest hit + //public float maxFraction; + //public Vector3 maxHitNormal; + //public Vector3 maxEndPosition; + } + public class PlayerMovement : Script { [Limit(0, 9000), Tooltip("Base Movement speed")] @@ -46,67 +64,393 @@ namespace Game viewRoll = initialEulerAngles.Z; } - private RayCastHit[] TracePlayer(Vector3 start, Vector3 end) + private TraceInfo TracePlayer(Vector3 start, Vector3 end) { - bool collided; - RayCastHit[] hitInfos; - + bool collided = false; + + TraceInfo traceInfo = new TraceInfo(); + var capsuleCollider = Actor.GetChild(); var boxCollider = Actor.GetChild(); - PhysicsColliderActor collider = null; + PhysicsColliderActor colliderActor = null; Vector3 delta = end - start; + float maxDistance = delta.Length; + Vector3 direction = delta.Normalized; if (capsuleCollider && capsuleCollider.IsActive) { - collider = capsuleCollider; - + colliderActor = capsuleCollider; + //start.Y -= capsuleCollider.Height / 2; //start.Y -= capsuleCollider.Radius / 2; - + /*collided = Physics.BoxCastAll(start, new Vector3(capsuleCollider.Radius, (capsuleCollider.Height + capsuleCollider.Radius) / 2, capsuleCollider.Radius), delta.Normalized, out hitInfos, Quaternion.Identity, delta.Length, uint.MaxValue, false);*/ - - collided = Physics.CapsuleCastAll(start, - capsuleCollider.Radius, capsuleCollider.Height, - delta.Normalized, out hitInfos, capsuleCollider.Orientation, delta.Length, uint.MaxValue, - false); + + /*traceInfo.startSolid = Physics.OverlapCapsule(start, capsuleCollider.Radius, capsuleCollider.Height, + out Collider[] results, capsuleCollider.Orientation, uint.MaxValue, false); + + if (traceInfo.startSolid) + { + foreach (Collider collider in results) + { + if (collider == colliderActor) + continue; + + colliderActor = colliderActor; + } + } + else*/ + { + collided = Physics.CapsuleCastAll(start, + capsuleCollider.Radius, capsuleCollider.Height, + direction, out traceInfo.hitInfos, capsuleCollider.Orientation, maxDistance, + uint.MaxValue, + false); + } } else if (boxCollider && boxCollider.IsActive) { - collider = boxCollider; + colliderActor = boxCollider; //start.Y += boxCollider.Size.Y / 2; - - collided = Physics.BoxCastAll(start, - boxCollider.OrientedBox.Extents, - delta.Normalized, out hitInfos, boxCollider.Orientation, delta.Length, uint.MaxValue, - false); + + /*traceInfo.startSolid = Physics.CheckBox(start, boxCollider.OrientedBox.Extents, boxCollider.Orientation, + uint.MaxValue, false); + + if (!traceInfo.startSolid)*/ + { + collided = Physics.BoxCastAll(start, + boxCollider.OrientedBox.Extents, + direction, out traceInfo.hitInfos, boxCollider.Orientation, maxDistance, uint.MaxValue, + false); + } } - else - return new RayCastHit[0]; if (collided) { List hitInfosFiltered = new List(); - foreach (var hitInfo in hitInfos) + RayCastHit closest = new RayCastHit(); + RayCastHit furthest = new RayCastHit(); + closest.Distance = float.MaxValue; + furthest.Distance = float.MinValue; + foreach (var hitInfo in traceInfo.hitInfos) { - if (hitInfo.Collider == collider) + if (hitInfo.Collider == colliderActor) continue; hitInfosFiltered.Add(hitInfo); + + if (hitInfo.Distance < closest.Distance) + closest = hitInfo; + if (hitInfo.Distance > furthest.Distance) + furthest = hitInfo; } - hitInfos = hitInfosFiltered.ToArray(); + traceInfo.hitInfos = hitInfosFiltered.ToArray(); + + //if (!closest.Normal.IsZero) + if (closest.Distance > 0f) + { + //traceInfo.fraction = (closest.Point - start).Length / maxDistance; + //traceInfo.maxFraction = (furthest.Point - start).Length / maxDistance; + /*if (traceLength != 0f) + { + traceInfo.fraction = closest.Distance / traceLength; + traceInfo.maxFraction = furthest.Distance / traceLength; + } + else + { + traceInfo.fraction = 0f; + traceInfo.maxFraction = 0f; + }*/ + + + + // convoluted shit incoming... + // trace a ray back from the hitpoints to calculate the actual fraction travelled... + Physics.RayCastAll(closest.Point, -direction, out RayCastHit[] rayHitInfos, maxDistance * 2f, + uint.MaxValue, true); + float altFraction = 0f; + float oldFraction = closest.Distance / maxDistance; + foreach (var hitInfo in rayHitInfos) + { + if (hitInfo.Collider != colliderActor) + continue; + + traceInfo.fraction = hitInfo.Distance / maxDistance; + altFraction = (closest.Point - hitInfo.Point).Length / maxDistance; + break; + } + + traceInfo.hitNormal = closest.Normal; + traceInfo.hitPosition = closest.Point; + traceInfo.endPosition = start + (direction * traceInfo.fraction); + + //traceInfo.maxHitNormal = furthest.Normal; + //traceInfo.hitPosition = furthest.Point; + //traceInfo.maxEndPosition = start + ((end - start).Normalized * traceInfo.maxFraction); + + if (traceInfo.fraction == 0f && maxDistance > 0f) + traceInfo.startSolid = true; + } + else + { + traceInfo.startSolid = true; + traceInfo.fraction = 0f; + } + + /*traceInfo.hitInfos = hitInfosFiltered.ToArray(); + + float travel = (end - start).Length; + if (travel != 0f) + { + traceInfo.fraction = closest.Distance / travel; + traceInfo.maxFraction = furthest.Distance / travel; + } + else + { + traceInfo.fraction = 0f; + traceInfo.maxFraction = 0f; + } + + traceInfo.hitNormal = closest.Normal; + traceInfo.hitPosition = closest.Point; + traceInfo.endPosition = start + ((end - start).Normalized * traceInfo.fraction); + + traceInfo.maxHitNormal = furthest.Normal; + //traceInfo.hitPosition = furthest.Point; + traceInfo.maxEndPosition = start + ((end - start).Normalized * traceInfo.maxFraction); + + if (traceInfo.fraction == 0f && travel > 0f) + traceInfo.startSolid = true;*/ } - - return hitInfos; + else + { + traceInfo.hitInfos = new RayCastHit[0]; + traceInfo.fraction = traceInfo.startSolid ? 0f : 1f; + traceInfo.endPosition = end; + } + + return traceInfo; } - private bool SlideMove(Vector3 start, bool stepUp, ref Vector3 velocity) + public override void OnDebugDraw() + { + base.OnDebugDraw(); + + var capsuleCollider = Actor.GetChild(); + var boxCollider = Actor.GetChild(); + var rigidBody = Actor.As(); + if (capsuleCollider && capsuleCollider.IsActive) + { + Quaternion rotation = capsuleCollider.LocalOrientation * Quaternion.Euler(0f, 90f, 0f); + DebugDraw.DrawWireTube(rigidBody.Position, rotation, capsuleCollider.Radius, capsuleCollider.Height, Color.GreenYellow * 0.8f); + } + else if (boxCollider && boxCollider.IsActive) + { + DebugDraw.DrawWireBox(boxCollider.OrientedBox.GetBoundingBox(), Color.GreenYellow * 0.8f); + } + } + + private void SlideMove(ref Vector3 position, bool stepUp, ref Vector3 velocity, bool asdf = false) + { + if (velocity.IsZero) + return; + + Vector3 originalPosition = position; + Vector3 originalVelocity = velocity; + + float timeleft = Time.DeltaTime; + + List hitNormals = new List(); + + // margin in fte: 0.0312 away from the wall + + Vector3 traceOffset = Vector3.Zero; + for (int bump = 0; bump < 4; bump++) + { + Vector3 startPos = position; + Vector3 endPos = position + (velocity * timeleft); + + TraceInfo trace = TracePlayer(startPos + traceOffset, endPos); + // TODO: handle portals here + + float fraction = trace.fraction; + Vector3 hitNormal = trace.hitNormal; + Vector3 hitEndPosition = trace.endPosition; + /*if (bump > 0 && trace.startSolid) + { + fraction = trace.maxFraction; + hitNormal = trace.maxHitNormal; + hitEndPosition = trace.maxEndPosition; + }*/ + + if (fraction > 0f) + { + position = hitEndPosition; + hitNormals.Clear(); + + /*if (position.Z > 368f) + { + position = position; + TracePlayer(startPos + traceOffset, endPos); + }*/ + } + else if (trace.startSolid) + { + velocity = Vector3.Zero; + break; + } + + if (fraction >= 1f) + break; + + timeleft -= timeleft * fraction; + + bool hitPreviousNormal = false; + foreach (Vector3 normal in hitNormals) + { + if (Vector3.Dot(hitNormal, normal) > 0.99) + { + // nudge away from the same wall we hit earlier and try again + velocity += hitNormal; + hitPreviousNormal = true; + break; + } + } + if (hitPreviousNormal) + continue; + + hitNormals.Add(hitNormal); + + /* + bool stuck = true; + foreach (Vector3 normal in hitNormals) + { + // clip velocity + Vector3 velocityProjected = Vector3.ProjectOnPlane(velocity, normal); + float backoff = Vector3.Dot(velocity, normal) * 1f; + velocity -= normal * backoff; + //velocity = velocityProjected; + + bool parallel = true; + foreach (Vector3 otherNormal in hitNormals) + { + if (otherNormal == normal) + continue; + + if (Vector3.Dot(velocity, otherNormal) < 0f) + { + parallel = false; + break; + } + } + + if (parallel) + { + // moving away from all touched walls + stuck = false; + break; + } + } + + if (stuck) + { + if (hitNormals.Count == 2) + { + Vector3 dir = Vector3.Cross(hitNormals[0], hitNormals[1]); + float dist = Vector3.Dot(dir, velocity); + velocity = dist * dir; + } + else + { + velocity = Vector3.Zero; + break; + } + } + else + { + // nudge very slightly away from the wall to avoid getting stuck + //position += trace.hitNormal * 0.01f; + } + */ + int plane; + Vector3 normalMargin = Vector3.Zero; + for (plane = 0; plane < hitNormals.Count; plane++) + { + Vector3 normal = hitNormals[plane]; + + // clip velocity + velocity = velocity - normal * Vector3.Dot(velocity, normal); + //velocity = Vector3.ProjectOnPlane(velocity, normal); + + //traceOffset = normal * 1f; + normalMargin += normal; + //position += normal * 0.031f; + + int plane2; + for (plane2 = 0; plane2 < hitNormals.Count; plane2++) + { + if (plane == plane2) + continue; + + if (Vector3.Dot(velocity, hitNormals[plane2]) < 0f) + break; + } + + if (plane2 == hitNormals.Count) + break; + } + + position += normalMargin.Normalized * 0.031f; + + if (plane == hitNormals.Count) + { + if (hitNormals.Count == 2) + { + Vector3 dir = Vector3.Cross(hitNormals[0], hitNormals[1]); + float dist = Vector3.Dot(dir, velocity); + velocity = dist * dir; + } + else + { + velocity = Vector3.Zero; + break; + } + } + else + { + // nudge very slightly away from the wall to avoid getting stuck + //position += trace.hitNormal * 0.01f; + //velocity += trace.hitNormal * 0.01f; + } + + // prevents bouncing against the wall + if (/*velocity.Length > 0f && */Vector3.Dot(velocity, originalVelocity) <= 0f) + { + velocity = Vector3.Zero; + break; + } + } + + if (!asdf) + { + /*var finalTrace = TracePlayer(position, position); + if (finalTrace.startSolid) + { + position = originalPosition; + velocity = originalVelocity; + SlideMove(ref position, false, ref velocity, true); + }*/ + } + } + + private bool SlideMove2(ref Vector3 position, bool stepUp, ref Vector3 velocity) { // PM_SlideMove /* @@ -127,53 +471,122 @@ namespace Game */ - - - - Vector3 startPos = start; - Vector3 endPos = startPos + (velocity * Time.DeltaTime); - Vector3 delta = endPos - startPos; - bool blocked = false; + if (velocity.IsZero) + return false; + + Vector3 originalVelocity = velocity; + + Vector3 startPos = position; + //float distanceLeft = (velocity * Time.DeltaTime).Length; + float timeLeft = Time.DeltaTime; - RayCastHit[] hitInfos = TracePlayer(startPos, endPos); - bool collided = hitInfos.Length > 0; - float distance = 1.0f; - - Vector3 normal = Vector3.Zero; - Vector3 point; - if (collided) + bool anyCollisions = false; + + for (int i = 0; i < 3; i++) { - collided = false; - foreach (var hitInfo in hitInfos) + Vector3 normal = Vector3.Zero; + //float distance = distanceLeft; + Vector3 direction = velocity.Normalized; + //Vector3 endPos = startPos + (direction * distanceLeft); + Vector3 endPos = startPos + (velocity * timeLeft); + float travel = (endPos - startPos).Length; + + //if (endPos == startPos) + // break; + + TraceInfo trace = TracePlayer(startPos, endPos); + bool collided = trace.hitInfos.Length > 0; + float fraction = 1.0f; + float distance = 0f; + + if (trace.startSolid) { - //if (hitInfo.Distance < minDistanceFromFloor) - // continue; - - float fraction = hitInfo.Distance / delta.Length; - - collided = true; - if (fraction <= distance) - { - normal = hitInfo.Normal; - point = hitInfo.Point; - distance = fraction; - } - + velocity = Vector3.Zero; + anyCollisions = true; break; - - //Console.Print("collided " + hitInfo.Distance.ToString()); - //break; } - } - if (collided) - velocity = Vector3.ProjectOnPlane(velocity, normal); + if (collided) + { + collided = false; + if (trace.hitInfos.Length > 1) + Console.Print("fixme more traces!"); - blocked = collided; - - return blocked; + foreach (var hitInfo in trace.hitInfos) + { + //if (hitInfo.Distance < minDistanceFromFloor) + // continue; + + //if (hitInfo.Distance > distance) + // Console.Print("hit distance is greater: " + hitInfo.Distance.ToString() + " > " + distance.ToString()); + + + fraction = hitInfo.Distance / travel; + + collided = true; + //if (hitInfo.Distance <= distance) + { + normal = hitInfo.Normal; + distance = hitInfo.Distance; + } + + break; + + //Console.Print("collided " + hitInfo.Distance.ToString()); + //break; + } + } + + if (collided) + { + + + // move to contact position, continue from here + startPos += direction * distance; // what if this points to different direction? + //distanceLeft -= distance; + timeLeft *= fraction; + + //Console.Print("timeleft: " + timeLeft.ToString() + ", frac:" + fraction.ToString()); + + //velocity = Vector3.ProjectOnPlane(velocity, normal); + + Vector3 velocityProjected = Vector3.ProjectOnPlane(velocity, normal); + float backoff = Vector3.Dot(velocity, normal) * 1f; + velocity -= normal * backoff; + velocity = velocityProjected; + + //Console.Print((velocityProjected-velocity).Length.ToString()); + + + // prevents bouncing against the wall + if (velocity.Length > 0f && Vector3.Dot(velocity, originalVelocity) <= 0f) + { + velocity = Vector3.Zero; + //distanceLeft = 0f; + timeLeft = 0f; + } + } + else + { + + //distanceLeft = 0f; + timeLeft = 0f; + startPos = endPos; + + } + + anyCollisions |= collided; + + if (timeLeft <= 0f)//if (distanceLeft <= 0f) + break; + } + + position = startPos; + + + return anyCollisions; } //Vector3 wishVelocity = Vector3.Zero; @@ -187,7 +600,7 @@ namespace Game private const float jumpVelocity = 270f; private const float maxAirSpeed = 320f; - private const float maxAirStrafeSpeed = 320f; //Q2+ + private const float maxAirStrafeSpeed = 30f; //Q2+ private const float airAcceleration = 0.4f * 0f; //Q2+ private const float airStopAcceleration = 2.5f * 0f; //Q2+ private const float airStrafeAcceleration = 70f * 0f; //CPM? @@ -195,6 +608,8 @@ namespace Game private const float airControl = 0f; //CPM private bool jumped = false; + + private Vector3 safePosition; public override void OnFixedUpdate() { @@ -206,29 +621,98 @@ namespace Game Vector3 wishVelocity = Vector3.Zero; if (!inputDirection.IsZero) + wishVelocity = moveDirection.Normalized * MoveSpeed; + + // categorize position + onGround = true; + //TraceInfo traceGround = TracePlayer(rigidBody.Position, rigidBody.Position + Physics.Gravity.Normalized); + + /*if (!traceGround.startSolid && traceGround.fraction < 1f && + -Vector3.Dot(Physics.Gravity.Normalized, traceGround.hitNormal) < 0.7f) { - //move = moveDirection.Normalized * MoveSpeed * Time.DeltaTime / (1.0f/Time.PhysicsFPS); - inputDirection = moveDirection.Normalized * MoveSpeed; - wishVelocity = inputDirection; + // slope + // clip velocity + Vector3 bounce = Physics.Gravity.Normalized; + //Vector3 velocityProjected = Vector3.ProjectOnPlane(velocity, normal); + float backoff = Vector3.Dot(bounce, traceGround.hitNormal) * 2f; + bounce -= traceGround.hitNormal * backoff; + //velocity = velocityProjected; + + Vector3 point = (rigidBody.Position + Physics.Gravity.Normalized) + + (1f - traceGround.fraction) * bounce; + + // retrace + traceGround = TracePlayer(rigidBody.Position, rigidBody.Position + point, + false); } - - // onGround checks - RayCastHit[] hitInfosGround = TracePlayer(rigidBody.Position, rigidBody.Position + (Vector3.Down * 1f)); - onGround = false; - foreach (var hitInfo in hitInfosGround) + + if (!traceGround.startSolid && (traceGround.fraction >= 1f || + -Vector3.Dot(Physics.Gravity.Normalized, traceGround.hitNormal) < 0.7f)) { - var dot = Vector3.Dot(Vector3.Down, hitInfo.Normal); - if (dot < -0.7) //~45deg + // falling or sliding down a slope + onGround = false; + } + else + { + onGround = !traceGround.startSolid; + } + + if (onGround) + { + // snap to ground + if (!traceGround.startSolid) { - onGround = true; Vector3 newPos = rigidBody.Position; - newPos += Vector3.Down * (hitInfo.Distance - 0.01f); - //newPos.Y = hitInfo.Point.Y + 0.0001f; - //rigidBody.Position = newPos; - //currentVelocity.Y = 0.0f; + + if (traceGround.fraction < 1f) + { + //newPos += -Physics.Gravity.Normalized * traceGround.fraction; + } + rigidBody.Position = newPos; } + }*/ + /*if (traceGround.startSolid) + { + Console.Print("stuk: "); + + rigidBody.Position = safePosition; + + traceGround = TracePlayer(rigidBody.Position, rigidBody.Position + Physics.Gravity.Normalized, + false); + + //onGround = true; + + //currentVelocity.Y = 0f; } - + + if (!traceGround.startSolid) + { + foreach (var hitInfo in traceGround.hitInfos) + { + var dot = Vector3.Dot(Physics.Gravity.Normalized, hitInfo.Normal); + if (-dot >= 0.7) //~45deg slope + { + //Console.Print("d: " + hitInfo.Distance); + Vector3 newPos = rigidBody.Position; + + if (hitInfo.Distance > 0f) + newPos += Physics.Gravity.Normalized * (hitInfo.Distance - 0.01f); + else + newPos += hitInfo.Normal * 0.1f; + + rigidBody.Position = newPos; + + onGround = true; + currentVelocity.Y = 0f; + break; + + //if (currentVelocity.Length > 0.01f) + // Console.Print("groundvel: " + currentVelocity.ToString()); + //currentVelocity.Y = 0.0f; + } + } + }*/ + // jump if (onGround) { @@ -236,7 +720,8 @@ namespace Game { //jumped = true; - currentVelocity += Vector3.Up * jumpVelocity; + currentVelocity += Vector3.Up * jumpVelocity; + onGround = false; } else if (jumped) // jump released jumped = false; @@ -261,22 +746,11 @@ namespace Game currentVelocity *= newspeed / currentSpeed; } - bool stepUp = false; + //bool stepUp = false; if (onGround) // ground acceleration { - ApplyAcceleration(wishVelocity.Normalized, wishVelocity.Length, 0f, accelerationGround); - /*float currentSpeed = Vector3.Dot(currentVelocity, wishVelocity.Normalized); - float addSpeed = wishVelocity.Length - currentSpeed; - - if (addSpeed > 0) - { - float accelSpeed = accelerationGround * wishVelocity.Length * Time.DeltaTime; - if (accelSpeed > addSpeed) - accelSpeed = addSpeed; - - currentVelocity += accelSpeed * wishVelocity.Normalized; - }*/ + ApplyAcceleration(wishVelocity.Normalized, wishVelocity.Length, float.MaxValue, accelerationGround); } else // air acceleration { @@ -284,59 +758,67 @@ namespace Game if (wishspeed > maxAirSpeed) wishspeed = maxAirSpeed; - if (strafeAcceleration != 0) + if (strafeAcceleration != 0f) ApplyAcceleration(wishVelocity.Normalized, wishspeed, maxAirStrafeSpeed, strafeAcceleration); - stepUp = true; + //stepUp = true; } if (!onGround) - currentVelocity += Physics.Gravity * Time.DeltaTime; - - bool blocked2 = SlideMove(rigidBody.Position, stepUp, ref currentVelocity); - if (currentVelocity.Length > 0.0f) - rigidBody.Position += currentVelocity * Time.DeltaTime; + { + //currentVelocity += Physics.Gravity * Time.DeltaTime; + //Console.Print("grav"); + } + //else + // Console.Print("Yv: " + currentVelocity.Y); + + Vector3 newPosition = rigidBody.Position; + SlideMove(ref newPosition, false, ref currentVelocity); + + safePosition = rigidBody.Position; + rigidBody.Position = newPosition; + //if (currentVelocity.Length > 0.0f) + // rigidBody.Position += currentVelocity * Time.DeltaTime; + rigidBody.LinearVelocity = Vector3.Zero; + + //if (currentVelocity.Length > 0.01f) + // Console.Print("vel: " + currentVelocity.ToString()); } void ApplyAcceleration(Vector3 wishDir, float wishspeed, float maxWishspeed, float acceleration) { float wishspeedOrig = wishspeed; - if (wishspeed > 0f && wishspeed > maxWishspeed) + if (wishspeed > maxWishspeed) wishspeed = maxWishspeed; float currentSpeed = Vector3.Dot(currentVelocity, wishDir); float addSpeed = wishspeed - currentSpeed; + if (addSpeed <= 0f) + return; - if (addSpeed > 0) - { - float accelSpeed = acceleration * wishspeedOrig * Time.DeltaTime; - if (accelSpeed > addSpeed) - accelSpeed = addSpeed; + float accelSpeed = acceleration * wishspeedOrig * Time.DeltaTime; + if (accelSpeed > addSpeed) + accelSpeed = addSpeed; - currentVelocity += accelSpeed * wishDir; - } + currentVelocity += accelSpeed * wishDir; } public override void OnUpdate() { - float xAxis = InputManager.GetAxis("Mouse X"); - float yAxis = InputManager.GetAxis("Mouse Y"); + float xAxis = InputManager.GetAxisRaw("Mouse X"); + float yAxis = InputManager.GetAxisRaw("Mouse Y"); if (xAxis != 0.0f || yAxis != 0.0f) { var camera = rootActor.GetChild(); - var camTrans = camera.Transform; - var rootTrans = rootActor.Transform; viewPitch += yAxis; viewYaw += xAxis; viewPitch = Mathf.Clamp(viewPitch, -90.0f, 90.0f); - camTrans.Orientation = Quaternion.Euler(viewPitch, viewYaw, viewRoll); - rootTrans.Orientation = Quaternion.Euler(0, viewYaw, 0); - - camera.Transform = camTrans; - rootActor.Transform = rootTrans; + // root orientation must be set first + rootActor.Orientation = Quaternion.Euler(0, viewYaw, 0); + camera.Orientation = Quaternion.Euler(viewPitch, viewYaw, viewRoll); } } }