• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Cameras

Cameras

Introduction:

What are cameras?

Cameras are objects that can change the perspective and view (literally) of a player. They are one of the more flexible objects in Warcraft III, allowing you to modify several of its properties, even via triggers.

This tutorial will tell you all about cameras, how to use them, and advanced methods to utilize them to the fullest.

Camera Creation:

There are a few ways to create cameras. The first method is to create them as an actual modifiable object in-game. The second method is to create them and modify their values in the trigger editor.

First, let us begin with showing you the camera palette. To do this, move your mouse to the upper toolbar and select "Layer", and choose the option "Cameras". If you already have a palette open, you can just select the selection bar and choose "Camera Palette". Else, you can just press the standard hot-key, "M".
attachment.php

attachment.php


Let's take note of the three buttons listed in the palette.
  • Create Camera - This creates a camera object with the current view you have in your editor. For example, if you are looking at the map zoomed out, it will apply the camera settings to zoom out to your current position.
  • View Selected Camera - Once you have camera objects created, this will allow you to view the camera you have selected in the palette. This is useful to cycle through cameras to check if they are all on their proper positions.
  • Set Camera to Current View - This is a great feature. If you don't feel like finding out all the values of the camera manually, you can move around your current view, and then set the camera object to that view. You can mess around with your camera angle in the World Editor with "Mousewheel Scroll-Up/Scroll-Down" to zoom in or zoom out, "Right-Click, Hold, and Drag" to change your camera's position, "CTRL+Right-Click,Hold, and Drag" to change your camera's angle of viewing and angle of facing, and "CTRL+Shift+C" to reset to the game's default camera.

Okay, by now you've probably created a camera object. It should show up as Camera 001. This is the naming convention blizzard has created for cameras:
- Camera ###
The # symbolizes the camera number it is. The second camera created would be Camera 002, third Camera 003, and so forth. Anyway, this is just default naming, you can name it whatever you want. How? Right-click the camera in the palette, and select "Rename Camera".
attachment.php


Whoa, lots of data now. Time for the explanation of the values:
  • Target X - This is the X-coordinate of the camera's target point. Maps are created by several thousands of coordinates, similar to a standard graph. The origin is 0, and it spreads out across the map into tons of coordinates of the quadrants. The "x" value denotes the horizontal location of the camera. These are changed simply by moving the camera around. (changing its position)
  • Target Y - This is the Y-coordinate. In graphs, you have ordered pairs (x,y). This is the y-coordinate, basically the vertical location of the coordinate. Together with x-y coordinates, you can have a point on the map. These are changed simply by moving the camera around. (changing its position)
  • Z-Offset - The height the camera is from the ground. The entire camera is moved upward, and thus has an increased "Z" value. Z-coordinates are basically the height of objects, how high something is from a standard ground-position of 0.
    attachment.php
  • Rotation - This rotates the object. The values to input should be in the range from 1-360 degrees. 90 degrees is facing north, 180 degrees faces west, 270 degrees faces south, and 360/0 degrees faces east.
    attachment.php
  • Angle of Attack - This modifies the angle of viewing. This does not modify the angle from left to right like rotation, but rather from up to down. The range of values is 1-360. 360/0 degrees is directly horizontal, and it parallel to flat ground. As you increase it from 0, it will begin to sink underground and keep changing its angle. At 90 degrees, it will be underground and looking directly upward. At 180 degrees, you'll have an upside down camera that is parallel to flat ground. At 270 it will face directly down at the ground. 304 degrees is the standard game camera AoA. Approximately 345 degrees or so is usually used for RPG-like cameras.
    attachment.php
  • Distance - The distance the camera is from the target point. This has a standard value of 1650. You can get very close though, and pretty far by modifying this value.
    attachment.php
  • Roll - Roll is just like doing a barrel roll in a plane. Or a dog rolling over. The camera rolls over according to the input angle, and can even go upside down. Rolling can create amazing camera effects if used well.
    attachment.php
  • Field of View - This just basically controls the amount of area you see in your camera. Increasing it is kind of like a zoom out. It doesn't really affect the camera itself, but it makes kind of a zoom out effect so more things are on screen.
  • Far Z - This modifies the range in which far objects can be seen. So say there is a tree 10,000 coordinates away. You can set this to 10,000 to be able to see that tree. The maximum is actually 10,000. Even if you set it higher in triggers, it will most likely have the same effect as 10,000. Be careful when doing this though, it may enhance terrain screenshots, but in actual games, you will just be sending a death note to the players. This is probably one of the most impacting visual effects created. If you set it too high, and there are too many objects in view, it can reduce the FPS (frames per second, type /fps in-game) by 20's or possibly more. It depends on the Angle of Attack ultimately, but if there are too many objects seen, then it will generally cause a large amount of lag.
  • Preview Values in Main Window - Basically allows you to actually see what you are altering in the editor while you have the options open. This is very useful for making minor tweaks, without having to rename -> change -> exit -> rename -> change etc. over and over.

