Rotate an object on X not working when facing a specific direction

Hi,

I’m trying to rotate my FPS Camera, attached to my character, with the mouse: when I go up it rotates up, and when I go down it rotates down. I’m experiencing a strange problem, which I manage to reproduce in a very simple scene. It works fine, EXCEPT when my character is oriented on (0,0,-1): it is then very slow to rotate!

To reproduce it, create an empty object, attach a Camera called CameraSub with the following script on the empty object:

Vector3 lookingPoint = new Vector3();

// Update is called once per frame
void Update () {
		Vector3 directionCamera = VectorDirection(new Vector2(Screen.width/2, Screen.height/2), Input.mousePosition);
					
		float rotationSpeedX = 2.0f;	
		float rotationSpeedY = 2.0f;			
	
		
		lookingPoint = transform.Find("CameraSub").transform.position + transform.Find("CameraSub").transform.TransformDirection(directionCamera);
		lookingPoint = lookingPoint + transform.Find("CameraSub").transform.TransformDirection(new Vector3(0,0,3));
					
		Quaternion rotationCamera = new Quaternion();
		if ((lookingPoint - transform.Find("CameraSub").transform.position )!= Vector3.zero) rotationCamera = Quaternion.LookRotation(lookingPoint - transform.Find("CameraSub").transform.position);
		rotationCamera = new Quaternion(rotationCamera.x, 0.0f, 0.0f, rotationCamera.w);
		transform.Find("CameraSub").transform.localRotation = Quaternion.Slerp(transform.Find("CameraSub").transform.localRotation, rotationCamera, Time.deltaTime * rotationSpeedY);			
		//rotationPlayer = new Quaternion(0.0f,newRotation.y,0.0f, newRotation.w);
}


Vector3 VectorDirection(Vector3 from, Vector3 to)
{
	Vector3 diff = to - from;
	return (diff).normalized;
}

Then rotate the object by 180 on Y. I tried on several computers and it always happens so, so i think it comes from Unity. Why is it so? Is it a bug??

Many thanks for any help.
Nicolas

I believe you are running into gimbal lock which occurs when two axes align

Try this script. It allows the player to move according the the mouse movement.
NOTE: I have restricted Y axis movement and to not always allow camera to be moved, simply an excerpt of what i am using.

Modifications like removing the if statement all together to allow completely freedom, BUT make sure to bound your axis so you don’t have weird movements when you decide to go over 180 degree on the y axis.

using UnityEngine;
using System.Collections;

public class CameraController : MonoBehaviour 
{
	// What the camera should focus on, typically the player for 3rd person or in front of the player's face. Just adjust the camera position for 1st person view
	public Transform target;
	
	// How high the camera is relative to the rotational direction of the camera
	public float heightOffset   = 0.27f;
		
	// How far the camera is relative to the rotational direction of the camera
	public float distanceOffset = 0.73f;
	
	// How fast the player will rotate when moving horizontally
	public float rotationSpeed  = 250.00f;

	
	private GameObject _myCamera;
	private GameObject _myPlayer;
	
	private float horizontal = 0.0f, vertical = 0.0f;
	
	// Use this for initialization
	void Start () 
	{
		_myCamera = Camera.main.gameObject;
		_myPlayer = GameObject.FindGameObjectWithTag("Player").gameObject;
		
		if(!target)
			Debug.Log("Missing target! Camera will act weird.");
		
		SetCamera();
	}
	
	// Update is called once per frame
	void Update ()
	{
		// Only allow camera rotation when
		if(Input.GetKey(KeyCode.LeftAlt))
		{
			horizontal = Input.GetAxis("Mouse X") * rotationSpeed;
			
			// How much to rotate the player
			_myPlayer.transform.Rotate(0, horizontal * Time.deltaTime, 0);
		}
		else
			horizontal = 0.0f;
	}

	void SetCamera ()
	{				
		// Set position for the camera to by away from the target
		_myCamera.transform.position = new Vector3(target.transform.position.x,
												  target.transform.position.y - heightOffset*-1, // *-1 to maintain heightOffset as a positive value
												  target.transform.position.z - distanceOffset);
		
		// Look a little above target
		_myCamera.transform.LookAt(target.transform.position);		
	}		
}