HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Camera Issues

01-04-2008, 09:38 PM#1
Burning Rose
So, I'm trying to make a sort of Camera System for a Campaign I'm fiddling around with.

It's mostly looking good, especially since this type of camera shows off the terrain (It's Third Person View from behind one unit).

Two problems though:

First off, how do you stop the player from returning the camera to the game camera by scrolling with the mouse button? I apply a camera with the sort of Angle of Attack, Distance, Field of View, Etc. before I lock the camera to the unit, but whenever I scroll down and then up, it puts it back at normal view only locked to the unit. How do I stop this?

Secondly, when the unit moves to a high region or a low region, the camera doesn't raise of lower on it's own, even though it's locked to the unit. If I knew a formula to find the current terrain height that the unit is on I could fix this, but I don't. Any suggestions?

EDIT: Oh, and on a side note, I was using a Formula like this to calculate the unit moving forward (With the Arrow Keys):
Trigger:
Unit - Move Paladin 0003 <gen> instantly to (Point(((X of (Position of Paladin 0003 <gen>)) + ((Sign((Facing of Paladin 0003 <gen>))) x 4.00)), ((Y of (Position of Paladin 0003 <gen>)) + ((Cos((Facing of Paladin 0003 <gen>))) x 4.00))))

The problem is it only seems to move him up and to the right; it will change angles, but always only up and to the right. I haven't gotten to Sine and Cosine yet in Geometry, but My older brother who hasn't taken a math course in a while gave me his best formula idea. Unfortunately, it doesn't seem to work
Any Ideas?
01-04-2008, 10:09 PM#2
TaintedReality
Quote:
Secondly, when the unit moves to a high region or a low region, the camera doesn't raise of lower on it's own, even though it's locked to the unit. If I knew a formula to find the current terrain height that the unit is on I could fix this, but I don't. Any suggestions?

There's a function called GetLocationZ. Unfortunately I'm not sure if there's a GUI equivalent.

Collapse JASS:
native GetLocationZ             takes location whichLocation returns real

You've got the trig all messed up for the movement. First off, you're using the Sign function instead of the Sine function. Secondly, you've got them mixed up - Cosine finds the X value, Sine finds the Y. Try:

Trigger:
Unit - Move Paladin 0003 <gen> instantly to (Point(((X of (Position of Paladin 0003 <gen>)) + ((Cos((Facing of Paladin 0003 <gen>))) x 4.00)), ((Y of (Position of Paladin 0003 <gen>)) + ((Sine((Facing of Paladin 0003 <gen>))) x 4.00))))

For your first problem, I think the only solution is to periodically reset the camera...which kinda sucks. I could be wrong on that one though.
01-05-2008, 05:06 AM#3
Ammorth
Apply the settings over a period of time that is longer than your camera period. For example, if you update the camera every 0.035 seconds, apply the camera settings over 0.05 seconds or greater. When the camera is being applied, the player cannot rotate of zoom.

The second problem is because of the camera Z map. Using GetLocationZ() can work, but to an extent. This is because the camera smooths its z offset and is not exactly with the terrain. The correction with GetLocationZ() should be enough to solve your problem though.
01-05-2008, 04:14 PM#4
Burning Rose
Wow, thanks!

Big happies all around!

Although, I'm kind of noob at JASS... Which functions would I use to get the Location of the Unit for the Z thing, and then to flush that location (Or whatever you call it)?

Also, Again it's not related so much to the first ones, but when he's moving I want him to play his walk animation. I thought that doing it like this:
Hidden information:
Trigger:
Forward_On
Collapse Events
Player - Player 1 (Red) Presses the Up Arrow key
Conditions
Collapse Actions
Trigger - Turn on Forward <gen>
Animation - Play Paladin 0003 <gen>'s walk animation

Trigger:
Forward_Off
Collapse Events
Player - Player 1 (Red) Releases the Up Arrow key
Conditions
Collapse Actions
Trigger - Turn off Forward <gen>
Animation - Reset Paladin 0003 <gen>'s animation

Trigger:
Forward
Collapse Events
Time - Every 0.01 seconds of game time
Conditions
Collapse Actions
Unit - Move Paladin 0003 <gen> instantly to (Point(((X of (Position of Paladin 0003 <gen>)) + ((Cos((Facing of Paladin 0003 <gen>))) x 1.50)), ((Y of (Position of Paladin 0003 <gen>)) + ((Sin((Facing of Paladin 0003 <gen>))) x 1.50))))
Camera - Set Player 1 (Red)'s camera Rotation to (Facing of Paladin 0003 <gen>) over 0.00 seconds


But it doesn't seem to work. Any Ideas?
01-05-2008, 06:32 PM#5
TaintedReality
Quote:
Although, I'm kind of noob at JASS... Which functions would I use to get the Location of the Unit for the Z thing, and then to flush that location (Or whatever you call it)?

First, make 2 variables, a point variable that will hold the location, and a real variable that will hold the Z value. Let's say they're named TempLocation and LocationZ, then you would want this:

