I have no idea how to make AI and i feel burnt

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.

1 Like

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

2 Likes

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.

Try learn how to use the pathfinding api thats what I did, also have you seen this video

1 Like

Yes, i did watch it. I didn’t understand.

1 Like

You sure it’s the same one as this person explains it all very well

1 Like

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.

1 Like

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.

2 Likes

I have only 1 waypoint (the player’s humanoid) so do i still use a loop?

1 Like

Gnome code made his game open-sourced so if you really feel down and burnt out you could take inspiration from his ai script

2 Likes

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

1 Like

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)
5 Likes

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.

2 Likes

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.