Home > Back-end >  Unity calculate how much object moved on a given axis
Unity calculate how much object moved on a given axis

Time:11-04

I am working on a VR project in Unity (2020.3.40f), and need to add the option to move an object on its axis based on the controller's (the user's hand) movement.

Currently I store the controller's position when it grabs the object, and continuously calculate the distance the controller has moved from the initial position. But it is inaccurate, because the controller might have moved in a direction that shouldn't affect the object's position.

For example:

I have this blue lever that the user has to pull. I want to know how much the controller has moved along the green axis, so I can move the lever accordingly.

If the user moves their hand upwards, it shouldn't affect the lever (but in my current implementation, I use Vector3.Distance so the lever moves anyway).

An example

My code:

    private void OnTriggerEnter(Collider other)
    {
        controller = other.GetComponentInParent<IController>();
        if (controller == null || controller.IsOccupied)
        {
            return;
        }

        controller.IsOccupied = true;
        controllerStartPosition = controller.GetPosition();
    }

    private void Update()
    {
        if (controller == null) return;

        Vector3 currentControllerPosition = controller.GetPosition();
        float distance = Vector3.Distance(currentControllerPosition, controllerStartPosition);
        transform.Translate(0, 0, distance * sensitivity);  // The object always moves along its forward axis.
    }

I assume that I need to project the controller's position on the object's forward axis and calculate the distance of that, but I have very basic knowledge in vectors maths so I am not sure about that.

So my question is, What are the calculations that I should do to get the correct distance?

CodePudding user response:

what you are currently doing is;

you are calculating the distance in every axis which the movment on every axis will change the outcome. What you need is when calculating the distance only pass in the parameters in the desired axis for example: float distance = currentControllerPosition.x - controllerStartPosition.x; this will give you the diffrence between the x axis of these points.

for example if it was at 5 and it moved to 8 this will return you 3 regardless the movement on the other axis.

CodePudding user response:

As mentioned what you want to do is Vector3.Project your given hand movement onto the desired target axis direction and only move about this delta.

Something like

private void Update()
{
    Vetcor3 currentControllerPosition = controller.GetPosition();

    // the total vector in world space your hand has moved since start
    Vector3 delta = currentControllerPosition - controllerStartPosition;

    // the delta projected onto this objects forward vector in world space
    // you can of course adjust the vector but from your usage this seems the desired one
    Vector3 projectedDelta = Vector3.Project(delta, transform.forward);

    // finally moving only about that projected vector in world space
    transform.position  = projectedDelta * sensitivity; 
}
  • Related