public void Move(Vector3 input, out Vector3 movement)
    {
        Vector3 position  = transform.position;
        Vector3 direction = input.normalized;
        float   distance  = input.magnitude;

        ContactFilter2D filter = new ContactFilter2D();

        filter.layerMask = groundLayer;

        //Perform a sweep test to see if there are any objects in the way
        RaycastHit2D hit = Physics2D.CapsuleCast(transform.position + (Vector3)collider.offset, collider.size, collider.direction, transform.rotation.eulerAngles.z, direction, distance, groundLayer);

        if (hit && !hit.collider.CompareTag("Platform"))
        {
            float normalDistance = distance - hit.distance;

            position += input * hit.distance;
            position += (Vector3)hit.normal * normalOffset;

            //slide along the surface hit
            Vector3 slide = Vector3.ProjectOnPlane(direction * normalDistance * slideAmount, hit.normal);
            position += slide;
        }
        else
        {
            position += input;
        }
        movement           = position - transform.position;
        transform.position = position;
    }
Ejemplo n.º 2
0
    private bool IsGrounded()
    {
        var          bounds = _capCollider.bounds;
        RaycastHit2D hit    = Physics2D.CapsuleCast(bounds.center, bounds.size, CapsuleDirection2D.Vertical, 0, Vector2.down, bounds.extents.y + .01f, groundLayerMask);

        return(hit.collider != null || IsOnScrollable());
    }
Ejemplo n.º 3
0
    // Use this for initialization
    void Awake()
    {
        animator          = GetComponent <Animator>();
        rigidbody2D       = GetComponent <Rigidbody2D>();
        spriteRenderer    = GetComponent <SpriteRenderer>();
        capsuleCollider2D = GetComponent <CapsuleCollider2D>();
        jumpCount         = maxJumps;

        //should be safe???


        int intMask = 0;

        intMask  |= (1 << LayerMask.NameToLayer("Player"));
        layerMask = ~intMask;


        bool selfCast = Physics2D.CapsuleCast(capsuleCollider2D.offset + (Vector2)transform.position, capsuleCollider2D.size * 0.95f, CapsuleDirection2D.Vertical, transform.rotation.eulerAngles.z, -transform.up, 0, layerMask);
        bool DownCast = Physics2D.CircleCast(capsuleCollider2D.offset + (Vector2)(transform.position) - new Vector2(0, ((capsuleCollider2D.size.y - capsuleCollider2D.size.x) / 2f + capsuleCollider2D.size.x / 2f)), capsuleCollider2D.size.x * 0.49f, -transform.up, capsuleCollider2D.size.x * 0.05f, layerMask);

        Debug.Log(DownCast + " " + selfCast);
        if (DownCast == true && selfCast == false)
        {
            onGround = true;
        }
        else
        {
            onGround = false;
        }
    }
Ejemplo n.º 4
0
    private bool IsGrounded()
    {
        RaycastHit2D raycastHit2d = Physics2D.CapsuleCast(capsuleCollider2d.bounds.center, capsuleCollider2d.bounds.size, capsuleCollider2d.direction, 0f, Vector2.down, .03f, platformsLayerMask);

        Debug.Log(raycastHit2d.collider);
        return(raycastHit2d.collider != null);
    }
Ejemplo n.º 5
0
    private void DetectingEnemies()
    {
        if (!invulnerabity)
        {
            RaycastHit2D[] results = new RaycastHit2D[16];
            List <Vector2> normals = new List <Vector2>();
            int            count   = Physics2D.CapsuleCast(GetComponent <Transform>().position, GetComponent <CapsuleCollider2D>().size * 1.05f, CapsuleDirection2D.Vertical, 0, Vector2.zero, enemyContactFilter, results);

            if (count > 0)
            {
                GameObject firstEnemy = results[0].collider.gameObject;
                for (int i = 0; i < count; i++)
                {
                    if (results[i].collider.gameObject.Equals(firstEnemy))
                    {
                        normals.Add(results[i].normal);
                    }
                }

                EnemyBehaviour enemy = firstEnemy.GetComponent <EnemyBehaviour>();
                stats.ChangePatience(-enemy.GetDamage() / 100);
                enemy.CollideWithPlayer();
                soundsmanager.PlaySound("Daño");

                inputActivated = false;
                Invulnerable(true);
                KnockBack(normals);
            }
        }
    }
