示例#1
0
        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();
        }
示例#2
0
        /// <summary>
        /// Move rigidbody according to a complex collision system.
        /// When hitting something, continue movement all along hit surface.
        /// Perform movement according to ground surface angle.
        /// </summary>
        private void ComplexCollisionsSystem()
        {
            // If grounded, adjust velocity according to ground normal.
            Vector2 _velocity = GetVelocity();

            if (isGrounded)
            {
                Vector2 _x = Vector2.Perpendicular(groundNormal);
                if (_x.x < 0)
                {
                    _x *= -1;
                }
                _x *= _velocity.x;

                Vector2 _y = (_velocity.y < 0 ? groundNormal : Vector2.up) * _velocity.y;

                _velocity = _x + _y;
            }

            castBufferCount = 0;
            RecursiveComplexCollisions(_velocity, groundNormal);

            // Modify force according to hit surfaces.
            if (!force.IsNull())
            {
                for (int _i = 0; _i < castBufferCount; _i++)
                {
                    if (Mathm.HaveDifferentSignAndNotNull(force.x, castBuffer[_i].normal.x) && (Mathf.Abs(castBuffer[_i].normal.x) == 1))
                    {
                        force.x = 0;
                        if (force.y == 0)
                        {
                            break;
                        }
                    }

                    if ((force.y < 0) && (castBuffer[_i].normal.y > ProgramSettings.I.GroundMinYNormal))
                    {
                        force.y = 0;
                        if (force.x == 0)
                        {
                            break;
                        }
                    }
                }
            }

            // Reset instant force and movement.
            instantForce = movement = Vector2.zero;
        }
示例#3
0
 /// <summary>
 /// Rotates this vector of a certain angle.
 /// </summary>
 /// <param name="_vector">Vector to rotate.</param>
 /// <param name="_angle">Angle to rotate vector by.</param>
 /// <returns>Returns new rotated vector.</returns>
 public static Vector2 Rotate(this Vector2 _vector, float _angle) => Mathm.RotateVector(_vector, _angle);
示例#4
0
 /// <summary>
 /// Get if a Vector2 is null, that is
 /// if its x & y values are equal to zero.
 /// </summary>
 /// <param name="_vector">Vector to check.</param>
 /// <returns>Returns true if both x & y Vector2 values
 /// are equal to zero, false otherwise.</returns>
 public static bool IsNull(this Vector2 _vector) => Mathm.IsVectorNull(_vector);
示例#5
0
        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);
            }
        }