• 🏆 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!

Few problems with First Person Camera.

Status
Not open for further replies.
Level 8
Joined
Apr 17, 2008
Messages
212
Hello,

I long time ago I made a first person camera tutorial here on the hive, but there were always some problems i never seemed to be able to solve.

First of all. When you press Insert or Delete, the camera resets itself. I tried fixing this by changing the event in the "camera base trigger" from "map initialization" to "every ... seconds", but that comes with problems because the camera always stays at the same height and angle, and that didnt work with my other triggers. Any way to disable inserts fuction?

Second, the camera is fixed at 200 or 250 or something. But when the hero enters higher ground, the camera doest go higher with him, it just goes through the terrain. Any way to make the camera hieght adapt to the height of the unit?

And third. How to make a unit invisible. When you have the unit at full size you have the problem you can sometimes see parts of it when using FPC. When set at minimum size you cant see projectiles it makes.

If someone could help me it would be great, and I can improve my tutorial :p
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
The second question is an easy fix, but requires JASS.
Well, in my opinion it requires JASS (as custom scripts are JASS for me, not GUI).

  • Custom script: set udg_ZHeight = GetLocationZ(udg_Loc)
  • Camera - Set Player X's camera Height Offset to ZHeight + 80. over 0.00 seconds
I chose "ZHeight + 80." because that's what I use in one of my own systems.
Of course, my system is in JASS an utilizes RtC (mouse-movement), but it's still pretty much the same concerning the camera.


For the third question, would:
  • Unit - Hide unit
work?

If not, you might want to add the ability "invisibility" to the unit (I'm sorry, I did not quite understand the problem so this might not be what you're looking for).


I cannot help you with the first problem :/
Never noticed it up till now, and it is indeed rather annoying.
The only thing I can advice you is to use a -debug camera command or something.
 
Level 8
Joined
Apr 17, 2008
Messages
212
The second question is an easy fix, but requires JASS.
Well, in my opinion it requires JASS (as custom scripts are JASS for me, not GUI).

  • Custom script: set udg_ZHeight = GetLocationZ(udg_Loc)
  • Camera - Set Player X's camera Height Offset to ZHeight + 80. over 0.00 seconds
I chose "ZHeight + 80." because that's what I use in one of my own systems.
Of course, my system is in JASS an utilizes RtC (mouse-movement), but it's still pretty much the same concerning the camera.


For the third question, would:
  • Unit - Hide unit
work?

If not, you might want to add the ability "invisibility" to the unit (I'm sorry, I did not quite understand the problem so this might not be what you're looking for).


I cannot help you with the first problem :/
Never noticed it up till now, and it is indeed rather annoying.
The only thing I can advice you is to use a -debug camera command or something.

Thnx I'll try the solution for the second.
EDIT: You want me to make a variable called Zheight?

What I mean with invisible, is that it is like it has no model attached, completely transparent etc. Like in any First person game. You cant actually see yourself except for like a hand with a sword. Thats what i want. I want the model of the unit to be gone, but still a portrait.
EDIT: Hide doesnt work, as expected.


And what do you mean with debug camera command lol?
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Yes, the variable ZHeight must be a real variable.

In warcraft it's impossible to just show the hand of a real model, unless you make the model huge... and the model is only the hand.
Most people use fade filters to show a hand/gun/whatever.
Set the model to "_" (will result in "none", so no model) and for the portrait you can easily use a unit that's somewhere far away in the corner of the map. As long as people THINK they've selected their own unit, that's good enough.


You know, debug-command... when the camera gets ruined because of the delete/insert-button (I tested this with my system and it got completely ruined), you can reset the default camera values by typing -cam debug or something.
 
Level 8
Joined
Apr 17, 2008
Messages
212
Yes, the variable ZHeight must be a real variable.

I must also make an udg_Loc (0r something) variable?

In warcraft it's impossible to just show the hand of a real model, unless you make the model huge... and the model is only the hand.
Most people use fade filters to show a hand/gun/whatever.
Set the model to "_" (will result in "none", so no model) and for the portrait you can easily use a unit that's somewhere far away in the corner of the map. As long as people THINK they've selected their own unit, that's good enough.

The no model and portrait thing won't work. You're controlling the unit that's "behind" the camera, so if you needed to select another unit for the portrait you couln't controll the actual hero anymore.

You know, debug-command... when the camera gets ruined because of the delete/insert-button (I tested this with my system and it got completely ruined), you can reset the default camera values by typing -cam debug or something.

Ah yes ofc. I've done that already, but I wanted to know if there was an actual fix.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
I must also make an udg_Loc (0r something) variable?
A point-variable called "Loc", indeed.
It's used to remove leaks (and leaks are the main problem of people who mod warcraft 3, as they're one of the main reasons for lag).

Magamdy said:
The no model and portrait thing won't work. You're controlling the unit that's "behind" the camera, so if you needed to select another unit for the portrait you couln't controll the actual hero anymore.
What do you mean, you can't control the actual hero anymore? With your method, you want the hero to have a model although you can't see the model? What's the difference with there being no model in the first place? You can't click what you can't see, right?
I wonder, how would you click your regular portrait back with your method and control it back again?

Magamdy said:
Ah yes ofc. I've done that already, but I wanted to know if there was an actual fix.
Since you cannot detect those buttons, the only 'fix' is that you compare the actual camera values with the theoretical camera values (every 0.1 /0.05 seconds or something).
e.g.: you press delete and the camera value "Z Offset" or something changes, the trigger would then see the actual cam value is 0 while it should be 100.
You can then reset the camera values.

No fool-proof method exists afaik.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Uhh, to the location of your unit :p

Have you never worked with location variables before? I can assure you that it pays of (because you know... memory leaks, you always have to fix them and the only way of doing so is with these variables and custom scripts).

  • Set Loc = Position of your unit
  • Custom script: set udg_ZHeight = GetLocationZ(udg_Loc)
  • Camera - Set Player X's camera Height Offset to ZHeight + 80. over 0.00 seconds
  • Custom script: call RemoveLocation(udg_Loc)
That's the full code, but I thought you were already cleaning leaks so I left out the first and last action.
 
Level 8
Joined
Apr 17, 2008
Messages
212
Uhh, to the location of your unit :p

Have you never worked with location variables before? I can assure you that it pays of (because you know... memory leaks, you always have to fix them and the only way of doing so is with these variables and custom scripts).

  • set Loc = Position of your unit
  • Custom script: set udg_ZHeight = GetLocationZ(udg_Loc)
  • Camera - Set Player X's camera Height Offset to ZHeight + 80. over 0.00 seconds
  • Custom script: call RemoveLocation(udg_Loc)
That's the full code, but I thought you were already cleaning leaks so I left out the first and last action.

Well, actually I just started destroying triggers :p

One more question. This may sound really stupid..... But how to give a player a fixed race xD Mine seem to change always. I dont know if i need to do it with triggers or if im doing something wrong in player options...

