Make it so other players cant collide with someone's local part

  1. The goal of this project is for each player to be able to spawn a boulder, and push it up this small hill. The idea being that each players has their own “client side” boulder that only they can interact with. The issue is, even though each player can only see their own boulder, they are still able to collide with other players boulders- as shown in the video.

  1. I have experimented with collision filtering, but if I’m not wrong that would entail making a new collision group for each players, so that each player can only collide with their boulders.
local pls = game:GetService("Players")
local rs = game.ReplicatedStorage
local ps = game:GetService("PhysicsService")

local plr = pls.LocalPlayer

local boulder;
local colliders;

repeat 
	wait()
	colliders = workspace.Levels.Colliders:GetChildren()
until #colliders >= 2

-- check collider parts
for part, child in pairs(colliders) do
	print(part)
	-- if collider touched
	child.Touched:Connect(function(hit) 
		if (hit ~= boulder) then
			-- checks if you touched the collider, summons your boulder to be able to push
			if (hit.Parent:FindFirstChild("Humanoid") and game.Players.LocalPlayer.Character.Humanoid:GetState() == Enum.HumanoidStateType.Running and hit.Name == "HumanoidRootPart" and hit.Parent.Name == plr.Name) then
				if (child.Name == "1") then					
					boulder = rs.boulder:clone()
					boulder.CanCollide = true
					boulder.Parent = workspace.CurrentCamera
					boulder.Position = Vector3.new(13.5, 8, -134)
				end
			end
		else
			-- if boulder touches second collider, teleport him and remove boulder
			if (child.Name == "1f") then
				wait(1)
				boulder:Remove()
				plr.Character:FindFirstChild("HumanoidRootPart").CFrame = CFrame.new(Vector3.new(12, 8, -100))
				print("you win nig")
			end
		end
	end)
	
	-- if collider touch ended
	child.TouchEnded:Connect(function(hit)
		if (hit ~= boulder) then
			-- if you leave the area, remove your boulder
			if (hit.Parent:FindFirstChild("Humanoid") and game.Players.LocalPlayer.Character.Humanoid:GetState() == Enum.HumanoidStateType.Running and hit.Name == "HumanoidRootPart" and hit.Parent.Name == plr.Name) then
				if child.Name == "1" then
					boulder:Remove()
				end
			end
		end
	end)
end


The general idea behind the script is to go through my colliders, and if the player walks into the right area, create a boulder using a clone in rs, move it to the current camera to make it client side, and then allow collisions, and set its position.

If anyone has ideas for a collision filtering system, or if there is a simple fix for local collisions lmk.

5 Likes

You may be able to solve the issue using two Collision Groups for characters. The standard character group should be assigned to all characters by the server when they spawn in, and this group cannot collide with boulders. The second character group should be configured to be able to collide with boulders, and this group should be assigned by the local client to their character model only.

1 Like

Do collision groups work with local scripts? i.e. would you only need two groups and then each player’s client knows not to collide with other boulders, or would you need to dynamically create a collision group for each player…?

Set network ownership of the boulder to the player who owns it, then disable collisions for the boulder for every other player locally (e.g through a RemoteEvent which tells each client to disable collisions), orrr…

Set network ownership of the boulder to the player who owns it, then disable collisions for the boulder on server, and then enable collisions locally for the player who owns it. (Not entirely sure if this would work, but if the player owns network ownership i’m pretty sure it should!)

1 Like

Thanks for the idea, just having trouble with a few things. For one, how would I access the boulder through a server script in order to set network ownership (as you can’t do it in a local script)? I’ve tried passing the Boulder instance through a RemoteEvent, but the server sees it as nil since I guess it is being stored client-side…?

Code for passing boulder into server script:

boulder = rs.boulder:clone()
boulder.Parent = workspace.CurrentCamera
game.ReplicatedStorage.BoulderSpawned:FireServer(boulder)

Code that’s actually in the server script:

game.ReplicatedStorage.BoulderSpawned.OnServerEvent:Connect(function(plr, boulder)
	boulder:SetNetworkOwner(plr)
	--game.ReplicatedStorage.BoulderSpawned:FireClient(plr)
end)

Error:

ServerScriptService.BoulderCollisions:5: attempt to index nil with 'SetNetworkOwner'  -  Server - BoulderCollisions:5

Again, any help is appreciated, thank you.

Collision Groups can be set via LocalScript, but the changes do not replicate to other clients; however, you only need the two groups specifically because the local changes don’t replicate. This allows each player to change their group to the boulder-colliding group without affecting other players.

1 Like

hey i think i may have a solution how about you make the boulder uncollideable and set it collidable via localScript? that worked out fine for me hope this helps! here is how it should look like:

replicatedStorage: boulder: CanCollide: false

localScript handling boulder cloning: boulder: CanCollide: true

like this it should work just fine for player1 but player2 will not collide with the boulder at all

1 Like

Yeah! I tried this already but I couldn’t seem to get it to work… thank you for the suggestion though!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.