Ejemplo n.º 6
0
    public void Move(Vector2 velocityBias, bool isDash = false)
    {
//        DebugExtension.DebugArrow( BodyPosition, velocityBias, Color.blue );
//        DebugExtension.DebugArrow( BodyPosition, CurrentVelocity, Color.red );

        if (Time.deltaTime <= 0)
        {
            return;
        }

        var amount = (CurrentVelocity + velocityBias) * Time.deltaTime;

        var length = amount.magnitude;

        var direction = amount.normalized;

        var hit = Physics2D.CapsuleCast(BodyPosition, 0.6f * BodySize, CapsuleDirection2D.Vertical, 0, direction,
                                        length,
                                        _moveBlockingLayerMask | (isDash ? 0 : _dashableObstacleLayerMask));

        if (hit.collider != null && !transform.IsAncestorOf(hit.collider.transform))
        {
            DebugExtension.DebugPoint(hit.point, Color.yellow, 0.1f, 1);
            BodyPosition = hit.centroid;
            CancelHorizontalMovement();
        }
        else
        {
            transform.Translate(direction * length);
        }

        CheckWallCollisions(isDash);
    }
Ejemplo n.º 7
0
    private void DetectingMotionPlatform()
    {
        RaycastHit2D[] results = new RaycastHit2D[16];
        int            count   = Physics2D.CapsuleCast(GetComponent <Transform>().position, GetComponent <CapsuleCollider2D>().size * 1.05f, CapsuleDirection2D.Vertical, 0, Vector2.zero, motionPlatformContactFilter, results);

        if (count > 0)
        {
            bool existsOne = false;
            int  j         = -1;
            for (int i = 0; i < count; i++)
            {
                if (results[i].normal.y > 0.65f)
                {
                    j = i;
                }
            }
            if (j != -1)
            {
                onMotionPlatform = results[j].collider.gameObject.GetComponent <Transform>();
                GetComponent <Transform>().parent = onMotionPlatform;
            }
        }
        else
        {
            GetComponent <Transform>().parent = null;
            onMotionPlatform = null;
        }
    }
Ejemplo n.º 8
0
    protected virtual void Attacks()
    {
        bool attack = false;

        if (grounded || canKick)
        {
            if (Input.GetButtonDown("AttackLeft") && !attacking)
            {
                side   = LEFT;
                attack = true;

                canKick = false;
            }
            else if (Input.GetButtonDown("AttackRight") && !attacking)
            {
                side   = RIGHT;
                attack = true;

                canKick = false;
            }
        }

        if (attack)
        {
            attacking = true;
            if (grounded)
            {
            }
            else
            {
                rigidbody.velocity = side == RIGHT ? Vector2.right * 20 : Vector2.left * 20;
            }
            Invoke("StopAttack", 0.25f);
        }

        if (attacking)
        {
            Vector3 dir;
            if (side == RIGHT)
            {
                dir = Vector3.right;
            }
            else
            {
                dir = Vector3.left;
            }

            RaycastHit2D hit = Physics2D.CapsuleCast(transform.position, new Vector2(0.2f, 0.8f), CapsuleDirection2D.Vertical, 0, dir, 1f, int.MaxValue);
            if (hit.collider)
            {
                Enemy enemy = hit.collider.GetComponent <Enemy>();
                if (enemy)
                {
                    enemy.Die(side);
                }
            }
        }
    }
Ejemplo n.º 9
0
    private RaycastHit2D CapsuleCast(Vector2 sizeMultiplier, Vector2 direction, float distance)
    {
        Vector2 pos = _capsuleCollider.offset + Vector2.up * 0.1f;

        Vector2 size = _capsuleCollider.size;

        size.x *= sizeMultiplier.x;
        size.y *= sizeMultiplier.y;

        return(Physics2D.CapsuleCast(transform.TransformPoint(pos), size, _capsuleCollider.direction, 0, direction, distance, _movementRaycastMask));
    }
Ejemplo n.º 10
0
 public override RaycastHit2D Cast(Vector2 position, Vector2 scale, float rotation, Vector2 motion)
 {
     return(Physics2D.CapsuleCast(position + PositionOffset,
                                  Size * scale,
                                  Direction,
                                  rotation + AngleOffset,
                                  motion.normalized,
                                  motion.magnitude,
                                  CollisionMask.value,
                                  CollisionMinDepth,
                                  CollisionMaxDepth));
 }
Ejemplo n.º 11
0
    private bool IsGrounded()
    {
        float        extraHeightText = 0.01f;
        var          bounds          = _capsuleCollider2D.bounds;
        Vector2      origin          = new Vector2(bounds.center.x, bounds.center.y - 0.5f);
        Vector2      size            = new Vector2(bounds.size.x * 0.8f, bounds.size.y);
        RaycastHit2D raycastHit      = Physics2D.CapsuleCast(origin, size, CapsuleDirection2D.Vertical,
                                                             0f, Vector2.down, extraHeightText, platformLayerMask);

        _isGrounded = raycastHit.collider != null;
        return(_isGrounded);
    }
