HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Fluent Arial Motion

01-08-2008, 05:38 AM#1
xombie
I'm trying to simulate a fluent air-motion, meaning not having a unit's height fluctuate radically if the terrain height changes - just a smooth "straight" motion.

call SetUnitFlyHeight(TESTER, 200 + Z - z, 0)
This is the call that dictates all of that. Depending on what values I have for Z it goes from fluent to jagged motion. My 'z' variable is the LocationZ of TESTER's current location.

set Z = GetLocationZ(Location(GetUnitX(TESTER), GetUnitY(TESTER)))
If I set 'Z' like this right when TESTER is created, and never change it, I get the fluent motion I desire. If I set 'Z' before moving TESTER every interval, it doesn't work. To me it should bear the same results, either way. My question I guess is why won't the second way work?

If it helps, here is a brief summary of my code:

Collapse JASS:
globals
    unit TESTER
    real Z
endglobals

private function main takes nothing returns nothing
    local real oldX = GetUnitX(TESTER)
    local real oldY = GetUnitY(TESTER)
    local real newX = oldX + 10 * Cos(bj_PI/4) // 45 degrees
    local real newY = oldY + 10 * Sin(bj_PI/4)
    local real z = GetLocationZ(Location(newX, newY))

    //set Z = GetLocationZ(Location(oldX, oldY))

    call SetUnitX(TESTER, newX)
    call SetUnitY(TESTER, newY)
    call SetUnitFlyHeight(TESTER, 200 + Z - z, 0)
endfunction

private function init takes nothing returns nothing
    local timer t = CreateTimer()
    
    set TESTER = CreateUnit(Player(0), 'hpea', -2700, -2500, 0)
    set Z = GetLocationZ(Location(-2700, -2500))

    call TimerStart(t, 0.025, true, function main)
endfunction

Its only a test-map, I ignored memory leaks.
01-08-2008, 05:58 AM#2
Ammorth
Make sure the unit has a movement type of foot and you are using the "Fly Trick" (adding and removing crow form). This gets rid of the smoothing of fly heights created by uneven terrain.
01-08-2008, 06:00 AM#3
MaD[Lion]
There have already been alot of this kind of things, made in the past. you may wanna check the resources for systems that move units in 3d.
01-08-2008, 02:18 PM#4
xombie
Quote:
Originally Posted by Ammorth
This gets rid of the smoothing of fly heights created by uneven terrain.

No no, I mean adjusting a unit's flyheight based on the change in terrain-level so that the unit (while flying) "seems" unaffected by changes in the terrain.

Quote:
Originally Posted by MaD[Lion]
There have already been alot of this kind of things, made in the past. you may wanna check the resources for systems that move units in 3d.

As I said I've gotten it to work already, the question was why doesn't this work when I constantly update the "reference point" as opposed to having it constant.
01-08-2008, 02:25 PM#5
Tide-Arc Ephemera
What if you have some random super-massive hill somewhere in your map? I know it's a stupid question, but what will happen?
01-08-2008, 02:30 PM#6
xombie
Quote:
Originally Posted by Tide-Arc Ephemera
What if you have some random super-massive hill somewhere in your map? I know it's a stupid question, but what will happen?

The difference in the terrain height will be incredibly large, therefore decreasing the flyheight far below 0. It would basically make the unit go through said mountain - which is what I would expect. What does this have to do with anything?

Basically waht I'm asking is why is it that when I set the reference height 'Z' upon the unit's creation, everything works as expected - yet when I update the reference height every interval, the unit TESTER doesn't seem to have his height adjusted according to the change in terrain. The change in terrain is the difference of [b]LocationZ[b]'s from one point to another, and I wish to 'add' this difference to a unit's fly-height - thus keeping him at a steady overall Z (fly-height + terrain-height).
01-08-2008, 03:28 PM#8
xombie
I could tell you right now that that wouldn't work.

The problem is with my reference point. When I set my reference point as the LocationZ of TESTER when it is created, everything works fine, but when I update the reference point (which mathematically should work) then I get problems.
01-08-2008, 04:58 PM#10
xombie
Okay well for all of those who do not know how to calculate a unit's fly-height based on a change in terrain-height (so that the unit doesn't wave up and down with the terrain) it goes as follows, and its really easy:

LocationZ of the first location subtract the LocationZ of the second location added to the desired fly-height.

This means that if the terrain is a downwards slope, then a unit will have increasing fly-height, causing him to remain at the same general level. This is what I am trying to achieve.

The problem that I am having is that for some reason doing this:
Collapse JASS:
call SetUnitFlyHeight(<unit>, genHeight + oldZ - newZ, 0)

Does not give me the result of the unit getting increasing fly-height, instead the unit seems to follow the terrain regardless. oldZ represents the height (Z) of the terrain before the unit's movement, while newZ represents the height afterwards.

At the same time, using a fixed oldZ does seem to work, though mathematically they should both work. Does anybody know why my first method is not giving the expected results?

Whether it be a mistake of mine, or something else I do not know about, I don't care, I just would like to know why it isn't working. I'm not at home right now, if I was I would be doing more testing. I think I have an idea of why it isn't working and that is because I need to incorperate GetUnitFlyHeight into the equation. I cannot test this, if somebody else could that would be fantastic I'm at university right now and I should be back around...

Well I'm not sure - I will try to check this post. As I think about it I'm more and more certain that the GetUnitFlyHeight is what I'm missing so, if you, Need_O2 would so kind as to check it for me I'd be much appreciative.
01-08-2008, 10:14 PM#11
Ammorth
Post your test map so we can see what you mean by uneven z height.

The idea is simple:

Create unit with a "true" z height (this means the units height in relation to spacial units, instead of in relation to terrain).
Collapse JASS:
set trueZ = 800 // true z of unit

Each time-step, move the unit, and subtract the terrain height from the true height to find the remaining height, or flying height.
Collapse JASS:
call MoveLocation(UnitPosition, NewX, NewY)
set terrainZ = GetLocationZ(UnitPosition)
set FlyHeight = trueZ - terrainZ

Now, set the flying height of the unit to the calculated flying height
Collapse JASS:
call SetUnitFlyHeight(YourUnit, FlyHeight, 0)

And that is all.
01-08-2008, 10:35 PM#12
xombie
Yes, I've solved the problem - I was being stupid about it - probably just tired.

Collapse JASS:
function GetUnitZ takes unit whichUnit returns real
    local location loc = GetUnitLoc(whichUnit)
    local real z = GetLocationZ(loc) + GetUnitFlyHeight(whichUnit)
    call RemoveLocation(loc)
    set loc = null
    return z
endfunction

function SetUnitZ takes unit whichUnit, real newZ returns nothing
    local location loc = GetUnitLoc(whichUnit)
    local real fly = newZ - GetLocationZ(loc)
    call RemoveLocation(loc)
    call SetUnitFlyHeight(whichUnit, fly, 0)
    set loc = null
endfunction

Those can be used to set adjust it nicely. If you want to check whether or not the unit is touching the ground then you just have to check whether or not GetUnitZ is equal to the terrain-height at the unit's location.
01-09-2008, 10:25 PM#13
Ammorth
When you optimize, I suggest using a single global location and utilize the MoveLocation native.
01-10-2008, 12:34 AM#14
xombie
Indeed good idea.