How to move camera automatically?

Does anyone know how to move the camera automatically with first

  1. moving camera from ground and then elevate upwards to a certain position. 2) moving the camera forwards in a constant speed automatically ?

i have tried using the following coding but i have fail to get my requirements. Does anybody know why?

var speed = 5.0;
var terrainData : TerrainData;
var parent : Transform;
var moveSpeed : float = 1;


function Update(){
	var camera = camera.transform.localPosition;	

	//transform.Translate(Vector3.forward * Time.deltaTime*5);	
	
    if(camera.z < terrainData.size.z  camera.z > 0 ){

			transform.Translate(Vector3.up * (Time.deltaTime*5), Space.World);
			transform.Translate(Vector3.foward * Time.deltaTime*5);		
			}
	else
		{
		transform.Translate(Vector3.zero,Space.World);
		}

}

Thanks in advance.

:? :cry:

To add on to this post, i have tired the following coding but i still does not get the output that i want. I am now able to move my camera from ground and elevate upwards to the certain level. However, when my camera reaches certain height, at the top, my camera fail to move forward. In fact, the camera is consistently moving upwards. What i want is to move my camera forward after it have reaches the top.

Is there something wrong in my coding? Or do i need to set some condition to stop the movement when it reach the certain height ? Any idea or recommendation? Thanks in advance.

var speed = 5.0;
var terrainData : TerrainData;
var parent : Transform;
var moveSpeed : float = 1;
//terrainData.size.x
var smooth = 2.0;
var tiltAngle = 30.0;

	
function Update(){
	var camera = camera.transform.localPosition;
	
    var rotateAroundYInput: float = Input.GetAxis("Horizontal");
    var objectUp: Vector3 = transform.TransformDirection(Vector3.up);
    

print ("Camera displays from " + camera + " to " + tiltY + " pixel");    
    

// allow camera to move automatically forwards and upwards
	
	if(camera.z < terrainData.size.z  camera.z > 0 ){
	
			transform.Translate(Vector3.forward * Time.deltaTime*5);
			transform.Translate(Vector3.up * (Time.deltaTime*5), Space.World);
	
	if(camera.y < terrainData.size.y  camera.y > 100){
		
			transform.Translate(Vector3.forward * Time.deltaTime*5);		
			}
		else
		{
			transform.Translate(Vector3.zero,Space.World);
		}
	}

The immediate problem I see given the description above and the code you’ve provided is that you want the camera to move “up” first (world’s y-direction), yet your code checks against a z-position (not the world’s up).

I think that at this point it’s wise to simplify things and start with the basics. As such, here’s a script that will move the camera “up” (y-direction) until it reaches a specified trigger altitude, once at/above that altitude the camera will move forward:

function Update () {
	
  // Get the camera's current position
  var tCameraPosn = transform.localPosition;
	
  // Set the trigger altitude (above this we'll move the camera forward)
  var tTriggerAltitude = 20.0;
	
  // Check the camera's altitude (y-position) against the trigger altitude
  if (tCameraPosn.y < tTriggerAltitude) {
		
    // Move the camera up
    transform.Translate((Vector3.up * (Time.deltaTime * 5.0)), Space.World);
		
  } else {
		
    // Move the camera forward
    transform.Translate((Vector3.forward * (Time.deltaTime * 5.0)));

  }

}

Make a new scene and attach the above to your camera and see what happens. The script is very simple:

  • Get the camera’s position
  • Set a trigger altitude (manually set to 20.0 for now)
  • Check the camera’s y-position against that altitude
  • If we’re below the trigger altitude then move the camera up
  • If we’re above the trigger altitude then move the camera forward

Done. Without worrying about the next steps (like dealing with your terrain or user input), does the above make sense?

I don’t generally like “giving” code as it’s best for you to write it yourself (helps you understand it more), so if you do understand the above then try it again yourself, keeping things simple, and see how things work on your end.

Once you have a handle in the above we can worry about checking the camera’s position against a terrain as you seem interested in doing.

its a pleasure to read such complete replies

Thanks alot for the reply HiggyB. Now i get what i wanted. Thanks alot. =))

