protected override void ComputeVelocityBeforeMovement() { // When going in opposite direction from previous movement, transit to it. if (isGoingOppositeSide || ((lastMovement != 0) && !Mathm.HaveDifferentSign(lastMovement - movement.x, lastMovement))) { isGoingOppositeSide = true; // About-Turn. if ((movement.x != 0) && Mathm.HaveDifferentSign(lastMovement, movement.x)) { float _coef = isGrounded ? attributes.GroundAboutTurnAccel : attributes.AirAboutTurnAccel; movement.x = Mathf.MoveTowards(lastMovement, movement.x, speed * Time.deltaTime * _coef); } // Deceleration. else if (lastMovement != movement.x) { float _coef = isGrounded ? attributes.GroundMovementDecel : attributes.AirMovementDecel; movement.x = Mathf.MoveTowards(lastMovement, movement.x, Time.deltaTime * _coef); } else { isGoingOppositeSide = false; } } lastMovement = movement.x; base.ComputeVelocityBeforeMovement(); }
protected virtual void ComputeVelocityBeforeMovement() { // Slowly decrease force over time. if (force.x != 0) { float _maxDelta = isGrounded ? ProgramSettings.I.GroundDecelerationForce : ProgramSettings.I.AirDecelerationForce; // Calculs when going to opposite force direction. if (movement.x != 0) { if (Mathm.HaveDifferentSign(force.x, movement.x)) { _maxDelta = Mathf.Max(_maxDelta, Mathf.Abs(movement.x) * 2); movement.x = Mathf.MoveTowards(movement.x, 0, Mathf.Abs(force.x) * Time.deltaTime); } else { movement.x = Mathf.Max(0, Mathf.Abs(movement.x) - Mathf.Abs(force.x)) * Mathf.Sign(movement.x); } } // Calculs when going to opposite force direction, // compared to previous frame. float _previousXOtherVelocity = previousXVelocity - previousXForce; if (Mathm.HaveDifferentSignAndNotNull(_previousXOtherVelocity, previousXForce)) { float _difference = Mathf.Abs(_previousXOtherVelocity); if (!Mathm.HaveDifferentSign(_previousXOtherVelocity, instantForce.x + movement.x)) { _difference -= Mathf.Abs(instantForce.x + movement.x); } if (_difference > 0) { force.x = Mathf.MoveTowards(force.x, 0, _difference); } } // Reduce force if (_maxDelta != 0) { force.x = Mathf.MoveTowards(force.x, 0, _maxDelta * Time.deltaTime); } } // ----------------------- previousXForce = force.x; previousXVelocity = force.x + instantForce.x + movement.x; // If going to opposite force direction, accordingly reduce force and movement. if (Mathm.HaveDifferentSignAndNotNull(force.y, movement.y)) { float _maxDelta = Mathf.Abs(movement.y); movement.y = Mathf.MoveTowards(movement.y, 0, Mathf.Abs(force.y)); force.y = Mathf.MoveTowards(force.y, 0, _maxDelta * Time.deltaTime); } }