EDIT: It still doesnt work :( I dunno what I'm doing wrong. Are you sure you understand what I wanted to do? (For the camera trigger u use arithmetic right?)
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
AAAAAAAAH!!! I never noted that stupid little check mark >.< Thanks!!! Anyway, any idea what I'm doing wrong with your JASS script?
Depends, which JASS script? :D
The call RemoveLocation one, or the GetLocationZ one?

There are a lot of things that can go wrong with JASS scripts:
  • JASS is Case Sensitive, this includes everything from "call" to the variable names.
  • The variable name must be exact (With "udg_" in front of it).
  • Do all variables exist and are set to the correct value?

I just decided to give you a test-map so you can check it out yourself ^^
If that doesn't clear things up, perhaps you could send me your map :/

(I hope I uploaded the correct file :X).
 

Attachments

  • Camera Map.w3x
    22.7 KB · Views: 103
Level 8
Joined
Apr 17, 2008
Messages
212
It is amazing! It is a miracle!! It works! You know what the problems was? My event was set to map initialization >_>

Sir, you just fixed the biggest flaw in my system. Thanks. I will include it in my tutorial and give a credit to you :DD

The only problems are bridges. The script doesn't see them as terrain so it adjusts to the hieght of the water underneath it. Buuut thats easily fixable ^^

Thanks again ^^ I've searched for a solution for this shit for soo long xD
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Glad I could help ^^

If you do not like math, you might want to read the problem and then scroll down to the trigger on how to fix it!
(And perhaps check the screenies).

And since this is for a tutorial, I hope I'm not disturbing you with this, but there's still one problem.
When you get really high (a huge hill) with such a camera, warcraft is being stupid and the camera height will be completely screwed.

To illustrate this, here is my system WITHOUT anything to cover up the bug (screenshots resized to 1200x900).


wonormal.jpg


This is how it should be. I will always show that same arc for you to use as a reference point.


womedium.jpg


At medium heights, it still reacts okay.
The problem here is the screeny itself: you can't really see it, but the camera is still higher than it needs to be.
The next screeny will make that pretty clear though.


wohigh.jpg


Dude, he's flying now... the highest patch of ground you can see is the same height as where I'm standing.
This is NOT what we want from a camera system.


How to fix this?
Well, umm... it's actually really easy.
We know this:
  • At normal height (low), the system functions perfectly and needs nearly no height change.
  • At medium height, the system is a bit stupid and needs minor/avarage height change.
  • At great heights, the system is completely bugged and needs an heavy height change.

After a bit of fidling with numbers, I found that this formula pretty much covers it:
1- (TerrainZ/(TerrainZ+256))

Yeah, okay... that's not really clear.
Basically this will result in a number from 0.00 to 1.00.
If the terrain is really high, then the number will be lower.
If the terrain is low (or normal), the number will edge towards 1.00

If you multiply that with the actual terrain height, you get the camera height :D

In triggers:

  • Actions
    • Custom script: set udg_TerrainZ = GetLocationZ(udg_Loc)
    • Set Modifier = (1.00 - (TerrainZ / (TerrainZ + 256.00)))
    • Set CameraZ = (TerrainZ x Modifier)
    • Camera - Set Player 1 (Red)'s camera Height Offset to CameraZ over 0.00 seconds

Examples:
  • TerrainZ = 1000 (high)
  • Modifier = 1-(1000/1256) = 0.204
  • CameraZ = 0.204 * 1000 = 204
Due to the large height, the difference will be pretty significant.

  • TerrainZ = 100 (pretty normal)
  • Modifier = 1-(100/356) = 0.72
  • CameraZ = 0.72 * 100 = 72
As you can see: the difference is barely noticable here.



In-game results:

withnormal.jpg

No change from the first screeny (without the system), apart from the fact that I screenshotted the other side of the arc ^^


withmedium.jpg

Not that much change as well, but you can see a difference here.


withhigh.jpg

Aha! I'm standing on the ground, just like I should!
Don't be afraid that the height difference might be too extreme: I'm just looking down (easier to do because I use RtC, but this map cannot be played with regular warcraft :/).


Small note: when the hill is too big, then the modifier might get too small. The thing is that the height rarely needs to go to such extends.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Variable NameVariable TypeArray?Variable Function
LocPointNoTo remove location leaks
TerrainZRealNoTo calculate the terrain height
CameraZRealNoTo set the camera height to the correct value
ModifierRealNoTo debug the camera height

I hope I didn't foget anything.

The trigger should be:
  • Actions
    • Custom script: set udg_TerrainZ = GetLocationZ(udg_Loc)
    • Set Modifier = (1.00 - (TerrainZ / (TerrainZ + 256.00)))
    • Set CameraZ = (TerrainZ x Modifier)
    • Camera - Set Player 1 (Red)'s camera Height Offset to CameraZ over 0.00 seconds
Because without the modifier, large hills will bug the camera.

And the trigger to debug the camera once something strange happens (delete/insert has been pressed, or the player scrolled) is:

  • Debugging Camera
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • -------- Camera has been bugged? --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Distance to target of the current camera view) Greater than 120.00
        • Then - Actions
          • Game - Display to (All players) for 7.00 seconds the text: Camera reset
          • -------- Setting main camera values --------
          • Camera - Apply Camera 001 <gen> for Player 1 (Red) over 0.00 seconds
          • -------- Setting the location variable again --------
          • Set Loc = (Point(X, Y))
          • -------- Setting camera to the correct location --------
          • Camera - Pan camera for Player 1 (Red) to Loc over 0.00 seconds
          • -------- Setting camera to the correct height --------
          • Custom script: set udg_ZHeight = GetLocationZ(udg_Loc)
          • Camera - Set Player 1 (Red)'s camera Height Offset to (ZHeight + 80.00) over 0.00 seconds
          • -------- Removing the leak --------
          • Custom script: call RemoveLocation(udg_Loc)
        • Else - Actions
