Rotating A Vector2 Input Into A Vector3

I’m getting a normalized Vector2 direction from a touch screen. (Joystick)
The input is supposed to control the movement of a ball. The ball can change its gravity when it comes in contact with a wall so that the wall becomes the new ‘down’.

My issue arrives here because I was converting the Vector2 input into the XZ axis. However now the ball is rolling on, say, a surface along the XY axis, and so it cant properly move around on it. The issue gets more complicated when trying to use surfaces that aren’t aligned to an axis.

I found several people talking about using “Quaternion.Euler()” and “vector = Quaternion.AngleAxis(-45, Vector3.up) * vector”. However I don’t always know the new angle or axis at which to use because I will be using surfaces of all different orientations.

It is probably useful to note that I am getting the new gravity directions from the normals of downward raycasts.

This sounds like it might be pretty challenging for a user to stay oriented…maybe if you oriented the camera to the new surface at each hit everything will work out okay. As for your question…

How you handle the situation will depend on what you build your surfaces out of. For my suggestions below, I’m going to assume that you build the surfaces out of cubes or quads. In particular, I’m going to assume that for any given surface, that gravity is applied in the negative ‘y’ direction of the object, that forward is the ‘z’ direction, and that right is the local ‘x’ of that object. It is important to be consistent on this definition no matter what orientation you place the surfaces.

Each time you hit a surface, you can get information about the surface in the OnCollisionEnter() function. In particular, you want to get information from the transform:

So on collision, your ball will do:

private var right = Vector3.right;
private var down = Vector3.down;
private var forward = Vector3.forward;

function OnCollisionEnter(col : Collision) {

	var tr = col.collider.transform;
	down = -tr.up;
	right = tr.right;
	forward = tr.forward;
}

Now you did not indicate how you move the ball. Let me assume rigidbody. For gravity you will do something like:

rigidbody.AddForce(down * forceOfGravityContant);

For the forward and right movement, you will do something like:

var movement = forward * Input.GetAxis("Vertical") * upAmount + right * Input.GetAxis("Horizontal) * rightAmount;

‘movement’ can then be passed to AddForce() or CharacterController.Move().

Since you did not provide any code, this is pretty soft, but this is the general concept.