Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

SiteDoors is not a valid member of Workspace "Workspace"?

--[[
	Author: WelpNathan
	Date: 31/05/2018
	
	Script: This script will control how the SCP reacts to touching
			and other interactions.
--]]

---------------------------
--   V A R I A B L E S   --
---------------------------

-- ROBLOX Services
local players = game:GetService('Players')
local physicsService = game:GetService("PhysicsService")
local pathfindingService = game:GetService("PathfindingService")

-- Locate the physical SCP
local this = script.Parent.Parent:WaitForChild('PhysicalSCP')

-- Store the settings of the SCP
local settingsSCP = {
	magnitudeMax = 500,
	sound = {
		damageSound = 1542642349,
		standbySound = {}
	}
}

-- Store the previous weld in memory
local previousWeld = nil

local scpBreached = false

---------------------------
-- M A I N   S C R I P T --
---------------------------

script.Parent.BreachSCP.Changed:Connect(function(value)
	scpBreached = value
end)

--[[
	Function:
		Usage:
			- When called, it will loop through the parts in the model
		  	  and will generate a weld to weld them all together.
		Arguments:
			- model:
				- This is the model which will be welded together. Only
				  supports singular for loop. Won't go into other models.
	
--]]
local weldModel = function(model)
	local parts = model:GetChildren()
	for _, part in pairs(parts) do
		if part:IsA("Part") then
			if previousWeld ~= nil then
				local weld = Instance.new("Weld")
				weld.Part0 = previousWeld
				weld.Part1 = part
				weld.C0 = previousWeld.CFrame:inverse()
				weld.C1 = part.CFrame:inverse()
				weld.Parent = previousWeld
				part.Anchored = false
			end
			previousWeld = part
		end
	end
end
-- Weld the humanoid parts
weldModel(script.Parent.Parent.PhysicalSCP)

--[[
	Make sure that the SCP cannot collide with doors.
--]]
local scpGroup = "GroupSCP"
local doorGroup = "GroupDoor"
 
physicsService:CreateCollisionGroup(scpGroup)
physicsService:CreateCollisionGroup(doorGroup)

function addPartToCollisionGroup(root, colissionGroup)
	for _, child in pairs (root:GetChildren()) do
		addPartToCollisionGroup(child, colissionGroup)
	end
	
	if root:IsA('Part') or root:IsA('UnionOperation') then
		physicsService:SetPartCollisionGroup(root, colissionGroup)
	end
end
addPartToCollisionGroup(workspace.SiteDoors, doorGroup)
addPartToCollisionGroup(this, scpGroup)
physicsService:CollisionGroupSetCollidable(doorGroup, scpGroup, false)

--[[
	Function:
		Usage:
			- When called, it will attempt to locate the nearest player
			  model to attack. It will only attack players. SCPs are
			  allies.
		Arguments:
			- positionSCP:
				- This is the current position of the SCP. This is usually
				  the Torso found in PhysicalSCP.
--]]
local findNearestAttack = function(positionSCP)
	local currentPlayers = players:GetPlayers()
	local pos = settingsSCP.magnitudeMax
	local attackPart = nil
	for _, player in pairs(currentPlayers) do
		-- Check to see if there is a valid model of the player
		if player.Character and player.Character:FindFirstChild('Humanoid') and player.Character:FindFirstChild('HumanoidRootPart') and player.Character.Humanoid.Health > 0 then
			local distance = player:DistanceFromCharacter(positionSCP)
			if distance < settingsSCP.magnitudeMax and distance ~= 0 and distance < pos then
				pos = distance
				attackPart = player.Character.HumanoidRootPart
			end
		end
	end
	
	return attackPart
end

--[[
	Function:
		Usage:
			- When called, it will scroll through a table and see
			  if there is a matching value.
		Arguments:
			- tablePhysical: The table.
			- tableValue: The table value we're trying to find.
--]]
local searchTable = function(tablePhysical, tableValue)
	for i, v in pairs(tablePhysical) do
		if v == tableValue then
			return i
		end
	end
	return nil
end