Ejemplo n.º 12
0
    void FixedUpdate()
    {
        Vector2 v = rb.velocity;

        v.x = movement * movementSpeed;



        grounded = Physics2D.CapsuleCast(transform.position, new Vector2(1, 2), CapsuleDirection2D.Vertical, 0, Vector2.down, 0.1f, groundMask);

        if (input.axis.x != 0)
        {
            if (Physics2D.BoxCast(new Vector3(0, 0.5f, 0) + transform.position, new Vector2(0.5f, 0.5f), 0, new Vector2(movement, 0), 0.5f, groundMask))
            {
                v.x = 0;
                if (input.axis.y > 0 && canJump)
                {
                    movement         = input.axis.x * -1f;
                    movementCooldown = 0.3f;
                    rb.AddForce(Vector2.up * jumpForce);
                    canJump     = false;
                    wallSliding = false;
                }
                else
                {
                    wallSliding = true;
                    v.y         = slideSpeed;
                }

                grounded = true;
            }
            else
            {
                wallSliding = false;
            }
        }
        if (!canJump && grounded && input.axis.y <= 0)
        {
            canJump = true;
        }
        if (input.axis.y > 0 && canJump)
        {
            rb.AddForce(Vector2.up * jumpForce);
            canJump = false;
        }

        input.axis.y = 0;

        rb.velocity = v;
    }
Ejemplo n.º 13
0
    public bool DetectGap()
    {
        var          ahead = enemy.Stats.Direction.x < 0 ? enemy.Components.Collider.bounds.min.x : enemy.Components.Collider.bounds.max.x;
        RaycastHit2D hit   = Physics2D.CapsuleCast(
            new Vector2(ahead, enemy.Components.Collider.bounds.center.y),
            enemy.Components.Collider.bounds.size,
            CapsuleDirection2D.Vertical,
            0,
            Vector2.down,
            0.1f,
            enemy.Components.GroundLayer);

        return(hit.collider == null);
    }
Ejemplo n.º 14
0
    public void LateUpdate()
    {
        Physics2D.queriesHitTriggers = false;
        //RaycastHit2D hit = Physics2D.Raycast(transform.position, transform.up, 0.1f);
        RaycastHit2D hit = Physics2D.CapsuleCast(transform.position, new Vector3(0.3f, 0.3f, 0.3f), CapsuleDirection2D.Vertical, 360, transform.up, 0.2f);

        Physics2D.queriesHitTriggers = true;

        if (hit.collider != null && hit.collider.transform.root != transform.root)
        {
            HitSomething(hit.collider.gameObject, hit.point);
        }
        Debug.DrawRay(transform.position, transform.up);
    }
Ejemplo n.º 15
0
    public Collider2D DetectCollider(LayerMask colliderLayer)
    {
        var          capsuleSize = new Vector2(collider.bounds.size.x, collider.bounds.size.y);
        RaycastHit2D hit         = Physics2D.CapsuleCast(
            collider.bounds.center,
            capsuleSize,
            CapsuleDirection2D.Vertical,
            0,
            new Vector2(transform.localScale.x, 0),
            0.1f,
            colliderLayer);

        return(hit.collider);
    }
Ejemplo n.º 16
0
    bool Gap()
    {
        RaycastHit2D hit;

        if (side == RIGHT)
        {
            hit = Physics2D.CapsuleCast(transform.position + Vector3.right * 0.5f, new Vector2(0.5f, 1.0f), CapsuleDirection2D.Vertical, 0, Vector3.down, 1.0f, int.MaxValue);
        }
        else
        {
            hit = Physics2D.CapsuleCast(transform.position + Vector3.left * 0.5f, new Vector2(0.5f, 1.0f), CapsuleDirection2D.Vertical, 0, Vector3.down, 1.0f, int.MaxValue);
        }

        return(!hit.collider);
    }
Ejemplo n.º 17
0
    public bool CheckCast(float reduceOfs, Vector2 dir, out RaycastHit2D hit, float dist, int mask)
    {
        if (mCapsuleColl)
        {
            Transform collT    = transform;
            Vector2   collPos  = collT.position + collT.localToWorldMatrix.MultiplyPoint3x4(mCapsuleColl.offset);
            Vector2   collSize = mCapsuleColl.size; collSize.y -= reduceOfs;

            hit = Physics2D.CapsuleCast(collPos, collSize, mCapsuleColl.direction, collT.eulerAngles.z, dir, dist, mask);
            return(hit.collider != null);
        }
        else
        {
            hit = Physics2D.CircleCast(transform.position, mRadius - reduceOfs, dir, dist, mask);
            return(hit.collider != null);
        }
    }
