private void CheckSlope() { if (_surfer.MoveData.Surfing) { return; } var origin = _surfer.MoveData.Origin + new Vector3(0, _surfer.Collider.bounds.extents.y + 0.1f, 0); var direction = Vector3.down; var distance = 0.2f; var hitCount = Physics.BoxCastNonAlloc(results: _hitCache, center: origin, direction: direction, orientation: Quaternion.identity, maxDistance: distance, halfExtents: _surfer.Collider.bounds.extents, layerMask: SurfPhysics.GroundLayerMask, queryTriggerInteraction: QueryTriggerInteraction.Ignore); for (int i = 0; i < hitCount; i++) { if (_hitCache[i].normal.y <= SurfPhysics.SurfSlope) { continue; } if (_hitCache[i].normal.y >= 1) { continue; } var slopeDir = Vector3.Cross(Vector3.up, Vector3.Cross(Vector3.up, _hitCache[i].normal)); var dot = Vector3.Dot(_surfer.MoveData.AbsVelocity.normalized, slopeDir); var goingAgainstSlope = dot > 0; if (!goingAgainstSlope) { continue; } Debug.DrawLine(origin, _hitCache[i].point, Color.magenta, 5f); _surfer.MoveData.MomentumModifier = _hitCache[i].normal; SurfPhysics.ClipVelocity(_surfer.MoveData.Velocity, _hitCache[i].normal, ref _surfer.MoveData.Velocity, 1.0f); SurfPhysics.ClipVelocity(_surfer.MoveData.BaseVelocity, _hitCache[i].normal, ref _surfer.MoveData.BaseVelocity, 1.0f); var end = origin + _surfer.MoveData.AbsVelocity.normalized * 2f; Debug.DrawLine(origin, end, Color.red, 5f); } //// todo: remove reflect function, seems useless when all it does is clip velocity? //if (_surfer.GroundObject != null) ////if (!_surfer.MoveData.JustGrounded && !_surfer.MoveData.Surfing && _surfer.GroundObject != null) //{ // //SurfPhysics.Reflect(_surfer, _deltaTime); //} }
private void IncrementOrigin(Vector3 amount) { _surfer.MoveData.PreviousOrigin = _surfer.MoveData.Origin; _surfer.MoveData.Origin += amount; if (_surfer.MoveType == MoveType.Noclip && !_config.NoclipCollide) { return; } SurfPhysics.ResolveCollisions(_surfer); var prevOrigin = _surfer.MoveData.PreviousOrigin; var newOrigin = _surfer.MoveData.Origin; var movementThisStep = newOrigin - prevOrigin; var newMovement = movementThisStep; if (movementThisStep.magnitude >= _surfer.Collider.bounds.extents.x) { var center = prevOrigin; center.y += _surfer.Collider.bounds.extents.y; var hitCount = Physics.BoxCastNonAlloc(center: center, halfExtents: _surfer.Collider.bounds.extents * 0.5f, direction: movementThisStep.normalized, orientation: Quaternion.identity, results: _hitCache, maxDistance: movementThisStep.magnitude, layerMask: SurfPhysics.GroundLayerMask, queryTriggerInteraction: QueryTriggerInteraction.Ignore); if (hitCount > 0) { for (int i = 0; i < hitCount; i++) { newMovement += _hitCache[i].normal * (movementThisStep.magnitude - _hitCache[i].distance); SurfPhysics.ClipVelocity(_surfer.MoveData.Velocity, _hitCache[i].normal, ref _surfer.MoveData.Velocity, 1.01f); } _surfer.MoveData.Origin = prevOrigin + newMovement; } } }
private void ApplyMomentum() { if (!_surfer.MoveData.Momentum && _surfer.MoveData.BaseVelocity != Vector3.zero) { _surfer.MoveData.Velocity += (1.0f + (_deltaTime * 0.5f)) * _surfer.MoveData.BaseVelocity; _surfer.MoveData.BaseVelocity = Vector3.zero; if (_surfer.MoveData.MomentumModifier != Vector3.zero) { SurfPhysics.ClipVelocity(_surfer.MoveData.Velocity, _surfer.MoveData.MomentumModifier, ref _surfer.MoveData.Velocity, 1.0f); SurfPhysics.ClipVelocity(_surfer.MoveData.BaseVelocity, _surfer.MoveData.MomentumModifier, ref _surfer.MoveData.BaseVelocity, 1.0f); _surfer.MoveData.MomentumModifier = Vector3.zero; } } else if (_surfer.MoveData.Momentum) { CheckSlope(); } _surfer.MoveData.Momentum = false; }
private bool CheckGrounded() { var wasSurfing = _surfer.MoveData.Surfing; _surfer.MoveData.SurfaceFriction = 1f; _surfer.MoveData.Surfing = false; _surfer.MoveData.Sliding = false; var trace = BoxCastToFloor(.1f, .99f); var movingUp = _surfer.MoveData.Velocity.y > 0; var goingAgainstSlope = false; var quickJump = false; if (trace.HitCollider != null) { var slopeDir = Vector3.Cross(Vector3.up, Vector3.Cross(Vector3.up, trace.PlaneNormal)); var dot = Vector3.Dot(_surfer.MoveData.Velocity.normalized, slopeDir); goingAgainstSlope = dot > 0; if (trace.PlaneNormal.y <= SurfPhysics.SurfSlope) { _surfer.MoveData.Surfing = true; _surfer.MoveData.SurfNormal = trace.PlaneNormal; } else if (goingAgainstSlope && dot >= _config.SlideDot) { var tempVel = _surfer.MoveData.Velocity; SurfPhysics.ClipVelocity(tempVel, trace.PlaneNormal, ref tempVel, 1.0f); if (tempVel.y > _config.JumpPower * _config.SlideFactor) { _surfer.MoveData.Sliding = true; } } quickJump = _surfer.GroundObject == null && !goingAgainstSlope && movingUp && trace.Distance < _surfer.MoveData.Velocity.y; } if (MovingUpRapidly() || trace.HitCollider == null || _surfer.MoveData.Surfing || _surfer.MoveData.Sliding || _surfer.MoveData.GravityFactor < 0 || quickJump || (_surfer.MoveType == MoveType.Ladder && movingUp)) { _surfer.MoveData.GroundTest = 0; SetGround(null); return(false); } else { if (wasSurfing && _surfer.MoveData.GroundTest == 0) { _surfer.MoveData.GroundTest++; SetGround(null); return(false); } _surfer.MoveData.GroundTest = 0; SetGround(trace.HitCollider.gameObject); _surfer.MoveData.Origin.y = trace.HitPoint.y + HammerScale; // slant boost, but only if velocity is away from slope if (_surfer.MoveData.JustGrounded) { if (!goingAgainstSlope) { //SurfPhysics.ClipVelocity(_surfer.MoveData.Velocity, trace.PlaneNormal, ref _surfer.MoveData.Velocity, 1.0f); SurfPhysics.Reflect(_surfer, _deltaTime, trace.PlaneNormal); } _surfer.MoveData.Velocity.y = 0; } return(true); } }