| 03-18-2008, 01:38 PM | #1 |
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 lets 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 UnitTrigger: Actions
![]() Unit - Remove Paladin 0000 <gen> from the gameNow 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. Im 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 Trigger: Player Keyboard EventTrigger: Player - Player 1 (Red) Presses the Right Arrow keyConvert 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. 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. 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. 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 isnt 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 Lets 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 its 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 its 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 doesnt 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. Thats 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 Thats it! Your done. Test your system and enjoy the smooth movement. Have fun! ~RolePlayngamer |
| 03-22-2008, 04:51 PM | #2 |
No feedback? What is good about this tutorial, what is bad? Could i improve anything or add more? |
| 03-24-2008, 04:16 PM | #3 |
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 |
| 03-24-2008, 06:45 PM | #4 |
Thanks =) |
| 04-03-2008, 01:38 PM | #5 |
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. |
| 04-03-2008, 02:36 PM | #6 |
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? |
| 04-03-2008, 03:04 PM | #7 | ||
Quote:
Quote:
I'm sure it will be great, once it's finished. |
| 04-05-2008, 12:47 PM | #8 |
~Updated~ i have rewriten the entire tutorial to make a better system. |
| 04-19-2008, 11:17 PM | #9 |
Yep, that's cool. I'll give you a reppy and then approve. |
| 04-20-2008, 06:28 AM | #10 |
ok great ! =) |
| 05-03-2008, 05:14 AM | #11 |
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! |
| 05-23-2008, 02:00 PM | #12 |
Nice tutorial, good collaboration with PitzerMike ;) I'm going to give this a go! |
| 07-14-2010, 01:53 PM | #14 |
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. |
