Пример #1
0
    void Awake()
    {
        animator = GetComponent<Animator>();
        dragonCollider = GetComponentInChildren<Collider2D>();
        body = GetComponent<Rigidbody2D>();
        mover = GetComponent<MoveAlongWaypoints>();

        attackIsOnCooldown = true;
        randomAttackIsOnCooldown = false;
        headAnimatonLayerWeight = 0;

        StartCoroutine(RandomAttackCooldown());
    }
 void Start()
 {
     mover = GetComponent<MoveAlongWaypoints>();
 }
    void Start()
    {
        boxCollider = GetComponent<BoxCollider2D>();
        animator = sprite.GetComponent<Animator>();
        playerLogic = GetComponent<PlayerLogic>();

        isGrounded = false;
        isTouchingWall = false;
        doubleJump = false;
        onSlope = false;
        ControlsEnabled = true;
        notGroundedCountdown = 0;
        runningMotrSpeed = 0;
        relativeJumpSpeed = jumpSpeed;
        HorizontalMovmentDirection = Vector2.right * Mathf.Sign(velocity.x);

        jumpingCountdown = Mathf.NegativeInfinity;
        disableControlsCountdown = Mathf.NegativeInfinity;
        ParachuteCountdown = Mathf.Infinity;

        jumpKeyReleased = true;
        usingParachute = false;
        parachuteScale = 0;

        windZoneAcceleration = 0;
        windZoneMaxSpeed = 0;

        input = 0;
        jumpSpeed = jumpSpeedMin;

        movablePlatform = null;

        speedAnimHash = Animator.StringToHash("Speed");
        jumpAnimHash = Animator.StringToHash("Jump");
        doubleJumpAnimHash = Animator.StringToHash("DoubleJump");
        fallingSpeedAnimHash = Animator.StringToHash("FallingSpeed");
        isGroundedAnimHash = Animator.StringToHash("IsGrounded");
        wallSlidingAnimHash = Animator.StringToHash("IsWallSliding");
    }
    public void Move()
    {
        const float bias = 0.2f;
        const float minGravityRayLenght = 0.3f;

        //vertical box cast collider
        Vector2 verticalCastBoxSize = new Vector2(boxCollider.size.x, bias);
        Vector2 boxOrigin;

        bool wasOnSlope = onSlope;

        Vector2 displacement = velocity * Time.deltaTime;
        RaycastHit2D hit;

        isGrounded = false;
        onSlope = false;
        isTouchingWall = false;
        HorizontalMovmentDirection = Vector2.right;

        //Movable Platform
        if (velocity.y > 0 || (movablePlatformCollider != null &&
            (boxCollider.bounds.max.x < movablePlatformCollider.bounds.min.x || boxCollider.bounds.min.x > movablePlatformCollider.bounds.max.x)))
        {
            movablePlatform = null;
        }

        if (movablePlatform != null && velocity.y <= 0)
        {
            OnGrounded();
            displacement.y = 0;
            transform.SetPositionXY(transform.position.x + movablePlatform.LastFrameDisplacement.x, transform.position.y + movablePlatform.LastFrameDisplacement.y);
        }
        else
        {
            float rayLength = (velocity.y < 0) ? Mathf.Max(Mathf.Abs(displacement.y), minGravityRayLenght) : minGravityRayLenght;

            boxOrigin = new Vector2(boxCollider.bounds.center.x, boxCollider.bounds.min.y + bias / 2.0f);
            hit = Physics2D.BoxCast(boxOrigin, verticalCastBoxSize, 0, Vector2.down, rayLength, obstaclesMask | onewayMask);

            if (hit.collider != null && hit.collider.gameObject.layer == Layers.MovablePlatform)
            {
                movablePlatform = hit.collider.GetComponent<MoveAlongWaypoints>();
                movablePlatformCollider = hit.collider.GetComponent<Collider2D>();

                if (movablePlatform.Velocity.y > velocity.y)
                {
                    Vector2 size = new Vector2(boxCollider.size.x, bias);
                    boxOrigin = new Vector2(boxCollider.bounds.center.x, boxCollider.bounds.max.y - bias);

                    displacement.y = 0;

                    hit = Physics2D.BoxCast(boxOrigin, size, 0, Vector2.down, Mathf.Infinity, movablePlatformMask);

                    if (hit.collider != null)
                    {
                        OnGrounded();

                        HorizontalMovmentDirection = Vector3.Cross(hit.normal, Vector3.forward).normalized;

                        transform.SetPositionX(transform.position.x + movablePlatform.LastFrameDisplacement.x);
                        transform.SetPositionY(transform.position.y + hit.point.y - boxCollider.bounds.min.y + bias);
                    }
                }
                else
                {
                    movablePlatform = null;
                }
            }
            else
            {
                movablePlatform = null;
            }
        }

        //Vertical Movement
        if (velocity.y < Mathf.Epsilon && movablePlatform == null)
        {
            boxOrigin = new Vector2(boxCollider.bounds.center.x, boxCollider.bounds.min.y + bias / 2.0f);
            hit = Physics2D.BoxCast(boxOrigin, verticalCastBoxSize, 0, Vector2.down, Mathf.Max(Mathf.Abs(displacement.y), minGravityRayLenght), obstaclesMask | onewayMask);

            if (hit.collider != null)
            {
                const float minHorizontalDirectionX = 0.3f;

                displacement.y = -(hit.distance - bias);
                HorizontalMovmentDirection = Vector3.Cross(hit.normal, Vector3.forward).normalized;
                HorizontalMovmentDirection.x = Mathf.Max(Mathf.Abs(HorizontalMovmentDirection.x), minHorizontalDirectionX) * Mathf.Sign(HorizontalMovmentDirection.x);
                onSlope = Mathf.Abs(HorizontalMovmentDirection.y) > slopeLimit.min;

                if (Mathf.Abs(HorizontalMovmentDirection.y) < slopeLimit.max)
                {
                    OnGrounded(!onSlope);
                }
            }
        }
        else if (velocity.y > Mathf.Epsilon)
        {
            boxOrigin = new Vector2(boxCollider.bounds.center.x, boxCollider.bounds.max.y - bias / 2.0f);

            hit = Physics2D.BoxCast(boxOrigin, verticalCastBoxSize, 0, Vector2.up, Mathf.Abs(displacement.y), obstaclesMask);
            if (hit.collider != null)
            {
                displacement.y = (hit.distance - bias);
                velocity.y = 0;
            }
        }

        transform.SetPositionY(transform.position.y + displacement.y);

        //Horizontal movement
        if (HorizontalMovmentDirection.x > 0)
        {
            displacement = HorizontalMovmentDirection * Mathf.Sign(velocity.x) * Mathf.Abs(displacement.x);
            Vector2 direction = displacement.normalized;

            hit = Physics2D.BoxCast(boxCollider.bounds.center, boxCollider.size, 0, direction, displacement.magnitude, obstaclesMask);

            if (hit.collider != null)
            {
                if (Mathf.Sign(hit.normal.x) != Mathf.Sign(displacement.x) && Mathf.Abs(hit.normal.x) > slopeLimit.min)
                {
                    wallNormal = hit.normal;
                    wallDirection = -Mathf.Sign(velocity.x);
                    velocity.x = runningMotrSpeed = 0;
                }

                transform.SetPositionXY(transform.position.XY() + direction * (hit.distance - bias));
            }
            else
            {
                transform.SetPositionXY(transform.position.XY() + displacement);
            }
        }

        //Check if player is touching the wall
        if (!isGrounded && !usingParachute)
        {
            const float colliderIncreaseFactor = 1.2f;

            Vector2 boxSize = new Vector2(boxCollider.size.x * colliderIncreaseFactor, boxCollider.size.y);

            hit = Physics2D.BoxCast(boxCollider.bounds.center, boxSize, 0, Vector2.right, 0, obstaclesMask);

            if (hit.collider != null)
            {
                isTouchingWall = true;
            }
        }

        //push player when falling on a steep slope
        if (onSlope && !wasOnSlope)
        {
            runningMotrSpeed += Mathf.Abs(velocity.y * HorizontalMovmentDirection.x) * -Mathf.Sign(HorizontalMovmentDirection.y);
            velocity.y *= Mathf.Abs(HorizontalMovmentDirection.y);
        }
    }