Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Camera path technique

Discussion in 'Made With Unity' started by Eric5h5, Jun 26, 2007.

  1. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Here's the Blender camera path project that I mentioned here. In the interest of focus (and size), I stripped out everything except the basics. I got the basic idea when I came across this page on making control-point-less bezier curve motion in Flash. Or rather, the control points are generated from the points already existing in the path. This way you can get nice curves straight from mesh data.

    To use it, in Blender first make a straight line using the curve tool (if that isn't a contradiction ;) ). Add -> Curve -> Bezier Curve, then press V to straighten the points, and then press Tab to leave edit mode. In the Link Materials pane, call it "line". You only have to make one of these and you can use it with any number of 3D paths.

    So, make a 3D path (Add -> Curve -> Path). In the Curve Surface pane, click in the BevOb: field and type "line". This uses the bezier curve we made first to define the shape. In this case we just want a simple line so we can tilt the path and get surface normals from it later. Move points in the path by clicking on them and pressing G (Grab) then clicking again to place. Extend the path by selecting a point on the end and pressing E and clicking to place. Press T to tilt selected points left or right. Continue as long as you want, but if you're making a looping path, do not try to close the loop...just leave a gap between the first and last points. In the DefResolU: field, you can go very low; probably 1 is fine, or 2 if you want extra precision. Outside of edit mode, press option-C to convert the path to a mesh, and save it (be sure to make a copy of the pre-converted path, in case you want to go back and easily edit it later).

    When you bring it into Unity, make sure that "Automatically calculate normals" is set to 180. Otherwise, if you did some funky things with the path (like 360 degree spins), Unity makes some extra points, which obviously messes up the end of the path.

    When you place the path somewhere in your scene, you can position, rotate, and scale it however you want, and these transforms are accounted for properly. You can leave the mesh renderer on to visually see where the path goes exactly, and then disable the renderer when you have it positioned where you want it.

    To make a camera go along the path, put the PathFollow script on it (I put it in the Camera-Control menu, but you can also use it for other objects). Drag the path from Blender onto the Path slot. Use Move Speed to control the overall speed of the camera movement, though relative speeds within the path are controlled by how far apart the points are. So if you want a completely even speed, make all the points pretty much the same distance apart from each other.

    Direction is either forward or backward, though backward just traverses the points in reverse order; it doesn't make the camera face backward or anything. The little arrows you see in Blender, conveniently enough, tell you what direction the path goes in.

    Movement Only makes the camera follow the points through space, but leaves the rotation alone so the camera stays facing the direction it's in when it starts. Typically you'd use this with the Motion Record script (see below) to add manual rotation to all the points.

    Loop...I'm sure you can figure that one out. ;)

    Startpoint starts the camera movement at a given point. So if you have a path made up of 120 points, using 60 for Startpoint makes the camera start halfway along the path.

    Endpoint ends the camera movement at a given point, counting backwards from the last point. It only works in non-looping mode. If you're not looping, this should be set to at least 3, or else movement data from the first few points "bleeds" into the last few. This is how loop mode works, but you typically don't want that for non-looping.

    Ease in and Ease out are for starting and ending smoothly. Intended for non-looping mode.

    "Object to track" is a transform, which if used makes the camera always point at that object as it moves along the path. If this is none, then it has no effect.

    Rotation Data is a string generated by Motion Record. If you leave it empty, it does nothing.

    Zoom Data is also a string generated by Motion Record. If left empty, it does nothing. Otherwise it behaves like Rotation Data, but changes the zoom (field of view).

    The rest of the variables you can ignore, but they need to be public for Motion Record to access...is there a way to do hidden public variables? (Short of static, which won't work in this case since you might want to use multiple objects on paths at once).

    The use of Motion Record is detailed in the next post.

    --Eric
     

    Attached Files:

  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    OK, docs for Motion Record:

    If you want to add extra rotation to camera path movement, either in combination with Movement Only or just to add some additional rotation to that which you get from the path itself, put the Motion Record script on the same camera that's using the Path Follow script. This allows you to steer the view with the mouse/keyboard as the camera goes along, and edit each point afterward if you want.

    (My Storm City demo uses Movement Only with manual rotation for the helicopter--this allows the helicopter to move along the path, with the manual rotation making it behave more like a helicopter. It also uses regular mode--not Movement Only--with extra manual rotation for the chase viewpoint, in order to get a sort of "hand-held" movement which you can't get from the path alone. The car demo in that same topic uses regular mode without any extra rotation, with the Object To Track set to the car.)

    You also need the three Motion Record GUI objects, which exist as a prefab. Probably easiest to make a package of this and import it into whatever project you want.

    Sensitivity is how sensitive the mouse controls are. Key Sensitivity is how sensitive the keyboard controls are for motion. Invert Y Axis does just that, and File Name is the name of a text file that will be generated when you're done. This gets put in the base folder of the project, outside of Assets, because it's not used directly.

    When you run the scene, you'll see "Recording" in the lower right. This means you can move the view around as you go along the path, and the rotation and/or zoom at each point is recorded. If it says Rotation/Zoom, then you are recording both. If it says Rotation, then you're using zoom data that you recorded before and put on the camera, so you're only recording rotation, but you can edit the zoom. If it says Zoom, then you've got some rotation data, so you're only recording zoom, but you can edit the rotation. If you have both rotation and zoom data, then you can only edit them. If you remove the rotation and/or zoom data from the camera, then you can record them again.

    The % in the upper left is what point you're on at the moment, out of the total number of points in the path.

    Press H to get a reminder of keyboard commands. (Or the help key, theoretically, though it doesn't seem to work even though Unity doesn't object to the name.) These are:

    WSAD to rotate the view on the X and Y axes instead of/in addition to the mouse. ZX or < > (really . and ,) rotates on the forward axis. [ (left bracket) zooms out, ] (right bracket) zooms in. Hold down shift to make the movement go 10 times slower for fine control. Press space to reset all axes to 0 and the zoom back to the field of view you started out with (usually 60, unless you've changed it).

    Press 0 (zero) to set the overall speed to none. That way you can move the view around as much as you want at that point before continuing. Press 1 to go back to 100% speed, or 2 to go 10X faster. Press + and - (really = and -) or left and right arrows to go a little bit faster or slower. It's sometimes useful to go in slow-motion...I did most of the helicopter movement in one "take" that way, with a little editing afterward. On the other hand, the viewpoint movement was done in real-time to get a sort of hand-held feel.

    When you get to the end of the path, or if you press Q, then the rotation data is saved to a text file with the specified name. Open this file up and select all, then copy, then switch back to Unity and paste into the Rotation Data field on the Path Follow script. (Yep, the whole thing will fit even if you've got zillions of points.) This may seem slightly clunky, but I can't think of any other way to do this, short of just reading a data file directly, which I don't want to do because I want the data to be self-contained in the project. Any suggestions welcome.

    If you run the scene again with data in the Rotation Data field, you can then edit each point. "Recording" no longer shows, to be replaced by "Edit" if you're in edit mode. Controls as above, except you normally can't rotate the view, but now you can press E to enter edit mode. This allows you to change the rotation of whatever point you're at (see upper left display). E again goes back to movement mode (or you can use 1 or 2 to jump to that speed and exit edit mode at the same time). Press up or down arrows to jump to the next or previous point (and enter edit mode if it's not active already). Again, pressing Q or reaching the end of the path will save the edited data, which you can then paste into the Rotation Data field, overwriting the original data. Probably a good idea to use different names for the files so you can go back to the pre-edited version if necessary.

    Keep in mind that you're just creating/editing rotations on each point in the path, so the Path Follow script is generating bezier curves on the fly. This means that playback will probably not exactly match what you did when recording. It's useful after editing some points to go backward before those points and then enter play mode to see exactly what you did. If you want finer control, make the path resolution higher in Blender (and adjust Move Speed to compensate).

    And I think that's about it, unless I forgot something.... If anyone uses this, let me know if you find any bugs/problems. Also let me know if you think of some additional functionality. Or better yet, implement it yourself and post it. ;) I can already think of an external view mode for editing the rotation of objects on the path, though it was surprisingly intuitive to do the helicopter rotation from first-person mode...also quite a bit faster than external editing would be, I think.

    --Eric
     
  3. drJones

    drJones

    Joined:
    Oct 19, 2005
    Posts:
    1,351
    i find if i click off "Extra Rotation" the camera travels alot smoother - if a bit more sluggish which i guess would make sense. with it on it seems like the camera unnaturally jerks from time to time (like its correcting itself - but if i turn the path renderer on it does seem to happen on the sharper angles from one face to the next) - though in the webplayer you posted it gives the scene a nice kind of handheld camera feel.

    cool useful project, thanks for sharing ; )
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Yep, the jerkiness/handheld feel was completely intentional. The speed with it off should be the same though, just smoother which maybe makes it seem slower. Normally I'd leave it off, or record smoother/more subtle movements, but I was playing around. ;)

    Also, this sort of camera movement really makes you appreciate the vsync option....

    --Eric
     
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I changed the project file in the first post to a new version. Changed stuff:

    In addition to startpoint, there is now an endpoint variable. This is counted backwards from the last point and is for the non-looping mode (and doesn't do anything in loop mode). Without it, non-looping was kind of broken, since it takes data from a few points ahead to compute the bezier curves, so you would get some wacky movement at the end unless you were looping. Using 3 is normally a good value for this (so it's probably a good idea to make a few more points past the "real" end on the path in Blender as well).

    There's also ease in and ease out, for starting and ending smoothly. Intended for non-looping mode...actually I'm not sure what happens with loop mode with these on; probably should look into that. ;)

    You can have an object to track now, which makes the camera always point at a given object as it moves along the path. If there is none selected, then it doesn't track anything.

    You can have zoom (field of view) data now in addition to rotation data. Use the motion record script to add zoom if you want at any point by using the [ and ] keys. This is a separate thing from rotation, so record mode is active for rotation, zoom, or both (or neither), and will indicate what you're recording.

    Again, any variables after that have no effect (they're used by the motion record script and can't be private).

    This hasn't been stress-tested yet, so if anyone uses this and finds any problems, let me know.

    --Eric
     
  6. drJones

    drJones

    Joined:
    Oct 19, 2005
    Posts:
    1,351
    sweet - that'll make "film" style moves easier (emulating a crane shot for instance). i haven't had the chance to play with it yet but i will later.

    ; )
     
  7. Samantha

    Samantha

    Joined:
    Aug 31, 2005
    Posts:
    609
    Wow Eric, this is great! I'm very excited to sit down and play with this for a while. In the meantime, this definitely seems like it should go up on Unify. Maintenance and update tracking there will be much easier too.
     
  8. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Yep...I wanted to get it into a more usable state first, which it probably is now. :) I'll bang on it some more to make sure nothing falls apart too badly and put it on Unify sometime in the near future.

    --Eric
     
  9. Predster

    Predster

    Joined:
    Sep 11, 2007
    Posts:
    145
    Hey I couldn't find this on the wiki yet. It looks really cool and I was wondering if it could be extended to be used with a branching path. For example, the camera is animated along the path to a branch point, at which time they choose a direction to proceed.
     
  10. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Oops, yeah, never quite got around to that.... It could use some updating to 2.0+ now, though. Someday. :)

    Probably somehow it could, though I'm not sure what the best way would be.

    --Eric
     
  11. Predster

    Predster

    Joined:
    Sep 11, 2007
    Posts:
    145
    Thanks! Maybe I will play around with it a bit.
     
  12. jurito

    jurito

    Joined:
    May 6, 2009
    Posts:
    2
  13. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I don't know anything about Maya, sorry.

    --Eric
     
  14. 001visualizer

    001visualizer

    Joined:
    Aug 24, 2008
    Posts:
    113
    Hi

    That script is very very helpful!!
    Thanks to the coder!
    That script should be included in the Unity3D standard package..

    But there is a limitation, which I hope can be left. > If the path is moved or and rotate around, the object follows the path where it was in the start position. It is not updating the new position of the path.

    Think about a driving car, in which you want move around a camera on a path.

    Have you an idea, how the PathFollow script can modify for this goal?

    Roman
     
  15. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Thanks, but nah, this is pretty old, and in the meantime, others have come up with more elegant ways of doing this. If you look around on the forums, or possibly the wiki, there are other path scripts that are more flexible.

    --Eric
     
  16. 001visualizer

    001visualizer

    Joined:
    Aug 24, 2008
    Posts:
    113
    Hi Eric

    Old however, but the advantage of your script is that one can construct a polygone stripe for the path and can control very precise the movement of your object.

    Therefore I realy please you to think about a little update of that script so that the spline (polygone stripe) can move and rotate and the object is always following the actual path.

    Many thanks for this
    Roman
     
  17. mgiambanco

    mgiambanco

    Joined:
    Dec 30, 2009
    Posts:
    1
    Anyone know how to create the path to follow in 3dsmax?

    I'm trying to translate the instructions - i created a line, converted it to a mesh and exported it as a fbx as i would. Followed the rest of the instructions.

    It looks like the camera repositions itself, but it does not move :(

    ?

    -Mario
     
  18. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Just creating a line isn't enough. I'd recommend using Blender--it's free, so if you only use it for just this one thing, it's still worth it.

    --Eric
     
  19. carpediem23

    carpediem23

    Joined:
    Dec 7, 2009
    Posts:
    16
    How can i make a static speed on this script? Because, if the turns is hard, speed has slowly i want static speed all times...

    ty for the script:)
     
  20. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    If you make the points in the path be consistently spaced, then the speed would be even. That said, this particular technique doesn't really lend itself to perfectly even speeds, and you'd probably be better off with something else. (Look around in the forums or on the wiki and you should be able to find something.)

    --Eric
     
  21. carpediem23

    carpediem23

    Joined:
    Dec 7, 2009
    Posts:
    16
    thank you for your help... :):)
     
  22. havingfun1987

    havingfun1987

    Joined:
    Feb 16, 2010
    Posts:
    1
    Hi, I am new to Unity 3d and i tried to implement the camera path technique. I did what you have mentioned in the post. But when I play the game it shows two errors.

    1. MissingComponentException: There is no 'MeshFilter' attached to the "path" game object, but a script is trying to access it.
    You probably need to add a MeshFilter to the game object "path". Or your script needs to check if the component is attached before using it.

    I saw this error and I added a mesh filter to my path but still it shows the error

    2. NullReferenceException: Object reference not set to an instance of an object
    Boo.Lang.Runtime.RuntimeServices.NormalizeArrayIndex (System.Array array, Int32 index)
    PathFollow.ComputePoints () (at Assets\Standard Assets\Camera Scripts\PathFollow.js:278)
    PathFollow.GetNextPoint () (at Assets\Standard Assets\Camera Scripts\PathFollow.js:248)
    PathFollow+Start$16+$.MoveNext () (at Assets\Standard Assets\Camera Scripts\PathFollow.js:229)

    This is the other one when I select the error, it points to the line 278 in the PathFollow script.

    Could you please help me with this??
     
  23. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Sounds like you didn't put the path mesh on the object.

    --Eric
     
  24. Maksimilian

    Maksimilian

    Joined:
    Mar 5, 2010
    Posts:
    7
    :D i love your script, its really great and you saved me from become desperate.
    its really great with the aim on something.
    My problem is, i want to change the camera on the end of the path to my main Character.
    But i don't get it to work, because i cant find the point in the script where the last point is located.
    My next try was a trigger so if the camera hits a trigger change the cam, but the camera dont activates my trigger. Next try was to make a cube child to the cam to activate my trigger, you know what follows: don't work. both had a collider.
    Excuse me if my question is stupid.
    Hope you can help me.
     
  25. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I think you can set the transform position and rotation from the camera to your character at the end of the Start function.

    --Eric
     
  26. Sailendu

    Sailendu

    Joined:
    Jul 23, 2009
    Posts:
    254
    Nice... I've to try it...
     
  27. Maksimilian

    Maksimilian

    Joined:
    Mar 5, 2010
    Posts:
    7
    I tried it again with a cam change but when i use my debug.log i'd noticed that it updates every frame or something like that. by the way, how can i get the position and rotation of an other object?
    sorry for the noob questions :D
     
  28. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You can get the position/rotation of other objects by using public variables. I'd recommend doing some of the tutorials so you get used to working with Unity.

    --Eric
     
  29. Axox games

    Axox games

    Joined:
    Mar 13, 2013
    Posts:
    2
    This script is very very helpfull......Thanks a lot.....But i want to more about camera rotation and zoom .....
     
  30. Axox games

    Axox games

    Joined:
    Mar 13, 2013
    Posts:
    2
    Can i record animation from this script?
     
  31. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    This is really outdated and isn't necessary anymore since Unity has a number of animation tools it didn't have back then.

    --Eric