0
votes

I'm trying to move an object around my player in a 2.5d sidescroller game based on analog stick input. The thing is, my player rotates around in the world (with the camera fixed to the side) so it's local horizontal direction (transform.right) is not always the global x direction same for it's local up direction (transform.up). I had this working just fine back when the player's movement direction was fixed on the X axis by setting an offset of the players position and adding the analog on the same axis like so:

 Vector3 endPoint = new Vector3(transform.position.x + inputs.x * floraDistanceMultiplier, transform.position.y + inputs.y * floraDistanceMultiplier, transform.position.z);

but now that the player is "off axis" so to speak, this of course doesn't work.

I am able to get it working one axis at a time:

 Vector3 h = player.transform.position + player.transform.right * floraDistanceMultiplier * inputs.x;
 Vector3 v = player.transform.position + player.transform.up * floraDistanceMultiplier * inputs.y;

But couldn't figure out how to get both vectors influencing the final position. Using localPosition or applying the x and y of the final vector manually didn't work I'm assuming because x and y are always global rather than defining the transform.right as a long some kind of local X axis.

I had the thought to lerp the two - which almost has successful results, in that the end point properly move around the player from left to up only though, not in a full circle around the player, and the diagonal is severely closer than the full extent at up and left.

 Vector3 endPoint = Vector3.Lerp(h, v, inputs.x + inputs.y);

is there a better way to do this overall? Or is there some way to lerp between 2 vectors using 2 floats? (the analog stick x and y) or using a vector? Thanks!

1

1 Answers

2
votes

What you do originally

var endPoint = new Vector3(transform.position.x + inputs.x * floraDistanceMultiplier, transform.position.y + inputs.y * floraDistanceMultiplier, transform.position.z);

basically equals using

var endPoint = transform.position + Vector3.right * input.x * floraDistanceMultiplier + Vector3.up * input.y * floraDistanceMultiplier;

So in order to convert this into local space simply replacing the global vectors Vector3.right and Vector3.up by the local transform.right and transform.up should already do it

var endPoint = transform.position + transform.right * input.x * floraDistanceMultiplier + transform.up * input.y * floraDistanceMultiplier; 

Another way to write it a bit shorter would be

var endPoint = transform.position + (Vector3)input * floraDistanceMultiplier;

and in order to convert this one into the local space simply multiply (Quaternion * Vector3 operator) the movement vector with the rotation of the player

var endPoint = transform.position + transform.rotation * input * floraDistanceMultiplier;

As an alternative if you don't necessarily need the endPoint as a vector you could directly use transform.Translate where you can simply decide via the second parameter if you want to apply the movement in world or local space

transform.Translate(input * floraDistanceMultiplier);

By default this already moves the object in local space. Note though, that here the scaling of your objects is taken into account as well. So this might not behave as expected.