/// <summary> /// /// </summary> /// <returns></returns> private Trace TraceToFloor() { var down = _surfer.MoveData.Origin; down.y -= 0.1f; return(Tracer.TraceCollider(_surfer.Collider, _surfer.MoveData.Origin, down, SurfPhysics.GroundLayerMask)); }
/// <summary> /// /// </summary> /// <returns></returns> private Trace TraceToFloor() { Vector3 colliderCenter = _surfer.moveData.origin + _surfer.collider.transform.localPosition; var down = colliderCenter; down.y -= 0.01f; return(Tracer.TraceCollider(_surfer.collider, colliderCenter, down, SurfPhysics.groundLayerMask)); }
/// <summary> /// /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="layerMask"></param> /// <returns></returns> private Trace TraceBounds(Vector3 start, Vector3 end, int layerMask) { return(Tracer.TraceCollider(_surfer.collider, start, end, layerMask)); }
/// <summary> /// /// </summary> /// <param name="velocity"></param> /// <param name="origin"></param> /// <param name="firstDestination"></param> /// <param name="firstTrace"></param> /// <returns></returns> public static int Reflect(ref Vector3 velocity, Collider collider, Vector3 origin, float deltaTime) { float d; var newVelocity = Vector3.zero; var blocked = 0; // Assume not blocked var numplanes = 0; // and not sliding along any planes var originalVelocity = velocity; // Store original velocity var primalVelocity = velocity; var allFraction = 0f; var timeLeft = deltaTime; // Total time for this movement operation. for (int bumpcount = 0; bumpcount < NumBumps; bumpcount++) { if (velocity.magnitude == 0f) { break; } // Assume we can move all the way from the current origin to the // end point. var end = VectorExtensions.VectorMa(origin, timeLeft, velocity); var trace = Tracer.TraceCollider(collider, origin, end, GroundLayerMask); allFraction += trace.Fraction; if (trace.Fraction > 0) { // actually covered some distance originalVelocity = velocity; numplanes = 0; } // If we covered the entire distance, we are done // and can return. if (trace.Fraction == 1) { break; // moved the entire distance } // If the plane we hit has a high z component in the normal, then // it's probably a floor if (trace.PlaneNormal.y > SurfSlope) { blocked |= 1; // floor } // If the plane has a zero z component in the normal, then it's a // step or wall if (trace.PlaneNormal.y == 0) { blocked |= 2; // step / wall } // Reduce amount of m_flFrameTime left by total time left * fraction // that we covered. timeLeft -= timeLeft * trace.Fraction; // Did we run out of planes to clip against? if (numplanes >= MaxClipPlanes) { // this shouldn't really happen // Stop our movement if so. velocity = Vector3.zero; //Con_DPrintf("Too many planes 4\n"); break; } // Set up next clipping plane _planes[numplanes] = trace.PlaneNormal; numplanes++; // modify original_velocity so it parallels all of the clip planes // // reflect player velocity // Only give this a try for first impact plane because you can get yourself stuck in an acute corner by jumping in place // and pressing forward and nobody was really using this bounce/reflection feature anyway... if (numplanes == 1) { for (int i = 0; i < numplanes; i++) { if (_planes[i][1] > SurfSlope) { // floor or slope return(blocked); //ClipVelocity(originalVelocity, _planes[i], ref newVelocity, 1f); //originalVelocity = newVelocity; } else { ClipVelocity(originalVelocity, _planes[i], ref newVelocity, 1f); } } velocity = newVelocity; originalVelocity = newVelocity; } else { int i = 0; for (i = 0; i < numplanes; i++) { ClipVelocity(originalVelocity, _planes[i], ref velocity, 1); int j = 0; for (j = 0; j < numplanes; j++) { if (j != i) { // Are we now moving against this plane? if (Vector3.Dot(velocity, _planes[j]) < 0) { break; } } } if (j == numplanes) // Didn't have to clip, so we're ok { break; } } // Did we go all the way through plane set if (i != numplanes) { // go along this plane // pmove.velocity is set in clipping call, no need to set again. ; } else { // go along the crease if (numplanes != 2) { velocity = Vector3.zero; break; } var dir = Vector3.Cross(_planes[0], _planes[1]).normalized; d = Vector3.Dot(dir, velocity); velocity = dir * d; } // // if original velocity is against the original velocity, stop dead // to avoid tiny occilations in sloping corners // d = Vector3.Dot(velocity, primalVelocity); if (d <= 0f) { //Con_DPrintf("Back\n"); velocity = Vector3.zero; break; } } } if (allFraction == 0f) { velocity = Vector3.zero; } // Check if they slammed into a wall //float fSlamVol = 0.0f; //var primal2dLen = new Vector2(primal_velocity.x, primal_velocity.z).magnitude; //var vel2dLen = new Vector2(_moveData.Velocity.x, _moveData.Velocity.z).magnitude; //float fLateralStoppingAmount = primal2dLen - vel2dLen; //if (fLateralStoppingAmount > PLAYER_MAX_SAFE_FALL_SPEED * 2.0f) //{ // fSlamVol = 1.0f; //} //else if (fLateralStoppingAmount > PLAYER_MAX_SAFE_FALL_SPEED) //{ // fSlamVol = 0.85f; //} //PlayerRoughLandingEffects(fSlamVol); return(blocked); }
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); } }