Ejemplo n.º 18
0
    private void TryRaycast(Vector2 from, Vector2 to)
    {
        RaycastHit2D hit = Physics2D.CapsuleCast(from, size, CapsuleDirection2D.Vertical, _angle, to - from);

        if (hit)
        {
            Debug.Log("Raycast hit in: " + hit.transform.name);

            if (boxPosition != null)
            {
                boxPosition.position = hit.centroid;
                Quaternion rotation = boxPosition.rotation;
                rotation.eulerAngles = new Vector3(0f, 0f, _angle);
                boxPosition.rotation = rotation;
            }
        }
    }
Ejemplo n.º 19
0
    public void Attack()
    {
        if (!dead && currentHitChest == null)
        {
            _animator.SetTrigger("attack");

            Vector2 pos = _capsuleCollider.offset + Vector2.up * 0.1f;
            if (!FacingRight)
            {
                pos.x *= -1;
            }
            var result = Physics2D.CapsuleCast(transform.TransformPoint(pos), _capsuleCollider.size, _capsuleCollider.direction, 0, Vector2.right * (FacingRight ? 1 : -1), 1f, _enemyRaycastMask);
            if (result.collider != null)
            {
                result.collider.GetComponent <Hunter> ().Die();
            }
        }
    }
Ejemplo n.º 20
0
    private bool IsGrounded()
    {
        float        extraHeightText = 0.04f;
        RaycastHit2D raycastHit      =
            Physics2D.CapsuleCast(capsuleCollider.bounds.center, capsuleCollider.bounds.size, CapsuleDirection2D.Vertical, 0, Vector2.down, extraHeightText, platformLayerMask);

        //Color rayColor;
        //if (raycastHit.collider != null)
        //{
        //    rayColor = Color.green;
        //} else
        //{
        //    rayColor = Color.red;
        //}
        //Debug.DrawRay(collider.bounds.center + new Vector3(collider.bounds.extents.x, 0), Vector2.down * (collider.bounds.extents.y + extraHeightText), rayColor);
        //Debug.DrawRay(collider.bounds.center - new Vector3(collider.bounds.extents.x, 0), Vector2.down * (collider.bounds.extents.y + extraHeightText), rayColor);
        //Debug.DrawRay(collider.bounds.center - new Vector3(collider.bounds.extents.x, collider.bounds.extents.y), Vector2.right * (collider.bounds.extents.y + extraHeightText), rayColor);
        //Debug.Log(raycastHit.collider);
        return(raycastHit.collider != null);
    }
Ejemplo n.º 21
0
    private bool CheckGrounded()
    {
        bool      result    = false;
        LayerMask layerMask = (1 << 8) | (1 << 9) | (1 << 11);

        ;
        //layerMask = ~layerMask;
        List <Collider2D> results         = new List <Collider2D>();
        ContactFilter2D   contactFilter2D = new ContactFilter2D();

        contactFilter2D.SetLayerMask(layerMask);

        RaycastHit2D raycastHit2D;

        raycastHit2D = Physics2D.CapsuleCast(transform.position, capsuleCollider2D.size, capsuleCollider2D.direction, 0, Vector2.down, 1, layerMask);

        if (raycastHit2D.collider != null && raycastHit2D.distance > 0 && raycastHit2D.distance < 0.035)
        {
            result = true;
        }

        return(result);
    }
Ejemplo n.º 22
0
    public bool CheckFront()
    {
        if (forwardHits == null)
        {
            forwardHits = new RaycastHit2D[raycastBuffer];
        }
        Vector2 faceVector = new Vector2(facing, 0f);

        ContactFilter2D filter = new ContactFilter2D();

        filter.useTriggers = false;

        int hitCount = Physics2D.CapsuleCast(new Vector2(playerCollider.bounds.center.x + (facing * playerCollider.bounds.extents.x), playerCollider.bounds.center.y), new Vector2(.1f, playerCollider.bounds.size.y), CapsuleDirection2D.Vertical, 0f, faceVector, filter, forwardHits, .1f);

        for (int i = 0; i < hitCount; i++)
        {
            RaycastHit2D hit = forwardHits[i];
            if (hit.collider != null && hit.collider != playerCollider)
            {
                return(true);
            }
        }
        return(false);
    }
