Help writing bound rotation code for a single axis.

I’m writing a script to make my player’s y rotation = my camera’s y rotation, but leave the player’s x and z rotation the same. The player is a rolling ball, so I can’t fix the x and z rotations, and I’m using a 3d Cinemachine camera that I need to be able to rotate in all directions as well. This is my current script:

player.transform.rotation = camera.transform.rotation;

However this affects each axis, so I tried this:

player.transform.rotation = (player.transform.rotation.x, camera.transform.rotation.y, player.transform.rotation.z);

…but that gave me an error involving Quaternions, which I’ve yet to have a 100% solid understanding of. Any help is appreciated, especially if it results in progress, and if more info is needed, I’ll gladly provide. :slight_smile:

Based on our earlier chat, I think you mean you want the camera to affect how the inputs rotate based on which way you’re facing, right?

If you want to see an example of what I spoke of in the other thread, where you take normal “raw” input and rotate it to match the camera, check this file, like line 124 to line 128 or so.

https://github.com/kurtdekker/proximity_buttons/blob/master/proximity_buttons/Assets/DemoCameraRotatedControls/RotatedControlsPlayerController.cs

See how it uses the heading (0 to 360 around the compass) and then changes the vector?

Line 124 gets the heading off the camera transform

Line 126 makes a Quaternion that is that heading rotated around Y (like a spinning top)

Line 128 modifies the input vector (rotating it around Y to face the heading)

Note: the inputs are put in X, Z, because this is what you want in world. This would be the forces you put on the ball.

You can get that whole project and run the scene in that directory I linked above and see it in action.

1 Like

@Kurt-Dekker I tried the code you linked, and I’ve been given the error “type of name or namespace name ‘_____’ could not be found” for two instances of ‘VAButton’, and one instance of ‘IPushable’… I assume I’m missing something here?

Also @Kurt-Dekker , I managed to work out all of my other issues independently, many thanks to your previous help! I thought I solved this problem as well, but soon realized that the ball didn’t really rotate anymore, since all rotations were made to match the camera.

I figured out how I am going to make the player move relative to its Y rotation, all I need is a way to make the Y rotation of the player and the camera match, without affecting the players other axis rotations.

You need to use eulerAngles. Quaternions use complex math and a quaternion’s x, y, and z values are not what is seen in the editor. The editor shows eulerAngles.

Vector3 rot = player.rotation.eulerAngles;
rot.y = camera.rotation.eulerAngles.y;
player.transform.rotation = Quaternion.Euler(rot);

That should work just fine for simply updating a single axis.

EDIT: Also look into Quaternion.AngleAxis(). That static method is designed to specially rotate around a single axis.

After some serious trial and error and manual reading, I’ve found a solution, which I’ll attach for the sake of anyone with a related problem.

using UnityEngine;

public class PlayerMovement : MonoBehaviour
{

    public Rigidbody player;
    public Camera camera;

    public float maxSpeedInput;

    void FixedUpdate()
    {

        GetComponent<Rigidbody>().maxAngularVelocity = Mathf.Infinity;

        float torque = maxSpeedInput;

        float speed = GetComponent<Rigidbody>().velocity.magnitude;

        Rigidbody rb = GetComponent<Rigidbody>();

        Vector3 cameraForward = Vector3.Cross(camera.transform.right, Vector3.up);

        rb.AddTorque(cameraForward * -Input.GetAxis("Horizontal") * torque * Time.deltaTime);

        rb.AddTorque(camera.transform.right * Input.GetAxis("Vertical") * torque * Time.deltaTime);

    }
}

I used a Cinemachine FreeLook Camera to avoid having to write unnecessary code, and the settings are pretty straightforward too! I’m sure there’s some further simplifying that can be done, but it will suffice for me. Thanks those that aided me in achieving this milestone (definitely a newb, so this is a huge achievement for me).

1 Like

+1 to that achievement for getting into Cinemachine. Cinemachine is SUPER powerful, so I’m glad it was able to do what you needed here.

1 Like