Custom Camera Setting (First Person and Third Person)

From HIVE
Revision as of 06:16, 21 November 2010 by DevliN (talk | contribs) (1 revision: StarEdit.net Wiki)
Jump to navigation Jump to search

This is a very simple way to create a third-person camera. The distance behind the unit is easily modified. This method is intended for multiple users as well (and is modifiable to work with just one), but note: The triggers used in this tutorial WILL cause major lag if played on battle.net. If someone can find a way to do it with less lag, please update this wiki article.

Creating the Camera Object

The first thing that is needed is a camera object. Go to Layer->Cameras, and then hit "Create Camera" on the left hand side bar under the minimap. A camera object will be created that copies the view you have over your map at the moment you create it. We will change the values though, so don't worry about that.

Understand that there are two points to a camera. The cameras position, and the literal camera position. The camera position is the X,Y,Z value that the camera is located at. This is also know as the focal point. The literal camera position is where the actual camera is located, and where the player will be looking from. This is usually far away from the focal point, but is pointed directly at the focal point. In a standard game, the focal point is on the ground, and the camera is in the air, pointed down. We wish to move the camera close to the ground as well, but slightly elevated, with the focal point on the unit that needs the third person camera. This gives the effect that you are looking over the unit's shoulder, aka, a third person camera.

Setting up the Camera Object

