diff --git a/Modified fragsurf/Movement/MoveData.cs b/Modified fragsurf/Movement/MoveData.cs
index 2cf833c..8677d27 100644
--- a/Modified fragsurf/Movement/MoveData.cs
+++ b/Modified fragsurf/Movement/MoveData.cs
@@ -32,6 +32,8 @@ namespace Fragsurf.Movement {
public bool crouching = false;
public bool sprinting = false;
+ public float slopeLimit = 45f;
+
public float rigidbodyPushForce = 1f;
public float defaultHeight = 2f;
@@ -48,5 +50,8 @@ namespace Fragsurf.Movement {
public bool groundedTemp = false;
public float fallingVelocity = 0f;
+ public bool useStepOffset = false;
+ public float stepOffset = 0f;
+
}
}
diff --git a/Modified fragsurf/Movement/SurfCharacter.cs b/Modified fragsurf/Movement/SurfCharacter.cs
index 8a0afeb..7c47a5a 100644
--- a/Modified fragsurf/Movement/SurfCharacter.cs
+++ b/Modified fragsurf/Movement/SurfCharacter.cs
@@ -38,7 +38,11 @@ namespace Fragsurf.Movement {
[Header ("Features")]
public bool crouchingEnabled = true;
public bool slidingEnabled = false;
-
+
+ [Header ("Step offset (can be buggy, enable at your own risk)")]
+ public bool useStepOffset = false;
+ public float stepOffset = 0.35f;
+
[Header ("Movement Config")]
[SerializeField]
public MovementConfig movementConfig;
@@ -179,6 +183,8 @@ namespace Fragsurf.Movement {
}
+ _moveData.slopeLimit = movementConfig.slopeLimit;
+
_moveData.rigidbodyPushForce = rigidbodyPushForce;
_moveData.slidingEnabled = slidingEnabled;
@@ -194,7 +200,10 @@ namespace Fragsurf.Movement {
_collider.isTrigger = !solidCollider;
_moveData.origin = transform.position;
_startPosition = transform.position;
-
+
+ _moveData.useStepOffset = useStepOffset;
+ _moveData.stepOffset = stepOffset;
+
}
private void Update () {
diff --git a/Modified fragsurf/Movement/SurfController.cs b/Modified fragsurf/Movement/SurfController.cs
index 48cda9b..50027b2 100644
--- a/Modified fragsurf/Movement/SurfController.cs
+++ b/Modified fragsurf/Movement/SurfController.cs
@@ -76,7 +76,8 @@ namespace Fragsurf.Movement {
float maxDistPerFrame = 0.05f;
Vector3 velocityThisFrame = _surfer.moveData.velocity * _deltaTime;
- float velocityDistLeft = velocityThisFrame.magnitude;
+ float velocityDist = velocityThisFrame.magnitude;
+ float velocityDistLeft = velocityDist;
float initialVel = velocityDistLeft;
while (velocityDistLeft > 0f) {
@@ -88,7 +89,7 @@ namespace Fragsurf.Movement {
_surfer.moveData.origin += velThisLoop;
// don't penetrate walls
- SurfPhysics.ResolveCollisions (_surfer.collider, ref _surfer.moveData.origin, ref _surfer.moveData.velocity, _surfer.moveData.rigidbodyPushForce, amountThisLoop / initialVel);
+ SurfPhysics.ResolveCollisions (_surfer.collider, ref _surfer.moveData.origin, ref _surfer.moveData.velocity, _surfer.moveData.rigidbodyPushForce, amountThisLoop / velocityDist, _surfer.moveData.useStepOffset ? _surfer.moveData.stepOffset : 0f, _surfer);
}
diff --git a/Modified fragsurf/Movement/SurfPhysics.cs b/Modified fragsurf/Movement/SurfPhysics.cs
index 7f7dd45..9fd5c89 100644
--- a/Modified fragsurf/Movement/SurfPhysics.cs
+++ b/Modified fragsurf/Movement/SurfPhysics.cs
@@ -29,12 +29,8 @@ namespace Fragsurf.Movement {
///
///
/// http://www.00jknight.com/blog/unity-character-controller
-
- public static void ResolveCollisions (Collider collider, ref Vector3 origin, ref Vector3 velocity, float rigidbodyPushForce) {
- ResolveCollisions (collider, ref origin, ref velocity, rigidbodyPushForce, 1f);
- }
-
- public static void ResolveCollisions (Collider collider, ref Vector3 origin, ref Vector3 velocity, float rigidbodyPushForce, float velocityMultiplier) {
+
+ public static void ResolveCollisions (Collider collider, ref Vector3 origin, ref Vector3 velocity, float rigidbodyPushForce, float velocityMultiplier = 1f, float stepOffset = 0f, ISurfControllable surfer = null) {
// manual collision resolving
int numOverlaps = 0;
@@ -55,6 +51,7 @@ namespace Fragsurf.Movement {
}
+ Vector3 forwardVelocity = Vector3.Scale (velocity, new Vector3 (1f, 0f, 1f));
for (int i = 0; i < numOverlaps; i++) {
Vector3 direction;
@@ -64,6 +61,11 @@ namespace Fragsurf.Movement {
Quaternion.identity, _colliders [i], _colliders [i].transform.position,
_colliders [i].transform.rotation, out direction, out distance)) {
+ // Step offset
+ if (stepOffset > 0f && surfer != null && surfer.moveData.useStepOffset)
+ if (StepOffset (collider, _colliders [i], ref origin, ref velocity, rigidbodyPushForce, velocityMultiplier, stepOffset, direction, distance, forwardVelocity, surfer))
+ return;
+
// Handle collision
direction.Normalize ();
Vector3 penetrationVector = direction * distance;
@@ -71,18 +73,91 @@ namespace Fragsurf.Movement {
velocityProjected.y = 0; // don't touch y velocity, we need it to calculate fall damage elsewhere
origin += penetrationVector;
velocity -= velocityProjected * velocityMultiplier;
-
+
Rigidbody rb = _colliders [i].GetComponentInParent ();
- if (rb)
- if (!rb.isKinematic)
- rb.AddForceAtPosition (velocityProjected * velocityMultiplier * rigidbodyPushForce, origin, ForceMode.Impulse);
-
+ if (rb != null && !rb.isKinematic)
+ rb.AddForceAtPosition (velocityProjected * velocityMultiplier * rigidbodyPushForce, origin, ForceMode.Impulse);
+
}
}
}
+ public static bool StepOffset (Collider collider, Collider otherCollider, ref Vector3 origin, ref Vector3 velocity, float rigidbodyPushForce, float velocityMultiplier, float stepOffset, Vector3 direction, float distance, Vector3 forwardVelocity, ISurfControllable surfer) {
+
+ // Return if step offset is 0
+ if (stepOffset <= 0f)
+ return false;
+
+ // Get forward direction (return if we aren't moving/are only moving vertically)
+ Vector3 forwardDirection = forwardVelocity.normalized;
+ if (forwardDirection.sqrMagnitude == 0f)
+ return false;
+
+ // Trace ground
+ Trace groundTrace = Tracer.TraceCollider (collider, origin, origin + Vector3.down * 0.1f, groundLayerMask);
+ if (groundTrace.hitCollider == null || Vector3.Angle (Vector3.up, groundTrace.planeNormal) > surfer.moveData.slopeLimit)
+ return false;
+
+ // Trace wall
+ Trace wallTrace = Tracer.TraceCollider (collider, origin, origin + velocity, groundLayerMask, 0.9f);
+ if (wallTrace.hitCollider == null || Vector3.Angle (Vector3.up, wallTrace.planeNormal) <= surfer.moveData.slopeLimit)
+ return false;
+
+ // Trace upwards (check for roof etc)
+ float upDistance = stepOffset;
+ Trace upTrace = Tracer.TraceCollider (collider, origin, origin + Vector3.up * stepOffset, groundLayerMask);
+ if (upTrace.hitCollider != null)
+ upDistance = upTrace.distance;
+
+ // Don't bother doing the rest if we can't move up at all anyway
+ if (upDistance <= 0f)
+ return false;
+
+ Vector3 upOrigin = origin + Vector3.up * upDistance;
+
+ // Trace forwards (check for walls etc)
+ float forwardMagnitude = stepOffset;
+ float forwardDistance = forwardMagnitude;
+ Trace forwardTrace = Tracer.TraceCollider (collider, upOrigin, upOrigin + forwardDirection * Mathf.Max (0.2f, forwardMagnitude), groundLayerMask);
+ if (forwardTrace.hitCollider != null)
+ forwardDistance = forwardTrace.distance;
+
+ // Don't bother doing the rest if we can't move forward anyway
+ if (forwardDistance <= 0f)
+ return false;
+
+ Vector3 upForwardOrigin = upOrigin + forwardDirection * forwardDistance;
+
+ // Trace down (find ground)
+ float downDistance = upDistance;
+ Trace downTrace = Tracer.TraceCollider (collider, upForwardOrigin, upForwardOrigin + Vector3.down * upDistance, groundLayerMask);
+ if (downTrace.hitCollider != null)
+ downDistance = downTrace.distance;
+
+ // Check step size/angle
+ float verticalStep = Mathf.Clamp (upDistance - downDistance, 0f, stepOffset);
+ float horizontalStep = forwardDistance;
+ float stepAngle = Vector3.Angle (Vector3.forward, new Vector3 (0f, verticalStep, horizontalStep));
+ if (stepAngle > surfer.moveData.slopeLimit)
+ return false;
+
+ // Get new position
+ Vector3 endOrigin = origin + Vector3.up * verticalStep;
+
+ // Actually move
+ if (origin != endOrigin && forwardDistance > 0f) {
+
+ Debug.Log ("Moved up step!");
+ origin = endOrigin + forwardDirection * forwardDistance * Time.deltaTime;
+ return true;
+
+ } else
+ return false;
+
+ }
+
///
///
///