Although this trigger depends from system to system.
I just happened to use 100. as my Distance to Target-value.

Note: this does not work for multiple players, the trigger below would be correct then.
The problem is... I don't know if it will cause a server split or not :/


  • Debugging Camera
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • -------- Camera has been bugged? --------
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Custom script: if GetLocalPlayer() == GetEnumPlayer() then
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance to target of the current camera view) Greater than 120.00
            • Then - Actions
              • Game - Display to (Player group((Picked player))) for 7.00 seconds the text: Camera reset
              • -------- Setting main camera values --------
              • Camera - Apply Camera 001 <gen> for (Picked player) over 0.00 seconds
              • -------- Setting the location variable again --------
              • Set Loc = Position of Hero[Player number of (Picked Player)]
              • -------- Setting camera to the correct location --------
              • Camera - Pan camera for (Picked player) to Loc over 0.00 seconds
              • -------- Setting camera to the correct height --------
              • Custom script: set udg_ZHeight = GetLocationZ(udg_Loc)
              • Camera - Set (Picked Player's) camera Height Offset to (ZHeight + 80.00) over 0.00 seconds
              • -------- Removing the leak --------
              • Custom script: call RemoveLocation(udg_Loc)
            • Else - Actions
          • Custom script: endif
 
Level 8
Joined
Apr 17, 2008
Messages
212
Do you have to adapt the value of the first trigger to your standart height (80 for you) because for me its 200. Also, does it replace the tirgger you gave me earlier?

I also cant get the second trigger as you placed it here. With Point(x, Y) etc..
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Yes, it does replace the first trigger (the first trigger I gave will bug the camera when you're on a high hill).

And the second trigger: the location should be that of your unit.
The Point(X, Y) was for my example (because I used coordinates instead of a unit :/).
You can see that trigger in the map I posted a bit earlier.
 
Level 8
Joined
Apr 17, 2008
Messages
212
Yes, it does replace the first trigger (the first trigger I gave will bug the camera when you're on a high hill).

And the second trigger: the location should be that of your unit.
The Point(X, Y) was for my example (because I used coordinates instead of a unit :/).
You can see that trigger in the map I posted a bit earlier.

I'm pretty sure the first trigger needs another vlaue because with me it just goes underneath the terrain...
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
"The entry you are trying to display has expired or does not exist"? O_O
- nevermind, you put "value" at the end of your URL so I removed it and it worked :D

Edit: it works for me, the camera does rise/lower when you walk over higher terrain.
The only problem I see is that the timer should be set to every 0.04 or 0.03 seconds (otherwise it isn't very fluid).

Pretty neat idea actually... :p
 
Status
Not open for further replies.
Top