コード例 #1
0
ファイル: Movable.cs プロジェクト: LucasJoestar/GGJ2020
    protected bool PerformMovement(Vector2 _movement)
    {
        // Create variables
        bool  _isGrounded        = false;
        bool  _isOverlappingWarp = false;
        int   _count             = 0;
        int   _closestHitIndex   = -1;
        float _distance          = _movement.magnitude;

        RaycastHit2D[] _hitResults = new RaycastHit2D[16];

        // Return if not enough movement
        if (_distance < MinMovementDistance)
        {
            return(false);
        }

        // Cast collider and collide on obstacles
        contactFilter.useTriggers = true;
        _count = collider.Cast(_movement, contactFilter, _hitResults, _distance + Physics2D.defaultContactOffset);
        contactFilter.useTriggers = false;
        for (int _i = 0; _i < _count; _i++)
        {
            // Check warp
            if (_hitResults[_i].collider.isTrigger)
            {
                if (_hitResults[_i].collider.gameObject.HasTag("Warp") && collider.Distance(_hitResults[_i].collider).isOverlapped)
                {
                    _isOverlappingWarp = true;
                    if (currentWarp == null)
                    {
                        currentWarp = _hitResults[_i].collider.GetComponent <Warp>();
                    }
                }
                continue;
            }

            if (!CheckColliderTag(_hitResults[_i], _movement))
            {
                continue;
            }

            // Cache normal hit
            Vector2 _normal = _hitResults[_i].normal;

            // Y movement related calculs
            if (Mathf.Approximately(_normal.y, 1))
            {
                _isGrounded = true;
                velocity.y  = 0;
            }
            else if (Mathf.Approximately(_normal.y, -1))
            {
                velocity.y = 0;
            }

            // Get minimum distance
            float _newDistance = _hitResults[_i].distance - Physics2D.defaultContactOffset;
            if (_newDistance < _distance)
            {
                _distance        = _newDistance;
                _closestHitIndex = _i;
            }
        }

        // Teleport if needed
        if (!_isOverlappingWarp && (currentWarp != null))
        {
            currentWarp.TryToTeleport(this);
            currentWarp = null;
        }

        // Return if not enough movement
        if (_distance < MinMovementDistance)
        {
            OnHitSomething?.Invoke(_hitResults[_closestHitIndex]);
            return(true);
        }

        // Set isGrounded
        if ((_isGrounded != isGrounded) && (_movement.y != 0))
        {
            IsGrounded = _isGrounded;
        }

        // Flip if needed
        if ((_movement.x != 0) && (Mathf.Sign(_movement.x) != (isFacingRight ? 1 : -1)))
        {
            Flip();
        }

        // Move the object
        _movement           = _movement.normalized * _distance;
        transform.position  = (Vector2)transform.position + _movement;
        rigidbody.position += _movement;

        // Return if hit something or not
        if (_closestHitIndex > -1)
        {
            OnHitSomething?.Invoke(_hitResults[_closestHitIndex]);
            return(true);
        }
        return(false);
    }