moving somewhat
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ID": "ffe0e84c49607480f67a3994a7fe11a8",
|
||||
"TypeName": "FlaxEngine.PhysicalMaterial",
|
||||
"EngineBuild": 6216,
|
||||
"EngineBuild": 6217,
|
||||
"Data": {
|
||||
"Friction": 30.0,
|
||||
"FrictionCombineMode": 2,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"EnableSubstepping": false,
|
||||
"SubstepDeltaTime": 0.008333334,
|
||||
"MaxSubsteps": 5,
|
||||
"SupportCookingAtRuntime": false,
|
||||
"SupportCookingAtRuntime": true,
|
||||
"LayerMasks": [
|
||||
4294967295,
|
||||
4294967295,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ID": "a55dc3c04da4ea3744b7f1994565beac",
|
||||
"TypeName": "FlaxEditor.Content.Settings.TimeSettings",
|
||||
"EngineBuild": 6217,
|
||||
"EngineBuild": 6218,
|
||||
"Data": {
|
||||
"UpdateFPS": 60.0,
|
||||
"PhysicsFPS": 60.0,
|
||||
|
||||
@@ -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<CapsuleCollider>();
|
||||
var boxCollider = Actor.GetChild<BoxCollider>();
|
||||
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<RayCastHit> hitInfosFiltered = new List<RayCastHit>();
|
||||
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<CapsuleCollider>();
|
||||
var boxCollider = Actor.GetChild<BoxCollider>();
|
||||
var rigidBody = Actor.As<RigidBody>();
|
||||
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<Vector3> hitNormals = new List<Vector3>();
|
||||
|
||||
// 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<Camera>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user