• 🏆 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!

Making a camera system

Level 9
Joined
Apr 5, 2008
Messages
529
Hey there. This tutorial will teach you how to make a camera system. The system will follow a unit and you can rotate and zoom using the 4 arrow keys.

But before we begin let’s make the variables. We need 6 variables.
Name | Type | Initial Value

Rotation | Real | 0
Zoom | Real | 0
UpPressed | Boolean | false
DownPressed | Boolean | false
RightPressed | Boolean | false
LeftPressed | Boolean | false

First we will place a unit and the camera in the map. Place the unit you want the camera to apply to, and create the camera. Now make a new trigger with no event or condition. As an action add

  • Actions
    • Unit – Remove Unit

  • Actions
    • Unit - Remove Paladin 0000 <gen> from the game
Now convert to custom text.

JASS:
function Trig_GetId_Actions takes nothing returns nothing
    call RemoveUnit( gg_unit_Hpal_0000 )
endfunction

gg_unit_Hpal_0000 is the id of my unit. It might be something different in your case. Write the id down and delete the trigger.

Now we will start making the system.

First make a new trigger called ‘InitCamera’ or something. Convert to custom text.

JASS:
function Trig_InitCamera_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_InitCamera takes nothing returns nothing
    set gg_trg_InitCamera = CreateTrigger(  )
    call TriggerAddAction( gg_trg_InitCamera, function Trig_InitCamera_Actions )
endfunction

Now delete everything except the InitTrig_InitCamera function.

JASS:
function InitTrig_InitCamera takes nothing returns nothing
    set gg_trg_InitCamera = CreateTrigger(  )
    call TriggerAddAction( gg_trg_InitCamera, function Trig_InitCamera_Actions )
endfunction

Delete everything in it.

JASS:
function InitTrig_InitCamera takes nothing returns nothing
endfunction

The code we put between this will run when the game is loading.

First we apply the camera to your decided player. To do this we will use:

JASS:
native CameraSetupApply                     takes camerasetup whichSetup, boolean doPan, boolean panTimed returns nothing

Just leave the Booleans false.

As camera setup we need the cameras id. This is not as hard to get as the units id.

Ids of cameras starts with “gg_cam_”. The rest is the name of the camera. In my case the cameras name is just “Camera”, so my id will be “gg_cam_Camera”.

JASS:
function InitTrig_InitCamera takes nothing returns nothing
    call CameraSetupApply(gg_cam_Camera, false, false)
endfunction

Now we need to lock the camera to the unit. For this we will use:

JASS:
native SetCameraTargetController    takes unit whichUnit, real xoffset, real yoffset, boolean inheritOrientation returns nothing

set x/y offset to 0, inheritOrientation to true and WhichUnit to the id you got in the start, in my case “gg_unit_Hpal_0000”.

JASS:
function InitTrig_InitCamera takes nothing returns nothing
    call CameraSetupApply(gg_cam_Camera, false, false)
    call SetCameraTargetController(gg_unit_Hpal_0000, 0, 0, true)
endfunction

Now we will set the Zoom variable to the players current zoom. We will use the function:

JASS:
constant native GetCameraField              takes camerafield whichField returns real

As camerafield use “CAMERA_FIELD_TARGET_DISTANCE”

Remember to put udg_ before the variable name.

JASS:
function InitTrig_InitCamera takes nothing returns nothing
    call CameraSetupApply(gg_cam_Camera, false, false)
    call SetCameraTargetController(gg_unit_Hpal_0000, 0, 0, true)
    set udg_Zoom = GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)
endfunction

Also we will set the rotation variable to the units facing.


JASS:
function InitTrig_InitCamera takes nothing returns nothing
    call CameraSetupApply(gg_cam_Camera, false, false)
    call SetCameraTargetController(gg_unit_Hpal_0000, 0, 0, true)
    set udg_Zoom = GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)
    set udg_Rotation = GetUnitFacing(gg_unit_Hpal_0000)
endfunction

If you test the system now the camera will lock to your unit.



Now for the trigger that runs all the system. Create a new trigger and name it something like “CameraTrigger”. I’m not creative at naming triggers…

Just convert to custom text as we will add the event in JASS.

JASS:
function Trig_CameraTrigger_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_CameraTrigger takes nothing returns nothing
    set gg_trg_CameraTrigger = CreateTrigger(  )
    call TriggerAddAction( gg_trg_CameraTrigger, function Trig_CameraTrigger_Actions )
endfunction

As an event we will use:

JASS:
native TriggerRegisterTimerEvent takes trigger whichTrigger, real timeout, boolean periodic returns event

Whichtrigger to your trigger.

Timeout to 0.10

Periodic to true

JASS:
function Trig_CameraTrigger_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_CameraTrigger takes nothing returns nothing
    set gg_trg_CameraTrigger = CreateTrigger(  )
    call TriggerRegisterTimerEvent(gg_trg_CameraTrigger, 0.10, true)
    call TriggerAddAction( gg_trg_CameraTrigger, function Trig_CameraTrigger_Actions )
endfunction


Now for the actions.

First we set the rotation to the Rotation variable. We will use:

JASS:
native SetCameraField               takes camerafield whichField, real value, real duration returns nothing

As camerafield write CAMERA_FIELD_ROTATION

As real value write udg_Rotation

As real duration write 0.10

JASS:
function Trig_CameraTrigger_Actions takes nothing returns nothing
  call SetCameraField(CAMERA_FIELD_ROTATION, udg_Rotation, 0.10)
endfunction

We also need to set the zoom. This is called “CAMERA_FIELD_TARGET_DISTANCE”. We use the same function, but as value write udg_Zoom instead.

JASS:
function Trig_CameraTrigger_Actions takes nothing returns nothing
  call SetCameraField(CAMERA_FIELD_ROTATION, udg_Rotation, 0.10)
  call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, udg_Zoom, 0.10)
endfunction

Great … But the player cant use arrow keys to manipulate the camera. right?
-True. We will have to make that now.

First create a new trigger named “RotateRight”, or similar. As event make the

  • Player – Keyboard Event

  • Player - Player 1 (Red) Presses the Right Arrow key
Convert to custom text.

Now in the actions function we only need 1 line of code. We need to set the variable RightPressed to true.

JASS:
function Trig_RotateRight_Actions takes nothing returns nothing
  set udg_RightPressed = true
endfunction

//===========================================================================
function InitTrig_RotateRight takes nothing returns nothing
    set gg_trg_RotateRight = CreateTrigger(  )
    call TriggerRegisterPlayerKeyEventBJ( gg_trg_RotateRight, Player(0), bj_KEYEVENTTYPE_DEPRESS, bj_KEYEVENTKEY_RIGHT )
    call TriggerAddAction( gg_trg_RotateRight, function Trig_RotateRight_Actions )
endfunction

Now you could also make this one for the left arrow key.

JASS:
function Trig_RotateLeft_Actions takes nothing returns nothing
  set udg_LeftPressed = true
endfunction

//===========================================================================
function InitTrig_RotateLeft takes nothing returns nothing
    set gg_trg_RotateLeft = CreateTrigger(  )
    call TriggerRegisterPlayerKeyEventBJ( gg_trg_RotateLeft, Player(0), bj_KEYEVENTTYPE_DEPRESS, bj_KEYEVENTKEY_LEFT )
    call TriggerAddAction( gg_trg_RotateLeft, function Trig_RotateLeft_Actions )
endfunction


Now for the StopRotate triggers.

Create 2 new triggers. “StopRight” and “StopLeft”. Add the same event before and leave the fields the same EXCEPT PRESSES!!! This time use Releases.

  • StopRight
    • Events
      • Player - Player 1 (Red) Releases the Right Arrow key
    • Conditions
    • Actions
  • StopLeft
    • Events
      • Player - Player 1 (Red) Releases the Left Arrow key
    • Conditions
    • Actions
Now convert them to custom text.

JASS:
function Trig_StopRight_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_StopRight takes nothing returns nothing
    set gg_trg_StopRight = CreateTrigger(  )
    call TriggerRegisterPlayerKeyEventBJ( gg_trg_StopRight, Player(0), bj_KEYEVENTTYPE_RELEASE, bj_KEYEVENTKEY_RIGHT )
    call TriggerAddAction( gg_trg_StopRight, function Trig_StopRight_Actions )
endfunction



JASS:
function Trig_StopLeft_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_StopLeft takes nothing returns nothing
    set gg_trg_StopLeft = CreateTrigger(  )
    call TriggerRegisterPlayerKeyEventBJ( gg_trg_StopLeft, Player(0), bj_KEYEVENTTYPE_RELEASE, bj_KEYEVENTKEY_LEFT )
    call TriggerAddAction( gg_trg_StopLeft, function Trig_StopLeft_Actions )
endfunction

Now in the action function write

Set udg_<Right/Left>Pressed = false

JASS:
function Trig_StopRight_Actions takes nothing returns nothing
  set udg_RightPressed = false
endfunction

JASS:
function Trig_StopLeft_Actions takes nothing returns nothing
  set udg_LeftPressed = false
endfunction

Now go back to the camera trigger. Here we will use some if/then/else statements. Remember to place them above the SetCameraField calls.

In the first if/then/else statement we will check if RightPressed is true, and in the second we will check if Leftpressed is true.


JASS:
function Trig_CameraTrigger_Actions takes nothing returns nothing
  if (udg_RightPressed == true) then
  endif
  if (udg_Leftpressed == true) then
  endif
  call SetCameraField(CAMERA_FIELD_ROTATION, udg_Rotation, 0.10)
  call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, udg_Zoom, 0.10)
endfunction

Now we will increase/decrease the value of Rotation. In the PressedRight statement you should set the variable to +10 and in the LeftPressed statement to –10.

JASS:
function Trig_CameraTrigger_Actions takes nothing returns nothing
  if (udg_RightPressed == true) then
    set udg_Rotation = udg_Rotation+10
  endif
  if (udg_LeftPressed == true) then
    set udg_Rotation = udg_Rotation-10
  endif
  call SetCameraField(CAMERA_FIELD_ROTATION, udg_Rotation, 0.10)
  call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, udg_Zoom, 0.10)
endfunction

If you test the system now you will be able to rotate the camera around the hero.

I think you can handle the zoom in/out trigger on your own, but I will go through them anyway.

First create 2 triggers, one with presses up and one with presses down.
  • ZoomOut
    • Events
      • Player - Player 1 (Red) Presses the Down Arrow key
    • Conditions
    • Actions
  • ZoomIn
    • Events
      • Player - Player 1 (Red) Presses the Up Arrow key
    • Conditions
    • Actions
Now convert them to custom text.

In the ZoomIn trigger write
JASS:
Set udg_UpPressed = true

In the ZoomOut trigger write
JASS:
Set udg_DownPressed = true

JASS:
function Trig_ZoomIn_Actions takes nothing returns nothing
  set udg_UpPressed = true
endfunction

JASS:
function Trig_ZoomOut_Actions takes nothing returns nothing
  set udg_DownPressed = true
endfunction

Now create to new triggers, this time with Releases event, and you set the variables to false.

  • StopIn
    • Events
      • Player - Player 1 (Red) Releases the Up Arrow key
    • Conditions
    • Actions
  • StopOut
    • Events
      • Player - Player 1 (Red) Releases the Down Arrow key
    • Conditions
    • Actions
JASS:
function Trig_StopIn_Actions takes nothing returns nothing
  set udg_UpPressed = false
endfunction

JASS:
function Trig_StopOut_Actions takes nothing returns nothing
  set udg_DownPressed = false
endfunction

Now go to the first trigger and make an if/then/else statement for each of the zooms. I set the values to +50 and –50.

JASS:
function Trig_CameraTrigger_Actions takes nothing returns nothing
  if (udg_RightPressed == true) then
    set udg_Rotation = udg_Rotation+10
  endif
  if (udg_LeftPressed == true) then
    set udg_Rotation = udg_Rotation-10
  endif
  if (udg_UpPressed == true) then
    set udg_Zoom = udg_Zoom-50
  endif
  if (udg_DownPressed == true) then
    set udg_Zoom = udg_Zoom+50
  endif
  call SetCameraField(CAMERA_FIELD_ROTATION, udg_Rotation, 0.10)
  call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, udg_Zoom, 0.10)
endfunction


Making zoom limitations

If you test the system now you are able to zoom VERY close and VERY far away. This is not good…

It isn’t very hard to fix this. We only need to work with the ‘CameraTrigger’ trigger.

We need an if/then/else statement inside the zoom if/then/else statements.

JASS:
  if (udg_UpPressed == true) then
    set udg_Zoom = udg_Zoom-50
  endif

JASS:
  if (udg_DownPressed == true) then
    set udg_Zoom = udg_Zoom+50
  endif

Let’s start with the first, UpPressed.

The if/then/else statement should run when udg_Zoom is under a desired value. I think 300 is a good number.

JASS:
  if (udg_UpPressed == true) then
    set udg_Zoom = udg_Zoom-50
    if (udg_Zoom < 300) then
    endif
  endif

Now we just need to reset udg_Zoom, to the value it had before. This is done easily, by increasing it’s value with 50.

JASS:
  if (udg_UpPressed == true) then
    set udg_Zoom = udg_Zoom-50
    if (udg_Zoom < 300) then
      set udg_Zoom = udg_Zoom+50
    endif
  endif

Now you should also do this to the other if/then/else/statement.

JASS:
  if (udg_DownPressed == true) then
    set udg_Zoom = udg_Zoom+50
    if (udg_Zoom > 2300) then
      set udg_Zoom = udg_Zoom-50
    endif
  endif

Remember to check when it’s Over a value, in my case, 2300. Now just set the value to –50.

Also you might want to display a message to the player, so he doesn’t freak out when he cant zoom anymore. We will use ‘DisplayTextToPlayer’.

JASS:
      call DisplayTextToPlayer(Player(0), 0, 0, "Cannot zoom anymore!")

Remember that player 1 (Red) is player 0 in JASS.

That’s it. You have your zoom limitation.

JASS:
  if (udg_UpPressed == true) then
    set udg_Zoom = udg_Zoom-50
    if (udg_Zoom < 300) then
      set udg_Zoom = udg_Zoom+50
      call DisplayTextToPlayer(Player(0), 0, 0, "Cannot zoom anymore!")
    endif
  endif
  if (udg_DownPressed == true) then
    set udg_Zoom = udg_Zoom+50
    if (udg_Zoom > 2300) then
      set udg_Zoom = udg_Zoom-50
      call DisplayTextToPlayer(Player(0), 0, 0, "Cannot zoom anymore!")
    endif
  endif

That’s it! Your done. Test your system and enjoy the smooth movement.

Have fun! :thumbs_up:


~RolePlayngamer
 

Attachments

  • CameraSystem.w3m
    9.6 KB · Views: 509
Last edited:
Level 4
Joined
Sep 27, 2007
Messages
85
umm well i was testing it in your test map and the camera screwed up.... and i might try it again and see if it happens again.... i kept spinning and going out and in and then the cvamera started spinnnign at a really fast speed andi couldn't stop it
sorry!
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
From what does the bug occur? I haven't had time to test this myself, and it's not very easy to read in the tutorial page as a script.

In other news, some Jass stuff --

JASS:
if blahblah == true then //==true is redundant - ifs must always compare to true anyways, since that is how they work

if blahblah then //works the same way as the above

//======================

if blahblah then
endif
if blahblah2 then
endif
if blahblah3 then
endif

//these sort of if-blocks can be compressed using elseif in many cases (assuming only one can activate at once)

if blahblah then
elseif blahblah2 then
elseif blahblah 3 then
endif
 
Level 9
Joined
Apr 5, 2008
Messages
529
the if/ you posted is a little messy because the if/then/else statement will end if right bottom is hit, so you cant zoom and rotate at the same time. But the solution is easy, just split it into 2 statements. One with the rotation and one with the zoom.

And i haven't even begun the GUI tutorial yet...

Also, please explain the bug a ltttle more. Does it spin very fast so you have no chance of controlling the hero, or does it just move a little from side to side?
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
I am not sure if I come to the same bug as the above, but when I rotate the camera a lot to the right, it starts spinning "fast"(to the right) if I press the left arrow key, it stops after enough time.
The camera was nowhere the camera bounds and I managed to do that a couple of times.
Did not manage doing the same thing with left :D
I tried increasing the values of the rotation from +10 to +40. Result - the spinning occurred faster, and still nothing happens with left. Also a glich appeared when rotating right(camera jumps a little).
I think it is because value of the variable goes too high for the function - just capping it should remove this.
 
Top