Пример #1
0
    private void CastRaysAbove()
    {
        float rayLength = State.IsGrounded?RayOffset : _newPosition.y * Time.deltaTime;

        rayLength += _rayBoundsRectangle.height / 2;

        bool hitConnected      = false;
        int  hitConnectedIndex = 0;

        Vector2 verticalRayCastStart = new Vector2(_rayBoundsRectangle.xMin + _newPosition.x,
                                                   _rayBoundsRectangle.center.y);
        Vector2 verticalRayCastEnd = new Vector2(_rayBoundsRectangle.xMax + _newPosition.x,
                                                 _rayBoundsRectangle.center.y);

        RaycastHit2D[] hitsStorage = new RaycastHit2D[NumberOfVerticalRays];

        for (int i = 0; i < NumberOfVerticalRays; i++)
        {
            Vector2 rayOriginPoint = Vector2.Lerp(verticalRayCastStart, verticalRayCastEnd, (float)i / (float)(NumberOfVerticalRays - 1));
            hitsStorage[i] = GameTools.GameRaycast(rayOriginPoint, Vector2.up, rayLength, PlatformMask & ~EdgeColliderPlatformMask, true, Color.green);

            if (hitsStorage[i])
            {
                hitConnected      = true;
                hitConnectedIndex = i;
                break;
            }
        }

        if (hitConnected)
        {
            _speed.y               = 0;
            _newPosition.y         = hitsStorage[hitConnectedIndex].distance - _rayBoundsRectangle.height / 2;
            State.IsCollidingAbove = true;
        }
    }
Пример #2
0
    private void CastRaysBelow()
    {
        if (_newPosition.y < -_smallValue)
        {
            State.IsFalling = true;
        }
        else
        {
            State.IsFalling = false;
        }

        if ((Parameters.Gravity > 0) && (!State.IsFalling))
        {
            return;
        }

        float rayLength = _rayBoundsRectangle.height / 2 + RayOffset;

        if (_newPosition.y < 0)
        {
            rayLength += Mathf.Abs(_newPosition.y);
        }


        Vector2 verticalRayCastFromLeft = new Vector2(_rayBoundsRectangle.xMin + _newPosition.x,
                                                      _rayBoundsRectangle.center.y + RayOffset);
        Vector2 verticalRayCastToRight = new Vector2(_rayBoundsRectangle.xMax + _newPosition.x,
                                                     _rayBoundsRectangle.center.y + RayOffset);

        RaycastHit2D[] hitsStorage           = new RaycastHit2D[NumberOfVerticalRays];
        float          smallestDistance      = _largeValue;
        int            smallestDistanceIndex = 0;
        bool           hitConnected          = false;

        for (int i = 0; i < NumberOfVerticalRays; i++)
        {
            Vector2 rayOriginPoint = Vector2.Lerp(verticalRayCastFromLeft, verticalRayCastToRight, (float)i / (float)(NumberOfVerticalRays - 1));

            if ((_newPosition.y > 0) && (!State.WasGroundedLastFrame))
            {
                hitsStorage[i] = GameTools.GameRaycast(rayOriginPoint, -Vector2.up, rayLength, PlatformMask & ~EdgeColliderPlatformMask, true, Color.blue);
            }
            else
            {
                hitsStorage[i] = GameTools.GameRaycast(rayOriginPoint, -Vector2.up, rayLength, PlatformMask, true, Color.blue);
            }

            if ((Mathf.Abs(hitsStorage[smallestDistanceIndex].point.y - verticalRayCastFromLeft.y)) < _smallValue)
            {
                break;
            }

            if (hitsStorage[i])
            {
                hitConnected = true;
                if (hitsStorage[i].distance < smallestDistance)
                {
                    smallestDistanceIndex = i;
                    smallestDistance      = hitsStorage[i].distance;
                }
            }
        }
        if (hitConnected)
        {
            State.IsFalling        = false;
            State.IsCollidingBelow = true;

            _newPosition.y = -Mathf.Abs(hitsStorage[smallestDistanceIndex].point.y - verticalRayCastFromLeft.y)
                             + _rayBoundsRectangle.height / 2
                             + RayOffset;

            if (_externalForce.y > 0)
            {
                _newPosition.y        += _speed.y * Time.deltaTime;
                State.IsCollidingBelow = false;
            }

            if (!State.WasGroundedLastFrame && _speed.y > 0)
            {
                _newPosition.y += _speed.y * Time.deltaTime;
            }

            if (Mathf.Abs(_newPosition.y) < _smallValue)
            {
                _newPosition.y = 0;
            }

            StandingOn = hitsStorage[smallestDistanceIndex].collider.gameObject;
            PathFollow movingPlatform = hitsStorage[smallestDistanceIndex].collider.GetComponent <PathFollow>();
            if (movingPlatform != null)
            {
                _transform.Translate(movingPlatform.CurrentSpeed * Time.deltaTime);
            }
        }
        else
        {
            State.IsCollidingBelow = false;
        }
    }
Пример #3
0
    //角色左右上下射線碰撞偵測
    private void CastRaysToTheSides()
    {
        float movementDirection = 1;

        if ((_newPosition.x < 0) || (_externalForce.x < 0))
        {
            movementDirection = -1;
        }

        float horizontalRayLength = Mathf.Abs(_speed.x * Time.deltaTime) + _rayBoundsRectangle.width / 2 + RayOffset;

        Vector2 horizontalRayCastFromBottom = new Vector2(_rayBoundsRectangle.center.x,
                                                          _rayBoundsRectangle.yMin + _obstacleHeightTolerance);
        Vector2 horizontalRayCastToTop = new Vector2(_rayBoundsRectangle.center.x,
                                                     _rayBoundsRectangle.yMax);

        RaycastHit2D[] hitsStorage = new RaycastHit2D[NumberOfHorizontalRays];


        for (int i = 0; i < NumberOfHorizontalRays; i++)
        {
            Vector2 rayOriginPoint = Vector2.Lerp(horizontalRayCastFromBottom, horizontalRayCastToTop, (float)i / (float)(NumberOfHorizontalRays - 1));

            if (State.WasGroundedLastFrame && i == 0)
            {
                hitsStorage[i] = GameTools.GameRaycast(rayOriginPoint, movementDirection * Vector2.right, horizontalRayLength, PlatformMask, true, Color.red);
            }
            else
            {
                hitsStorage[i] = GameTools.GameRaycast(rayOriginPoint, movementDirection * Vector2.right, horizontalRayLength, PlatformMask & ~EdgeColliderPlatformMask, true, Color.red);
            }

            if (hitsStorage[i].distance > 0)
            {
                float hitAngle = Mathf.Abs(Vector2.Angle(hitsStorage[i].normal, Vector2.up));

                if (hitAngle > Parameters.MaximumSlopeAngle)
                {
                    if (movementDirection < 0)
                    {
                        State.IsCollidingLeft = true;
                    }
                    else
                    {
                        State.IsCollidingRight = true;
                    }

                    State.SlopeAngleOK = false;

                    if (movementDirection <= 0)
                    {
                        _newPosition.x = -Mathf.Abs(hitsStorage[i].point.x - horizontalRayCastFromBottom.x)
                                         + _rayBoundsRectangle.width / 2
                                         + RayOffset;
                    }
                    else
                    {
                        _newPosition.x = Mathf.Abs(hitsStorage[i].point.x - horizontalRayCastFromBottom.x)
                                         - _rayBoundsRectangle.width / 2
                                         - RayOffset;
                    }

                    _speed = new Vector2(0, _speed.y);
                    break;
                }
            }
        }
    }