I can’t understand AI. I’m so burnt out from that. I need the monster to follow the player in a scripted chase scene and when the monster touches the player it plays an animation. I’ll just need to move the camera of the player and stop both of them which isn’t that hard but i don’t know how to make the monster follow the player. I tried following gnome code’s tutorial but i just don’t understand. I don’t really understand functions that well and i don’t really understand waypoints. Please, could anyone help? It’s a massive roadblock for me. I could make its waypoint the player’s humanoid.
What you need to use is pathfinding. Pathfinding is sort of like an advanced version of humanoid.MoveTo
Here is a video link on a tutorial:
(4) Advanced Roblox Scripting Tutorial #21 - Pathfinding (Beginner to Pro 2019) - YouTube
I did. I didn’t understand. I watched that video. I’ll try to rewatch it. I think i understand, but i can’t test right now. I’ll make the player’s humanoid a waypoint (it’s singleplayer) and if it finishes its path it freezes both, turns the camera around and plays the jumpscare.
Yes, i did watch it. I didn’t understand.
You sure it’s the same one as this person explains it all very well
Yes. I said in my post i didn’t understand gnome code’s tutorial. I don’t really know functions that well. My brain just stopped.
So, there are some functions and services you need to know for using pathfinding:
This is how to first set up the service for use
local pathfindingService = game:GetService("PathfindingService")
This is the agentData, this basically gives the server an idea of how big the ai is and whether it can jump or not (Ex: For a regular humanoid)
local agentData = {
AgentRadius = 2,
AgentCanJump = true
}
After this you create a path, basically sending the agent data
local path = pathfindingService:CreatePath(agentData)
Now we get to the part where you actually get all the waypoints
So, once all of the agentData is sent, do this:
--Target root is the target your monster is chasing, the humanoidroot is your monster's main part
path:ComputeAsync(humanoidRootPart.Position, targetRoot.Position)
After that, you want to create a for loop so it can go to every waypoint
for i, waypoint in pairs(path:GetWaypoints()) do
humanoid:MoveTo(waypoint.Position)
--This is if the monster needs to jump
if waypoint.Action == Enum.PathWaypointAction.jump then
humanoid.Jump = true
end
humanoid.MoveToFinish:Wait(5) --how long to wait to go to next point unless the previous point has been reached
These are the general components you need in order to use pathfinding effectively.
I have only 1 waypoint (the player’s humanoid) so do i still use a loop?
Gnome code made his game open-sourced so if you really feel down and burnt out you could take inspiration from his ai script
So, waypoints are where the monster has to walk to reach its goal.
Lets say that there is a maze between the two targets, one point would be having the monster turn right to this area, then after that turn over here to go to the next point, etc.
Regardless, yes you need the for loop
Here is a visual example, red representing the monster, green the goal target, and blue as the waypoints
Here’s my AI code that I use for pretty much anywhere.
Do note that this is a pretty advanced script, as it has things like directly moving to player when visible with raycasting (this makes the movement smoother when the target is in line of sight), custom function for MoveToFinished (default built-in function has an 8 second timeout for when the AI is stuck which is undesireable), and other stuff.
local PTS = game:GetService("PathfindingService")
local PS = game:GetService("Players")
local char = script.Parent
local HRP = char.PrimaryPart
local hum = char:FindFirstChildWhichIsA("Humanoid")
local path: Path = PTS:CreatePath({
AgentRadius = 2,
AgentHeight = 5,
AgentCanJump = true,
WaypointSpacing = 5
})
local target: BasePart? = nil
local function FindTarget(char: Model): BasePart
local primary = char.PrimaryPart
local target, distance = nil, nil
for _,v: Player in ipairs(PS:GetPlayers()) do
if v.Character then
local targetChar = v.Character
local targetHRP = targetChar.PrimaryPart
local targetHum = targetChar:FindFirstChildWhichIsA("Humanoid")
local mag = v:DistanceFromCharacter(primary.Position)
if targetChar and targetHRP and targetHum and targetHum.Health ~= 0 then
if target and distance then
if mag < distance then
target = targetHRP
distance = mag
end
else
target = targetHRP
distance = mag
end
end
end
end
return target
end
local function MoveToFinished(hum: Humanoid, timeout: number): boolean
local event: BindableEvent = Instance.new("BindableEvent")
local success: boolean = true
task.delay(timeout, function()
success = false
event:Fire()
end)
task.defer(function()
hum.MoveToFinished:Wait()
event:Fire()
end)
event.Event:Wait()
event:Destroy()
return success
end
local function CheckRaycastTo(HRP: BasePart, targetHRP: BasePart): boolean
local params: RaycastParams = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Blacklist
params.FilterDescendantsInstances = {HRP.Parent}
local origin: Vector3 = HRP.Position
local dir: Vector3 = (targetHRP.Position - HRP.Position).Unit * 100
local ray: RaycastResult = workspace:Raycast(origin, dir, params)
if ray and ray.Instance and ray.Instance:IsDescendantOf(targetHRP.Parent) and math.abs(HRP.Position.Y - targetHRP.Position.Y) < 8 then
return true
end
return false
end
local function MoveToTarget(char: Model, targetChar: Model)
local HRP = char:FindFirstChild("HumanoidRootPart")
local hum = char:FindFirstChildWhichIsA("Humanoid")
local targetHRP = targetChar:FindFirstChild("HumanoidRootPart")
local targetHum = targetChar:FindFirstChildWhichIsA("Humanoid")
path:ComputeAsync(HRP.Position, targetHRP.Position)
if path.Status ~= Enum.PathStatus.Success then
return
end
local waypoints: {PathWaypoint} = path:GetWaypoints()
for i: number, v in ipairs(waypoints) do
local pos = v.Position
if v.Action == Enum.PathWaypointAction.Jump then
warn("moving: jumping")
hum.Jump = true
end
hum:MoveTo(pos)
warn("moving: normal")
local check = MoveToFinished(hum, .5)
if not check then
hum.Jump = true
warn("resetting: ai got stuck, jump: ")
break
end
if i > 8 and (targetHRP.Position - waypoints[#waypoints].Position).Magnitude > 3 then
warn("resetting: ai's goal is too far from actual position of player")
break
end
if CheckRaycastTo(HRP, targetHRP) then
repeat
hum:MoveTo(targetHRP.Position)
warn("moving: raycast")
task.wait(.05)
until not CheckRaycastTo(HRP, targetHRP) or not targetChar or targetHum.Health <= 0 or not target
break
end
end
end
task.spawn(function()
while true do
if not HRP.Anchored and HRP:IsDescendantOf(workspace) then
HRP:SetNetworkOwner(nil)
end
target = FindTarget(char)
task.wait(.1)
end
end)
while true do
if target then
MoveToTarget(char, target.Parent)
else
warn("could not find target!")
end
task.wait()
end
Here’s some simple explanations for the functions that PathfindingService has to offer.
PathfindingService:CreatePath()
- Creates a ‘Path’ object
- You can give information to the AI (such as how tall it is, how big it is, if it can jump or not, and etc.)
- You only need to do this once in your script
pathObject:ComputeAsync()
- First parameter is the starting position, and second parameter is the goal position
- If successful, it returns an array of waypoints (think of it as small dots that break up a path)
I don’t currently need that because the first chase just follows the player.
could i make the player’s humanoidrootpart the waypoint?
So when creating a path, it already sets everything up for you. The jumping, walking, everything is already set up, all you have to do is set up a for loop to go through the waypoints. As long as you have your monster’s humanoid root as the start, and the target humanoid root as the goal, it should work flawless. I will say though that you should continuously keep creating a new path so it can catch up with the player.
i randomly found this post again while searching stuff for an ai commission. i know how to make ai now.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.