void Releasing()
    {
        if (_inputs.LeftHandUp && _leftGrabbable != null)
        {
            if (_leftHandHasAttachment)
            {
                _leftGrabbable.grabbable.Throw(_handMovementView.HeadForward, _throwSpeed);
            }
            else
            {
                _leftGrabbable.grabbable.Release();
            }

            _leftGrabbable         = null;
            _leftHandHasAttachment = false;
            UpdateCombinables();
        }

        if (_inputs.RightHandUp && _rightGrabbable != null)
        {
            if (_rightHandHasAttachment)
            {
                _rightGrabbable.grabbable.Throw(_handMovementView.HeadForward, _throwSpeed);
            }
            else
            {
                _rightGrabbable.grabbable.Release();
            }

            _rightGrabbable         = null;
            _rightHandHasAttachment = false;
            UpdateCombinables();
        }
    }
    void Shake()
    {
        if (_leftHandHasAttachment)
        {
            bool orbWasDestroyedByShake = _leftGrabbable.shakable.Shake();

            if (orbWasDestroyedByShake)
            {
                _leftGrabbable         = null;
                _leftHandHasAttachment = false;
                UpdateCombinables();
            }
        }
        if (_rightHandHasAttachment)
        {
            bool orbWasDestroyedByShake = _rightGrabbable.shakable.Shake();

            if (orbWasDestroyedByShake)
            {
                _rightGrabbable         = null;
                _rightHandHasAttachment = false;
                UpdateCombinables();
            }
        }
    }
    bool AttemptGrab(Transform handTransform, out GrabbableData grabbableDataBuffer)
    {
        _detectionRay = new Ray(_cameraTransform.position, _cameraTransform.forward);
        int numberOfHits = Physics.RaycastNonAlloc(_detectionRay, _rayHits, _rayMaxLength, _orbDetectionMask);

        if (numberOfHits > 0)
        {
            IGrabbable hitGrabbable = _rayHits[0].transform.GetComponent <IGrabbable>();

            if (hitGrabbable == null)
            {
                Debug.LogError("AttemptGrab attempted to pick up something that had no IGrabbable component attached", _rayHits[0].transform);
            }

            bool pullIsSuccesful = hitGrabbable.RequestPull(handTransform);
            if (pullIsSuccesful)
            {
                grabbableDataBuffer = new GrabbableData(hitGrabbable, _rayHits[0].transform);
                return(true);
            }
            else
            {
                grabbableDataBuffer = null;
                return(false);
            }
        }
        else
        {
            grabbableDataBuffer = null;
            return(false);
        }
    }
    void Combine()
    {
        if (_combiningIsPossible)
        {
            if (_combiningTimer <= 0)
            {
                _combiningIsPossible = false;

                GameObject combiningResult = CombiningEngine.instance.CombineIngredients(_leftGrabbable.combinable.Ingredient, _rightGrabbable.combinable.Ingredient);
                Orb        newOrb          = Instantiate(combiningResult, _combiningSpawnPosition.position, Quaternion.identity).GetComponent <Orb>();
                newOrb.Activate(CombiningSpawnAnchors.instance.GetRandomAnchor());

                _leftGrabbable.combinable.Combine();
                _rightGrabbable.combinable.Combine();

                _leftGrabbable          = null;
                _leftHandHasAttachment  = false;
                _rightGrabbable         = null;
                _rightHandHasAttachment = false;

                Instantiate(_combiningCompleteParticlesPrefab, _combiningSpawnPosition.position, Quaternion.identity);
                UpdateCombinables();
            }
            else
            {
                _combiningTimer -= Time.deltaTime;
            }
        }
    }
    void Grabbing()
    {
        if (_inputs.LeftHandHeld && _leftGrabbable == null)
        {
            bool grabbableGrabbed = AttemptGrab(_stretchedLeftHandTransform, out _leftGrabbable);

            if (grabbableGrabbed && _leftGrabbable?.InstanceID == _rightGrabbable?.InstanceID)
            {
                _rightGrabbable = null;
            }
        }
        else if (_inputs.RightHandHeld && _rightGrabbable == null)
        {
            bool grabbableGrabbed = AttemptGrab(_stretchedRightHandTransform, out _rightGrabbable);

            if (grabbableGrabbed && _rightGrabbable?.InstanceID == _leftGrabbable?.InstanceID)
            {
                _leftGrabbable = null;
            }
        }
    }