/// <summary> /// /// </summary> private void CalculateMovementVelocity() { switch (_surfer.MoveType) { case MoveType.Walk: if (_surfer.GroundObject == null) { // apply movement from input _surfer.MoveData.Velocity += AirInputMovement(); // let the magic happen SurfPhysics.Reflect(ref _surfer.MoveData.Velocity, _surfer.Collider, _surfer.MoveData.Origin, _deltaTime); } else { // apply movement from input _surfer.MoveData.Velocity += GroundInputMovement(); // jump/friction if (_surfer.MoveData.Buttons.HasFlag((int)InputButtons.Jump)) { Jump(); } else { var friction = _surfer.MoveData.SurfaceFriction * _config.Friction; var stopSpeed = _config.StopSpeed; SurfPhysics.Friction(ref _surfer.MoveData.Velocity, stopSpeed, friction, _deltaTime); } } break; } }
/// <summary> /// /// </summary> public void ProcessMovement(ISurfControllable surfer, MovementConfig config, float deltaTime) { // cache instead of passing around parameters _surfer = surfer; _config = config; _deltaTime = deltaTime; if (!_surfer.moveData.underwater) { if (_surfer.moveData.velocity.y <= 0f) { jumping = false; } // apply gravity if (_surfer.groundObject == null) { _surfer.moveData.velocity.y -= (_surfer.moveData.gravityFactor * _config.gravity * _deltaTime); _surfer.moveData.velocity.y += _surfer.baseVelocity.y * _deltaTime; } // input velocity, check for ground CheckGrounded(); CalculateMovementVelocity(); } else { // Do underwater logic UnderwaterPhysics(); } float yVel = _surfer.moveData.velocity.y; _surfer.moveData.velocity.y = 0f; _surfer.moveData.velocity = Vector3.ClampMagnitude(_surfer.moveData.velocity, _config.maxVelocity); speed = _surfer.moveData.velocity.magnitude; _surfer.moveData.velocity.y = yVel; float maxDistPerFrame = 1f; Vector3 velocityThisFrame = _surfer.moveData.velocity * _deltaTime; float velocityDistLeft = velocityThisFrame.magnitude; float initialVel = velocityDistLeft; while (velocityDistLeft > 0f) { float amountThisLoop = Mathf.Min(maxDistPerFrame, velocityDistLeft); velocityDistLeft -= amountThisLoop; // increment origin Vector3 velThisLoop = velocityThisFrame * (amountThisLoop / initialVel); _surfer.moveData.origin += velThisLoop; // don't penetrate walls SurfPhysics.ResolveCollisions(_surfer.collider, ref _surfer.moveData.origin, ref _surfer.moveData.velocity, _surfer.moveData.rigidbodyPushForce); } _surfer.moveData.groundedTemp = _surfer.moveData.grounded; _surfer = null; }
///// Methods ///// /// <summary> /// /// </summary> public void ProcessMovement(ISurfControllable surfer, MovementConfig config, float deltaTime) { // cache instead of passing around parameters _surfer = surfer; _config = config; _deltaTime = deltaTime; // apply gravity if (_surfer.GroundObject == null) { _surfer.MoveData.Velocity.y -= (_surfer.MoveData.GravityFactor * _config.Gravity * _deltaTime); _surfer.MoveData.Velocity.y += _surfer.BaseVelocity.y * _deltaTime; } // input velocity, check for ground CheckGrounded(); CalculateMovementVelocity(); // increment origin _surfer.MoveData.Origin += _surfer.MoveData.Velocity * _deltaTime; // don't penetrate walls SurfPhysics.ResolveCollisions(_surfer.Collider, ref _surfer.MoveData.Origin, ref _surfer.MoveData.Velocity); _surfer = null; }
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 Vector3 GroundInputMovement() { GetWishValues(out Vector3 wishVel, out Vector3 wishDir, out float wishSpeed); wishSpeed *= _surfer.MoveData.WalkFactor; return(SurfPhysics.Accelerate(_surfer.MoveData.Velocity, wishDir, wishSpeed, _config.Accelerate, _deltaTime, _surfer.MoveData.SurfaceFriction)); }
private Vector3 AirInputMovement() { GetWishValues(out Vector3 wishVel, out Vector3 wishDir, out float wishSpeed); var aircap = _surfer.MoveData.Surfing ? _config.AirCap * _config.AirCapSurfModifier : _config.AirCap; var result = SurfPhysics.AirAccelerate(_surfer.MoveData.Velocity, wishDir, wishSpeed, _config.AirAccel, aircap, _deltaTime); return(result); }
/// <summary> /// /// </summary> /// <returns></returns> private Vector3 AirInputMovement() { Vector3 wishVel, wishDir; float wishSpeed; GetWishValues(out wishVel, out wishDir, out wishSpeed); if (_config.clampAirSpeed && (wishSpeed != 0f && (wishSpeed > _config.maxSpeed))) { wishVel = wishVel * (_config.maxSpeed / wishSpeed); wishSpeed = _config.maxSpeed; } return(SurfPhysics.AirAccelerate(_surfer.moveData.velocity, wishDir, wishSpeed, _config.airAcceleration, _config.airCap, _deltaTime)); }
private void CalculateNoclipVelocity() { AngleVectors(_surfer.MoveData.ViewAngles, out Vector3 forward, out Vector3 right, out Vector3 up); var wishVel = Vector3.zero; for (int i = 0; i < 3; i++) { wishVel[i] = forward[i] * _surfer.MoveData.ForwardMove + right[i] * _surfer.MoveData.SideMove; } var wishDir = wishVel.normalized; _surfer.MoveData.Velocity += wishDir * _config.NoclipSpeed; SurfPhysics.Friction(ref _surfer.MoveData.Velocity, _config.StopSpeed, _config.NoclipFriction, _deltaTime); }
/// <summary> /// /// </summary> /// <returns></returns> private Vector3 GroundInputMovement() { Vector3 wishVel, wishDir; float wishSpeed; GetWishValues(out wishVel, out wishDir, out wishSpeed); if ((wishSpeed != 0.0f) && (wishSpeed > _config.MaxSpeed)) { wishVel *= _config.MaxSpeed / wishSpeed; wishSpeed = _config.MaxSpeed; } wishSpeed *= _surfer.MoveData.WalkFactor; return(SurfPhysics.Accelerate(_surfer.MoveData.Velocity, wishDir, wishSpeed, _config.Accel, _deltaTime, _surfer.MoveData.SurfaceFriction)); }
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 CalculateWalkVelocity(float modifier = 1.0f) { if (_surfer.GroundObject == null) { _surfer.MoveData.Velocity += AirInputMovement() * modifier; if (_surfer.MoveData.Buttons.HasFlag(InputActions.Brake)) { var vely = _surfer.MoveData.Velocity.y; SurfPhysics.Friction(ref _surfer.MoveData.Velocity, 0f, _config.BrakeSpeed, _deltaTime); _surfer.MoveData.Velocity.y = vely; } } else { _surfer.MoveData.Velocity += GroundInputMovement() * modifier; var friction = _surfer.MoveData.SurfaceFriction * _config.Friction; var stopSpeed = _config.StopSpeed; SurfPhysics.Friction(ref _surfer.MoveData.Velocity, stopSpeed, friction, _deltaTime); } }
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 void UpdateRotation() { var angles = MoveData.ViewAngles; float mx = (Input.GetAxis("Mouse X") * XSens * .02200f); float my = Input.GetAxis("Mouse Y") * YSens * .02200f; var rot = angles + new Vector3(-my, mx, 0f); rot.x = SurfPhysics.ClampAngle(rot.x, -89f, 89f); var yaw = 0; if (Input.GetKey(YawLeft)) { yaw = -YawSpeed; } else if (Input.GetKey(YawRight)) { yaw = YawSpeed; } rot.y += yaw * Time.deltaTime; Camera.transform.rotation = Quaternion.Euler(rot); }
/// <summary> /// /// </summary> private void CalculateMovementVelocity() { switch (_surfer.moveType) { case MoveType.Walk: if (_surfer.groundObject == null) { /* * // AIR MOVEMENT */ wasSliding = false; // apply movement from input _surfer.moveData.velocity += AirInputMovement(); // let the magic happen SurfPhysics.Reflect(ref _surfer.moveData.velocity, _surfer.collider, _surfer.moveData.origin, _deltaTime); if (_surfer.moveData.wishJump && jumpsLeft > 0) { jumpsLeft--; ApplyFriction(0.0f, true, false); _surfer.moveData.velocity.y = 0; Jump(); } } else { /* * // GROUND MOVEMENT */ // Sliding if (!wasSliding) { slideDirection = new Vector3(_surfer.moveData.velocity.x, 0f, _surfer.moveData.velocity.z) .normalized; slideSpeedCurrent = Mathf.Max(_config.maximumSlideSpeed, new Vector3(_surfer.moveData.velocity.x, 0f, _surfer.moveData.velocity.z).magnitude); } sliding = false; if (_surfer.moveData.velocity.magnitude > _config.minimumSlideSpeed && _surfer.moveData.slidingEnabled && _surfer.moveData.crouching && slideDelay <= 0f) { if (!wasSliding) { slideSpeedCurrent = Mathf.Clamp(slideSpeedCurrent * _config.slideSpeedMultiplier, _config.minimumSlideSpeed, _config.maximumSlideSpeed); } sliding = true; wasSliding = true; SlideMovement(); //return; } else { if (slideDelay > 0f) { slideDelay -= _deltaTime; } if (wasSliding) { slideDelay = _config.slideDelay; } wasSliding = false; } float fric = crouching ? _config.crouchFriction : _config.friction; float accel = crouching ? _config.crouchAcceleration : _config.acceleration; float decel = crouching ? _config.crouchDeceleration : _config.deceleration; // Get movement directions Vector3 forward = Vector3.Cross(groundNormal, -playerTransform.right); Vector3 right = Vector3.Cross(groundNormal, forward); float speed = _surfer.moveData.sprinting ? _config.sprintSpeed : _config.walkSpeed; if (crouching) { speed = _config.crouchSpeed; } Vector3 _wishDir; // Jump and friction if (_surfer.moveData.wishJump) { ApplyFriction(0.0f, true, true); Jump(); return; } else { ApplyFriction(1.0f * frictionMult, true, true); } float forwardMove = _surfer.moveData.verticalAxis; float rightMove = _surfer.moveData.horizontalAxis; _wishDir = forwardMove * forward + rightMove * right; _wishDir.Normalize(); Vector3 moveDirNorm = _wishDir; Vector3 forwardVelocity = Vector3.Cross(groundNormal, Quaternion.AngleAxis(-90, Vector3.up) * new Vector3(_surfer.moveData.velocity.x, 0f, _surfer.moveData.velocity.z)); // Set the target speed of the player float _wishSpeed = _wishDir.magnitude; _wishSpeed *= speed; // Accelerate float yVel = _surfer.moveData.velocity.y; Accelerate(_wishDir, _wishSpeed, accel * Mathf.Min(frictionMult, 1f), false); float maxVelocityMagnitude = _config.maxVelocity; _surfer.moveData.velocity = Vector3.ClampMagnitude( new Vector3(_surfer.moveData.velocity.x, 0f, _surfer.moveData.velocity.z), maxVelocityMagnitude); _surfer.moveData.velocity.y = yVel; // Calculate how much slopes should affect movement float yVelocityNew = forwardVelocity.normalized.y * new Vector3(_surfer.moveData.velocity.x, 0f, _surfer.moveData.velocity.z) .magnitude; // Apply the Y-movement from slopes _surfer.moveData.velocity.y = yVelocityNew * (_wishDir.y < 0f ? 1.2f : 1.0f); float removableYVelocity = _surfer.moveData.velocity.y - yVelocityNew; } break; } // END OF SWITCH STATEMENT }
/// <summary> /// /// </summary> public void ProcessMovement(ISurfControllable surfer, MovementConfig config, float deltaTime) { // cache instead of passing around parameters _surfer = surfer; _config = config; _deltaTime = deltaTime; if (_surfer.moveData.laddersEnabled && !_surfer.moveData.climbingLadder) { // Look for ladders LadderCheck(new Vector3(1f, 0.95f, 1f), _surfer.moveData.velocity * Mathf.Clamp(Time.deltaTime * 2f, 0.025f, 0.25f)); } if (_surfer.moveData.laddersEnabled && _surfer.moveData.climbingLadder) { LadderPhysics(); } else if (!_surfer.moveData.underwater) { if (_surfer.moveData.velocity.y <= 0f) { jumping = false; } // apply gravity if (_surfer.groundObject == null) { _surfer.moveData.velocity.y -= (_surfer.moveData.gravityFactor * _config.gravity * _deltaTime); _surfer.moveData.velocity.y += _surfer.baseVelocity.y * _deltaTime; } // input velocity, check for ground CheckGrounded(); CalculateMovementVelocity(); } else { // Do underwater logic UnderwaterPhysics(); } float yVel = _surfer.moveData.velocity.y; _surfer.moveData.velocity.y = 0f; _surfer.moveData.velocity = Vector3.ClampMagnitude(_surfer.moveData.velocity, _config.maxVelocity); speed = _surfer.moveData.velocity.magnitude; _surfer.moveData.velocity.y = yVel; if (_surfer.moveData.velocity.sqrMagnitude == 0f) { // Do collisions while standing still SurfPhysics.ResolveCollisions(_surfer.collider, ref _surfer.moveData.origin, ref _surfer.moveData.velocity, _surfer.moveData.rigidbodyPushForce, _surfer.collider.transform.localPosition, 1f, _surfer.moveData.stepOffset, _surfer); } else { float maxDistPerFrame = 0.2f; Vector3 velocityThisFrame = _surfer.moveData.velocity * _deltaTime; float velocityDistLeft = velocityThisFrame.magnitude; float initialVel = velocityDistLeft; while (velocityDistLeft > 0f) { float amountThisLoop = Mathf.Min(maxDistPerFrame, velocityDistLeft); velocityDistLeft -= amountThisLoop; // increment origin Vector3 velThisLoop = velocityThisFrame * (amountThisLoop / initialVel); _surfer.moveData.origin += velThisLoop; // don't penetrate walls SurfPhysics.ResolveCollisions(_surfer.collider, ref _surfer.moveData.origin, ref _surfer.moveData.velocity, _surfer.moveData.rigidbodyPushForce, _surfer.collider.transform.localPosition, amountThisLoop / initialVel, _surfer.moveData.stepOffset, _surfer); } } _surfer.moveData.groundedTemp = _surfer.moveData.grounded; _surfer = null; }
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); } }