Hello developers!
I’m currently making a pathfinding monster that steals player’s skin, he walk across waypoints until he sees the player, after that, he’ll start chasing player, but the problem is that the npc is extremly dumb! I’m trying to make a system that when npc lost player, he’ll wander to the last point that the player was seen but there’s some bugs, when the monster kill player, he’ll steals player’s skin
Example:
Here’s his pathfinding script
script.Parent.HumanoidRootPart:SetNetworkOwner(nil)
local monster = script.Parent
local humanoid = monster.Humanoid
local chasing = false
local touch = false
local LostTarget = false
local IsDisguised = false
local insideChase = false
local PathfindingService = game:GetService("PathfindingService")
game.ReplicatedStorage.Remotes.DisguiseSkinStealer.OnServerEvent:Connect(function(plr)
IsDisguised = true
local playerId = plr.UserId
local apparence = game.Players:GetHumanoidDescriptionFromUserId(playerId)
humanoid:ApplyDescription(apparence)
monster["Right Arm"].Transparency = 0
monster["Left Arm"].Transparency = 0
monster.Torso.Transparency = 0
monster["Left Leg"].Transparency = 0
monster["Right Leg"].Transparency = 0
monster.Head.Transparency = 0
monster.Body.Transparency = 1
monster.Eye.Transparency = 1
monster.Head.face.Transparency = 0
end)
local function canSeeTarget(target)
local origin = monster.HumanoidRootPart.Position
local direction = (target.HumanoidRootPart.Position - monster.HumanoidRootPart.Position).Unit * 30
local ray = Ray.new(origin, direction)
local hit, pos = workspace:FindPartOnRay(ray, monster)
if hit then
if hit:IsDescendantOf(target) then
return true
end
else
return false
end
end
local function findTarget()
local players = game.Players:GetPlayers()
local maxDistance = 300
local nearestTarget = nil
for index, player in pairs(players) do
if player.Character and player.Character.Humanoid.Health > 0 then
local target = player.Character
local distance = (monster.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
if distance < maxDistance then
if canSeeTarget(target) or LostTarget == true then
nearestTarget = target
maxDistance = distance
end
end
end
end
return nearestTarget
end
local function attack(target)
local distance = (monster.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
if distance > 4.5 then
LostTarget = true
humanoid:MoveTo(target.HumanoidRootPart.Position)
if script.Parent.Body["HORROR SCREAM 07"].IsPlaying == false then
script.Parent.Body["HORROR SCREAM 07"]:Play()
end
humanoid.MoveToFinished:Connect(function()
LostTarget = false
end)
else
chasing = false
if touch == false then
touch = true
if IsDisguised == false then
game.ReplicatedStorage.Remotes.PlayCutscene:FireClient(game.Players:GetPlayerFromCharacter(target), 99, monster, script.AttackAnimation)
else
game.ReplicatedStorage.Remotes.PlayCutscene:FireClient(game.Players:GetPlayerFromCharacter(target), 99, monster, script.DAttackAnimation)
end
end
task.wait(3)
touch = false
end
end
local function getPath(destination)
local pathParams = {
["AgentHeight"] = 4,
["AgentRadius"] = 4,
["AgentCanJump"] = false
}
local path = PathfindingService:CreatePath(pathParams)
path:ComputeAsync(monster.HumanoidRootPart.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 = findTarget()
if target then
if chasing == false then
chasing = true
end
attack(target)
break
else
chasing = false
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
end
else
return
end
end
local function patrol()
local waypoints = workspace.waypoints1:GetChildren()
local randomNum = math.random(1, #waypoints)
--local walkAnim = humanoid:LoadAnimation(script.walk.Animation)
--walkAnim.Looped = true
--walkAnim:Play()
if chasing == true then
if IsDisguised == true then
humanoid.WalkSpeed = 16
local RunAnim = humanoid:LoadAnimation(script.walk.RunAnim)
local WalkAnim = humanoid:LoadAnimation(script.walk.Animation)
local DRunAnim = humanoid:LoadAnimation(script.walk.DisguisedRun)
local DWalkAnim = humanoid:LoadAnimation(script.walk.DisguisedWalk)
if insideChase == false then
insideChase = true
RunAnim:Stop()
DWalkAnim:Stop()
WalkAnim:Stop()
DRunAnim:Play()
end
else
humanoid.WalkSpeed = 17
local RunAnim = humanoid:LoadAnimation(script.walk.RunAnim)
local WalkAnim = humanoid:LoadAnimation(script.walk.Animation)
RunAnim.Looped = true
if insideChase == false then
insideChase = true
RunAnim:Play()
WalkAnim:Stop()
end
end
else
if IsDisguised == true then
humanoid.WalkSpeed = 12
insideChase = false
local WalkAnim = humanoid:LoadAnimation(script.walk.RunAnim)
local RunAnim = humanoid:LoadAnimation(script.walk.Animation)
local DWalkAnim = humanoid:LoadAnimation(script.walk.DisguisedWalk)
local DRunAnim = humanoid:LoadAnimation(script.walk.DisguisedRun)
DWalkAnim:Play()
RunAnim:Stop()
DRunAnim:Stop()
WalkAnim:Stop()
else
humanoid.WalkSpeed = 12
insideChase = false
local WalkAnim = humanoid:LoadAnimation(script.walk.RunAnim)
local RunAnim = humanoid:LoadAnimation(script.walk.Animation)
RunAnim.Looped = true
RunAnim:Play()
WalkAnim:Stop()
end
end
walkTo(waypoints[randomNum].Position)
end
while wait(0.01) do
patrol()
end
Here’s the jumpscare script (Not so usefull):
game.ReplicatedStorage.Remotes.PlayCutscene.OnClientEvent:Connect(function(level, monster, anim1)
local function AvatarAssync()
local userId = game.Players.LocalPlayer.UserId
local apparence = game.Players:GetHumanoidDescriptionFromUserId(userId)
return apparence
end
if level == 99 then
local animend = false
local cam = game.Workspace.CurrentCamera
local anim = monster.Humanoid:LoadAnimation(anim1)
anim:Play()
monster.Body["Brief Jumpscare"]:Play()
monster.Body["HORROR SCREAM 07"]:Stop()
repeat
cam.CameraType = Enum.CameraType.Scriptable
until cam.CameraType == Enum.CameraType.Scriptable
game.Players.LocalPlayer.Character.Humanoid.WalkSpeed = 0
anim.Ended:Connect(function()
repeat
cam.CameraType = Enum.CameraType.Custom
until cam.CameraType == Enum.CameraType.Custom
animend = true
game.Players.LocalPlayer.Character.Humanoid.Health = 0
game.Players.LocalPlayer.Character.Humanoid.WalkSpeed = 10
local Apparence = AvatarAssync()
game.ReplicatedStorage.Remotes.DisguiseSkinStealer:FireServer(Apparence)
end)
while not animend do
cam.CFrame = monster.CameraJumpscare.CFrame
monster.Humanoid:RemoveAccessories()
game:GetService("RunService").RenderStepped:Wait()
task.wait()
end
His model:
His pathfinding childrens: