I have a CanCollide false part covering the spawn area in my game, and without the script enabled I can spawn inside no issues, but with the script enabled I spawn on the roof. The script, as seen below, has a Touched event which I thought was the issue. I tried spawning in without the TouchInterest that the Touched event creates and still spawned on the roof. If anyone could help or explain why this happens I would appreciate it.
Script inside the part:
local parent = script.Parent
parent.Touched:Connect(function(part)
if part.Parent:FindFirstChild("Humanoid") then
if part == part.Parent.PrimaryPart then
Instance.new("ForceField", part.Parent)
end
end
end)
parent.TouchEnded:Connect(function(part)
if part.Parent:FindFirstChild("Humanoid") then
if part == part.Parent.PrimaryPart then
part.Parent:FindFirstChild("ForceField"):Destroy()
end
end
end)
Add a if statement to both your functions to check if the player already has a forcefield. Whenever the player moves inside of that part, the Touched event will be fired, so your script will create a lof of force fields. I’m not sure if this will fix the second issue that you just pointed out.
local parent = script.Parent
parent.Touched:Connect(function(part)
if part.Parent:FindFirstChild("Humanoid") and part ~= nil then -- Check if the part exists and if it's a humanoid character
if part == part.Parent.PrimaryPart then
if not part.Parent:FindFirstChildOfClass("ForceField") then -- If the player has not a forcefield yet...
local forceField = Instance.new("ForceField", part.Parent) -- Create a forcefield
end
end
end
end)
parent.TouchEnded:Connect(function(part)
if part.Parent:FindFirstChild("Humanoid") and part ~= nil then -- If is a humanoid character and the part exists, then...
if part == part.Parent.PrimaryPart then
if part.Parent:FindFirstChildOfClass("ForceField") then -- If the character has a forcefield...
part.Parent:FindFirstChild("ForceField"):Destroy() -- Remove the forcefield
end
end
end
end)
That’s not the case because it only fires if the HumanoidRootPart touches the part (if part == part.Parent.PrimaryPart then). That’s what I thought at first but it only fires once after testing.
Then I have no idea of how to fix this. But on my game, I had a part that covered an entire area of the game, anchored and with CanCollide set to false, and the players sometimes spawned on the roof, and sometimes on the ground, no scripts were inside of that part and it was only used to detect how many players are in that region and do a specific action with them, but stills not creating any instances on the player character.
After I removed this part and created a different system, this problem was gone.
I suggest creating two parts: one part on the player spawn (which the player will always touch when they spawn), with one script inside of it to create the force field. Then create another part in the end of the safe zone, that when the player touches, removes the force field. This worked for me, it was happening just because that the part was there and filling that area.
Alright so I just tested everything in multiple situations. My conclusion is that it is on Roblox’s side. Whenever a script uses the Touched function on a part that has CanCollide off and you try to spawn inside it, Roblox seems to view the part as if CanCollide is on.
local parent = script.Parent
parent.Touched:Connect(function(part)
wait(5)
print("test")
end)
Even this will cause you to spawn on the top. Might be a bug, because I assume none of this was intended to be this way.
If you want a player to have a forcefield within spawn area, you can do a distance check from the spawn part and if they are within range, give them a forcefield if they don’t have one.
This will be way more performant than using .Touched which will fire a lot more.
It doesn’t matter if it doesn’t pass the first if statement, it’s still being fired every time a part touches it which might cause lag with 10+ players and dozens of parts per player at spawn firing the event.