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

Finding the Z Axis

Status
Not open for further replies.
Level 10
Joined
Sep 21, 2007
Messages
517
The Z axis, in wc3, is found by the LocZ + Height of unit (model file, this is needed for my type of map) + Unit Flying height right?

then to calculate the Z increased by each iteration, you do SpeedPerIteration*Sin(ZAxis)

anything i missed in here?

i think that to find the ZAxis should be replaced by the ZAngle in the formula above, but im not sure.

ty for your time
 
Level 10
Joined
Sep 21, 2007
Messages
517
hey dgriff ), well im going to do something that is similar to shooting in a 3d cartesian plane, using vectors ofc, but instead of using a unit and moving it all the way, im using an x,y,z vector to check if the path between 2 units contains destructables that have a Z that is higher or equal to the vectors Z, so like a bullets path, would that bullet impact with the destructable or not? depending on the destructables occluder height+locZ, and the height of the bullet/particle+its locZ.

in all simplicity, im checking if the path between 2 units contain any destructables depending on the first units initial height, but resembling the movement of a bullet.

i already did all the work, i just need to know by what height should i increase the initial height every iteration?

just tell me how to get the Z Angle and Z Axis, il be able to finish up the rest, cus il just confuse u with my descriptions :p
 
Level 4
Joined
Dec 9, 2008
Messages
52
Here's how you can do this without any iteration.

So I assume that once you shoot, you generate a group of widgets that *could* get hit. Then you want to check each widget in order. That is you want to check the closest widget first, farthest widget last, and then just stop the bullet once it hits. Ok lets assume you have that. Now lets figure out if a unit is actually hit.

Here's the simple way that you've already figured out:

If widget's height > bullet height, then the widget is hit. The widget height = GetLocationZ(widgetlocation) + GetDestructableOccluderHeight(widget) + GetUnitFlyHeight(widget). The bullet height = 200 (or whatever random number you pick, perhaps based on the shooter's height). Ok we got that. But you want to know how high the bullet will *actually* be by the time you hit the target, right?

Here's how you figure out the bullet's height:

Height_at_given_Time = Initial Height + Initial Vertical Velocity * Time + (1/2)Gravity*Time^2

You have the initial height (height of your shooter), you have the initial vertical velocity (you get to make that up), you have gravity (you get to make that up). You just need time and height. You can get that, too:

Distance= Velocity*Time

Distance you can calculate between the point of the shooter and the point of the target (using DistanceBetweenPoints()), velocity you get to make up, and time we can now replace with the two things we do know.

Time = Distance/Velocity

So now if you substitute Distance/Velocity for time you have this equation:

Height_at_given_Time = Initial Height + Initial Vertical Velocity * (Distance/horizontal_velocity)+ (1/2)Gravity*(Distance/horizontal_velocity)^2

Height_at_given_time is now your bullet height once it reaches the widget. Now you're set. If widget's height > bullet height, then the widget is hit. You don't have to iterate anything at all, you can calculate all this the moment you cast your spell.

So the jass code for this would be:
Code:
local location shooter_location = GetUnitLoc(shooter)
local location target_location = GetUnitLoc(target)
local real horizontal_velocity = however fast you want the bullet to move
local real vertical_velocity = however fast you want the bullet to be moving up
local real gravity = whatever you want
local real shooter_height = GetLocationZ(shooter_location) + GetDestructableOccluderHeight(shooter) + GetUnitFlyHeight(shooter)
local real target_height = GetLocationZ(target_location) + GetDestructableOccluderHeight(target) + GetUnitFlyHeight(target)
local real distance = DistanceBetweenPoints(target_location,shooter_location)
local real bullet_height_on_impact =  shooter_height +  vertical_velocity* (distance/horizontal_velocity)+ (1/2)gravity*Pow(distance/horizontal_velocity,2)
if (bullet_height_on_impact < target_height) and (bullet_height_on_impact > 0) then
.... // whatever you do to a target that is hit

Note: I didn't actually check any of this. So it'd be best to do everything again yourself =P
 
Level 4
Joined
Dec 9, 2008
Messages
52
If you remove gravity, the bullet keeps flying higher and higher in a straight line. I'll describe the formula without gravity and do it in terms of "iterations".

Every iteration, you increase the bullet's height by an amount. If you didnt do this, the bullet's height would remain the same, right? The amount you increase the bullet's height every "iteration" is called the bullet's vertical velocity. So if your height starts at 0 and your vertical velocity is 10, then after 1 iteration your height will be 10 and your vertical velocity will be 10. After 2 iterations your height will be 20 and your vertical velocity will still be 10. After 3 iterations your height will be 30 and your vertical velocity will STILL be 10. See the pattern? The formula to generalize this would be "height = vertical_velocity*iterations". Ok I think that's clear enough.

Now gravity. Gravity doesn't affect your unit's height, it affects your unit's vertical velocity. Lets do the same example again. Height starts at 0, vertical velocity is 10, but gravity is -1. After 1 iteration, your height is 10, your vertical velocity is 9, and gravity is still -1. After 2 iterations, your height is 19, your vertical velocity is 8, and gravity is still -1. After 3 iterations your height is 27, vertical velocity is 7, and gravity is still -1. Now lets look at what has happened. Your height has gone up each time, your vertical velocity has gone down each time, and gravity has stayed the same. If we keep doing this, your vertical velocity will at some point turn negative. This is the point when your height starts decreasing. That is, at some point the bullet will stop going up and start falling. We can generalize this formula to be Height = vertical_velocity*iterations + 1/2*gravity*iterations^2. The few parts are the same as the simpler equation without gravity, and then the gravity part gets tricky. I don't really have a good way of explaining why that last part is so. Oh well.

Well rant aside, here's what you asked for.

Height_at_given_Time = Initial Height + Initial Vertical Velocity * (Distance/horizontal_velocity)+ (1/2)*Gravity*(Distance/horizontal_velocity)^2

Set gravity = 0

Height_at_given_Time = Initial Height + Initial Vertical Velocity * (Distance/horizontal_velocity)+ (1/2)*0*(Distance/horizontal_velocity)^2

Height_at_given_Time = Initial Height + Initial Vertical Velocity * (Distance/horizontal_velocity) + 0

Height = Initial Height + Vertical Velocity * Time. The longer the bullet is moving, the higher it gets. You probably won't hit anything.
 
Level 10
Joined
Sep 21, 2007
Messages
517
can u remove time from the equation, hmm, altho this math is amazing for a particle sysytem, u should create one )

also if gravity is 0 then anything multiplited by 0 = 0, so would that cause any problems?

btw YourNameHere, if you use speed, it would have to change based on angle, since im using it to decrease/increase height :/
 
Level 4
Joined
Dec 9, 2008
Messages
52
Ok I think I misunderstood a bit. So you want a straight line from your source moving at an angle towards your obstacle? And if the line touches that obstacle you want to know?

If so, you get the distance between the source and the obstacle. Then you get the height of the obstacle. Then you check if Atan(height/distance) > your angle. If it is, then that means you hit it.

Here it is in jass:
Code:
local location shooter_location = getunitloc(shooter)
local location target_location = getunitloc(target)
local real shooter_height = GetLocationZ(shooter_location) + GetDestructableOccluderHeight(shooter) + GetUnitFlyHeight(shooter)
local real target_height = GetLocationZ(target_location) + GetDestructableOccluderHeight(target) + GetUnitFlyHeight(target)
local real angle = 45 // or whatever value you plan on this being
local real height = target_height - shooter_height
local real distance = DistanceBetweenPoints(target_location,shooter_location)
if Atan(height/distance)*bj_RADTODEG > angle then
.... you hit it


This is a solution with no gravity and no time.
 
Level 10
Joined
Sep 21, 2007
Messages
517
thanks guys, but since im making this for an FPS, there wont be any particles going on, and i found a really good solution to see if a destructable blocks the view of the targeted unit or not, by taking the locZ of the unit and its model height, and the destructables occluder height + LocZ, if destructables Z >= the Z of the unit being shooted, then that means the shooter cannot see the shooted :) this is cus u can select units through destructables/doodads :(

btw simply Amazing solution you proposed dgriff, the angles one, the only issue here is that i cant get the correct angle, but il try to mess with it )

anyhow, how do u guys like my solution?

edit: i think il use urs Dgriff )
 
Last edited:
Status
Not open for further replies.
Top