Accurate tower defense movement prediction

I’m making a tower defense game, and I have a tower that shoots projectiles, the issue I have is that it shoots it where the enemy WAS, not where it IS.

I tried using npc:GetPivot().LookVector * npc.Humanoid.WalkSpeed(multiplied by the walkspeed since its measured in studs per second), for the location, which works perfectly if its straight, but unfortunately it turns, so it shoots a very strange way.

also, I can’t use the waypoints(from pathfindingservice:CreatePath()), as they generate a path randomly, and I don’t actually know the route until they already have spawned, and also the waypoints are only on corners, as I set the waypoint spacing to math.huge, which means it they will only be at turning/jumping locations

is there a good method to predict the movement of the enemy, or should I just try to not visually have projectiles?

One thing I don’t understand is that you don’t know the route. Cause most tower defenses has a path where they walk on or am I wrong?

I generate the path more every wave, so it changes each wave. it’s very similar to the game “rogue tower” on steam

Well if you expand the paths just make a script that checks where the route is with a variable or something. And then check where the path is. So basically just get the position of the path and then set the waypoints on that position(The corners I think, not sure.).

1 Like

well as I said, I had to set the waypoint spacing to math.huge, which makes the waypoints only where they need to turn or jump, and if it’s not math.huge, it stutters, and eventually stops entirely

Can u show me a vid and the script?

I found a method that kind of works, using align position, where I update the position every heartbeat, but it slows down weirdly when it gets closer
robloxapp-20220316-11531.wmv (1.2 MB)
which is not optimal

local bullet = Instance.new("Part", workspace)
bullet.Shape = Enum.PartType.Ball
bullet.Size = Vector3.new(1,1,1)
bullet.Anchored = false
bullet.CanCollide = false
bullet.CFrame = gun:GetPivot()
	
local attach = Instance.new("Attachment", bullet)
	
local align = Instance.new("AlignPosition", bullet)
align.Mode = Enum.PositionAlignmentMode.OneAttachment
align.Attachment0 = attach
align.Responsiveness = 15
	
local conn
conn = game:GetService("RunService").Heartbeat:Connect(function()
		align.Position = enemy:GetPivot().Position
		if (bullet.Position-enemy:GetPivot().Position).Magnitude < 2 then
			
			conn:Disconnect()
			
			if enemy:FindFirstChild("Humanoid") and enemy.Humanoid.Health > 0 then
				enemy.Humanoid:TakeDamage(math.random(towers.Damage[1], towers.Damage[2]))
			end
	
			bullet:Destroy()
			
			return
		end
	end)

this is what I’m using
It’s inside a function the gives the enemy/gun

So you’ve already tried an equivalent to this?

local npcRoot = npc.PrimaryPart.CFrame --//Like their root part
local towerBarrel = tower.Barrel.CFrame

local offset = npcRoot.LookVector.Unit*npcWalkSpeed

local direction = ( (npcRoot*offset).Position - towerBarrel.Position).Unit

I’m pretty confused as to what results it yields, could you show me??

1 Like

I can’t really see them slowing down but if you say so it probably is. And I think it slows down because of the RootPart.

robloxapp-20220316-11531.wmv (1.2 MB)
this is the current result, I don’t want it slowing down weirdly as it gets closer

can you elaborate on that please?

I think if you set the properties to this:

MaxForce = 10000
MaxVelocity = 20
Responsiveness = 200

You won’t be having trouble. I just tested it and it doesn’t slows down.

It makes it slow down because you set it to OneAttachment, I have set it to TwoAttachment and it works without slowing it down. But if I use OneAttachment like you have it does slows down at the end.

1 Like

if I leave the other attachment nil will it still align to the position i set? i tested, and no

Do you have 2 Attachments? Cause in order to set the mode to TwoAttachment you need to have 2 attachments in this case I the portal and the NPC. Allthough I think it might sabotage your waypoints.

You’re solution actually still works, it slows down very slightly, but all I had to do was set the position to subtract the lookvector of the npc since I check the proximity for damage so if it goes through its fine

1 Like

this is the actual solution ^, but I decided to leave the final code here just so people have a slightly better idea if they check here later.

local align = Instance.new("AlignPosition", bullet)
align.Visible = true
align.Mode = Enum.PositionAlignmentMode.OneAttachment
align.Attachment0 = attach
align.MaxForce = 10000
align.MaxVelocity = 50
align.Responsiveness = 200

and then loop this until the thing is nil or it reaches the intended location

local pos = enemy:GetPivot() * CFrame.new(-enemy:GetPivot().LookVector)
align.Position = pos.Position

(I check using magnitude being < 1)

2 Likes

Great that you placed it so other people can see it if they have the same problem.

1 Like