Moving VR Button in LocalSpace with only one axis Unlocked

180637-global.jpgHey Everyone

I’m trying to move this button along its local z position using a collider on my vr hands, finger. It has a box collider and a Rigid body. I am trying to constrain the movement of the local X and Y axis using code, but when I do I have to leave the Local X open, so that it can move proper or if I don’t it moves along the global path, when the X is open the user would be able to push the button side to side which is not ideal.

I’m Using this code to constrain the button:

public bool lockX;
public bool lockY;
public bool lockZ;

public float returnSpeed;

protected Vector3 startPosition;

void Start()
{
    // Remember start position of button
    startPosition = transform.localPosition;
}

// Update is called once per frame
void Update()
{
    ContrainButton();

    // Return button to startPosition over time
    transform.localPosition = Vector3.Lerp(transform.localPosition, startPosition, Time.deltaTime * returnSpeed);
}

private void ContrainButton()
{

    //Lock Axis of checked Bool
    Vector3 localPos = transform.localPosition;

    if (lockX && localPos.x != startPosition.x) localPos.x = startPosition.x;
    if (lockY && localPos.y != startPosition.y) localPos.y = startPosition.y;
    if (lockZ && localPos.z != startPosition.z) localPos.z = startPosition.z;
    transform.localPosition = localPos;
}

I’ve tried google search and read through the forums but couldn’t find much to fit my specific problem Any help to get me on the right path would be great, Thank you everyone :slight_smile:

Positional constraints of a rigidbody are calculated in world space, while rotational constraints are calculated in local space. Looking at your screenshot, a way to accomplish what you are trying to do is to create an empty gameobject which has a rigidbody and the collider you want to interact with. Rotate the gameobject so that its Z axis aligns with its intended path of travel, constraining the rigidbody’s X and Y position variables in the inspector. Make the button’s mesh a child of the gameobject you just set up and rotate it to match the rigidbody’s path of travel. Use a spring joint to control the rigidbody’s movement (play around with the spring joint values to make it feel right).


Using a spring joint will allow you to adjust the rebound time along with travel distance. The only things you have to worry about in code would be stopping the button from oscillating when you let it go:
//fake code if(button.transform.position.z > ButtonStartingPosition.z) { button.rigidbody.velocity = vector3.zero; button.transform.position = ButtonStartingPosition }

and triggering the buttons functionality when pressed.