need help with centering camera - script included

Hi everyone,

I have tried to make a script to attach to the main camera so that whenever a user is idle for X time, the camera rotates back to it’s original position.

The thing is that I am not able to do it permanently.

Follows my code:

var origem ;
var speed = 0.5;
var reset = 0.0;
var maxReset = 5.0;

function Start(){
	origem = transform.rotation;
}

function dostuff (){
	transform.rotation =
		Quaternion.Slerp (transform.rotation, origem, Time.time * speed);		
}

function OnGUI () {

	var event = Event.current;

	if (!event.isKey  !event.isMouse  event.type != EventType.MouseMove){
		reset += Time.deltaTime;
	}	

	else{
		reset = 0.0;
	} 
		
	if (reset > maxReset){
		dostuff ();
		reset = 0.0;
	}
}

Any suggestions?

Many thanks.

Your OnGUI code seems to be written well enough but your dostuff function seems a bit off. As it is now, the OnGUI function looks for key presses, mouse clicks or mouse movement, if none of those are found reset is increment, if any are found reset is, well, reset to zero. If the user is idle for more than maxReset seconds you call dostuff() and reset reset to zero.

Here’s where the problem comes in, namely that dostuff() does one single Slerp call which may or may not be the full rotation you want to have happen. One quick test would be to make dostuff() look like this:

function dostuff () {
  transform.rotation = origem;
}

Then if you’re idle for maxReset seconds, the camera will snap back to the original rotation. Sure, that’s not likely the desired effect but it will at least help verify that the OnGUI function is in fact solid.

If the snap brings the camera back to its original position then you’ll need to rewrite dostuff() to use coroutines/yield statements to animate the camera back to its original rotation instead of snapping it.

function dostuff () {
  var currentem = transform.rotation;
  for (var i = 1.0; i <= 10.0; i++) {
    var slerpPct = i / 10.0;
    transform.rotation = Quaternion.Slerp(currentem, origem, slerpPct);
    yield WaitForSeconds(0.1);
  }
}

Note that the above is quick forum hack code but it proves the point. You write a small animation loop that issues repeated slerp calls to slowly rotate the camera back into place (in my case I use ten iterations at 1/10th second per iteration so the animation takes 1 second).

Make sense?

Hi Tom,

Many thanks for your time. My apologies fo r the late reply but the holiday season took control of my time :slight_smile:

You provided valuable insight on the problem, and I have managed to solve it not exactly as you posted here but with the same effect. I also had some other constraints to deal with (mouselook script had to be updated with a “reset” function) and the final result has been most pleasing.

Follows my solution if you’d care to give your $0.02

function OnGUI () {

	var event = Event.current;

	if (!event.isKey  !event.isMouse  event.type != EventType.MouseMove){
		reset += Time.deltaTime;
	}	

	else{
		reset = 0.0;
	} 
		
	if (reset > maxReset){
		centerCamera = true;
		reset = 0.0;
	}
}

function Update(){
	// Se chegou a hora de centrar a camara
	if(centerCamera){
		// Desligar o Mouse Look
		mouseLook.enabled = false;
		
		// Rodar a camara para o centro
		transform.rotation =
			Quaternion.Slerp (transform.rotation, origem, speed);
		
		// Se a camara ja estah centrada
		if(Quaternion.Angle(transform.rotation, origem) == 0){
			// Ligar o Mouse Look e por o cursor no centro do ecra
			restartMouseLook();
		}
		
	}

}

function restartMouseLook(){

	Screen.lockCursor = true;

	mouseLook.Reset(origem);
	mouseLook.enabled = true;
	
	centerCamera = false;
	
	Screen.lockCursor = false;
}

Many thanks

Looks good to me. :slight_smile:

As you continue to work with Unity I really do think you should get comfortable with using yield/coroutines as they will allow you to be more flexible about how/where you do animation routines. In this case it can go either way, how I did it above or your own solution, both will work and all is good. But imagine a case where instead of just one type of animation (centering the camera) you have many types of animations, using your technique your Update function would quickly become a bulky state machine checking multiple variables like centerCamera. Imagine instead moving those animation routines to separate unique functions and doing that keeps things “cleaner” IMO.

But in any case your solution looks great so roll with it!

Many thanks for cheking it and also on the heads up for yield/coroutines. Will look into it in the future. Happy new year :slight_smile: