Animation101

Whats the trick to this?
When animating a camera betwwen multiple points, sometimes, infact, everytime, I find my camera way off in some other place during the sequence, in between keyframes, like its on rubber bands or something. What im after is a solid A to B to C setup. I tried clamp setting in the animation properties but thats not the one…
Thank you…
AC

In the case of cameras, I would just Lerp between the positions in a coroutine. But that’s just me.

Hey Star Manta. So you would do so via scripting? Mmmm, Is that a more efficient way to go I wonder.
If you have the time, Maybe you could help me a little?
1 What is lerping?
So far I undersand(I may be wrong) that lerping is kinda like an acceleration graph, where things change smoothly over time, rather than adruptly. Could anyone on this forum show me a real basic script with a lerp in it? That would be cool.

2.What is euler?Another word I’ve seen around, to do with angles…

Some times its easy to forget how much one has learned already, or its easy to take for granted all the work already achieved…
Thanks StarManta
AC

Lerp is simply shorthand for Linear Interpolation.
See Mathf.Lerp for an example.

Euler is, or more accurately was, an 18th century mathematician. Though I imagine you’re more interested in what an euler angle is :twisted:.
Euler angles are simply the “normal” way of describing a rotation, i.e. in degrees around each axis. E.g. the euler angle (20, 0, 50) is a rotation of 20 degrees around the x-axis and 50 degrees around the z-axis.

Cheers Talzor, I got all that
Little snippets like that add up…
Implementing them will take time though
Thanks
AC

Here you go. This lerps the camera’s positon and rotation between different waypoints.

MoveCamera.cs

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Camera))]
public class MoveCamera : MonoBehaviour {

	public CameraWaypoint[] waypoints;
	private int currentWaypoint = 0; //What waypoint are going toward
	private float timeAtLastWaypoint; //When did we reach the last waypoint
	
	void Awake() {
		if (waypoints.Length > 0) { //IF there are any waypoints
			//Teloport the caera to the first position
			camera.transform.position = waypoints[currentWaypoint].transform.position;
			camera.transform.rotation = waypoints[currentWaypoint].transform.rotation;
			
			currentWaypoint++;
			timeAtLastWaypoint = Time.time;
		}
	}
	
	// Update is called once per frame
	void Update () {
		if (waypoints.Length > currentWaypoint) { //IF we haven't reached the last waypoint yet
			//Compute the lerpTime, accouting for division by zero
			float lerpTime = (Time.time - timeAtLastWaypoint) / waypoints[currentWaypoint].time;
			lerpTime = Mathf.Clamp01(lerpTime); //Clamp lerpTime between 0 and 1;
			
			Debug.Log(lerpTime);
			
			Transform from = waypoints[currentWaypoint-1].transform;
			Transform to = waypoints[currentWaypoint].transform;
			
			camera.transform.position = Vector3.Lerp(from.position, to.position, lerpTime);
			camera.transform.rotation = Quaternion.Lerp(from.rotation, to.rotation, lerpTime);
			
			if (lerpTime >= 1) { //IF we have reached the waypoint
				currentWaypoint++; //THEN continue to the next
				timeAtLastWaypoint = Time.time;
			}
		}
		else //ELSE there isn't any more waypoints
			enabled = false; //No reason to waste more CPU on this script
	}
}

CameraWaypoint.cs (mainly used to draw a preview of the camera at the waypoint to ease setup. I pilfered your code Nicholas, I hope you don’t mind (or don’t read this post :smile:))

using UnityEngine;
using System.Collections;

public class CameraWaypoint : MonoBehaviour {
	public float time = 5.0f; //The time it takes the camera to go from the last wapoint to this one
	
	void OnDrawGizmosSelected () {
		//Find camera
		Camera camera = Camera.main;
		
		//Save position and rotation
		Vector3 oldPosition = camera.transform.position;
		Quaternion oldRotation = camera.transform.rotation;
		
		//Move to waypoint amd set rotation
		camera.transform.position = transform.position;
		camera.transform.rotation = transform.rotation;
		
		//Draw the preview
		float h = (float)Screen.width / 16f * 9f / (float)Screen.height * .3f;
		camera.rect = new Rect(.69f, 1f - h * 1.05f, .3f, h);
		camera.Render ();
		camera.rect = new Rect (0,0,1,1);
		
		//Restore position
		camera.transform.position = oldPosition;
		camera.transform.rotation = oldRotation;		
	}
}