Ejemplo n.º 23
0
    void Update()
    {
        if (GameController.instance == null)
        {
            return;
        }

        if (GameController.instance.currentState == GameController.GameState.Play || GameController.instance.currentState == GameController.GameState.Cutscene)
        {
            float hNewVel; // Nova velocidade horizontal do player.
            float vNewVel; // Nova velocidade vertical do player.

            // Movimento horizontal, também garante que o player nunca ultrapasse a velocidade máxima.
            if (GameController.instance.currentState == GameController.GameState.Cutscene)
            {
                target.input.verticalAxis = 0f;
            }

            if (grounded)
            {
                hNewVel = target.input.horizontalAxis * velocity;
            }
            else
            {
                hNewVel = Mathf.Clamp(_rigidbody.velocity.x + Mathf.CeilToInt(target.input.horizontalAxis * velocity) * airAcelerationMultiplier, -velocity, velocity);
            }
            // Movimento vertical.
            vNewVel = _rigidbody.velocity.y;

            // Verifica que esta tocando no chão.
            grounded = Physics2D.CapsuleCast(transform.position + new Vector3(_collider.offset.x, _collider.offset.y, 0), new Vector2(_collider.size.x, _collider.size.y), CapsuleDirection2D.Vertical, 0, -Vector2.up, 0.1f, rayMask);

            // DEBUG
#if UNITY_EDITOR
            if (grounded)
            {
                Debug.DrawLine(transform.position + new Vector3(_collider.offset.x, _collider.offset.y, 0) - new Vector3(0, _collider.size.y / 2, 0), transform.position + new Vector3(_collider.offset.x, _collider.offset.y, 0) - new Vector3(0, _collider.size.y / 2, 0) - new Vector3(0, _collider.size.y * 0.075f, 0), Color.red);
            }
            else
            {
                Debug.DrawLine(transform.position + new Vector3(_collider.offset.x, _collider.offset.y, 0) - new Vector3(0, _collider.size.y / 2, 0), transform.position + new Vector3(_collider.offset.x, _collider.offset.y, 0) - new Vector3(0, _collider.size.y / 2, 0) - new Vector3(0, _collider.size.y * 0.075f, 0), Color.green);
            }
#endif

            // Verifica se o player foi esmagado.
            if (grounded)
            {
                bool crushed = false;

                RaycastHit2D ray;
                if (ray = Physics2D.Raycast(transform.position + new Vector3(_collider.offset.x, _collider.offset.y, 0) + new Vector3(0, _collider.size.y / 2, 0), Vector2.up, _collider.size.y * 0.03f, rayMask))
                {
                    if (ray.collider.tag == "Plataform")
                    {
                        crushed = true;
                    }
                }

                if (crushed)
                {
                    Player.instance.Death();
                }

                // DEBUG
#if UNITY_EDITOR
                if (crushed)
                {
                    Debug.DrawLine(transform.position + new Vector3(_collider.offset.x, _collider.offset.y, 0) + new Vector3(0, _collider.size.y / 2, 0), transform.position + new Vector3(_collider.offset.x, _collider.offset.y, 0) + new Vector3(0, _collider.size.y / 2, 0) + new Vector3(0, _collider.size.y * 0.05f, 0), Color.red);
                }
                else
                {
                    Debug.DrawLine(transform.position + new Vector3(_collider.offset.x, _collider.offset.y, 0) + new Vector3(0, _collider.size.y / 2, 0), transform.position + new Vector3(_collider.offset.x, _collider.offset.y, 0) + new Vector3(0, _collider.size.y / 2, 0) + new Vector3(0, _collider.size.y * 0.05f, 0), Color.green);
                }
#endif
            }

            // Verifica se o Player está tentando andar contra uma parede, usado para evitar que ele possa "grudar em paredes" durante um pulo.
            bool blocked = Physics2D.CapsuleCast(transform.position + new Vector3(_collider.offset.x, _collider.offset.y, 0), new Vector2(_collider.size.x, _collider.size.y * 0.95f), CapsuleDirection2D.Vertical, 0, Player.instance.facing * Vector2.right, 0.05f, rayMask);

            if (blocked)
            {
                hNewVel = 0;
            }

            // DEBUG
#if UNITY_EDITOR
            if (blocked)
            {
                Debug.DrawLine(transform.position + new Vector3(_collider.offset.x, _collider.offset.y, 0), transform.position + Player.instance.facing * (new Vector3(0.05f, 0, 0) + new Vector3(_collider.size.x / 2, 0, 0)), Color.red);
            }
            else
            {
                Debug.DrawLine(transform.position + new Vector3(_collider.offset.x, _collider.offset.y, 0), transform.position + Player.instance.facing * (new Vector3(0.05f, 0, 0) + new Vector3(_collider.size.x / 2, 0, 0)), Color.green);
            }
#endif

            // Evita a soma de addForces no pulo.
            if (target.input.jumpButton && grounded && GameController.instance.currentState == GameController.GameState.Play)
            {
                vNewVel = 0;
            }

            if (GameController.instance.currentState == GameController.GameState.Cutscene)
            {
                hNewVel = velocity;
            }

            // Aplica a velocidade ao player.
            _rigidbody.velocity = new Vector2(hNewVel, vNewVel);

            // Realiza o pulo.
            if (target.input.jumpButton && grounded && GameController.instance.currentState == GameController.GameState.Play)
            {
                _rigidbody.AddForce(_rigidbody.mass * Mathf.Sqrt(2 * jumpHeight * 10) * Vector2.up, ForceMode2D.Impulse);
            }
        }
    }
