• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Trigger] Terrain/cliff height and camera height - Third Person Camera

Status
Not open for further replies.
Level 11
Joined
Oct 9, 2015
Messages
721
So I looked arround for a while and can't seem to think a solution that works for me, so how can I make the camera adjust to terrain height in a third person camera system?

  • Camera
    • Events
      • Time - Every 0.02 seconds of game time
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 12, do (Actions)
        • Loop - Actions
          • Set Location[(Integer A)] = (Position of Unit[(Integer A)])
          • Set Heigth[(Integer A)] = (Height of (Region centered at Location[(Integer A)] with size (0.50, 0.50)))
          • Camera - Lock camera target for (Player((Integer A))) to Unit[(Integer A)], offset by (0.00, 0.00) using The unit's rotation
          • Camera - Set (Player((Integer A)))'s camera Height Offset to (Heigth[(Integer A)] + 100.00) over 0.50 seconds
          • Custom script: call RemoveLocation(udg_Location[GetForLoopIndexA()])
 
The 'region height' function is misleading, it just calculates the difference between the maximum Y coordinate and the minimum Y coordinate.

To calculate the height at a given location, you'll have to use a JASS native: GetLocationZ

In your case, you would do this:
  • Camera
    • Events
      • Time - Every 0.02 seconds of game time
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 12, do (Actions)
        • Loop - Actions
          • Set Location[(Integer A)] = (Position of Unit[(Integer A)])
          • Custom script: set udg_Height[GetForLoopIndexA()] = GetLocationZ(udg_Location[GetForLoopIndexA()])
          • Camera - Lock camera target for (Player((Integer A))) to Unit[(Integer A)], offset by (0.00, 0.00) using The unit's rotation
          • Camera - Set (Player((Integer A)))'s camera Height Offset to (Height[(Integer A)] + 100.00) over 0.50 seconds
          • Custom script: call RemoveLocation(udg_Location[GetForLoopIndexA()])
Although, it can be difficult to really get the camera system behaving the way you want. Simply setting it to the height of the target isn't sufficient in some cases. For example, if the unit is going down a hill, and your camera's "eye" is at the top of the hill, then your current setup could clip through the ground if you don't set the angle of attack appropriately.

I personally recommend using a system like OppiCam (requires JassNewGenPack). It is a good implementation, works fast, and it is very polished. Give the test map a go and see if it fits your needs. There is nothing wrong with coding it yourself, but sometimes it can be annoying to think of all the corner cases. :)
 
Level 11
Joined
Oct 9, 2015
Messages
721
I have found people talking about this system:
http://www.hiveworkshop.com/forums/jass-resources-412/system-getcamoffset-131434/

however I don't know how to implement it, didn't found any guide either, I'll try the trigger you posted and if it don'ts fits in I'll try to setup this OpiCam, I'll be back and post the results, thanks a lot, you are being very helpful!

Edit:
I tried the trigger you posted, the editor returned an error at the line of "Custom script: set udg_Height[GetForLoopIndexA()] = GetLocationZ(udg_Location[GetForLoopIndexA()])
"
 
GetCamOffset can be used, but it is more geared towards setting camera offsets accurately. You won't really need to worry about that for your camera system. :)

As for the error, I apologize. I wrote down "Height"--but it seems that you named your variable "Heigth". :p

Try this:
  • Custom script: set udg_Heigth[GetForLoopIndexA()] = GetLocationZ(udg_Location[GetForLoopIndexA()])
If it still gets an error, post what the error is and I'll help you out. It isn't uncommon for me to make typos!
 
Level 11
Joined
Oct 9, 2015
Messages
721
Here is an old map of mine which adjusts the Z point of the camera.

View attachment 150904

I tried you map once before, but I could't figure out how you did the job :( I'll try PurgeandFire solution then I'll come back to tell if it worked.

Thanks a lot everyone, you're being very helpful!

EDIT:
The custom script PurgeandFire provided worked just fine, but it is only working for hills and not cliff level, sadly when I go to lower cliff grounds the camera glitches :(

kingkwong: I put some cliff levels up and below in some areas and tested your map and it only works on hills, just like mine :(

If I don't find a solution to bypass clifflevels then maybe I'll have to re-terrain my map to use hills instead of cliffs?
 
Last edited:
If you want a third person camera which is properly aligned to the terrain, you most definately need the GetCamOffset system. Basically, the wc3 camera interpolates between the height values of certain points on the terrain (corners of a grid), to make the camera movement smooth. Simply using GetLocationZ will make the camera appear bumpy, and it will sink through the ground if your character is climbing a hill.

It is very easy to use - the only function you need is GetCamOffset(x,y), which returns the value you need to compensate with. So basically, the height calculation would look the same as in PurgeAndFire's example, except with something like this inside the loop:

Code:
custom script: set udg_X = GetUnitX(udg_Unit)
custom script: set udg_Y = GetUnitY(udg_Unit)
custmo script: call MoveLocation(udg_tmpLoc, udg_X, udg_Y)
custom script: set udg_Height = GetLocationZ(udg_tmpLoc) - GetCameraOffset(udg_X, udg_Y) + GetUnitFlyHeight(udg_Unit) + 100

This also accounts for the units flying height.
 
Level 7
Joined
Nov 19, 2015
Messages
283
I tried you map once before, but I could't figure out how you did the job :( I'll try PurgeandFire solution then I'll come back to tell if it worked.

Thanks a lot everyone, you're being very helpful!

EDIT:
The custom script PurgeandFire provided worked just fine, but it is only working for hills and not cliff level, sadly when I go to lower cliff grounds the camera glitches :(

kingkwong: I put some cliff levels up and below in some areas and tested your map and it only works on hills, just like mine :(

If I don't find a solution to bypass clifflevels then maybe I'll have to re-terrain my map to use hills instead of cliffs?

I've just tested. I added hills and cliff levels in my map and it works fine. Make sure you don't change anything. Also you do know it uses arrow key movement right?
 
GetCamOffset can be used, but it is more geared towards setting camera offsets accurately. You won't really need to worry about that for your camera system. :)
Actually... that depends a lot on the terrain design in his map.

For now, he doen't need it, but as soon as he gets his system going, he should take a look at it.
 
Status
Not open for further replies.
Top