| 01-04-2008, 09:38 PM | #1 |
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 | |
Quote:
There's a function called GetLocationZ. Unfortunately I'm not sure if there's a GUI equivalent. 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 |
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, 06:32 PM | #5 | |
Quote:
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: 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
![]() Conditions
![]() 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 secondsI 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 |
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 |
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 |
Bleh, I may just give up on the idea. Whatever. Thanks for the help anyways though :) |
| 01-05-2008, 09:59 PM | #9 |
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 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) |
| 01-05-2008, 10:27 PM | #10 |
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 |
Hmm... I'll look at that, thanks. Well now I'm just confused. |
| 01-06-2008, 03:54 AM | #12 |
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 |