23193–829–$lerp_826.zip (175 KB)

Hey Talzor, Thanks!
That is a cool little package, its exactly the smooth kinda stuff I was after…
I had to remove a line to get it to work though. 4 lines of code in from the end,itsays

camera.Render ();

In the Zip file, that line says

camera.Render (Main);

I just deleted the whole line and away it went…so what actually happened there?
Just curious
Thanks
AC

Are you sure, when I download the zip file it says camera.Render ();

But in anyway case, this is a Unity 2.0 function. Sorry about that. :sweat_smile: It (and in fact most of the waypoint script) prints a small preview of the camera inside the scene view. Just ignore this code.

There is an alternate, not-really-standard technique for using Lerp that I like to use - it’s a matter of style and taste, and whether it would suit your game is entirely your call.

Basically, instead of:

camera.transform.position = Vector3.Lerp(from.position, to.position, lerpTime);

You would use

camera.transform.position = Vector3.Lerp(camera.transform.position, to.position, 0.1);

Where 0.1 can be changed to change the speed of the camera’s movement or set to Time.deltaTime. What this does is basically instantly snap the camera out of its old position while gradually moving it to the new one, instead of moving linearly.

Again, whether this is right for your game depends a lot on the style and pacing of the game itself. It works great for fast-paced, “twitch” games. But beware that the camera won’t get a chance to get a good look at the majority of the stuff in between the waypoints.

Hmm Starmanta, couldnt get that to work sorry.
UnityEngine.Transform' does not contain a definition for positon’
line34
Any idea?

Talzor=
Some-how -I ended up with that in my code? I dont know how
Thanks anyway :shock: :roll: :wink:

That was a typo I think. Sould be ‘position’ instead of ‘positon’.

Typo? There was no typo. I didn’t edit it just now to correct a typo. Because there was no typo to correct. None at all.

.>

hey i realize this is an old post, but it is exactly what i was looking for i just wanted to grasp it and tweak it into mine but now i am just scared of it

:sweat_smile:

basically i wanted to see how it worked and whatever i do when i hook it up to my camera and my waypoint it does start up somewhere odd for some reason i do not understand it :frowning:
if someone could possibly direct me in the right direction i would be quite happy

thanks!

Sure this was one of my turning points as far as using unity goes.

The camera Waypoint scripts go on empty gameobjects. You have 1 E.G.O. with script attatched for each waypoint.(Make one and cmd+d to duplicate)

So the camera moves between these.

The move camera script goes on your cinematic camera. On here once the script is attatched you should see a dropdown triangle-you may have to enter a numerical value to enable the drop down (Im writing this without unity open)

Make the number of slots on this script match the number of waypoints and drag and drop them from scene view into the slots (On the camera with MoveCamera script attatched)

Typically you would have this Cinematic Camera active at the start of a scene or trigger it due to some event. I use a timer in the below script.

Put Cinematic Camera depth to 1, Add another camera with depth at default -1.

note*remove the audio listener on either just to remove the error generated by having two in scene simultaneously.

With the second camera in the scene for this test, maybe put the mouselook script on it to make it interesting.

So create yet another EGO and attatch this:

var DelayTime: int=2;
var CineCam :Camera;
//this is the camera set to depth=1
//Remember to assign it
function Start(){
CineCam.active=false;
yield WaitForSeconds(DelayTime);
CineCam.active=true;
}

Is that a help? I did convert these scripts to javascript but Ive gone through a few computers since then-dont know where those scripts are right now.

Thanks again Talzor, I think I realised Unity’s huge flexiblility through this thread.

And Im writing this without unity around so i apologise if anythings errant.

AaronC :stuck_out_tongue:

Edit: Oh yes, position the waypoints wher eyou want the camera to move to and from. I line up the scen view how it should be, select a waypoint then press ctrl+shift+f at the same time.

For anyone interested:

I’m pretty sure the camera was on “Rubber Bands” because of the normal continuity requirements of camera control, that the velocity and acceleration of the camera be continuous functions, likely implemented as B-Spline interpolation. This is a good thing because it prevents people that watch from becoming seasick and seeing jerky motion.

Just an FYI. Not the best resource but: