Wc3C.net

Wc3C.net (http://www.wc3c.net/forums.php)
-   JASS/AI scripts tutorials (http://www.wc3c.net/forumdisplay.php?f=650)
-   -   Making a camera system (http://www.wc3c.net/showthread.php?t=99507)

RolePlaynGamer 03-18-2008 01:38 PM

Making a camera system
 
1 Attachment(s)
Making a camera system

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

Trigger:
Actions
Unit – Kill Unit


Trigger:
Actions
Unit - Remove Paladin 0000 <gen> from the game

Now convert to custom text.

Collapse 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.

Collapse 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.

Collapse 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.

Collapse 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:

Collapse 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”.

Collapse 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:

Collapse 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”.

Collapse 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:

Collapse JASS:
constant native GetCameraField              takes camerafield whichField returns real

As camerafield use “CAMERA_FIELD_TARGET_DISTANCE”

Remember to put udg_ before the variable name.

Collapse 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.


Collapse 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.

Collapse 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:

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

Whichtrigger to your trigger.

Timeout to 0.10

Periodic to true

Collapse 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:

Collapse 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

Collapse 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.

Collapse 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

Trigger:
Player – Keyboard Event


Trigger:
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.

Collapse 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.

Collapse 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.

Trigger:
StopRight
Collapse Events
Player - Player 1 (Red) Releases the Right Arrow key
Conditions
Actions

Trigger:
StopLeft
Collapse Events
Player - Player 1 (Red) Releases the Left Arrow key
Conditions
Actions

Now convert them to custom text.

Collapse 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



Collapse 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

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

Collapse 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.


Collapse 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.

Collapse 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.
Trigger:
ZoomOut
Collapse Events
Player - Player 1 (Red) Presses the Down Arrow key
Conditions
Actions

Trigger:
ZoomIn
Collapse Events
Player - Player 1 (Red) Presses the Up Arrow key
Conditions
Actions

Now convert them to custom text.

In the ZoomIn trigger write
Collapse JASS:
Set udg_UpPressed = true

In the ZoomOut trigger write
Collapse JASS:
Set udg_DownPressed = true

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

Collapse 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.

Trigger:
StopIn
Collapse Events
Player - Player 1 (Red) Releases the Up Arrow key
Conditions
Actions

Trigger:
StopOut
Collapse Events
Player - Player 1 (Red) Releases the Down Arrow key
Conditions
Actions

Collapse JASS:
function Trig_StopIn_Actions takes nothing returns nothing
  set udg_UpPressed = false
endfunction

Collapse 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.

Collapse 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.

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

Collapse 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.

Collapse 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.

Collapse 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.

Collapse 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’.

Collapse 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.

Collapse 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!:emote_thumbup:


~RolePlayngamer

RolePlaynGamer 03-22-2008 04:51 PM

No feedback? What is good about this tutorial, what is bad? Could i improve anything or add more?

Malfurion 03-24-2008 04:16 PM

Great tutorial. You explained every triggers function before posting the trigger,
so the person which is going to use this tutorial, didn't just copy the tutorial,
but improves his/her JASS knowledge a bit. I don't really understand JASS, but
with your explanations, I understood at least a bit. :)

I may use this system for my world map of my pirate campaign, because I think
this is perfect for navigation.

+rep and great tutorial

RolePlaynGamer 03-24-2008 06:45 PM

Thanks =)

PitzerMike 04-03-2008 01:38 PM

1 Attachment(s)
Hello, first of all a few smaller corrections:
In the text you say the camera is applied every 0.05 seconds, but the code says it's every 0.02.
And you should explain how to obtain the name of your hero variable (gg_unit_Hpal...) and camera variable (gg_cam_..). Namely by making a GUI trigger and then converting it to custom text.

I like the way you described and explained everything.
The only problem is WHAT you are explaining, namely a very poorly made camera system. It's very edgy and as soon as you press a button the new settings are applied abruptly. Then a 0.02 timeout for the periodic timer is really not necessary (if the rest of the system is well done). And having to press the keys repeatedly instead of just keeping them pressed is a real annoyance.

I've edited your sample map and attached it, so you can see how it can be improved. With just a few smaller changes I made it very smooth, more efficient (0.1 periodic interval vs. 0.02), made it so it rotates/zooms as long as you keep the arrow keys pressed.

NOTE: What I've made there is still far from perfect, but it's of acceptable quality.

Also you should add a check for max/min zoom, so you can't zoom closer to the unit than, say 200 or so,

If you're going to update your tutorial there shouldn't be a problem with approval, since as already mentioned, I like the way how your explaining everything.

EDIT: Maybe also add a screenshot to make it come to life a bit.

RolePlaynGamer 04-03-2008 02:36 PM

Actually i'm already making an updated tutorial with zoom in/out limitations, holding arrow keys down and MPI.

But remember the titel: Making a basic camera system. I made this tutorial to give people a feeling on how to use the SetCameraField.

Thanks for the map, I will update the tutorial soon with a new section ~How to improve the system~

And where did i say it was every 0.05 sec?

PitzerMike 04-03-2008 03:04 PM

Quote:

Originally Posted by RolePlaynGamer
And where did i say it was every 0.05 sec?


Quote:

NOTE: gg_unit_Hpal_0000 may not be the correct unit in your map.

Now we have the basic of the trigger. Now the trigger will apply the camera to the unit every 0.05 second.

I'm sure it will be great, once it's finished.

RolePlaynGamer 04-05-2008 12:47 PM

~Updated~

i have rewriten the entire tutorial to make a better system.

PitzerMike 04-19-2008 11:17 PM

Yep, that's cool.
I'll give you a reppy and then approve.

RolePlaynGamer 04-20-2008 06:28 AM

ok great ! =)

varsaigen 05-03-2008 05:14 AM

wow. its very detailed. I don't think it needs anything else. I couldn't even get close to describing it like this. Great job!

Angelusz 05-23-2008 02:00 PM

Nice tutorial, good collaboration with PitzerMike ;) I'm going to give this a go!

yatyfornetreg 07-14-2010 01:53 PM

Would you please put ALL the introductions of Camera Functions here? If you have enough time to do so.
I can hardly find useful informations about them.
And this thread had already helped me a lot about how to simply use cameras.
Thank you very much.


All times are GMT. The time now is 02:55 AM.

Powered by vBulletin (Copyright ©2000 - 2019, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services