You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? Keep it simple and clear!
i want to make a AI to talk when seen the player and then wait a cooldown before next player
-
What is the issue? Include screenshots / videos if possible!
the AI will stop when talking for some reason so i deleted that part of the script
-
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
it seems that no one made a topic with this problem
the AI script below doesnt have any error.
i want it to play sound per player found and then wait a certain cooldown before continue with the next player in the print place
function checkSight(target)
local ray = Ray.new(myRoot.Position, (target.Position - myRoot.Position).Unit * 40)
local hit,position = workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent})
if hit then
if hit:IsDescendantOf(target.Parent) and math.abs(hit.Position.Y - myRoot.Position.Y) < 3 then
print("I can see the target")
-- here should be the part when it plays the sound
end
end
return false
end
I dont understand exactly whats your goal with that code. But firstly, would be better you use Workspace:Raycast()
cause workspace:FindPartOnRayWithIgnoreList
is old and deprecated.
i want to the code play sound per player but when it reaches the cooldown the ai stops for some reason so i deleted the part of the code
What AI? stops doing what?
Focusing only on the code you are showing, you are firing that function on a loop I guess, so it constantly Raycast towards the NPC sight, if it hits a player, then play a sound right?
-- local myHuman = script.Parent:WaitForChild("Humanoid")
local myRoot = script.Parent:WaitForChild("HumanoidRootPart")
local head = script.Parent:WaitForChild("Head")
local lowerTorso = script.Parent:WaitForChild("Torso")
local spottedCooldown = 4
local spottedDB = true
local SCP = script.Parent
local SearchingPhrases = SCP.Searching:GetChildren()
local SpottedPhrases = SCP.Spotted:GetChildren()
local AttackPhrases = SCP.Attack:GetChildren()
local clone = SCP:Clone()
function walkRandomly()
local xRand = math.random(-50,50)
local zRand = math.random(-50,50)
local goal = myRoot.Position + Vector3.new(xRand,0,zRand)
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(myRoot.Position, goal)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
for _, waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
myHuman.Jump = true
end
myHuman:MoveTo(waypoint.Position)
local timeOut = myHuman.MoveToFinished:Wait(1)
if not timeOut then
print("Got stuck")
myHuman.Jump = true
walkRandomly()
end
end
else
print("Path failed")
wait(1)
walkRandomly()
end
end
function findPath(target)
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(myRoot.Position,target.Position)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
for _, waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
myHuman.Jump = true
end
myHuman:MoveTo(waypoint.Position)
local timeOut = myHuman.MoveToFinished:Wait(1)
if not timeOut then
myHuman.Jump = true
print("Path too long!")
findPath(target)
break
end
if checkSight(target) then
repeat
print("Moving directly to the target")
myHuman:MoveTo(target.Position)
attack(target)
wait(0.1)
if target == nil then
break
elseif target.Parent == nil then
break
end
until checkSight(target) == false or myHuman.Health < 1 or target.Parent.Humanoid.Health < 1
break
end
if (myRoot.Position - waypoints[1].Position).magnitude > 20 then
print("Target has moved, generating new path")
findPath(target)
break
end
end
end
end
function checkSight(target)
local ray = Ray.new(myRoot.Position, (target.Position - myRoot.Position).Unit * 40)
local hit,position = workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent})
if hit then
if hit:IsDescendantOf(target.Parent) and math.abs(hit.Position.Y - myRoot.Position.Y) < 3 then
print("I can see the target")
end
end
return false
end
function findTarget()
local dist = 50
local target = nil
local potentialTargets = {}
local seeTargets = {}
for i,v in ipairs(workspace:GetChildren()) do
local human = v:FindFirstChild("Humanoid")
local torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
if human and torso and v.Name ~= script.Parent.Name then
if (myRoot.Position - torso.Position).magnitude < dist and human.Health > 0 then
table.insert(potentialTargets,torso)
end
end
end
if #potentialTargets > 0 then
for i,v in ipairs(potentialTargets) do
if checkSight(v) then
table.insert(seeTargets, v)
elseif #seeTargets == 0 and (myRoot.Position - v.Position).magnitude < dist then
target = v
dist = (myRoot.Position - v.Position).magnitude
end
end
end
if #seeTargets > 0 then
dist = 200
for i,v in ipairs(seeTargets) do
if (myRoot.Position - v.Position).magnitude < dist then
target = v
dist = (myRoot.Position - v.Position).magnitude
end
end
end
if target then
if math.random(20) == 1 then
SearchingPhrases[math.random(1, #SearchingPhrases)]:Play()
end
end
return target
end
function attack(target)
if (myRoot.Position - target.Position).magnitude < 5 then
-- place for attack anim and sound
AttackPhrases[math.random(1, #AttackPhrases)]:Play()
if target.Parent ~= nil then
target.Parent.Humanoid:TakeDamage(target.Parent.Humanoid.Health)
end
wait(0.4)
end
end
function died()
wait(5)
clone.Parent = workspace
game:GetService("Debris"):AddItem(script.Parent,0.1)
end
myHuman.Died:Connect(died)
lowerTorso.Touched:Connect(function(obj)
if not obj.Parent:FindFirstChild("Humanoid") then
myHuman.Jump = true
end
end)
function main()
local target = findTarget()
if target then
myHuman.WalkSpeed = 18.25
findPath(target)
else
myHuman.WalkSpeed = 8
walkRandomly()
end
end
while wait(0.1) do
if myHuman.Health < 1 then
break
end
main()
end
at the start there is spottedCooldown and spottedDebounce and when i try to use it to play a sound it makes the NPC stop for 4 secunds but then again stops after 0.2 secunds of walking
nevermind i think i solved it myself
Ok, I kinda understand. But I think you should reThink the logic of what you are doing. You got that script from a tutorial or somewhere right? or made by chatGPT?
First. You are iterating workspace to find Potential Targets, would be better to iterate game.Players:GetPlayers() and not Workspace. BUT
Think about this. Your NPC has “eyes”, the Raycast is its eyes, it will tell you what the NPC is watching. When a player is in front of NPC’s eyes, then NPC will say “hey a see someone”. Why do you need to check each player in game to check if NPC can see that player? By just firing the Raycast you already know if the NPC can see a Player, what is the point of checking all other players that could be very far from the NPC?
i got it from the youtuber that made advanced soldier ai
wait how do i make a function that checks if the player looks in npc eyes?
A raycast from player towards player’s mouse/sight line, if the raycast hits a part called “NPC eyes” which is in the NPC character, then the Raycast will return “Im watching the NPC directly to its eyes”
can i also do it but making the npc eyes the head?
of course, could be the Head, the Leg, or whatever thing that is inside the NPC character
even a part called “Eyes” in head?
yeah… whatever part in character, workspace, other players, terrain like water, grass, anything…
Its a ray, it will hit something and will return a list of properties of the thing that collided with, like its name, orientation, material, the part itself, position of the hit, etc
it needs to be local script in starter gui?
A Raycast will return a list of these things. Plenty information so you can do whatever you want with it. Be sure to check the Raycast Documentation, its impossible to learn to script if you dont read the Documentation
wait i forgot how to get the players mouse in scripting
Could be server or client. No needing to be a specific side
nevermind i reminded it so yeah
Oh yeah, you can only get the mouse on client side, but Im not saying that you should only get use the Mouse… That depends, if the game is on FirstPerson or ThirdPerson, so it depends how you want to choose the Direction of the ray, maybe you only want to cast the ray facing to front from the head of the player