Ejemplo n.º 24
0
        //In here the speed is actually used, and collision is handled.
        private void HandleMovement()
        {
            //0. cache deltaTime.
            float deltaTime = Time.deltaTime;

            //0.5 check for ground.
            Vector2 origin         = transform.position;
            Vector2 groundCheckPos = origin;

            groundCheckPos.y            += verticalOriginToGroundOffset;
            Physics2D.queriesHitTriggers = false;
            //Collider2D groundCollider = Physics2D.OverlapCircle(groundCheckPos, groundCheckTolerance, groundMask);
            float        halfHeight = verticalGroundCheckOffset * 0.5f;
            RaycastHit2D groundHit  = Physics2D.CircleCast(origin + new Vector2(0, halfHeight), groundCheckTolerance, Vector2.down, -halfHeight, groundMask);

            if (!isGrounded && groundHit)
            {
                audioSource.PlayOneShot(landOnGroundSFX);
            }
            isGrounded = groundHit;
            //0.75 snap to the surface.
            if (isGrounded && velocity.y <= 0)
            {
                float groundY = groundHit.point.y - verticalOriginToGroundOffset;
                if (Mathf.Abs(groundY - origin.y) <= groundSnapDistance)
                {
                    origin.y = groundY;
                    //after snapping, also make sure that the desired downwards velocity is really low to avoid collision bugs.
                    if (desiredVelocity.y <= 0)
                    {
                        desiredVelocity.y = 0;
                    }
                }
            }
            //1. Do gravity stuff.
            if (!isGrounded)
            {
                desiredVelocity.y -= gravity * deltaTime;
                desiredVelocity.y  = Mathf.Max(desiredVelocity.y, -maxVerticalVelocity);
            }
            MoveWithCollision(true);

            //Making this bit a local method because i shouldnt think about using this outside of this context
            //also because it needs to be able to call itself without f*****g things up lol.
            void MoveWithCollision(bool allowRecursion)
            {
                //2. use the desired velocity to check where to go
                Vector2 translation       = desiredVelocity * deltaTime;
                Vector2 projectedPosition = origin + translation;

                //3. cast the collider, check for collision on the way there.
                //RaycastHit2D[] hits = new RaycastHit2D[5];
                float   distance  = translation.magnitude;
                Vector2 direction = translation.normalized;

                //I HAVE to write this long line because for some stupid reason, unity wont allow CapsuleCollider2D.Cast without a rigidbody???
                //ITS DOING THE EXACT SAME THING, WHY DOESNT ONE WORK WITHOUT A RIGIDBODY????
                Physics2D.queriesHitTriggers = false; //just make this query ignore triggers real quick <.<
                RaycastHit2D hit = Physics2D.CapsuleCast(origin + collider.offset, collider.size, collider.direction, 0, direction, distance, groundMask);

                Physics2D.queriesHitTriggers = true;

                //4. update velocity based on travelled distance.
                if (hit)
                {
                    //tiny distance away stops the player from getting stuck, but causes some stutter.
                    Vector2 maxTravelDist = Mathf.Max(0, hit.distance - 0.05f) * direction;
                    //if bumping into the ceiling, reset velocity to 0, the player should just fall down afterwards.
                    if (hit.normal.y < -0.9f && desiredVelocity.y > 0.0f)
                    {
                        desiredVelocity.y = 0.0f;
                        if (desiredVelocity.sqrMagnitude > 0.1f && allowRecursion)
                        {
                            MoveWithCollision(false);
                        }
                        return;
                    }
                    if ((hit.normal.x > 0.9f && desiredVelocity.x < 0.0f) || (hit.normal.x < -0.9f && desiredVelocity.x > 0f))
                    {
                        desiredVelocity.x = 0.0f;
                        if (desiredVelocity.sqrMagnitude > 0.1f && allowRecursion)
                        {
                            MoveWithCollision(false);
                        }
                        return;
                    }
                    transform.position = origin + maxTravelDist;
                    //remove velocity based on hit.normal?
                    velocity = maxTravelDist / deltaTime;
                }
                else
                {
                    transform.position = projectedPosition;
                    velocity           = desiredVelocity;
                }
            }
        }