Well, now you the big majority of cameras. But there are still a lot of things to learn! This is the method of creating cameras using the camera palette, which is one of the more easier methods of creating cameras. However, there is another way to create cameras completely using triggers.

Note: This area mostly involves JASS at the moment, skip down below if you are solely a GUI user. (Unless you want to look at it anyway)

JASS Camera Creation:
First off:

How do you make cameras? There is no camera variable type.

Nope, there is no camera variable type, but there is a camerasetup variable.
JASS:
type camerasetup        extends     handle

Cameras made with the palette are camera-setups. This is how blizzard creates cameras:
JASS:
//***************************************************************************
//*
//*  Cameras
//*
//***************************************************************************

function CreateCameras takes nothing returns nothing

    set gg_cam_Camera_001 = CreateCameraSetup()
    call CameraSetupSetField(gg_cam_Camera_001 , CAMERA_FIELD_ZOFFSET , 0.0 , 0.0)
    call CameraSetupSetField(gg_cam_Camera_001 , CAMERA_FIELD_ROTATION , 90.0 , 0.0)
    call CameraSetupSetField(gg_cam_Camera_001 , CAMERA_FIELD_ANGLE_OF_ATTACK , 345.0 , 0.0)
    call CameraSetupSetField(gg_cam_Camera_001 , CAMERA_FIELD_TARGET_DISTANCE , 1650.0 , 0.0)
    call CameraSetupSetField(gg_cam_Camera_001 , CAMERA_FIELD_ROLL , 0.0 , 0.0)
    call CameraSetupSetField(gg_cam_Camera_001 , CAMERA_FIELD_FIELD_OF_VIEW , 120.0 , 0.0)
    call CameraSetupSetField(gg_cam_Camera_001 , CAMERA_FIELD_FARZ , 5000.0 , 0.0)
    call CameraSetupSetDestPosition(gg_cam_Camera_001 , 2024.4 , 631.9 , 0.0)

endfunction

Generated globals: http://www.hiveworkshop.com/forums/...ls-278/mini-tutorial-generated-globals-43391/

Basically, this creates the cameras from the palette. Yes, this is just as efficient as creating it in JASS, but why create camerasetups in JASS then? Well, you can create a variety of more control this way. Generally, as a JASSer you might want to do more complex things with cameras. And who wants to refer to their camera as gg_cam_Camera_001 all the time?

This just basically will teach you how to make them this way. Okay, so the first thing is creating a camera-setup:
JASS:
native CreateCameraSetup                    takes nothing returns camerasetup
JASS:
globals
    camerasetup cam1
endglobals
function cam1 takes nothing returns nothing
    set cam1 = CreateCameraSetup()
//This creates the camera object.
endfunction

Great. However, this is not ready to be applied yet. At the moment, all of its values are null. Most likely 0 for every field.
JASS:
native CameraSetupSetField                  takes camerasetup whichSetup, camerafield whichField, real value, real duration returns nothing

This will set the desired field to the real - "value" over the duration specified. The fields are found by Blizzard using:
JASS:
constant native ConvertCameraField          takes integer i returns camerafield

