Hello scripters, I have a pretty big ask of you guys so any help is appreciated. I am trying to make an AI. I wont go into what features and everything that it does but feel free to look through the code to find out yourself. Basically, I am trying to use ray casting to find a player and attack them My issue is is that the attack is very inconsistent. what i mean by this is that the ai has a hard time seeing the player (see the video to fully understand what i mean). I have tried to new shape casting feature to expand the ray cast from a tiny line to a big area in order to “increase the ai’s vision” if you know what i mean. however, this did not work. it did the same exact thing. I would like to make it towards that the AI only checks if it can see the player (when attacking off corset) every 10-15 seconds. I unfortunately dont know how to do this unfortunately and am coming to you guys for help. Please help me out. ANY and i mean ANYTHING helps. Thank you for your time, have a blessed day.,
GUIDE: (find target function : line218. walkto function: line 263. attack function: line 596. where the attack function is called: line 666.)
VIDEO:
CODE:
local runservice = game:GetService(“RunService”)
local soundservice = game:GetService(“SoundService”)
local pathfindingservice = game:GetService(“PathfindingService”)
local idletasks = require(script.IdleTasks)
local neighbor = script.Parent
local humanoid = neighbor:WaitForChild(“Humanoid”)
local hrp = neighbor:WaitForChild(“HumanoidRootPart”)
local trapsfolder = game.ServerStorage.Traps
local distractions = workspace.Distractions
local rooms = workspace.Rooms:GetChildren()
local attackpaths = workspace:WaitForChild(“AttackPaths”)
local idlespeed = 12
local huntspeed = 16
local attackspeed = 18
local mode = neighbor.Mode
mode.Value = “Idle”
local bindables = game:GetService(“ReplicatedStorage”).Bindables
local remotes = game:GetService(“ReplicatedStorage”).RemoteEvents
local playerCaught = bindables:WaitForChild(“playerCaught”)
neighbor.HumanoidRootPart:SetNetworkOwner(nil)
local ogpositions = {}
local prevRooms = {}
for i, room in pairs (rooms) do
for i, instance in pairs (room:GetChildren()) do
if instance.Name == "KeyItems" and instance:IsA("Folder") then
for i, item in pairs (instance:GetChildren()) do
table.insert(ogpositions, item.Position)
end
end
end
end
local function getChase()
local sounds = soundservice.Ambiences.ChaseMusics:GetChildren()
local soundchosen = sounds[math.random(1, #sounds)]
soundchosen.TimePosition = 0
return soundchosen
end
–THIS FUNCTION IS TO FIX A GLITCH. DO NOT USE (unless u have to)
local function findnearestPlayer()
local players = game.Players:GetPlayers()
local maxDistance = 100
local nearestTarget
for i, player in pairs(players) do
local char = player.Character or player.CharacterAdded:Wait()
if char then
local target = char
local distance = (neighbor.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
if distance < maxDistance then
nearestTarget = target
maxDistance = distance
end
end
end
return nearestTarget
end
local function getDistance(pos1, pos2)
local distance = (pos1 - pos2).Magnitude
return distance
end
local function getRandomRoom()
for i = 1, #rooms do
local randomRoom = rooms[math.random(1, #rooms)]
if table.find(prevRooms,randomRoom) ~= nil then
repeat
randomRoom = rooms[math.random(1, #rooms)]
task.wait()
until table.find(prevRooms,randomRoom) == nil
end
table.insert(prevRooms,randomRoom)
task.wait()
return randomRoom
end
end
local function playAnim(animation, sound)
if mode.Value ~= "Attack" then
local anim = humanoid:LoadAnimation(animation)
anim:Play()
if sound then
sound:Play()
end
anim.Stopped:Wait()
end
end
local function findNearestRoom(plyr)
local target = plyr
local hrp = target:WaitForChild("HumanoidRootPart")
local rooms = workspace.Rooms
local distances = {}
for i, room in pairs(rooms:GetChildren()) do
local label = room:FindFirstChild("Label")
local distance = (hrp.Position - label.Position).Magnitude
table.insert(distances, distance)
end
local nearest = math.min(table.unpack(distances))
for i, room in pairs (rooms:GetChildren()) do
local label = room:FindFirstChild("Label")
if (hrp.Position - label.Position).Magnitude == nearest then
return room
end
end
end
local function addFavLoc(room)
if not room:FindFirstChild("Favorite") then
local fav = {}
for i, rooom in pairs (rooms) do
local isFav = room:FindFirstChild("Favorite")
table.insert(fav, rooom)
end
if #fav >= #fav/2 then
local tag = Instance.new("BoolValue")
tag.Name = "Favorite"
tag.Parent = room
end
end
end
local function catch(target)
local nearest = findNearestRoom(target)
addFavLoc(nearest)
neighbor.Head.Sounds.Angry:Play()
wait(.8)
target.HumanoidRootPart:PivotTo(workspace.Spawn.CFrame)
playerCaught:Fire()
target.Humanoid.WalkSpeed = 16
target.Humanoid.JumpPower = 50
end
local function placeTrap(trap, position)
if trap == "BearTrap" then
playAnim(script.Animations.PlaceBearTrap)
local trap = trapsfolder.BearTrap:Clone()
trap.Parent = distractions
trap.Union.Position = position + Vector3.new(0,-.14,0)
end
end
local function findIntruder()
local players = game.Players:GetPlayers()
local intruder
for i, plyr in pairs (players) do
local char = plyr.Character or plyr.CharacterAdded:Wait()
if char then
local direction = (char.PrimaryPart.Position - hrp.Position).Unit
local raycastResult = workspace:Raycast(hrp.Position, direction * 50)
if raycastResult then
if raycastResult.Instance:IsDescendantOf(char) then
intruder = char
break
end
end
end
end
return intruder
end
local function getPath(destination)
local path = pathfindingservice:CreatePath()
path:ComputeAsync(hrp.Position, destination)
return path
end
local function walkTo(destination)
local path = getPath(destination)
if path.Status == Enum.PathStatus.Success then
for index, waypoint in pairs(path:GetWaypoints()) do
local target = findIntruder()
if target and target.Humanoid.Health > 0 then
local chase = getChase()
local counter = 0
for i, sound in pairs (soundservice.Ambiences.ChaseMusics:GetChildren()) do
if sound.Playing == false then
counter += 1
end
end
if counter == #soundservice.Ambiences.ChaseMusics:GetChildren() then
chase.Playing = true
end
mode.Value = "Attack"
local nearestroom = findNearestRoom(target)
local tag = nearestroom:FindFirstChild("Favorite")
if not tag then
addFavLoc(nearestroom)
end
elseif not target then
for i, sound in pairs (soundservice.Ambiences.ChaseMusics:GetChildren()) do
sound.Playing = false
end
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
end
else
humanoid:MoveTo(destination - (hrp.CFrame.LookVector * 10)
)
end
end
local function changeMode()
for i, instance in pairs (distractions:GetDescendants()) do
if instance:IsA("BoolValue") and instance.Name == "Status" then
if instance.Value == true and mode.Value ~= "Attack" then
for i, instance in pairs (distractions:GetDescendants()) do
if instance:IsA("BoolValue") and instance.Name == "Status" then
if instance.Value == true and mode.Value ~= "Attack" then
local lookAnim = script:WaitForChild("Animations"):WaitForChild("Look")
if instance.Parent.Name == "Camera" then
walkTo(instance.Parent.End.Position)
elseif instance.Parent.Name == "BearTrap" then
walkTo(instance.Parent.HitBox.Position)
elseif instance.Parent.Name == "TV" then
walkTo(instance.Parent.Position)
end
local lookAnim = script.Animations.Look
playAnim(lookAnim, neighbor.Head.Sounds.Yell2)
instance.Value = false
end
end
end
mode.Value = "Hunt"
elseif instance.Value == false and mode.Value ~= "Attack" and mode.Value ~= "Hunt" then
mode.Value = "Idle"
end
end
end
end
local function detectMovedObject(room)
for i, rooom in pairs (rooms) do
if rooom.Name == room.Name then
for i, instance in pairs (room:GetChildren()) do
if instance.Name == "KeyItems" and instance:IsA("Folder") then
local item = instance.Item
for i, position in pairs (ogpositions) do
local pos = table.find(ogpositions, item.Position)
if not pos then
return true
elseif pos then
return false
end
end
end
end
end
end
end
local function idle()
humanoid.WalkSpeed = idlespeed
local randomroom = rooms[math.random(1, #rooms)]
local moved = detectMovedObject(randomroom)
if moved and randomroom.hasTrap.Value == false then
local lookAnim = script.Animations.Look
local tag = randomroom:FindFirstChild("Favorite")
if not tag then
addFavLoc(randomroom)
end
walkTo(randomroom.KeyItems.Item.Position)
playAnim(lookAnim, neighbor.Head.Sounds.Yell)
for i, item in pairs (randomroom:GetDescendants()) do
if item.Name == "BeartrapPosition" then
for i, position in pairs (item:GetChildren()) do
walkTo(position.Position)
placeTrap("BearTrap", position.Position)
randomroom.hasTrap.Value = true
end
end
end
mode.Value = "Hunt"
else
print(randomroom.Name)
walkTo(randomroom.Label.Position)
if randomroom.Name == "Kitchen" and not findIntruder() then
walkTo(randomroom.AnimationPart.Position)
idletasks.WashDishes()
end
end
end
local function hunt()
humanoid.WalkSpeed = huntspeed
local lookAnim = humanoid:LoadAnimation(script.Animations.Look)
local randomroom = getRandomRoom()
local label = randomroom.Label
local moved = detectMovedObject(randomroom)
local target = findIntruder()
if not label then
error("No Label Found")
end
if moved then
local lookAnim = script.Animations.Look
local tag = randomroom:FindFirstChild("Favorite")
if not tag then
addFavLoc(randomroom)
end
walkTo(randomroom.KeyItems.Item.Position)
playAnim(lookAnim, neighbor.Head.Sounds.Yell)
if randomroom.hasTrap.Value == false then
for i, item in pairs (randomroom:GetDescendants()) do
if item.Name == "BeartrapPosition" then
for i, position in pairs (item:GetChildren()) do
walkTo(position.Position)
placeTrap("BearTrap", position.Position)
randomroom.hasTrap.Value = true
end
end
end
end
else
local lookAnim = script.Animations.Look
walkTo(label.Position)
playAnim(lookAnim, neighbor.Head.Sounds.Grunt)
local tag = randomroom:FindFirstChild("Favorite")
local hideing = randomroom:FindFirstChild("Hideing")
if tag and hideing and mode.Value ~= "Attack" then
for i, spot in pairs (hideing:GetChildren()) do
local point = spot.Point
local anim = humanoid:LoadAnimation(script.Animations.OpenCloset)
walkTo(point.Position)
spot.Status.Value = true
humanoid.WalkSpeed = 0
anim:Play()
anim:GetMarkerReachedSignal("Stop"):Wait()
anim:AdjustSpeed(0)
if spot.Player.Value == true then
local target = findnearestPlayer()
if target then
catch(target)
end
end
wait(.5)
anim:AdjustSpeed(1)
spot.Status.Value = false
anim.Stopped:Wait()
humanoid.WalkSpeed = huntspeed
end
end
end
end
local function newPath(name)
local path = Instance.new("Folder")
path.Parent = attackpaths
path.Name = name
return path
end
local function logPath(target, path, previous)
local intruder = findIntruder()
if intruder then
local hrpart = target.HumanoidRootPart
local marker = Instance.new("Part")
marker.CFrame = hrpart.CFrame
marker.Size = Vector3.new(.5,.5,.5)
marker.Parent = path
marker.Anchored = true
marker.CanCollide = false
marker.CanTouch = false
marker.Transparency = .5
end
end
local function attack(target)
if target then
humanoid.WalkSpeed = attackspeed
local distance = (neighbor.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
if distance > 2 then
humanoid:MoveTo(target.HumanoidRootPart.Position)
else
catch(target)
mode.Value = ""
end
else
mode.Value = "Idle"
end
end
–[[
task.spawn(function()
while task.wait() do
changeMode()
end
end)
]]--
while wait(.1) do
changeMode()
if mode.Value == "Idle" then
humanoid.WalkSpeed = idlespeed
idle()
elseif mode.Value == "Hunt" then
humanoid.WalkSpeed = huntspeed
for i, sound in pairs (soundservice.Ambiences.ChaseMusics:GetChildren()) do
sound.Playing = false
end
if #prevRooms == #rooms then
table.clear(prevRooms)
mode.Value = "Idle"
else
hunt()
end
elseif mode.Value == "Attack" then
local intruder = findIntruder()
humanoid.WalkSpeed = attackspeed
attack(intruder)
logPath(intruder,attackpaths)
end
end