HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Drop of 30 fps from camera

03-16-2010, 11:22 PM#1
Tastingo
Recently I had a problem with the lag caused from projectiles moving. Thanks to everyone in the forum that had helped, they fixed and explained it to me. So now I wanted to create my own camera settings to follow a unit. Basically every .03 seconds it sets all the camera fields to what I want it to be, so you can't press control c or mouse wheel to mess it up. I was not sure if it was better to have one timer for both projectile movement and camera movement, or two seperate timers. So right now they are running off the same timer, please let me know which is better. Lastly, the fps seems to get better when not all 8 players are by each other. Well at least mine did, when I moved away. The fps dropped from 60 to 30, right after I implemented the camera.

Nutshell:

Best way to set up a camera that follows behind a unit, sort of in a 3rd person view. (Think gears of war) Also best way to prevent user from messing it up.

Is one timer better than one?

Any tips for cameras would help :).

I hope someone can take the time out to please help me, would be a very big help :).

playing - A global variable to check if player is playing
isDead - A global variable to check if player is dead
players - A global variable that holds the unit of each player

Summary of Code - Checks to see if player is living and alive. If so it locks the camera to his unit with adjusted settings. If not locks to another player on his team.

Collapse JASS:
function timerCameras takes nothing returns nothing
   local integer i = 0
    
    loop
        if playing[i] == true then  //Check if playing
            if isDead[i] == false then  //Keep camera on living target
                if GetLocalPlayer() == Player(i) then
                    call SetCameraTargetController(players[i], 0, 0, false)
                    call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 250.00, 0)
                    call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 185.00, 0)
                    call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, 100.00, 0)
                    call SetCameraField(CAMERA_FIELD_ROLL, 180.00, 0)
                    call SetCameraField(CAMERA_FIELD_ZOFFSET, 120.00, 0)
                    call SetCameraField(CAMERA_FIELD_ROTATION, GetUnitFacing(players[i]) + 180, 0)
                endif
            else //Swap camera to living person
                if i < 4 then   //On Team 1
                    if(GetLocalPlayer() == Player(i)) then  //Change camera for local player only
                        if isDead[0] == false then  //Change dead player camera to Red
                            call SetCameraTargetController(players[0], 0, 0, false)
                            call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 250.00, 0)
                            call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 185.00, 0)
                            call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, 100.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROLL, 180.00, 0)
                            call SetCameraField(CAMERA_FIELD_ZOFFSET, 120.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROTATION, GetUnitFacing(players[0]) + 180, 0)
                        elseif isDead[1] == false then  //Change dead player camera to Blue
                            call SetCameraTargetController(players[1], 0, 0, false)
                            call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 250.00, 0)
                            call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 185.00, 0)
                            call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, 100.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROLL, 180.00, 0)
                            call SetCameraField(CAMERA_FIELD_ZOFFSET, 120.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROTATION, GetUnitFacing(players[1]) + 180, 0)
                        elseif isDead[2] == false then  //Change dead player camera to Teal
                            call SetCameraTargetController(players[2], 0, 0, false)
                            call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 250.00, 0)
                            call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 185.00, 0)
                            call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, 100.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROLL, 180.00, 0)
                            call SetCameraField(CAMERA_FIELD_ZOFFSET, 120.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROTATION, GetUnitFacing(players[2]) + 180, 0)
                        elseif isDead[3] == false then  //Change dead player camera to Purple
                            call SetCameraTargetController(players[3], 0, 0, false)
                            call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 250.00, 0)
                            call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 185.00, 0)
                            call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, 100.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROLL, 180.00, 0)
                            call SetCameraField(CAMERA_FIELD_ZOFFSET, 120.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROTATION, GetUnitFacing(players[3]) + 180, 0)
                        endif
                    endif
                else    //On Team 2
                    if(GetLocalPlayer() == Player(i)) then  //Change for local player only
                        if isDead[4] == false then  //Change dead player camera to Yellow
                            call SetCameraTargetController(players[4], 0, 0, false)
                            call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 250.00, 0)
                            call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 185.00, 0)
                            call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, 100.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROLL, 180.00, 0)
                            call SetCameraField(CAMERA_FIELD_ZOFFSET, 120.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROTATION, GetUnitFacing(players[4]) + 180, 0)
                        elseif isDead[5] == false then  //Change dead player camera to Orange
                            call SetCameraTargetController(players[5], 0, 0, false)
                            call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 250.00, 0)
                            call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 185.00, 0)
                            call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, 100.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROLL, 180.00, 0)
                            call SetCameraField(CAMERA_FIELD_ZOFFSET, 120.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROTATION, GetUnitFacing(players[5]) + 180, 0)
                        elseif isDead[6] == false then  //Change dead player camera to Green
                            call SetCameraTargetController(players[6], 0, 0, false)
                            call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 250.00, 0)
                            call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 185.00, 0)
                            call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, 100.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROLL, 180.00, 0)
                            call SetCameraField(CAMERA_FIELD_ZOFFSET, 120.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROTATION, GetUnitFacing(players[6]) + 180, 0)
                        elseif isDead[7] == false then  //Change dead player camera to Pink
                            call SetCameraTargetController(players[7], 0, 0, false)
                            call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 250.00, 0)
                            call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 185.00, 0)
                            call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, 100.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROLL, 180.00, 0)
                            call SetCameraField(CAMERA_FIELD_ZOFFSET, 120.00, 0)
                            call SetCameraField(CAMERA_FIELD_ROTATION, GetUnitFacing(players[7]) + 180, 0)
                        endif
                    endif
                endif
            endif
        endif
        set i = i + 1
        exitwhen i > 7
    endloop
