Droppable Block

                Never    
C#
       
    public override void EndDrag(bool overideByConnected)
    {
        if (!IsDrag)
            return;

        base.EndDrag(false);

        _rigidbody.velocity = Vector3.zero;

        if (IsFreePosition())
            DropBlock();
        else
            PlaceBlock();
    }

    private void DropBlock()
    {
        _dropped = true;
        _rigidbody.isKinematic = false;

        GameSequence.SetPositionsIsFree(CurrentGridPositions);
    }

    private void PlaceBlock()
    {
        _dropped = false;
        _rigidbody.isKinematic = true;

        if (GameSequence.GetNearSwapPosition(this, out Vector2Int[] _gridPositions))
        {
            if (GameSequence.GetWorldPosition(_gridPositions, out _worldPositions))
            {
                _onDefaultPosition = true;

                CurrentGridPositions = _gridPositions;

                GameSequence.SetPositionsIsBusy(CurrentGridPositions);
            }
        }
    }

    private bool IsFreePosition()
    {
        if (GameSequence.GetNearSwapPosition(this, out Vector2Int[] _gridPositions))
        {
            NearPositions = _gridPositions;
            NearPositions[0] += Vector2Int.down;
        }

        if (GameSequence.IsFreePositions(NearPositions))
            return true;
        else
            return false;
    }

    private void FixedUpdate()
    {
        if (!_inited)
            return;

        if (!_dropped)
        {
            if (!IsDrag)
            {
                _rigidbody.position = Vector3.Lerp(_rigidbody.position, _worldPositions[0], Time.fixedDeltaTime * 25);
            }
        }
        else
        {
            _rigidbody.velocity = new Vector2(0, -10f);
        }
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (IsDrag)
        {
            Services.Feedback.HapticLimited(FeedbackHapticTypes.LightImpact);
        }

        if (_dropped)
        {
            PlaceBlock();
        }
    }

Raw Text