SCP-173/Creaking Effect

Short and simple! I wanna make the creaking effect in minecraft, SCP 173 effect in ROBLOX, but when I do it; it kinda… drags itself, and doesnt play the sound when you look at it, or play the scraping sound when it moves what can I improve? Here’s the full code.

local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local movedRandomID = {
	"rbxassetid://94917360964270",
	"rbxassetid://127912604336439",
	"rbxassetid://95185361770714",
	"rbxassetid://119097026636822",
	"rbxassetid://123712207543782"
}

local randomID = movedRandomID[math.random(1, #movedRandomID)]
local sound = script.Parent:FindFirstChild("MovedSound")
local stoneSlidingSound = script.Parent:FindFirstChild("Moved")


if sound then
	sound.SoundId = randomID
end

if stoneSlidingSound then
	stoneSlidingSound.Looped = true
end


local path = PathfindingService:CreatePath({
	AgentHeight = 6,
	AgentRadius = 3,
	AgentCanJump = false,
	Costs = { Water = 100, DangerZone = math.huge }
})

local npcRootPart = script.Parent:FindFirstChild("HumanoidRootPart")
local humanoid = script.Parent:WaitForChild("Humanoid")

if not npcRootPart then return end

local lastPosition = npcRootPart.Position
local hasMoved = false

function updateMovementState()
	local currentPosition = npcRootPart.Position
	hasMoved = (currentPosition - lastPosition).Magnitude > 0.1
	lastPosition = currentPosition
end

function isPlayerLookingAtNPC()
	for _, player in Players:GetPlayers() do
		local character = player.Character
		if character and character:FindFirstChild("HumanoidRootPart") then
			local lookVector = character.HumanoidRootPart.CFrame.LookVector
			local directionToNPC = (npcRootPart.Position - character.HumanoidRootPart.Position).Unit
			if lookVector:Dot(directionToNPC) > 0.7 then
				return true
			end
		end
	end
	return false
end


function getNearestPlayer()
	local nearestPlayer
	local maxDistance = 200
	for _, player in Players:GetPlayers() do
		local character = player.Character
		if character and character:FindFirstChild("HumanoidRootPart") then
			local distance = (npcRootPart.Position - character.HumanoidRootPart.Position).Magnitude
			if distance < maxDistance and character.Humanoid.Health > 0 then
				nearestPlayer = character
				maxDistance = distance
			end
		end
	end
	return nearestPlayer
end


function moveToTarget(destination)
	local success, errorMessage = pcall(function()
		path:ComputeAsync(npcRootPart.Position, destination)
	end)
	if success and path.Status == Enum.PathStatus.Complete then
		local waypoints = path:GetWaypoints()
		if #waypoints > 1 then
			humanoid:MoveTo(waypoints[2].Position)
			humanoid.MoveToFinished:Wait()
		end
	end
end

local soundCooldown = 0.01

RunService.Heartbeat:Connect(function()
	if isPlayerLookingAtNPC() then
		if hasMoved and sound and (tick() - soundCooldown > soundCooldown) then
			sound.TimePosition = 0
			sound:Play()
			hasMoved = false
			soundCooldown = tick()
		end
		if hasMoved and stoneSlidingSound then
stoneSliding:Play()
		end
	else
		local target = getNearestPlayer()
		if target then
			local distance = (npcRootPart.Position - target.HumanoidRootPart.Position).Magnitude
			if distance < 4 then
				target.Humanoid.Health = 0
				script.Parent["Neck Snap (Disturbing)"]:Play()
			else
				moveToTarget(target.HumanoidRootPart.Position)
				updateMovementState()
			end
		end
	end
end)

npcRootPart:SetNetworkOwner(nil)

Check the LinearVelocity of moving items. If the velocity is over a certain value (like .2 or whatever works for your situation) play the sound. As soon as it drops below that value stop the sound.

1 Like

Could you provide a video?
Unless its exactly like CB.

Of the expected behaviour that you want the sounds to do and what it currently is doin.