Esempio n. 1
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;
        }
Esempio n. 2
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);
            }
        }