Underneath the "Create Camera" Button, you will see a white box with the value "Camera 001" in it, right click it and hit "Modify Properties". Set the values to the following (Name - Sub - Value - (Description)):

  • Angle - Field Of View - 27.996 - (How wide the view is. This will be a 28 degrees view from the left of the screen to the right)
  • Angle - Roll - 0.0 - (How far to roll the camera from the left to right. Think barrel rolls.)
  • Depth of Field - Amount - 0.0 - (Unknown, feel free to update the wiki article if you know any information about this value)
  • Depth of Field - Depth - 8.0 - (How far the camera sees)
  • Depth of Field - End - 8.0 - (The end position of the view from the point of the camera)
  • Depth of Field - Start - 0.0 - (The start position of the view from the point of the camera)
  • Distance - 4 - (How far the literal camera is from the actual location of the camera. Setting this to 0 results in a FPS (First Person Shooter), around 4 with be a TPS (Third Person Shooter))
  • Distance - Far Clip - 300.0 - (The distance from which nothing will be rendered. If anything is farther than this from the camera, it WILL NOT RENDER)
  • Distance - Near Clip - .1 - (The distance when nothing will be rendered. If anything is closer than this from the camera, it WILL NOT RENDER)
  • Distance - Shadow Clip - 75.0 - (Assuming the distance after which shadows will not be rendered)
  • Target - Pitch - 12 - (Pitch of the camera. Pitch is the looking up/down movement)
  • Target - X - (Doesn't matter, this will change every frame of the game)
  • Target - Y - (Doesn't matter, this will change every frame of the game)
  • Target - Yaw - 180 - (Yaw of the camera. Think left to right movement that isn't barrel rolls)
  • Target - Z Offset - 1 - (How far the camera is off the ground)

The main value we need here is the Distance - 4. Setting this to 4 will create a third person camera (Although with units other than a marine, you may need to edit this). 0 will create a first person camera. The same goes for the Target - Z Offset - 1. A taller unit will need a higher value to raise the camera up some.

Global Variables

A few global variables are needed, the names and types of which are indicated below (Name - Type - Value - (Description)):

  • FaceOffset[8] - Real - 0.0 - (Where each player's respective units is facing)
  • Speed - Real - 0.03 - (The speed at which a unit moves)
  • Units[8] - Unit - [EMPTY] - (Stores each player's respective units)
  • PlayerA[8] - Real - 0 - (Stores is the players A key is down)
  • PlayerS[8] - Real - 0 - (Stores is the players S key is down)
  • PlayerD[8] - Real - 0 - (Stores is the players D key is down)
  • PlayerW[8] - Real - 0 - (Stores is the players W key is down)

Unit Creation

Now that the camera is set up, create the unit on the map that you wish to have the camera follow. Personally, I create them with triggers, and then store them in an global array of type "Unit", so if you had players 1 through 8 all being controlled by a third person camera, set the size of the Unit variable Array to 8, and then create the following simple loop on initialization:

http://vgshorts.com/BBCode/BBCode3.php?ID=4

Create Units
   Events
       Timer - Every 0.0 seconds of Game Time
   Local Variables
       Yaw = 0.0 <Real>
       CameraFocus = No Point <Point>
       Counter = 0 <Integer>
   Conditions
   Actions
       General - For each integer Counter from 1 to 8 with increment 1, do (Actions)
           Actions
               General - If (Conditions) then do (Actions) else do (Actions)
                   If
                       (Controller of player Counter) == User
                       (Status of player Counter) == Playing
                   Then
                       Unit - Create 1 Marine for player Counter at (Start location of player Counter) using default facing (No Options)
                       Variable - Set Units[Counter] = (Last created unit)
                   Else

This will create a Marine for each of the 8 players that will have a third person camera behind them.

Set Up Camera Trigger

Now we need to set up the camera object we created before for each player. This is a simple operation, and can actually be combined with the above trigger for simplicity:

http://vgshorts.com/BBCode/BBCode3.php?ID=5

Set Up Camera
   Events
       Timer - Every 0.0 seconds of Game Time
   Local Variables
       Yaw = 0.0 <Real>
       CameraFocus = No Point <Point>
       Counter = 0 <Integer>
   Conditions
   Actions
       General - For each integer Counter from 1 to 8 with increment 1, do (Actions)
           Actions
               General - If (Conditions) then do (Actions) else do (Actions)
                   If
                       (Controller of player Counter) == User
                       (Status of player Counter) == Playing
                   Then
                       Camera - Apply Camera 001 for player Counter over 0.0 seconds with Existing Velocity% initial velocity, 10% deceleration, and Don't Include Target
                       Camera - Lock camera mouse relative mode On for player Counter
                       Camera - Turn camera mouse rotation On for player Counter
                       Camera - Turn camera height smoothing Off for player Counter
                       Camera - Turn camera height displacement On for player Counter
                   Else

The first line applies the camera view we made earlier to the players camera (essentially making their look close to the ground). The second and third line enable mouse look for the player, meaning that their mouse will control where the camera points to. The third and fourth line smooth camera movement so it is not affected by terrain, or other abnormalities, and will stay in the same place relative to the unit.

Camera Update Trigger

Now we must set up a trigger to update the facing for each unit whenever the camera moves. It looks like this:

http://vgshorts.com/BBCode/BBCode3.php?ID=7

Camera Update
   Events
       Timer - Every 0.0 seconds of Game Time
   Local Variables
       Yaw = 0.0 <Real>
       CameraFocus = No Point <Point>
       Counter = 0 <Integer>
   Conditions
   Actions
       General - For each integer Counter from 1 to 8 with increment 1, do (Actions)
           Actions
               General - If (Conditions) then do (Actions) else do (Actions)
                   If
                       (Controller of player Counter) == User
                       (Status of player Counter) == Playing
                   Then
                       Variable - Set Yaw = (Current camera yaw of player Counter)
                       Variable - Set CameraFocus = ((Position of Units[Counter]) offset by 0.0 towards (Yaw + 90.0) degrees)
                       Unit - Make Units[Counter] face (Yaw + FaceOffset[Counter]) over 0.0 seconds
                       Camera - Set the camera bounds for (Player group(Counter)) to (Region((X of CameraFocus), (Y of CameraFocus), ((X of CameraFocus) + 0.01), ((Y of CameraFocus) + 0.01))) (Do Not adjust the minimap)
                   Else

Again, this uses some basic math the realign the unit facing with the camera facing, and the camera position with the unit position. Pretty simple, the mechanics of which aren't really necessary to know.

WASD Triggers

Now we need to create a function to read WASD input from the user. These triggers are simple:

http://vgshorts.com/BBCode/BBCode3.php?ID=8

LeftDown
   Events
       UI - Player Any Player presses A key Down with shift Allow, control Allow, alt Allow
   Local Variables
   Conditions
   Actions
       Animation - Play Walk animation for (Actor for Units[(Triggering player)]) as Default, using Play Forever options and Default Time blend time
       Variable - Set PlayerA[(Triggering player)] = 1.0
       Variable - Set FaceOffset[(Triggering player)] = 90.0

http://vgshorts.com/BBCode/BBCode3.php?ID=9

LeftUp
   Events
       UI - Player Any Player presses A key Up with shift Allow, control Allow, alt Allow
   Local Variables
   Conditions
   Actions
       Variable - Set PlayerA[(Triggering player)] = 0.0

These will need to be created for every button. The two above triggers are for the up/down value of A, and must be copied and modified for S, D, and W. The main factor here is to change the PlayerA/PlayerS/PlayerD/PlayerW variable for the respective player to 1 if the respective key is down, or 0 if it is not.

(Not Author)Addendum: Easy to use animations include: "Left" Animation for turning left "Right" Animation for turning right and "Right" or "Left" can be used for emulating a backwards walk There may be a way to combine multiple animations and combining "Left" and "Right" animations would be a pretty good animation for walking backwards. My scope on this field is somewhat limited but I figured this may push people in the right direction of "realistic" animations.

Movement Trigger

The last step is to create a movement trigger. This handles movement, if necessary, on every frame of play. It looks as follows:

http://vgshorts.com/BBCode/BBCode3.php?ID=10

MovePlayers
   Events
       Timer - Every 0.0 seconds of Game Time
   Local Variables
       XMovement = 0.0 <Real>
       XMult = 0.0 <Real>
       YMovement = 0.0 <Real>
       YMult = 0.0 <Real>
       Yaw = 0.0 <Real>
       Counter = 0 <Integer>
   Conditions
   Actions
       General - For each integer Counter from 1 to 8 with increment 1, do (Actions)
           Actions
               General - If (Conditions) then do (Actions) else do (Actions)
                   If
                       Or
                           Conditions
                               PlayerA[Counter] == 1.0
                               PlayerD[Counter] == 1.0
                               PlayerS[Counter] == 1.0
                               PlayerW[Counter] == 1.0
                   Then
                       Variable - Set Yaw = (Current camera yaw of player Counter)
                       Variable - Set XMult = (PlayerD[Counter] - PlayerA[Counter])
                       Variable - Set YMult = (PlayerW[Counter] - PlayerS[Counter])
                       Variable - Set XMovement = ((Cos((Yaw - 90.0))) * XMult)
                       Variable - Set YMovement = ((Sin((Yaw - 90.0))) * XMult)
                       Variable - Set XMovement = (XMovement + ((Cos(Yaw)) * YMult))
                       Variable - Set YMovement = (YMovement + ((Sin(Yaw)) * YMult))
                       Unit - Move Units[Counter] instantly to ((Position of Units[Counter]) offset by ((XMovement * Speed), (YMovement * Speed))) (Blend)
                       Unit - Move Units[Counter] instantly to ((Position of Units[Counter]) offset by ((XMovement * Speed), (YMovement * Speed))) (Blend)
                       Unit - Move Units[Counter] instantly to ((Position of Units[Counter]) offset by ((XMovement * Speed), (YMovement * Speed))) (Blend)
                       Unit - Move Units[Counter] instantly to ((Position of Units[Counter]) offset by ((XMovement * Speed), (YMovement * Speed))) (Blend)
                       Unit - Move Units[Counter] instantly to ((Position of Units[Counter]) offset by ((XMovement * Speed), (YMovement * Speed))) (Blend)
                   Else
                       Animation - Play Stand animation for (Actor for Units[Counter]) as Default, using Play Forever options and Default Time blend time

This will take each value and move the unit based. We find whether the unit is moving right or left by finding D - A, which will result in 0 if both are pressed, which will result in no movement. If the unit is moving right, we get a value of 1, and if they are moving left, we get a value of -1. The same goes for the forward/backward values.

Next, we find how far they will move in the X and Y direction by using trigonometric functions. This is some basic higher level math, but if you don't understand it, don't worry, it's not too important. Lastly, we move the unit to the new position (it's position, offset by the newly calculated values). This is done 5 fives over relatively short intervals to help smooth the movement.

Test

Test your map, and see if it works.

Afterword

That should be just about it to this tutorial. The movement system, again, works fine for one player, but lags over battle net. I'm currently working on a way to combine one or two other systems to create in hopefully less lag, smoother movement, and more realistic animations.

If there are any questions/errors, please let me know via PM on SEN. I'll update this with images and a demonstration map when I have the chance (and figure out how >.<)

Note: It is surmised that getting the Camera Pitch/Yaw/Roll and any trigonometric functions are VERY expensive to SC2 engine. Use these as sparingly as possibly, preferably once per trigger, and just store them in a variable if you need them more than once. These triggers are made to do this.

-Shmeeps

See Also