To add on to this post, does anybody know how to rotate the camera in x-axis automatically without using the Mouse and keyboard control ?

i have tried the following coding which i found from the scripting references in unity3d.

function Update(){
transform.RotateAround( Vector3.zero, Vector3.up,20 * Time.deltaTime);
}

i just want the camera to rotate in a 90 degree along the X-axis. shall i continue to edit in this script? Thanks in advance.

Hey there,
For questions like this, I’d suggest you first dig around the Script Reference, there is a lot to be found there :smile:

But, I think this function should solve your problem:

Transform.Rotate(x,y,z)

Applies a rotation of eulerAngles.x degrees around the x axis, eulerAngles.y degrees around the y axis and eulerAngles.z degrees around the z axis.

LINK: Unity - Scripting API: Transform.Rotate

For my board game I’ve got an overhead camera rotating around the Y axis on a boom (empty GameObject) that is offset from the center of rotation. I want to be able to step rotate the boom in 60° increments via user input. I’m using the RotateAround code example from the Script Reference which works perfectly. I’m just having trouble coding the start/stop part of the interface.

My first thought was to read the angle of the boom during each update to determine if it is evenly divisible by 60, but I can’t figure out which variable holds that angle. Also, I’m not sure if that variable will consistently be an even integer.

My next thought was to run a “for” loop for a second of time (the rate of rotation is 60° per second). But I can’t see how to use Time as a counter. Also, I’m not sure if a loop based on time will give me exact positioning for each rotation or if I will get drift.

The simplest would be to read the position of the boom and stop its rotation when it hits the correct angle, but I can’t get the position numbers because when I rotate the boom in the Inspector, it rotates the boom object around its center instead of around the rotation point.

I suspect this is rudimentary and I simply haven’t read some part of the manual or reference (though I’ve been scouring them and the forum and the wiki for the past three days), but I’m running out of time on my trial and I’d like to prove to myself that I can successfully code scripts for Unity before I commit to purchasing it. Thanks for any help or thoughts about other methods.

Thanks for the reply myraneal but i am sorry i think i have misinterpret it.

Actually what i really wanted is that i need my camera to rotate in a clockwise direction around an arc slowly in the middle of my terrain. Am i able to continue to use the script as you have suggested as above? Thanks in advance.

Yes, use either Transform.Rotate or Transform.RotateAround.

First off, you want to rotate around the X axis? Are you aware of what that will do? As you sit there, stick your right arm straight out, that is the x-axis, if you rotate around that you’ll make the camera look up/down, is that what you’re after? Or do you want to rotate around the Y axis, so you’ll orbit around a point on the terrain, as per your code above? I’m going to assume you want to rotate around the y-axis and not x …

The code you provided will rotate the camera continuously, what you need now is to use conditional statements (rotate until a specific condition is met, like “rotate until we’ve gone 90 degrees”) and coroutines as they really help with animations like this.

You can achieve this goal using code like this (untested forum code):

function DoRotateAroundAnimation (aPoint, aAxis, aAngle, aDuration) {

  // Determine the number of for loop steps needed (assume 30 fps for our loop)
  var tSteps = Mathf.Ceil(aDuration * 30.0);

  // Determine the angle delta per step
  var tAngle = aAngle / tSteps;

  // Do a for loop
  for (var i = 1; i <= tSteps; i++) {

    // Do the rotate around step
    transform.RotateAround (aPoint, aAxis, tAngle);
    
    // Yield for just a moment (assume 30 fps)
    yield WaitForSeconds(0.03333);

  }

}

When called the function above does a simple animation loop that won’t lock up the rest of the Unity scripting engine:

  • The function determines some animation variables based on the information provided
  • A for loop is done:
  • Each step a small rotation is made
  • It then pauses a moment so the animation is done at 30fps

The end result of the for loop will be the animation of your object (camera or whatever) as desired, you can offer different angles and durations (which can derive from a desired ‘speed’) as well as a point and an axis, and use the same function elsewhere. It could be called like this:

function Start () {

  // Trigger the rotate around animation
  DoRotateAroundAnimation(Vector3.zero, Vector3.up, 90.0, 1.0);

}

function DoRotateAroundAnimation (...) {
  ...
}

That would make the camera rotate 90-degress about the world origin and y-axis, over a period of 1 second. I’ll leave it as an exercise for you to:

  • Learn and understand for loops, coroutines/yield andWaitForSeconds

  • Figure out how to apply the techniques to create a translation function that can be used in the earlier animation questions you asked

:slight_smile:

Thanks so much, Tom. That was just what I needed, and very simple. I’m having to come up to speed very quickly with Javascript in the few weeks of the trial period and it’s encouraging to see how much support there is on the forum.

I like to learn backwards from working code, so program-specific code is very useful for understanding how to program in Unity. After many hours spent learning how Unity works it’s very motivating and satisfying to have part of my game working.

Hi HiggyB,

Firstly, i would like to thanks you for your quick reply and allowing me to understand the camera axis better. Next, i have some doubt to clarify and i hope you don’t mind.

You are right, i am going to rotate my camera around the y-axis.

May i ask for the code below is it showing the camera rotating only in 90 degree? Actually i wanted my camera to rotate in a circle from one degree to another degree, like rotating camera from 90 degree, 180 degree, 270 degree then to 360 degree. Can i still achieve that by following the script you given as an example below?

function DoRotateAroundAnimation (aPoint, aAxis, aAngle, aDuration) { 

  // Determine the number of for loop steps needed (assume 30 fps for our loop) 
  var tSteps = Mathf.Ceil(aDuration * 30.0); 

  // Determine the angle delta per step 
  var tAngle = aAngle / tSteps; 

  // Do a for loop 
  for (var i = 1; i <= tSteps; i++) { 

    // Do the rotate around step 
    transform.RotateAround (aPoint, aAxis, tAngle); 
    
    // Yield for just a moment (assume 30 fps) 
    yield WaitForSeconds(0.03333); 

  } 

}


Code:
function Start () { 

  // Trigger the rotate around animation 
  DoRotateAroundAnimation(Vector3.zero, Vector3.up, 90.0, 1.0); 

} 

function DoRotateAroundAnimation (...) { 
  ... 
}

However i have some doubt over the above coding. Firstly, may i ask what is “Mathf.Ceil” do ? i read from scripting references it stated that it will returns the smallest integer greater to or equal to f. However, i don’t understand the statement "Mathf.Ceil(aDuration * 30.0); "

Secondly, do i need to give a value myself for aPoint, aAxis, aAngle, aDuration inside the function DoRotateAroundAnimation()? I tried but it gave me errors.

Lastly, i would like to ask why is there two similar function DoRotateAroundAnimation in the code? Is there any differences between the two? I am very very sorry if i ask alot of silly question because i am really a new beginner and are not very familar with programming terms in unity3d. i really hope you will understand and thanks so much for the help.

[/code][/quote]

Yes, the example call I made to my function (the one in the Start function) triggers a rotation of 90 degrees over a period of one second.

You’ll note that my function doesn’t allow you to specify a starting point, it only lets you rotate from wherever you are now to the specified target (using the values provided when you call the function). If you want to change the numbers then go for it and you’ll get the behavior you want. Do a series of rotations, do them all at once, whatever. :slight_smile:

The Ceil function does what it says, it takes a value and “rounds it up”. Examples

Mathf.Ceil(1.6) = 2
Mathf.Ceil(2.1) = 3
Mathf.Ceil(1.0) = 1

In my case I have a duration (some amount of time, it might be 1.0 seconds, or it might be 3.923432 seconds), but from it I need an integer number of animation steps to perform and so I compute the number of steps required:

steps required = duration * step-frame-rate
-or-
steps required = aDuration * 30.0

But then to effectively use that in a loop I want an integer value, and one that ensures completion of the rotation so I round up instead of down.

Do not modify the function, just call it like I did in my example Start function and specify the values you want. The DoRotateAroundAnimation function should work without modification on your end.

But there aren’t, there is only one DoRotateAroundAnimation function. In one case I provided just the function, in the second case I offered a more “complete” example showing how you might actually use the function.

Just a quick note: The Ceil function in Unity is actually currently buggy, so that Mathf.Ceil(1.0) actually returns 2! It returns a value one too large for integers; for non-integers it works fine though.

(The bug is reported long ago as case 32389 so I’m sure they’re on it.)

Thanks for the heads-up Rune, that bug is open but doesn’t have any specific fix information just yet.

Thanks for the clear explanation HiggyB. i will tried out the code and post up my doubt again. Thanks =))

Oh well, i have tested and modify the above coding and realise i didn’t manage to get the output that i want. Though everything work fine but i realise my camera actually went beyond my terrain. :frowning:

Hence, i tried to use the transform.Rotate method, it did work and allow my camera to rotate in a circle in the middle of the terrain. However, when i start to set boundary, my camera can only rotate halfway. I know something must be wrong with the boundary setting that i have created. However i really lost and unsure how can i really improvise on it and am i on the correct track. I hope someone may help.

if( camera.y >= 300){	
					
    	  transform.Rotate(Vector3.up * (Time.deltaTime*speed), Space.World);
    	 
    	if(  camera.x >=100  camera.z >=200 || camera.z < 400){
    		
    		transform.Rotate(Vector3.up * (Time.deltaTime*speed), Space.World);
    	  }
    	  
		}

Thanks in advance.[/code]

What is the desired action when the camera somehow exceeds the terrain boundaries? You really need to make sure that your intended functional goal is clear as your code continues to confuse. By looking at the code above when you hit the boundary the camera “sits and spins” in place and I sense that’s not what you’re after.

So, explain what you want to have happen when the camera exceeds the terrain boundaries and we’ll go from there. Do you want it to rotate “up” until it’s back over the terrain? Do you want it to “move in”? Other?

i am sorry Higgyb. Firstly i guess i really have a big confusion between transform.rotate and transform.rotateAround.

Alright maybe i start explaining what i am trying to do. Oh well i have road, streets and different type of block such as block A, B, C , D etc. on my terrain. Hence i need to use the code to manually rotate my camera around the terrain via it y-axis.

This is the requirement which i need to do…

  1. if my camera.y position is greater or equal to 300( which is at block A position) , my camera will rotate around the terrain in a circle where block A is.

However, i realize my camera will rotate out of the terrain if i am using the transform.RotateAround code.

Hence, i modify the code to transform.Rotate and realize my rotation seem rotating too fast.

I really not sure am i right in scripting this way in achieving my requirements or not.

// To move the camera forward if the below condition is met such as camera.y position is greater than 230. 

		if( camera.z < terrainData.size.z  camera.y > 230){
			
			transform.Translate(Vector3.forward * Time.deltaTime*25);
			
	//	}
		
	if(camera.z < terrainData.size.z  camera.y > 250 || camera.x > 100 ){
		
			DoRotateAnimation ( Vector3.up * (Time.deltaTime* 5), Space.World );
	        
	
		}


function DoRotateAnimation (aAxis, Duration) {
	

var tSpeed = Time.deltaTime * speed;

//======= I not very sure is the below for loop will allow my camera to keep moving in a circle.======

// Do a for loop

for ( var i = 0 ; i<= 100 ; i++) { // ==> is this for loop referring that my camera will keep rotating in a circle? 

//Do the rotate around step
transform.Rotate ( aAxis , Duration);

// Yield for just a moment (assume 30 fps)

yield WaitForSeconds(0.03333);
    }
}

Thanks in advance. Really sorry for the confusion and trouble.

You still have not explained what you want, in words (not code!), to happen when the camera’s motion takes it “outside” the terrain’s x-z boundaries. Use words here and stop typing/thinking about code.

The camera starts circling block X, that animation makes it move into an x-z position that’s no longer over the terrain, what do you want to have happen with the camera?