- Joined
- Mar 29, 2012
- Messages
- 530
How to make a projectile to properly home-in to a target unit?
My problem is about the mathematical calculation.
Currently, I've managed to make the projectile move to a 3D point towards its facing direction with offset by [speed base] plus offset by [turn acceleration] towards the target unit --> on every frame update (32 iteration per second). But sometimes, if the projectile missed the target unit, it will just spin around the target because maybe the [turn acceleration] is too low to turn the projectile towards target.
If I set [turn acceleration] to a higher value, the projectile would not have a good curve.
How do I achieve this?
My current idea:
I might make the [turn acceleration] to have dynamic value, for example, the farther the projectile is from the target unit, [turn acceleration] will accordingly increase. But I have no idea how to achieve this, mathematically.
My problem is about the mathematical calculation.
Currently, I've managed to make the projectile move to a 3D point towards its facing direction with offset by [speed base] plus offset by [turn acceleration] towards the target unit --> on every frame update (32 iteration per second). But sometimes, if the projectile missed the target unit, it will just spin around the target because maybe the [turn acceleration] is too low to turn the projectile towards target.
If I set [turn acceleration] to a higher value, the projectile would not have a good curve.
How do I achieve this?
JASS:
set vectorX = .targetX - .posX
set vectorY = .targetY - .posY
set vectorZ = .targetZ - .posZ
set dist = GetDistance2D(vectorX, vectorY)
set angleZ = AngleZ(vectorX, vectorY)
set anglePointsZ = AnglePointsZ(dist, vectorZ)
set .posX = ((.posX + ROCKETS_SPEED_BASE[.node.level] * Cos(.roll) * Cos(.pitch))) + ROCKETS_TURN_ACCELERATION[.node.level] * Cos(angleZ) * Cos(anglePointsZ)
set .posY = ((.posY + ROCKETS_SPEED_BASE[.node.level] * Sin(.roll) * Cos(.pitch))) + ROCKETS_TURN_ACCELERATION[.node.level] * Sin(angleZ) * Cos(anglePointsZ)
set .posZ = ((.posZ + ROCKETS_SPEED_BASE[.node.level] * Sin(.pitch))) + ROCKETS_TURN_ACCELERATION[.node.level] * Sin(anglePointsZ)
set vectorX = .posX - .lastPosX
set vectorY = .posY - .lastPosY
set vectorZ = .posZ - .lastPosZ
call SetEffectOrientation3D(vectorX, vectorY, vectorZ)
set .pitch = AnglePointsZ(GetDistance2D(vectorX, vectorY), vectorZ)
JASS:
function GetDistance2D takes real x, real y returns real
return SquareRoot(x * x + y * y)
endfunction
function GetDistance3D takes real x, real y, real z returns real
return SquareRoot(x * x + y * y + z * z)
endfunction
function AngleZ takes real x, real y returns real
return Atan2(y, x)
endfunction
function AnglePointsZ takes real distance2D, real z returns real
return Atan2(z, distance2D)
endfunction
function GetTerrainZ takes real x, real y returns real
call MoveLocation(zLoc, x, y)
return GetLocationZ(zLoc)
endfunction
function GetUnitTerrainZ takes unit targetUnit, real x, real y returns real
local real height
set height = GetUnitFlyHeight(targetUnit) + TARGET_CHEST_HEIGHT
return height + GetTerrainZ(x, y)
endfunction
function GetDistanceToUnit3D takes real x, real y, real z, unit targetUnit returns real
local real targetX = GetUnitX(targetUnit)
local real targetY = GetUnitY(targetUnit)
local real targetZ = GetUnitTerrainZ(targetUnit, targetX, targetY)
return GetDistance3D(targetX-x, targetY-y, targetZ-z)
endfunction
function SetEffectOrientation3D takes real x, real y, real z returns nothing
// by Wareditor
local real ax
local real ay
local real px
local real py
if x == 0 and y == 0 then
if z > 0 then
set ax = -bj_PI*0.5
else
set ax = bj_PI*0.5
endif
elseif z != 0 then
set ax = RAbsBJ(x)
set ay = RAbsBJ(y)
set px = ax / (ax + ay)
set py = 1 - px
if y == 0 then
set ax = 0
else
set ax = Atan(z/y)*py
endif
if x == 0 then
set ay = 0
else
set ay = -Atan(z/x)*px
endif
endif
set .pitch = ay
set .roll = Atan2(y, x)
call BlzSetSpecialEffectOrientation(.rocket, ax, .lastPitch, .roll)
call BlzSetSpecialEffectPitch(.rocket, .pitch)
set .lastPitch = .pitch
endfunction
My current idea:
I might make the [turn acceleration] to have dynamic value, for example, the farther the projectile is from the target unit, [turn acceleration] will accordingly increase. But I have no idea how to achieve this, mathematically.