endfunction
03-17-2010, 01:23 AM#2
TheKid
I would definitely have them run off separate timers, just to eliminate unnecessary overhead.

Other than that, I really need to see some code to find sources of lag. To my knowledge updating the camera fields every 0.03 seconds should not cause such a significant drop in FPS.
03-17-2010, 02:10 AM#3
Ammorth
You should have seperate timers if the things you are looping are different things (aka the camera and projectiles are different things).
03-17-2010, 03:02 AM#4
Tastingo
Okay I will update the post with some code. Thanks for letting me know which was better to do with timers!
03-17-2010, 04:56 AM#5
sPyRaLz
On a separate note, you seem to have alot of repetitive code. I recommend you try to
implement a text macro to make it easier for you to edit.

This:
Expand JASS:

could be simplified to this:

Expand JASS:

PS: May be some errors in my syntax. But that should make things cleaner for you. Play around with it. I myself recently discovered how useful it is :)

Expand JASS:
03-17-2010, 04:59 AM#6
Ammorth
I can't see any reason why the code you posted would cause that much lag... unless SetCameraTargetController is super slow... Ive done more camera calculations at a higher frequency than that before and never noticed much lag.
03-17-2010, 08:28 PM#7
Tot
don't forget, jass code calculation is someway linked to the calculation of each frame. Therefore the oplimit (not enough time till the next frame is calced) and the dely within selection-events/functions (function is called, after the frame has been shown)

the italic parts are non-prooved, they're only conclusions I draw
03-17-2010, 10:20 PM#8
Tastingo
Yo dude sick thank you for the text macro stuff :). I'm new to VJass so, it helps a lot :). I will continue testing with it, maybe it's something else that I didn't even notice? Thanks all, and dude Ammorth, I love that sig lol. It's addicting to stare at, just because its very different lol.

Edit: Doh I feel like an idiot, I let my timer run once and turned off the rest of my timers. It still dropped from 60 to 30 fps. I guess just 6 units close up does that...
03-17-2010, 10:51 PM#9
TheKid
Its his girl friend.

Quote:
Originally Posted by Tastingo
I guess just 6 units close up does that...

It takes quite a bit to drop WarCraft III's frame-rate, or at least it isn't a very common problem. I have made cameras that follow behind units (like you have described) and I never ran into problems with serious lag due to code. The only problem I really ran into was the Far-Z, because with epic scenery the computer is going to have to load everything you can possibly see. If you use your fog of war then it helps quite a bit, but typically you want the user to be able to see everything when the camera is behind the unit.

Try lowering the value of the camera's far-z to 2500 and see if it still lags. This only needs to be done once since users cannot control the far-z in-game.
03-17-2010, 11:01 PM#10
Earth-Fury
Quote:
Originally Posted by Tot
don't forget, jass code calculation is someway linked to the calculation of each frame.
Not at all. The JASS VM is invoked when events occur. It is not at all tied to the frame rate.

Quote:
Originally Posted by Tot
Therefore the oplimit (not enough time till the next frame is calced)
The op limit is the limit of operations a thread can perform before it has to be slept. This is to prevent infinite loops from hard-freezing the game. It has nothing to do with the frame rate. Threads are started when the game executes a trigger, and via ExecuteFunc. (TriggerEvaluate also seems to start a new thread.)

JASS is not time sliced. Threads execute one at a time, and each thread executes until it dies, returns, or is slept.
03-18-2010, 12:59 PM#11
Tot
Quote:
Originally Posted by Earth-Fury
Not at all. The JASS VM is invoked when events occur. It is not at all tied to the frame rate.


The op limit is the limit of operations a thread can perform before it has to be slept. This is to prevent infinite loops from hard-freezing the game. It has nothing to do with the frame rate. Threads are started when the game executes a trigger, and via ExecuteFunc. (TriggerEvaluate also seems to start a new thread.)

JASS is not time sliced. Threads execute one at a time, and each thread executes until it dies, returns, or is slept.

it has at least something to do with your gma, cause i only changed my graphocs and now some maps don't lag anymore (new sappire 5870, old nvidia 7600)