Hi! I have recently begun creating my own interception missile. But im stuck on how i can make it turn realistically, I have tried to create my own script for this using my own math but it has proven to not work as intended
(my script)
function Ai.Calculate_Direction(Projectile,Target)
local Max_Turn_Rate = math.rad(Config.Turn_Rate_Per_Second.Value / Config.Ticks_Per_Second.Value)
local Direction = CFrame.lookAt(Projectile.CFrame.Position,Target.CFrame.Position).Position
local x,y,z = Projectile.CFrame.Rotation:ToOrientation()
local Orientation = Vector3.new(x,y,z)
local difference = Direction - Orientation
print(Direction," DIR")
print(Orientation," ORIEN")
local function TurnRate(number)
return math.clamp(number,-Max_Turn_Rate,Max_Turn_Rate)
end
return CFrame.Angles(TurnRate (x + difference.X),TurnRate(x + difference.Y),TurnRate(z + difference.Z))
end
(i forgor to make it move)
I would like to know if i can make a better version of my script or of there is a better way of doing this
Hey, if you want a constant angular speed turning through CFrame (not physics) then you can use this CFrame technique below.
The below aligns a parts up vector to the new surface normal upvector.
For your case you can align the parts look vector to the direction of the target (target - missilePos).
Currently your calculations do not make too much sense unless you were to convert Direction to orientation. Even if you choose this method you will face issues in the future when handling orientation number range limit [-180, 180].
After some time i have created my prototype missile wich now works as intended (sort of only a few fixes)
function Ai.Calculate_Direction(Projectile, Target)
local Max_Turn_Rate = math.rad(Config.Turn_Rate_Per_Second.Value / Config.Ticks_Per_Second.Value)
local dx, dy, dz = CFrame.lookAt(Projectile.CFrame.Position, Target.CFrame.Position).Rotation:ToOrientation()
local ox, oy, oz = Projectile.CFrame.Rotation:ToOrientation()
local function NormalizeAngle(angle)
return (angle + math.pi) % (2 * math.pi) - math.pi
end
local Direction = Vector3.new(dx, dy, dz)
local Orientation = Vector3.new(ox, oy, oz)
local difference = Vector3.new(
NormalizeAngle(Direction.X - Orientation.X),
NormalizeAngle(Direction.Y - Orientation.Y),
NormalizeAngle(Direction.Z - Orientation.Z)
)
local function TurnRate(number)
return math.clamp(number, -Max_Turn_Rate, Max_Turn_Rate)
end
return CFrame.Angles(TurnRate(difference.X), TurnRate(difference.Y), TurnRate(difference.Z))
end