I am trying to make an AI that chases the player and tries to kill them. The problem I am running into is that the AI is stuttering behind the player due to network differences. To account for this I want to set the AI’s destination to just in front of the player. How would I accomplish this?
Current AI Code:
local enabled = script.Parent.Enabled
local ServerStorage = game:GetService("ServerStorage")
local SimplePath = require(ServerStorage.SimplePath)
local ai = script.Parent
local maxVector = -0.9
local function findTarget()
local players = game:GetService("Players"):GetPlayers()
local nearestTarget
local maxDistance = 35
local ogMaxVector = maxVector
for i, player in players do
if player.Character then
if player.Character:FindFirstChild("HumanoidRootPart") then
if player.Character.Humanoid.Health > 0 then
-- calculate distance
local target = player.Character.HumanoidRootPart
local distance = (ai.HumanoidRootPart.Position - target.Position)
if distance.Magnitude < maxDistance then
nearestTarget = target
maxDistance = distance
end
end
end
end
end
-- add +10 to the distance so the ai can reach the player
return nearestTarget
end
local Path = SimplePath.new(ai)
Path.Visualize = true
enabled.Changed:Connect(function()
if enabled.Value == true then
while enabled.Value == true do
local target = findTarget()
local distance = (ai.HumanoidRootPart.Position - target.Position)
local lookVector = ai.HumanoidRootPart.CFrame.LookVector
local dotProduct = distance.Unit:Dot(lookVector)
print(dotProduct)
if dotProduct < maxVector then
ai.Humanoid:MoveTo(target.Position)
end
if target then
Path:Run(target)
else
task.wait()
end
end
end
end)
Use the Humanoid’s WalkDirection, this is a Unit vector that tells you where the character is going, from there, you can extrapolate the new position by doing
local target = HumanoidRootPart.Position + (Unit * Speed)
Use speed to set the offset that the ai should go infront of the rig (if it goes behind, set it to negative)`
This would break if the player tried moving in a direction that is not away from the enemy. Do you know how to make the AI try to move slightly more than it has to to reach the player? This would only be for when the AI enters phase of movement where it senses the player is in front of it using the dotProduct and uses MoveTo to reach it. Image if you don’t understand what I’m trying to say.
You could try and use the AI LookVector/WalkDirection instead since it will then always be behind the player from the AI’s view even if the player is moving towards the AI.
Another approach I would suggest is using rays to detect if the player is in view of the AI. If the player is in view of the AI and within a certain distance then rather than creating a path you would simply have the AI walk directly towards the player. This should avoid any stuttering issues since no calculations are needed for a path. This is something that a lot of AI on roblox use.
I already do that. When the player is in sight of the AI it uses Humanoid:MoveTo() instead of pathfinding. I’m confused about the exact math of modifying the destination, though.
Now that I’m thinking about this more, this isn’t actually a problem. In the actual game when the AI touches the player they will be killed instantly, so it doesn’t matter. The player won’t see the AI stuttering behind them in an actual game.
So LookVector is a unit Vector meaning it only has a size of 1 and is only used to get the direction a part is facing. So for example if the part is facing the Y direction it would be <0, 1, 0>
Now we don’t want the part to only be 1 stud infront of the player since that’s essentially on top of him so we multiply that with 5 so now we have (ai.HumanoidRootPart.CFrame.LookVector*5)
Using the example numbers would give <0, 5, 0>
Now that we have that we want to get the player position and them simply add that to the player vector and it will give you the position you want. So its essentially
Humanoid Position + 5 studs in the direction of where the AI is facing
Hope this helps!
(For anyone that runs into the same problem or if you decide to implement it.)
Decided to implement it anyway since it’s better to have it than to not. Works perfectly. Thanks for explaining it so well, I understand how it works now.