--[[
	Touch Event:
		- When this is fired, it will proceed to check if a
		  player has touched the SCP. If a player has, they will
		  take damage.
--]]
local damageDebounce = {}
this.BoundarySCP.Touched:Connect(function(hit)
	if scpBreached == false then return end
	local player = players:GetPlayerFromCharacter(hit.Parent)
	if player and player.Character and player.Character:FindFirstChild('Humanoid') and player.Character.Humanoid.Health > 0 then
		if searchTable(damageDebounce, player.UserId) == nil then
			-- Take damage from the player
			-- Add a debounce so they don't constantly take damage
			-- Remove the debounce
			player.Character.Humanoid:TakeDamage(20)
			table.insert(damageDebounce, player.UserId)
			
			-- If there is a damage sound, play it
			if settingsSCP.sound.damageSound ~= nil then
				local sound = Instance.new('Sound', this.Torso)
				sound.SoundId = 'rbxassetid://' .. settingsSCP.sound.damageSound
				sound.Volume = 1
				sound:Play()
				spawn(function()
					repeat wait(3) until sound.Playing == false
					sound:Destroy()
				end)
			end
			
			wait(0.5)
			local index = searchTable(damageDebounce, player.UserId)
			table.remove(damageDebounce, index)
		end
	end
end)

-- Make the SCP into a production environment (remove red)
for _, part in pairs(this:GetChildren()) do
	if part:IsA('Part') then
		part.Transparency = 1
	end
end
this.Torso.Transparency = 0

local destroyed = function(x)
	if x.Parent then return false end
	local _, result = pcall(function() x.Parent = x end)
	return result:match("locked") and true or false
end

--[[
	While Loop:
		Every 3 seconds, it will compare all distances of players and
		if the player is within the SCP's reach, it will attempt to move to it.
--]]
while true do
	while scpBreached do
		local targetPlayer = findNearestAttack(this:WaitForChild('Torso').Position)
		if targetPlayer ~= nil then
			-- Calculate the path and get the waypoints
			local start = this:WaitForChild('Torso')
			local path = pathfindingService:FindPathAsync(start.Position, targetPlayer.Character.HumanoidRootPart.Position)
			local waypoints = path:GetWaypoints()
			
			-- Loop through all of the waypoints in the path
			for waypointIndex, waypoint in pairs(waypoints) do
				if waypoint.Action == Enum.PathWaypointAction.Jump then
					this.Humanoid.Jump = true
				else
					local waypointPosition = waypoint.Position
					-- Make the humanoid move to the current waypoint
					this.Humanoid:MoveTo(waypointPosition)
					-- Wait until the humanoid has reached it's target
					this.Humanoid.MoveToFinished:Wait()
					
					if scpBreached == false then break end
					
					if targetPlayer and targetPlayer.Character:FindFirstChild('HumanoidRootPart') and targetPlayer.Character:FindFirstChild('Humanoid') and targetPlayer.Character.Humanoid.Health > 0 and (targetPlayer.Character.HumanoidRootPart.Position - this.Torso.Position).magnitude < 20 then
						break
					end
				end
			end
			
			if targetPlayer and targetPlayer.Character and targetPlayer.Character:FindFirstChild('Humanoid') and targetPlayer.Character.Humanoid.Health > 0 and targetPlayer.Character:FindFirstChild('HumanoidRootPart') then
				if (targetPlayer.Character.HumanoidRootPart.Position - this.Torso.Position).magnitude < 20 then
					while scpBreached == true and targetPlayer and targetPlayer.Character:FindFirstChild('HumanoidRootPart') and targetPlayer.Character:FindFirstChild('Humanoid') and targetPlayer.Character.Humanoid.Health > 0 and (targetPlayer.Character.HumanoidRootPart.Position - this.Torso.Position).magnitude < 20 do
						this.Humanoid:MoveTo(targetPlayer.Character.HumanoidRootPart.Position, targetPlayer.Character.HumanoidRootPart)
						wait(0.5)
					end
				end
			end
		end
		wait(0.25)
	end
	wait(0.25)
end

1 answer

Read the error it says sitedoors is not in workspace check if it exist or is correctly named

This discussion is preserved as it was. New answers, comments, and votes are closed.