Ejemplo n.º 25
0
    void Update()
    {
        inputVector.x = Input.GetAxis("Horizontal");
        inputVector.y = Input.GetAxis("Vertical");

        Vector3 lookAtTarget = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        lookAtTarget.z = 0;

        // don't bother reorienting if we're right on top of our character
        Vector2 lookAtVector = lookAtTarget - transform.position;

        if (lookAtVector.magnitude > GetComponent <CapsuleCollider2D>().size.x)
        {
            // We might normally use the code below in a 3D game but...
            // transform.LookAt(LookAtTarget); makes z face the target, therefore doesn't work in 2D
            transform.right = lookAtTarget - transform.position;
        }

        Vector3 moveVector     = inputVector * playerSpeed * Time.deltaTime;
        int     directHitCount = GetComponent <CapsuleCollider2D>().Cast(inputVector, directHits);

        if (directHitCount > 0)
        {
            RaycastHit2D directHit = directHits[0];

            if (moveVector.magnitude >= directHit.distance)
            {
                float   diameter       = GetComponent <CapsuleCollider2D>().size.x;
                float   radius         = diameter / 2.0f;
                Vector2 positionAtWall = directHit.point + directHit.normal * radius;

                float wallBounceDistance = 0.001f;
                positionAtWall += (directHit.normal * wallBounceDistance);

                Vector2 previousPosition = transform.position;
                float   distanceSoFar    = (positionAtWall - previousPosition).magnitude;

                DebugUtil.DrawCircle(transform.position + moveVector, radius, Color.red);

                Vector2 wallTangent       = Vector3.Cross(Vector3.forward, directHit.normal);
                float   remainingDistance = moveVector.magnitude - distanceSoFar;

                float   dotForSign             = Vector3.Dot(wallTangent, moveVector);
                Vector2 directionalWallTangent = (wallTangent * dotForSign).normalized;
                Vector2 finalTangentOffset     = directionalWallTangent * remainingDistance;

                int tangentHitCount = Physics2D.CapsuleCast(positionAtWall, GetComponent <CapsuleCollider2D>().size, CapsuleDirection2D.Horizontal, 0, directionalWallTangent, obstructionsToPlayer, tangentHits);
                if (tangentHitCount > 0)
                {
                    RaycastHit2D tangentHit = tangentHits[0];
                    if (remainingDistance >= tangentHit.distance)
                    {
                        DebugUtil.DrawCircle(positionAtWall + finalTangentOffset, radius, Color.magenta);
                        transform.position = tangentHit.point + tangentHit.normal * radius;
                        return;
                    }
                }

                Debug.DrawLine(positionAtWall, positionAtWall + directionalWallTangent);
                transform.position = positionAtWall + finalTangentOffset;
                return;
            }
        }

        transform.position += moveVector;
    }
