I have made AI in my game, but I am stuck on civilian AI as I want them to walk around in a radius where they spawn at to make sure they don’t wander off.
This is how I want it to be, and I just want to know how this would be achievable
I have made AI in my game, but I am stuck on civilian AI as I want them to walk around in a radius where they spawn at to make sure they don’t wander off.
Have you tried (Position0 - Position1).Magnitude?
https://developer.roblox.com/en-us/articles/Magnitude
Yes I know what magnitude is, I am just trying to find a position that is in the “radius” (or magnitude) of the AI
The radius of the initial position of that AI? If so, save the position and check it from there.
Okay, so how do I get the position of where I will move the AI to?
Depends on how your AI works. With direct uncaclulated movement you can use Humanoid:MoveTo
, otherwise PathfindingService is your better option.
if just wanting to move in a certain radius do something like
local OriginalPos = HumanoidRootPart.Position -- do this on initial run
-- to get a new random by radius maybe something like this
local Radius = 10
local NewPosition = OriginalPos + Vector3.new(math.random(-Radius , Radius), OriginalPos .Y, math.random(-Radius , Radius))
you could also do this on Y axis but i choose just to set it what HRP is at
if trying to make sure a position they are headed to is in that radius
if (OriginalPos - NewPosition).Magnitude > Radius then
-- call to get a new position this one is outside radius
end
This video might help you
This video makes NPC’s on the client side so they will use a very small amount of network and server resources
It also unloads the NPC’s when you player walks far away from the NPC so the client will only calculate the path of NPC’s there standing close to
If you’re not looking for advanced pathfinding you can just use :MoveTo
local Hum = script.Parent.Humanoid
local Limit = script.Parent.Limit -- Part inside your character that defines the origin
local Radius = 10
function gotoRandom_Pos()
local X = math.random(Limit.Position.X-Radius,Limit.Position.X+Radius)
local Z = math.random(Limit.Position.Z-Radius,Limit.Position.Z+Radius)
Hum:MoveTo(Vector3.new(X,0,Z))
end
game:GetService("RunService").Heartbeat:Connect(function()
if (script.Parent.PrimaryPart.AssemblyLinearVelocity*Vector3.new(1,0,1)).Magnitude <= 1 then
gotoRandom_Pos()
end
end)
Just make sure the PrimaryPart is the Humanoid and there’s an anchored part named Limit in your character
When I return the waypoints of this
path:ComputeAsync(Mob.HumanoidRootPart.Position, Vector3.new(X,0,Z))
it prints {}.
Does it not work with vector3’s?
So if you want the player to move in a circle, I would suggest using the unit circle theory. Lmk know if there is any errors
local PathfindingService = game:GetService("PathfindingService")
while wait() do
local character = script.Parent --- ur character
local Cx, Cz = 0, 0
local radius = 10
local angle = math.random(0,2*math.pi)
local x, y, z = math.cos(angle ) * radius , character.PrimaryPart.Position.Y, math.sin(angle) * radius
local humanoid = character.Humanoid --- ur humanoid
local success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, Vector3.new(x,y,z))
end)
if success and path.Status == Enum.PathStatus.Success then
-- Get the path waypoints
waypoints = path:GetWaypoints()
if not reachedConnection then
reachedConnection = humanoid.MoveToFinished:Connect(function(reached)
if reached and nextWaypointIndex < #waypoints then
-- Increase waypoint index and move to next waypoint
nextWaypointIndex += 1
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
reachedConnection:Disconnect()
blockedConnection:Disconnect()
end
end)
end
-- Initially move to second waypoint (first waypoint is path start; skip it)
nextWaypointIndex = 2
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
warn("Path not computed!", errorMessage)
end
end
Path not computed! nil
Again, I don’t know why pathfindingservice is acting weird when the 2nd parameter is a vector3.
ComputeAsync accepts only Vector3
local Hum = script.Parent.Humanoid
local Limit = script.Parent.Limit -- Part inside your character that defines the origin
local PathService = game:GetService("PathfindingService")
local path = PathService:CreatePath{
AgentRadius = 2.0,
AgentHeight = 5.0,
AgentCanJump = false
}
local Radius = 50
function gotoRandom_Pos()
local X = math.random(Limit.Position.X-Radius,Limit.Position.X+Radius)
local Z = math.random(Limit.Position.Z-Radius,Limit.Position.Z+Radius)
path:ComputeAsync(script.Parent.PrimaryPart.Position, Vector3.new(X,0,Z))
if path.Status ~= Enum.PathStatus.Success then return end
for _,v in path:GetWaypoints() do
Hum:MoveTo(v.Position)
end
end
game:GetService("RunService").Heartbeat:Connect(function()
if (script.Parent.PrimaryPart.AssemblyLinearVelocity*Vector3.new(1,0,1)).Magnitude <= 1 then
gotoRandom_Pos()
end
end)
The only problem I face now is path:GetWaypoints() occasionally returning {}.
This is the problem I sometimes have aswell. It finds the correct path but just refuses to follow it.
Are you using MoveToFinished??
Can u send me the file? char
It’s as Msorky said, the solution to fix it is by using MoveToFinished:Wait(), but this makes it “slow” and wait for each waypoint
Do u still need it fixed? Or r u fine?