Now, luckily Blizzard has created constant integers to represent the obtainable fields. This makes the job a ton easier for us:
JASS:
type camerafield        extends     handle    
    constant camerafield CAMERA_FIELD_TARGET_DISTANCE       = ConvertCameraField(0)
    constant camerafield CAMERA_FIELD_FARZ                  = ConvertCameraField(1)
    constant camerafield CAMERA_FIELD_ANGLE_OF_ATTACK       = ConvertCameraField(2)
    constant camerafield CAMERA_FIELD_FIELD_OF_VIEW         = ConvertCameraField(3)
    constant camerafield CAMERA_FIELD_ROLL                  = ConvertCameraField(4)
    constant camerafield CAMERA_FIELD_ROTATION              = ConvertCameraField(5)
    constant camerafield CAMERA_FIELD_ZOFFSET               = ConvertCameraField(6)

Now, how do we use these? Well, the example I showed above should sum it up pretty well, but I'll explain a bit more:
JASS:
globals
    camerasetup cam1
//Yeah, I could create it initially. Just want to clearly show the process.
endglobals
function cam1 takes nothing returns nothing
    set cam1 = CreateCameraSetup()
//This creates the camera object.
    call CameraSetupSetField(cam1,CAMERA_FIELD_TARGET_DISTANCE,1300,3)
//This will set the field - distance - of "cam1" to 1,300 over a time period of 3 seconds.
endfunction

To instantly snap for that field, you can set the duration to 0 and it will instantly set that field. The only real time where modifying it with a duration makes a difference is after you've applied the camera object. You can modify it to any value you'd like.

Yeah, this may seem tedious, but it is useful for naming purposes and basically will allow quick changes if you are sure what you're doing. Okay, this basically covers it for JASS, and although it is slightly less efficient and somewhat illogical (might as well use the generated cameras), it can be useful for certain camera systems in GUI.

GUI Camera Creation:
Ah, I see I can make a camera object variable in GUI!

Great. This will basically do the same as CreateCameraSetup() in JASS. Now, to be able to modify fields of a camera in GUI, you have to apply the camera first. To do this, I've created a camera object variable named "CameraCC".
  • Camera - Apply CameraCC for Player 1 (Red) over 0.00 seconds
This will allow you to modify the "current" camera's values since there is no way to actually set a specific camera's values in GUI.
  • Camera - Set Player 1 (Red)'s camera Distance to target to 1300.00 over 3.00 seconds
