public static void Reflect(ISurfControllable surfer, float deltaTime) { var workingVel = surfer.MoveData.JustGrounded ? surfer.MoveData.PreGroundedVelocity : surfer.MoveData.Velocity; workingVel += surfer.MoveData.BaseVelocity; var clipped = false; //if (contactOffset != 0) //{ // var longSide = Mathf.Sqrt(contactOffset * contactOffset + contactOffset * contactOffset); // distance += longSide; // extents *= (1f - contactOffset); //} //var center = surfer.MoveData.Origin + new Vector3(0, surfer.Collider.bounds.extents.y, 0); //var end = center + (Vector3.down * 0.2f) + (workingVel * deltaTime); //var dist = Vector3.Distance(center, end); //var dir = (end - center).normalized; var center = surfer.MoveData.Origin + new Vector3(0, surfer.Collider.bounds.extents.y + 0.1f, 0); var dist = 0.2f; var dir = (Vector3.down + (workingVel * deltaTime)).normalized; //var dir = (Vector3.down + (workingVel * deltaTime)).normalized; var hitCount = Physics.BoxCastNonAlloc(results: _hits, center: center, direction: dir, orientation: surfer.Orientation, maxDistance: dist, halfExtents: surfer.Collider.bounds.extents, layerMask: GroundLayerMask, queryTriggerInteraction: QueryTriggerInteraction.Ignore); for (int i = 0; i < hitCount; i++) { if (Tracer.HitIsShit(_hits[i]) || _hits[i].collider == null) { continue; } if (_hits[i].normal.y <= SurfSlope || _hits[i].normal.y >= 1) { continue; } var slopeDir = Vector3.Cross(Vector3.up, Vector3.Cross(Vector3.up, _hits[i].normal)); var dot = Vector3.Dot(workingVel.normalized, slopeDir); var goingAgainstSlope = dot > 0; if (!goingAgainstSlope) { continue; } ClipVelocity(workingVel, _hits[i].normal, ref workingVel, 1f); clipped = true; } workingVel -= surfer.MoveData.BaseVelocity; if (clipped) { surfer.MoveData.Velocity = workingVel; } //var oldVelocityMagnitude2d = new Vector2(surfer.MoveData.Velocity.x, surfer.MoveData.Velocity.z).magnitude; // //var newVelocityMagnitude2d = new Vector2(surfer.MoveData.Velocity.x, surfer.MoveData.Velocity.z).magnitude; //float fLateralStoppingAmount = oldVelocityMagnitude2d - newVelocityMagnitude2d; //Debug.Log(fLateralStoppingAmount); }
private Trace BoxCastToFloor(float distance = 0.05f, float extentModifier = 1.0f) { //var extents = _surfer.Collider.bounds.extents * extentModifier; //var center = _surfer.MoveData.Origin; //center.y += extents.y + 0.02f; //distance += 0.02f; //if (Physics.BoxCast(center, extents, Vector3.down, out RaycastHit hit, Quaternion.identity, distance, SurfPhysics.GroundLayerMask, QueryTriggerInteraction.Ignore)) //{ // return hit; //} //return default; var extents = _surfer.Collider.bounds.extents * extentModifier; var center = _surfer.MoveData.Origin; center.y += extents.y + 0.02f; distance += 0.02f; if (_surfer.MoveData.Velocity.y < 0) { var dv = _surfer.MoveData.Velocity.y * -1.01f * _deltaTime; distance = Mathf.Max(distance, dv); } var count = Physics.BoxCastNonAlloc(center, extents, Vector3.down, _hitCache, _surfer.Orientation, distance, SurfPhysics.GroundLayerMask, QueryTriggerInteraction.Ignore); var greatY = float.MinValue; RaycastHit bestHit = default; for (int i = 0; i < count; i++) { // trash physx interpenetration bullshit..... if (Tracer.HitIsShit(_hitCache[i])) { continue; } if (bestHit.collider == null) { bestHit = _hitCache[i]; greatY = _hitCache[i].point.y; } if (_hitCache[i].normal.y <= SurfPhysics.SurfSlope && _hitCache[i].normal.y > 0) { return(_hitCache[i]); } if (_hitCache[i].point.y > greatY) { bestHit = _hitCache[i]; greatY = _hitCache[i].point.y; } } return(bestHit); }