Issues translating code from global positions to local positions

Ive spent the last 4 hours reading through documentation and posts on the forum about translating world coordinates into local coordinates, i cant figure out what im doing wrong here.

im trying to make a drawer follow my hand, stop when fully closed and when opened before falling out. here is my code thats working perfectly (so long as the objects axis’ are identical to world axis)

public class DrawerPull : XRBaseInteractable
{
    [Header("Required variables")]
    public GameObject drawer; //the handle you grab needs to actually pull on its parent drawer so this is the drawer object that will be moving
    public float openPercentage; //lets user decide how far the drawer can open
    public IXRSelectInteractor hand;
    public float handOffset; //keeps the hand on the knob rather than (0,0,0) of the drawer

    //drawer renderer is need to get the depth of the drawer for open position calculation
    public new MeshRenderer renderer;

    private Vector3 closedPosition;
    private Vector3 openPosition;

    // Start is called before the first frame update
    void Start()
    {
        openPercentage /= 100; //converts percent to decimal

        //working world space z code
        closedPosition = drawer.transform.position;
        openPosition = new Vector3(closedPosition.x, closedPosition.y, closedPosition.z + (renderer.bounds.size.z * openPercentage));
    }

    // Update is called once per frame
    void Update()
    {
        if (interactorsSelecting.Count > 0) //checks for interactor selection
        {
            hand = interactorsSelecting[0];

            //this is all working code to move drawers forward in world space, not local space
            if (hand.transform.position.z - handOffset > drawer.transform.position.z && drawer.transform.position.z < openPosition.z)
            {
                drawer.transform.position = new Vector3(drawer.transform.position.x, drawer.transform.position.y, hand.transform.position.z - handOffset);
            }
            else if (hand.transform.position.z - handOffset < drawer.transform.position.z && drawer.transform.position.z > closedPosition.z)
            {
                drawer.transform.position = new Vector3(drawer.transform.position.x, drawer.transform.position.y, hand.transform.position.z - handOffset);
            }
        }
    }
}

i’m pretty new to Unity, and brand new to VR development. even if you cant help with the issue im currently trying to solve i wouldnt mind some feedback on what i may have over complicated. clearly i could have simplified the “hand.transform.position” into its own variable to make the code easier to read but i wanted the repetition to remember how to do it.

i attempted to make it work on local coordinates by using the inversePoint method and localPoint property but clearly did something wrong, as soon as i selected the drawer it quite literally shot into infinity. loging its position litterally had “infinity” as its z coords. heres that code.

    void Start()
    {
        openPercentage /= 100;

        //working local space z code
        closedPosition = drawer.transform.localPosition;
        openPosition = new Vector3(closedPosition.x, closedPosition.y, closedPosition.z + (renderer.localBounds.size.z * openPercentage));
        //drawer.transform.localPosition = openPosition; //used to test open drawer position, thats how i know it works above this point, the drawer was in the expected location.
    }

    // Update is called once per frame
    void Update()
    {
        if (interactorsSelecting.Count > 0)
        {
            hand = interactorsSelecting[0];
            // this is my attempt at local z code, but is not working
            if (transform.InverseTransformPoint(hand.transform.position).z - handOffset > drawer.transform.localPosition.z && drawer.transform.localPosition.z < openPosition.z)
            {
                drawer.transform.localPosition = new Vector3(drawer.transform.localPosition.x, drawer.transform.localPosition.y, transform.InverseTransformPoint(hand.transform.position).z - handOffset);
            }
            else if (transform.InverseTransformPoint(hand.transform.position).z - handOffset < drawer.transform.localPosition.z && drawer.transform.localPosition.z > closedPosition.z)
            {
                drawer.transform.localPosition = new Vector3(drawer.transform.localPosition.x, drawer.transform.localPosition.y, transform.InverseTransformPoint(hand.transform.position).z - handOffset);
            }
        }
    }
}

probably relevant information, the screenshot will show the object child tree im working with

So, I finally figured out a big part of it. I changed transform.InverseTransformPoint(hand.transform.position).z to drawer.transform.InverseTransformPoint(hand.transform.position).z

I realized that localPosition was calling the parent position of drawer and inverseTransformPoint was calling the position of the drawer itself so I was trying to do math on moving the drawer based on 2 different positions of (0,0,0)

Its mostly working now, the drawer stays in track no matter the rotation, if i get to closed position it stops moving, if it gets to open position it stops moving, however it seems my hand has to travel much further than the drawer does, and the drawer is flickering between 2 points in its track while selected and not in full open or full closed position.

Learned more about vector3.Dot and have now completely changed my approach to this problem. it is now working perfectly and the code is even shorter than it would have been if I got this to work