So I am making a tower defense game and for a better feel of the game, the bullets of the game don’t reach their target instantly
I don’t really know how to go about making a script that calculates where the turret should aim. The turret shoots bullets that go 15 studs a second and the enemies come out at 5 studs a second. Can someone suggest a way to calculate which direction the turret needs to aim?
I tried to calculate how many studs the enemies would have traveled with enemy’s walkspeed divided by the bullets speed times the distance between the enemy and the turret but I think that is completely wrong.
local TargetAim = EnemyCFrame * CFrame.new(0,0,-EnemySpeedInStuds +(BulletSpeedinStuds/EnemySpeedInStuds))
That’s just some rough calculations and can bug out on corners, but i think you get the idea, just get the velocity/movement direction of the enemy and use its speed to determinate where exactly should the turret shoot
I’d recommend simply faking it if you can, add a task.delay(0.25, function() target.health -= damage end)) where 0.25 is approximately how long a bullet takes. Still fire a bullet but purely for looks so you always do damage and aren’t reliant on projectiles which can be unpredictable.
I think I would still need to know how bullet moves or else it would look kind of weird as it would miss the target by a lot. I might try it if the prediction fails at some points
if you want the bullet to be physics based then this is how you do it
local bullet = ...
local target = ...
local distance = (target.Position - bullet.Position).Magnitude
local ratio = 200 / distance
local throwTime = 1 / ratio
local targetPosition = target.Position + target.AssemblyLinearVelocity * thowTime
local direction = targetPosition - bullet.Position
local force = direction * ratio + Vector3.new(0, game.Workspace.Gravity * 0.5 / ratio, 0)
bullet.AssemblyLinearVelocity = force
if the velocity stays the same then it will hit the target but if the target keeps going back and forward then it will miss
but i think this is over kill for your game you could just do something like this
local runService = game:GetService("RunService")
local connection = nil
local bullet = ...
local target = ...
local bulletSpeed = 1
connection = runService.Heartbeat:Connect(function(deltaTime)
local position = bullet.Position + bullet.CFrame.LookVector * bulletSpeed * deltaTime
bullet.CFrame = CFrame.lookAt(position, target.Position)
if (target.Position - position).Magnitude < 1 then
connection:Disconnect()
bullet:Destroy()
print("Hit!!!")
end
end)