Hi I have been haveing trouble figuring out what i did wrong with this script if anyone could help of revise it i would be grateful
local npc = script.Parent
local humanoid = npc:FindFirstChildOfClass("Humanoid")
local pathfindingService = game:GetService("PathfindingService")
local players = game:GetService("Players")
local rootPart = npc:FindFirstChild("HumanoidRootPart")
local upperTorso = npc:FindFirstChild("UpperTorso")
local lowerTorso = npc:FindFirstChild("LowerTorso")
-- Speed settings and alert distances
local walkingSpeed = 6
local runningSpeed = 12
local alertProximity = 100
local chaseProximity = 50
-- Sound Setup
local sounds = {
chase = npc:FindFirstChild("ChaseSound"),
idle = npc:FindFirstChild("IdleSound"),
alert = npc:FindFirstChild("AlertSound")
}
-- Find Animations
local animations = {}
for _, anim in ipairs(npc:GetDescendants()) do
if anim:IsA("Animation") then
if anim.Name:find("Run") then
animations.run = humanoid:LoadAnimation(anim)
elseif anim.Name:find("Walk") then
animations.walk = humanoid:LoadAnimation(anim)
elseif anim.Name:find("Idle") then
animations.idle = humanoid:LoadAnimation(anim)
elseif anim.Name:find("Alert") then
animations.alert = humanoid:LoadAnimation(anim)
end
end
end
-- Patrolling waypoints (example coordinates)
local waypoints = {
Vector3.new(20, 0, 20),
Vector3.new(-20, 0, -20),
Vector3.new(20, 0, -20),
Vector3.new(-20, 0, 20)
}
local currentWaypoint = 1
-- Utility functions
local function stopAllSounds()
for _, sound in pairs(sounds) do
if sound then sound:Stop() end
end
end
local function stopAllAnimations()
for _, animation in pairs(animations) do
if animation then animation:Stop() end
end
end
local function playSound(sound)
if sound then sound:Play() end
end
local function playAnimation(animation)
if animation then animation:Play() end
end
-- Detecting and Targeting Players
local function findNearestPlayer()
local closestPlayer = nil
local shortestDistance = alertProximity
for _, player in ipairs(players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("UpperTorso") and player.Character:FindFirstChild("LowerTorso") then
local upperTorso = player.Character.UpperTorso
local lowerTorso = player.Character.LowerTorso
local distance = (rootPart.Position - (upperTorso.Position + lowerTorso.Position) / 2).magnitude
if distance < shortestDistance then
closestPlayer = player
shortestDistance = distance
end
end
end
return closestPlayer, shortestDistance
end
-- Custom Pathfinding System
local function customPathfindTo(position, speed)
local function isWalkable(pos)
local region = Region3.new(pos - Vector3.new(2, 2, 2), pos + Vector3.new(2, 2, 2))
local parts = workspace:FindPartsInRegion3(region, nil, 10)
for _, part in ipairs(parts) do
if part:IsA("BasePart") and part.CanCollide then
return false
end
end
return true
end
local function getNeighbors(node)
local neighbors = {}
local directions = {
Vector3.new(1, 0, 0), Vector3.new(-1, 0, 0),
Vector3.new(0, 0, 1), Vector3.new(0, 0, -1),
Vector3.new(1, 0, 1), Vector3.new(1, 0, -1),
Vector3.new(-1, 0, 1), Vector3.new(-1, 0, -1)
}
for _, dir in ipairs(directions) do
local newPos = node + dir * 5
if isWalkable(newPos) then
table.insert(neighbors, newPos)
end
end
return neighbors
end
local function heuristic(a, b)
return (a - b).magnitude
end
local function findPath(start, goal)
local openSet = {start}
local cameFrom = {}
local gScore = {[start] = 0}
local fScore = {[start] = heuristic(start, goal)}
while #openSet > 0 do
table.sort(openSet, function(a, b) return fScore[a] < fScore[b] end)
local current = table.remove(openSet, 1)
if current == goal then
local path = {current}
while cameFrom[current] do
current = cameFrom[current]
table.insert(path, 1, current)
end
return path
end
for _, neighbor in ipairs(getNeighbors(current)) do
local tentativeGScore = gScore[current] + heuristic(current, neighbor)
if tentativeGScore < (gScore[neighbor] or math.huge) then
cameFrom[neighbor] = current
gScore[neighbor] = tentativeGScore
fScore[neighbor] = gScore[neighbor] + heuristic(neighbor, goal)
if not table.find(openSet, neighbor) then
table.insert(openSet, neighbor)
end
end
end
end
return nil
end
local path = findPath(rootPart.Position, position)
if path then
humanoid.WalkSpeed = speed
for _, waypoint in ipairs(path) do
humanoid:MoveTo(waypoint)
humanoid.MoveToFinished:Wait()
end
return true
else
return false
end
end
-- Body Part Movement
local function bodyPartMoveTo(part, target)
if part then
local weld = Instance.new("WeldConstraint")
weld.Part0 = part
weld.Part1 = target
weld.Parent = part
wait(1)
weld:Destroy()
end
end
local function armMoveTo(target)
local rightArm = npc:FindFirstChild("RightArm")
local leftArm = npc:FindFirstChild("LeftArm")
if rightArm then
bodyPartMoveTo(rightArm, target)
elseif leftArm then
bodyPartMoveTo(leftArm, target)
end
end
local function legMoveTo(target)
local rightLeg = npc:FindFirstChild("RightLeg")
local leftLeg = npc:FindFirstChild("LeftLeg")
if rightLeg then
bodyPartMoveTo(rightLeg, target)
elseif leftLeg then
bodyPartMoveTo(leftLeg, target)
end
end
local function torsoMoveTo(target)
if upperTorso then
bodyPartMoveTo(upperTorso, target)
elseif lowerTorso then
bodyPartMoveTo(lowerTorso, target)
end
end
-- Enhanced Pathfinding with Multiple Strategies
local function enhancedMoveTo(position, speed)
local strategies = {pathfindTo, directMoveTo, randomWaypointMove, zigzagMoveTo, gridMoveTo, recursivePathfindTo, customPathfindTo}
local success = false
for _, strategy in ipairs(strategies) do
success = strategy(position, speed)
if success then
break
end
end
if not success then
randomWaypointMove(speed)
end
end
-- State Machine and Behavior Patterns
local currentState = "idle"
local function setState(state)
if currentState == state then return end
stopAllSounds()
stopAllAnimations()
currentState = state
if state == "idle" then
playSound(sounds.idle)
playAnimation(animations.idle)
enhancedMoveTo(waypoints[currentWaypoint], walkingSpeed)
currentWaypoint = (currentWaypoint % #waypoints) + 1
elseif state == "patrolling" then
playAnimation(animations.walk)
enhancedMoveTo(waypoints[currentWaypoint], walkingSpeed)
currentWaypoint = (currentWaypoint % #waypoints) + 1
elseif state == "alert" then
playSound(sounds.alert)
playAnimation(animations.alert)
elseif state == "chasing" then
playSound(sounds.chase)
playAnimation(animations.run)
local nearestPlayer = findNearestPlayer()
if nearestPlayer then
local targetPosition = (nearestPlayer.Character.UpperTorso.Position + nearestPlayer.Character.LowerTorso.Position) / 2
enhancedMoveTo(targetPosition, runningSpeed)
armMoveTo(nearestPlayer.Character.Torso)
legMoveTo(nearestPlayer.Character.Torso)
torsoMoveTo(nearestPlayer.Character.Torso)
end
end
end
-- Main Behavior Loop
while true do
local nearestPlayer, distance = findNearestPlayer()
if nearestPlayer then
if distance < chaseProximity then
setState("chasing")
elseif distance < alertProximity then
setState("alert")
else
setState("idle")
end
else
setState("idle")
end
wait(0.1)
end