0
\$\begingroup\$

I'm currently trying to recreate how Space Engineers work with their first-person acmera in Unity 3D. I'm currently stuck on how to make sure the camera doesn't spin around its axis when looking downwards or upwards, like a sphere. I've looked through several available online snippets for assistance however they all use quaternion to rotate their camera around an axis; this isn't what I want.

Any advice or examples? I'm new to Unity3D by the way so I'd appreciate a basic overview of how it works before the "scientific" language.

This is what currently happens when I look up or down and move left/right:

enter image description here

What I want to happen wherever I look up/down or not at all:

enter image description here

My current code:

using UnityEngine;
using System.Collections;

[AddComponentMenu("Camera-Control/Mouse Look")]
public class MouseLook : MonoBehaviour
{

    public float rotationspeed = 6f;

    private float x, y = 0;

    void Update()
    {
        x += Input.GetAxis("Mouse X") * rotationspeed;
        y += -Input.GetAxis("Mouse Y") * rotationspeed;

        transform.eulerAngles = new Vector3(y, x);
    }

}

Inspector:

enter image description here

\$\endgroup\$
  • \$\begingroup\$ Why do you want so? Any reason behind this? \$\endgroup\$ – Hamza Hasan Jan 30 '16 at 21:45
  • 1
    \$\begingroup\$ I like Space games? \$\endgroup\$ – VirtualByte Jan 30 '16 at 22:09
  • \$\begingroup\$ btw you don't want to rotate camera in any direction except left and right? \$\endgroup\$ – Hamza Hasan Jan 30 '16 at 23:21
  • \$\begingroup\$ I want to rotate the camera in all directions. \$\endgroup\$ – VirtualByte Jan 30 '16 at 23:25
  • \$\begingroup\$ Your code should work fine \$\endgroup\$ – Hamza Hasan Jan 30 '16 at 23:27
2
\$\begingroup\$

The trouble you're encountering can be solved by applying small relative rotations to the camera's current transform rather than setting an absolute rotation with a Euler angle.

Sadly the Unity API is rather cryptic when it comes to this; I believe this code should work, but the concept is correct either way. When updating the camera take the mouse deltas and apply rotation around the current transform's up and right axes.

//Pitch rotates the camera around its local Right axis
transform.Rotate(Vector3.right * Time.deltaTime * Input.GetAxis("Mouse Y") * rotationspeed);

//Yaw rotates the camera around its local Up axis
transform.Rotate(Vector3.up * Time.deltaTime * Input.GetAxis("Mouse X") * rotationspeed);

For reference take a look at Unity's transform.Rotate documentation which I believe is what you're looking for.

\$\endgroup\$
  • \$\begingroup\$ Considering the new formulation of the questions as per the editing made by the OP, your answer is on spot and nicely simple. I would only add a tiny detail: although in the end it's a matter of taste, I would make either Input.GetAxis("Mouse X") or Input.GetAxis("Mouse Y") have a negative sign for movement consistency. \$\endgroup\$ – MAnd Jan 31 '16 at 6:10
0
\$\begingroup\$

EDIT: this answer was addressing the problem as originally formulated by the OP, i.e. "how to make sure the camera doesn't spin around its axis when looking downwards or upwards". For that, the answer was perfectly useful (I suggest fellows to always look at previous versions of edited questions before down-voting answers). That said, now, in the question's current state (i.e. how to implement a 360 degree turn to any direction a mouse-moved-camera looks at), the OP needs precisely what @Vector57's answer provides correctly and elegantly


It is very hard to give a proper answer without seeing anything that you have implemented so far. So, I can only give you a general-case answer, and I do that only because I suspect what you might be talking about is a rotation effect that can be easily solved by clamping the Y axis of the camera rotation.

So, I suppose that you are retrieving the mouse position with something like:

    x += Input.GetAxis("Mouse X") * rotationspeed;
    y += -Input.GetAxis("Mouse Y")* rotationspeed;

And then you are probably rotating the main camera with something like:

Camera.main.rotation = Quaternion.Euler(y,x,0.0f);

If that is what you are doing, you just have to clamp ybefore that last step. Clamping y means to force the above variable y to be greater than a givenlower_limit and smaller than another given upper_limit (usually -+85º works fine for me).

Bonus tip: although it is not exactly what you are asking, don't forget also to, first of all, convert the angle degrees in a way that they are always in the 360º scale, i.e. they are always both >=-360º and <=360º.

\$\endgroup\$
  • \$\begingroup\$ I have editted the question to be more clear :) \$\endgroup\$ – VirtualByte Jan 30 '16 at 22:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.