Ejemplo n.º 26
0
    void FixedUpdate()
    {
        _cancelMove = false;
        var          colliders            = GetComponentsInChildren <Collider2D>();
        var          currentPos           = (Vector2)gameObject.transform.position;
        var          currentAngle         = gameObject.transform.rotation.eulerAngles.z;
        var          timedDirection       = _direction * moveSpeed * Time.fixedDeltaTime;
        var          nextPos              = currentPos + timedDirection;
        var          hitColliders         = new List <Collider2D>();
        bool         _hitHorizontally     = false;
        bool         _hitVertically       = false;
        RaycastHit2D closestHorizontalHit = new RaycastHit2D();
        RaycastHit2D closestVerticalHit   = new RaycastHit2D();

        foreach (var col in colliders)
        {
            RaycastHit2D bestHit = new RaycastHit2D();
            if (typeof(BoxCollider2D) == col.GetType())
            {
                bestHit = Physics2D.BoxCast(currentPos, col.bounds.size, currentAngle, timedDirection.normalized, timedDirection.magnitude, collisionMask);
                Debug.DrawLine(currentPos, nextPos, Color.red);
            }
            else if (typeof(CircleCollider2D) == col.GetType())
            {
                var circleCol = (CircleCollider2D)col;
                bestHit = Physics2D.CircleCast(currentPos, circleCol.radius, timedDirection.normalized, timedDirection.magnitude, collisionMask);
                Debug.DrawLine(currentPos, nextPos, Color.red);
                Debug.DrawLine(currentPos, bestHit.point, Color.green);
            }
            else if (typeof(CapsuleCollider2D) == col.GetType())
            {
                var capsuleCol = (CapsuleCollider2D)col;
                bestHit = Physics2D.CapsuleCast(currentPos, capsuleCol.size, capsuleCol.direction, currentAngle, timedDirection.normalized, timedDirection.magnitude, collisionMask);
                Debug.DrawLine(currentPos, nextPos, Color.red);
            }
            else if (typeof(PolygonCollider2D) == col.GetType())
            {
                var          polygonCol = (PolygonCollider2D)col;
                var          closest    = Mathf.Infinity;
                RaycastHit2D hit        = new RaycastHit2D();
                foreach (var point in polygonCol.points)
                {
                    hit = Physics2D.Raycast(point, timedDirection.normalized, timedDirection.magnitude, collisionMask);
                    Debug.DrawLine(currentPos, nextPos, Color.red);
                    if (hit.collider != null && hit.distance < closest)
                    {
                        bestHit = hit;
                        closest = hit.distance;
                        break;
                    }
                }
            }

            if (bestHit.collider != null)
            {
                if (!Array.Exists(colliders, x => x == bestHit.collider))
                {
                    if (!hitColliders.Contains(bestHit.collider))
                    {
                        hitColliders.Add(bestHit.collider);
                    }
                    SendMessageUpwards("OnPOCollisionEnter", new object[] { col, bestHit.collider, bestHit }, SendMessageOptions.DontRequireReceiver);
                    bestHit.collider.gameObject.SendMessageUpwards("OnPOCollisionEnter", new object[] { bestHit.collider, col, bestHit }, SendMessageOptions.DontRequireReceiver);
                    if (!bestHit.collider.isTrigger)
                    {
                        var vector = bestHit.point - currentPos;
                        var angle  = Vector2.Angle(vector, _direction);
                        if (angle <= 120f)
                        {
                            _cancelMove = true;
                        }

                        var deltaX = Mathf.Abs(vector.x);
                        var deltaY = Mathf.Abs(vector.y);

                        if (deltaX > 0.01f)
                        {
                            if (closestHorizontalHit.collider == null || deltaX < Mathf.Abs((closestHorizontalHit.centroid - currentPos).x))
                            {
                                closestHorizontalHit = bestHit;
                            }

                            _hitHorizontally = true;
                        }

                        if (deltaY > 0.01f)
                        {
                            if (closestVerticalHit.collider == null || deltaY < Mathf.Abs((closestVerticalHit.centroid - currentPos).y))
                            {
                                closestVerticalHit = bestHit;
                            }

                            _hitVertically = true;
                        }
                    }
                }
            }
        }

        foreach (var t in _touching)
        {
            if (!hitColliders.Contains(t))
            {
                SendMessage("OnPOCollisionLeave", new object[] { t }, SendMessageOptions.DontRequireReceiver);
            }
        }

        _touching = hitColliders;

        if (!_cancelMove)
        {
            gameObject.transform.position = nextPos;
        }
        else
        {
            Vector2 newPos  = Vector2.zero;
            var     hOrigin = closestHorizontalHit.point - timedDirection;
            var     vOrigin = closestVerticalHit.point - timedDirection;
            var     deltaX  = hOrigin - currentPos;
            var     deltaY  = vOrigin - currentPos;
            //var newX = (closestHorizontalHit.point - deltaX).x - 0.01f * Mathf.Sign(timedDirection.x);
            //var newY = (closestVerticalHit.point - deltaY).y - 0.01f * Mathf.Sign(timedDirection.y);
            var newX = closestHorizontalHit.centroid.x;
            var newY = closestVerticalHit.centroid.y;

            if (_hitHorizontally && _hitVertically)
            {
                newPos = new Vector2(newX, newY);
            }
            else if (_hitHorizontally)
            {
                newPos = new Vector2(newX, nextPos.y);
            }
            else if (_hitVertically)
            {
                newPos = new Vector2(nextPos.x, newY);
            }
            else
            {
                // Hit to close, don't move
                newPos = currentPos;
                gameObject.transform.position = (Vector3)newPos;
                return;
            }

            gameObject.transform.position = (Vector3)newPos;
        }
    }