Trigger:
Actions
Set TempLocation = (Position of Paladin 0003 <gen>)
Custom script: set udg_LocationZ = GetLocationZ(udg_TempLocation)
Custom script: call RemoveLocation(udg_TempLocation)

The LocationZ variable would now hold the Z value.

Now for your second question...that would require more JASS :). The problem is, using SetUnitPosition(which is what the GUI action uses), resets the units current order and animation. You have to use SetUnitX and SetUnitY instead, which keeps the current order and animation. One problem with SetUnitX/Y though is that they don't have any checks to prevent a unit from going outside of the map, and if that happens then it will crash. So...most people create a new function that will check for that. I have one:

Collapse JASS:
function SetUnitXY takes unit u,real x,real y returns nothing
    local real rX = x
    local real rY = y
    local real maxX = GetRectMaxX(bj_mapInitialPlayableArea)
    local real maxY = GetRectMaxY(bj_mapInitialPlayableArea)
    local real minX = GetRectMinX(bj_mapInitialPlayableArea)
    local real minY = GetRectMinY(bj_mapInitialPlayableArea)
    if(rX>maxX) then
        set rX = maxX
    endif
    if(rX<minX) then
        set rX = minX
    endif
    if(rY>maxY) then
        set rY = maxY
    endif
    if(rY<minY) then
        set rY = minY
    endif
    call SetUnitX(u,rX)
    call SetUnitY(u,rY)
endfunction

Sooo. Put that in your custom script. Then make a unit variable which will hold the Paladin, let's say it's named TempUnit. Then you'll have something like this:

Trigger:
Forward
Collapse Events
Time - Every 0.03 seconds of game time
Conditions
Collapse Actions
Set TempUnit = Paladin 0003 <gen>
Custom script: call SetUnitXY(udg_TempUnit,GetUnitX(udg_TempUnit)+4.0*Cos(bj_DEGTORAD*GetUnitFacing(udg_TempUnit)),GetUnitY(udg_TempUnit)+4.0*Sin(bj_DEGTORAD*GetUnitFacing(udg_TempUnit)))
Camera - Set Player 1 (Red)'s camera Rotation to (Facing of (Paladin 0003 <gen>)) over 0.00 seconds

I also upped the periodic timer to 0.03 seconds - the frame rate of war3 is something between 0.03 and 0.04, I forget exactly (I THINK, but it's definitely more than 0.02), so there's no reason to move something every 0.01 seconds. Also, your trigger was leaking 2 locations. Hopefully you can figure out what this one is doing, I usually don't like just making triggers for people, but since you don't really know JASS I didn't have a choice ><.
01-05-2008, 06:51 PM#6
Burning Rose
Will that push him through Pathing Blockers, or will he still be blocked? (That's what I'm going for >_>)
01-05-2008, 06:57 PM#7
TaintedReality
It will push him through =\. Hmm...maybe you can have an invisible unit that you first move using SetUnitPosition, then use SetUnitXY to set the Paladin's position to the position of the invisible unit. So SetUnitXY(Paladin,GetUnitX(InvisibleDude),GetUnitY(InvisibleDude)). Theoretically that should work, but I've never tried it.
01-05-2008, 07:46 PM#8
Burning Rose
Bleh, I may just give up on the idea. Whatever. Thanks for the help anyways though :)
01-05-2008, 09:59 PM#9
Ammorth
You can just order the unit to move to an offset. Its not perfect, but with a bit of rigging, you can make it work nicely.

Since the animations are reset when you move a unit, you need to force it's animation with
Collapse JASS:
native          SetUnitAnimationByIndex     takes unit whichUnit, integer whichAnimation returns nothing

Each model will have its walk animation at a different index, so you will have to test until you get it.

Calling is GUI is as simple as:

Trigger:
Actions
Custom Script: call SetUnitAnimationByIndex(udg_HeroUnit, 1)
Where 1 is the correct animation ID and HeroUnit is the unit.
01-05-2008, 10:27 PM#10
Toadcop
btw @ Ammorth
the feature in your case was\is
war3 frames and you custom period. i mean they are async SO in that async frames you camera get shacked ! do you want the prove ?
ok

create a periodical timer with 0.015 period

and do this things
setcamerposition(x,y,0)
"align camera Z" over (0.01) // otherwise i getted some extreme camera jumps sometimes.

the feature IS what your camera is moving "together" with the terrain position so you can exactly align it to this place xD. yes it's may be a bit confusing.

simple to say. your probleme was "smoothing moving camera" cause it change it's position with every frame (but your code don't align cam Z every frage ;))
get it ?

to achive "perfect" result you must avoid using blizz camera moving/smoothing (idk maybe camera smooth will not screw it up. must be tested) elements.

yes sorry it's bit offtop. but not really =)
01-06-2008, 12:08 AM#11
Burning Rose
Hmm... I'll look at that, thanks.

Well now I'm just confused.
01-06-2008, 03:54 AM#12
TaintedReality
Crap...I think Ammorth is right with the SetUnitAnimationByIndex. Forgot about that, my way was much harder, and might not have actually helped any... o.o