This is the function, "Camera - Set Camera Field (Timed)". It is essentially doing the same as the JASS function, except this one calls a function in blizzard.j which already has a GetLocalPlayer() == Player(#) so you can specify which player you want to modify the camera for. This, obviously is easily doable in JASS, but since you can't detect the local player without custom script, Blizz decided to make some premade functions to help you all out. Just be careful of disconnections if you use GetLocalPlayer(). Read this guide. You will use GetLocalPlayer() a lot for cameras if you are a JASSer. In GUI, they do it for you.

Anywho, this will allow you to modify any of the fields listed above to the appropriate value you specify. I don't think much explanation is needed for that considering there are some thick explanations (as well as neat animations) if you scroll up.

Camera Functions:
attachment.php


attachment.php

  • Apply Camera Object (Timed) - What this does is what it says. It will apply a camera object that you specify over a duration that you also specify. If you "Apply without panning", it will basically apply all of the object fields except it won't change the camera's position. Panning the camera moves the object to a point. The rest of the applications, ex: angle of attack, distance, are applied regardless of whether it pans or not. The player you specify is just whichever player you want the camera to move for. This function does NOT disconnect. This will apply all values, not just position.
    attachment.php

    attachment.php
  • Pan Camera (Timed) - This will basically move the camera to a position specified over a duration. This does not alter anything such as distance or angle of attack, it will simply move the camera.
    attachment.php
  • Pan Camera With Interpolated Height (Timed) - This function is pretty good if you are in an annoyingly hilly map. This will basically make it so that it will climb over terrain so the height is somewhat constant from the ground. This will add 300 to the height of the ground beneath it, not the actual Z reference point of 0. (So if you pan something, it won't stay at a constant height, it will change based on the terrain)
  • Pan Camera as Necessary - This is a Goldilocks Function. This function will determine whether the camera object is too close or too far. If it is too close, it will not do anything. (It won't move the camera at all) If it is too far, the camera will instantly snap to the location in 0 seconds. If it is just right, it will do the duration. =) Except that it desyncs! It uses "GetCameraTargetPositionLoc()"
    JASS:
    constant native GetCameraTargetPositionLoc  takes nothing returns location

    Inside its GetLocalPlayer() block. This causes disconnections. The proper function is:
    http://www.hiveworkshop.com/forums/...ls-279/fixing-smartcamerapanbj-desync-243334/

    That is mostly going to be used by JASS users, but even then it makes more sense to just determine the distance and use that if you are going to JASS. The original function is called SmartCameraPanBJ. More like StupidCameraPanBJ.
  • Set Camera Field (Timed) - Discussed above. Sets the specific field to a value specified over a duration. Instant if you input 0 as the duration.
  • Rotate Camera Around Point - A fun function. This basically simulates something that would require a timer and some extra functions. Completely doable without this function, but Blizz added a native for it. Hooray! This just basically adjusts the rotation constantly to make one full revolution in the duration specified. This will rotate around a point.
  • Lock Camera Target to Unit - This will make it so that the camera is locked to a specific unit. This is great for RPG's and one-character maps, since you can easily just attach the camera to the unit. A neat feature is that it also lets you offset the camera off the unit. The values are (x-coordinates,y-coordinates) to offset. The rotation is just like the rotation mentioned above.
  • Lock Camera Orientation to Unit - This is a pretty neat function. It locks the camera to a specified unit. But there is a catch, it locks its current camera source in place, but then the target follows the unit. It is cool because it doesn't just rotate, it also does some cool rolling effects based on where the unit is. This is mostly useful in cinematics, since it might be a bit annoying to control in-game.
  • Play Cinematic Camera - Applies a camera model file. There are special camera models contained in the MPQ, I'll update with more info later.
  • Stop Camera - Aborts the camera movement. Things like "Apply Camera Object (Timed)" or panning will be stopped.
  • Reset Game Camera - A useful camera that will reset the values of the camera to that of the game camera. (Ex: dist = 1650, AoA = 304)
  • Change Camera Smoothing Factor - Yeah, you might be thinking "Hey, I can make my cameras more smooth." Well, that isn't really what this does, sadly. It makes scrolling more smooth, via scrolling with the arrow keys or using the mouse.
  • Reset Camera Smoothing Factor - Resets the camera smoothing to its original value, which is 0. You can just use the function above and input 0, it is more direct.
  • Sway Camera Source - I wish I had the time to animate this. It is a very fun function. It will cause slight "sways" in the function, moving it back and forth. The magnitude determines how devastating/extreme the sway is. A low magnitude will be hardly noticeable. Velocity determines how fast it will sway. Set these both high and you'll be in for a ride. It is useful for cinematics when you want some big event to happen. This will sway the source, or the bird's eye point.
  • Sway Camera Target - The same as above, but instead it sways the target. It will have a different sort of effect, but still just as awesome.
  • Shake Camera - This will basically cause a sort of earthquake effect, so that it shakes a lot. This was actually Blizzard doing some nice calculations. It is merely an extension to swaying. Basically, it will multiply the input magnitude by 2, and for the velocity, it will multiply the magnitude * 10^richter. If the magnitude input is greater than 5, the richter will be 5. If it is 2-5, then it will set it to that value, and if it is less than 2, it will be set to 2. So say you input a magnitude of 10, it will be 10*10^5 for velocity, or 1,000,000. This makes very high frequencies of change, resembling a "rumble" effect. Great function for "powerful" abilities and battle cinematics.
  • Stop Swaying/Shaking Camera - Just sets the value of source and target noise (swaying/shaking) to 0. Just a quick function to stop all the swaying and shaking.
  • Extend/Shrink Camera Bounds - There are points on the map where the camera can't extend pass. It'll simply stop at the edge. These are the camera bounds. This function is useful to bypass that; however, you can change it at the start of the map as well. Just go to - Scenario -> Map Size and Camera Bounds.
    attachment.php
  • Set Camera Bounds - Create a region using the region palette, and this will do the dirty work of figuring out the amount you want to change your camera bounds by.
  • Set Spacebar Point - This will allow you to press the spacebar to snap your camera to a specific point.

    Can I use this to detect a player pressing spacebar?

    Yes, but it is hardly efficient. First of all, people can move to the spacebar point occasionally with their camera. Second, it can sometimes bug out and is a little slow with detecting the amount of presses. Third, it has less of a chance of working as you get the timer check below 0.03. However, with some proper functions and a lengthy system it could work. I made a very small system with a few arrays (and a recycling method so it wouldn't get over 8190) that worked with it to quickly set the camera position back after pressing spacebar, but I never released it due to it being pretty inefficient. It was just meant for testing.

JASS Extra Functions:
JASS:
native AdjustCameraField            takes camerafield whichField, real offset, real duration returns nothing
Pretty much the same thing as SetCameraField(). Except you can use it to add or subtract as far as I know.
JASS:
native CameraSetupApplyForceDuration        takes camerasetup whichSetup, boolean doPan, real forceDuration returns nothing
native CameraSetupApplyForceDurationWithZ   takes camerasetup whichSetup, real zDestOffset, real forceDuration returns nothing

This will allow you to apply a camera with duration and Z. GUI has these, but they are called by other functions.
JASS:
native CameraSetupGetDestPositionLoc        takes camerasetup whichSetup returns location
native CameraSetupGetDestPositionX          takes camerasetup whichSetup returns real
native CameraSetupGetDestPositionY          takes camerasetup whichSetup returns real
native CameraSetupGetField                  takes camerasetup whichSetup, camerafield whichField returns real

These are useful for retrieving fields and positions. Doable in GUI, but useful to mention since it is great for creating camera systems.
JASS:
constant native GetCameraEyePositionLoc     takes nothing returns location
constant native GetCameraEyePositionX       takes nothing returns real
constant native GetCameraEyePositionY       takes nothing returns real
constant native GetCameraEyePositionZ       takes nothing returns real
Instead of the target X/Y, this will return the X/Y/Z of the eye position. For GUI, you'd probably use the Loc. For JASS, you'd use the X, Y, and Z. The eye position is basically the camera viewer, instead of the actual target point the camera is directed toward.
JASS:
constant native GetCameraTargetPositionLoc  takes nothing returns location
constant native GetCameraTargetPositionX    takes nothing returns real
constant native GetCameraTargetPositionY    takes nothing returns real
constant native GetCameraTargetPositionZ    takes nothing returns real
Same as above, except it gets the data of the target point the camera is oriented toward.
JASS:
native PanCameraTo                  takes real x, real y returns nothing 
native PanCameraToWithZ             takes real x, real y, real zOffsetDest returns nothing                                                                          
native PanCameraToTimed             takes real x, real y, real duration returns nothing
native PanCameraToTimedWithZ        takes real x, real y, real zOffsetDest, real duration returns nothing
Panning functions, easily allow you to pan to points without modifying camera fields. Use the GetLocalPlayer() block to apply them for only a single player.
JASS:
native SetCameraPosition            takes real x, real y returns nothing
Basically like PanCameraTo. It just doesn't pan as far as I know.
JASS:
native SetCameraQuickPosition       takes real x, real y returns nothing
Modifies the point where a camera moves when a player presses the spacebar.
JASS:
native CameraSetSourceNoise             takes real mag, real velocity returns nothing
Swaying and earthquakes.

There are more, but many of them have GUI counterparts or are self-explanatory.

Cinematic Systems:

The most famous:
http://www.wc3c.net/showthread.php?t=79554
EDIT: This is a more recent version:
http://www.wc3c.net/showthread.php?t=110341

Why are these used? They provide several functions that do a lot of complicating/dirty work. Some are not necessarily needed, but they are useful to have. As a longer-time JASSer, you might not need too many of these, but some of the camera functions are very useful and complex. The system makes it kind of so that you only need to use the functions in the system for your cinematic. If you change cameras, you'll probably realize that it is annoying how changing your camera will cause it to abruptly change speeds and have a crappy transition. The cameras are not good for easing, so this system helps a lot for that.

Conclusion:

Cameras are complex, but easy once you get used to them. Play around with them and you'll love them. I might extend this tutorial a bit more if people want to know about smooth camera applications and easing, but this is all for now. Good luck with your future camera-creations!

Camera Testing:
This is a quick test map to test camera fields. Type /help to get a list of in-game commands. This is just if the camera fields are confusing you.

~Purge
 

Attachments

  • mapProp.jpg
    mapProp.jpg
    73 KB · Views: 9,769
  • CameraTests.w3x
    22 KB · Views: 1,050
  • actconfig.jpg
    actconfig.jpg
    74.2 KB · Views: 9,783
  • Applycobj.jpg
    Applycobj.jpg
    39.2 KB · Views: 9,770
  • cpalette.jpg
    cpalette.jpg
    24.7 KB · Views: 9,929
  • pctimed.jpg
    pctimed.jpg
    43.8 KB · Views: 9,737
  • camerarename.jpg
    camerarename.jpg
    112.9 KB · Views: 10,100
  • layer.jpg
    layer.jpg
    42.7 KB · Views: 10,006
  • AngleofAttack.gif
    AngleofAttack.gif
    12.6 KB · Views: 12,239
  • Applycam.gif
    Applycam.gif
    7 KB · Views: 9,777
  • Distance.gif
    Distance.gif
    15.6 KB · Views: 12,192
  • Pancamera.gif
    Pancamera.gif
    8.4 KB · Views: 9,970
  • Roll.gif
    Roll.gif
    8.7 KB · Views: 11,918
  • Rotate.gif
    Rotate.gif
    4.3 KB · Views: 11,966
  • ZOffset.gif
    ZOffset.gif
    15.6 KB · Views: 11,811
Last edited:
Level 14
Joined
Nov 18, 2007
Messages
1,084
The jass camera you mention, it was for vjass.. isn't it?
It should be regular Jass. (The functions described are natives)

I only briefly looked at this and I'm amazed. (Neat animations!)
If you haven't, you may want to talk a little bit about Preview Camera Motion. (I think you can only do this if you applied a camera object with the GUI.)
 
Yep, it is doable in JASS and vJASS. Like two of the examples use vJASS's global blocks for readability but it is completely doable in both.

I only briefly looked at this and I'm amazed. (Neat animations!)
If you haven't, you may want to talk a little bit about Preview Camera Motion. (I think you can only do this if you applied a camera object with the GUI.)

Thanks. =D And I will definitely add the preview camera motion later on, I completely forgot about it! =P Thanks for the feedback guys.
 
Level 8
Joined
Dec 12, 2010
Messages
280
Nothing worst than starring at the gui trigger editor at all these different camera options and not having any definitions for them. Thanks for shedding some light on the subject.

And thanks for having the link in you sig, I'da never found this.
I'm too lazy to hunt for it :)
 
Level 12
Joined
Mar 13, 2012
Messages
1,121
Play Cinematic Camera - Applies a camera model file. There are special camera models contained in the MPQ, I'll update with more info later.
If you know what it does, please insert the info about it into your guide :).

edit2: if you should know, pm me if possible.
 
Last edited:
Question: how to get point from current camera target for a player

There are functions for it, but the data is all local. So when you use GetCameraTargetPositionX() and GetCameraTargetPositionY(), they have different values for different players. In order to make the data global, you have to broadcast it using synchronization methods (only available in JASS).

You can check out sample code here in case you're interested:
http://www.hiveworkshop.com/forums/lab-715/observermode-playercameradata-244987/

Even the system itself is usable (ex: PlayerCameraData.x[0] will give the x-coordinate of Player 1 (Red)), but note that you are limited by sync times so it will pretty much always be a couple hundred milliseconds behind the player's true camera coordinates.
 

deepstrasz

Map Reviewer
Level 69
Joined
Jun 4, 2009
Messages
18,801
How can you make Preview Camera Motion work? It just discordantly pans the cameras. Would actually be helpful if it worked since testing the map each time kills a lot of time. Would be great to start the motion from the selected camera onward.
 
Top