Changing the size of a part welded to a player via a LocalScript is breaking some player collisions

I have been working on a roblox game that is meant to play similarly to the multiplayer gamemode in Bomberman 64, and that includes picking up and throwing bombs.
When a player tries to pick up a bomb, the server will move the bomb a few studs in the direction of their UpperTorso’s lookVector, and then weld the bomb to the player’s torso using a WeldConstraint. The bomb itself is just a massless sphere that has its collisions disabled, but is also welded to a a second, massless, completely transparent sphere with its collisions enabled and a defined non-changing size of 3, which acts as the bomb’s collider. The collider is in a CollisionGroup to ignore collisions between it, other bombs, and players. The purpose of the collider is to prevent players from picking up a bomb and clipping it through a wall.
The reason why I have a separate part for the bomb and the collider is so I can change the apparent size of the bomb without affecting the collider. The need to be able change the size of the bomb is in order to make it appear as if the bomb is pulsing:
A1pePlfYhF
The collisions work fine if I change the size of the bomb using a script.

This is done using the following code inside of a script parented under the bomb.

local bomb = script.Parent;
local growing = false;
local bombsizeBig = {};
bombsizeBig.Size = bomb.Size*1.1;
local bombsizeSmall = {};
bombsizeSmall.Size = bomb.Size*.9; --reason why I declared bombsizeBig and small like this was because I initially used a tween 
--but decided against it since the size could change faster than the tween completed
function pulse()
	local size = bomb:FindFirstChild("Size").Value; --Size is a Vector3 Value attached to the bomb.
	bombsizeBig.Size = size*1.1;
	bombsizeSmall.Size =  size*.9;
	if growing then
		bomb.Size = bomb.Size + Vector3.new(.05,.05,.05);
		if bomb.Size.X >= bombsizeBig.Size.X then
			growing = false;
		end
	else
		bomb.Size = bomb.Size - Vector3.new(.05,.05,.05);
		if bomb.Size.X <= bombsizeSmall.Size.X then
			growing = true;
		end
	end
end
game:GetService("RunService").Heartbeat:Connect(pulse);

The collider will stay the same size even as the bomb’s size varies. It also works perfectly fine if the bomb’s size isn’t changed:

But it seems to break things if I dare change the bomb’s size using a LocalScript:


Using the following code located in a LocalScript under StarterPlayerScripts

--this function will be run on every bomb in the workspace every time RenderStepped fires.
local function pulseBomb(bom)
	local tval = bom:FindFirstChild("Growing");
	if not tval then
		tval = Instance.new("BoolValue");
		tval.Name = "Growing";
		tval.Value = true;
		tval.Parent = bom;
	end
	local size = bom:FindFirstChild("Size").Value;
	local bombsizeBigSize = size*1.1;
	local bombsizeSmallSize =  size*.9;
	if tval.Value then
		bom.Size = bom.Size + Vector3.new(.05,.05,.05);
		if bom.Size.X >= bombsizeBigSize.X then
			tval.Value = false;
		end
	else
		bom.Size = bom.Size - Vector3.new(.05,.05,.05);
		if bom.Size.X <= bombsizeSmallSize.X then
			tval.Value = true;
		end
	end
end

Has anyone come across a similar issue and was able to fix it?

Also as a quick sidenote, the server-sided script “solution” is unusable as is since it comes with its own problems that the LocalScript solution doesn’t, only concerning player replication instead of player collisions.

2 Likes

Hi. This not a generalizable solution, but in this case you could avoid setting the part’s size from the client and change a sphere-type SpecialMesh’s Scale instead. If you ever wanted another shape for the bomb, you could change its FileMesh to the desired mesh. As you can see, you would still need to resize stuff or do other complex workarounds if you later decided to use more parts as details.

2 Likes

I’m unable to see anything here in your code that should be causing this. Are you certain there’s nothing else that changes collisions? Or possibly a problem with how you’re setting them?

Huh, so I decided to try your suggestion and replaced the Bomb Part and Collider Part welded together with just a Ball Part and a SpecialMesh with it’s parent set to that Ball Part and it seems to work just fine, even if the SpecialMesh’s scale is set on the client-side.


The quick and dirty scaling code I replaced the old pulseBomb function with in the same LocalScript:

local function newPulseBomb(bom)
	local tval = bom:FindFirstChild("Growing");
	if not tval then
		tval = Instance.new("BoolValue");
		tval.Name = "Growing";
		tval.Value = true;
		tval.Parent = bom;
	end
	local size = bom:FindFirstChild("Size").Value;
	local bombsizeBigSize = Vector3.new(.09,.09,.09);
	local bombsizeSmallSize =  Vector3.new(.07,.07,.07);
	if tval.Value then
		bom.Mesh.Scale = bom.Mesh.Scale + Vector3.new(.001,.001,.001);
		if bom.Mesh.Scale.X >= bombsizeBigSize.X then
			tval.Value = false;
		end
	else
		bom.Mesh.Scale = bom.Mesh.Scale - Vector3.new(.001,.001,.001);
		if bom.Mesh.Scale.X <= bombsizeSmallSize.X then
			tval.Value = true;
		end
	end
	
end

Even though it works perfectly and I’m deeply appreciative of your solution, I’m afraid to mark it as a solution since it’s only a workaround rather than an explanation to what the issue is in the first place. I’d like to keep the thread open for discussion a bit longer since I really am curious about what might be causing it.

The only changes I made between the videos I took in the OP post were disabling/enabling the code blocks I provided.

Hmmm, that was the only thing I was able to think of could be causing this. Hopefully someone else can figure this out. I’ll return if I can come up with anything else.

1 Like

That’s alright, thank you for your help. I appreciate it a lot.

I actually just forgot until now because I disabled the effect a long time ago, but changing the size of the bomb locally isn’t the only thing that breaks collisions. I made an effect to bob the sprites for power-ups up and down slowly, and yet again, doing the effect on the server works but doing it in a local script breaks collisions when a player picks up the powerup:

On the server:

local yoff = .5;
local t = 0;
local anch = script.Parent.Parent;
local img = script.Parent;
local sp = img:FindFirstChild("PowerupGUI");
local grav = anch:FindFirstChild("Pause");
function bob()
	t = t + .05;
	img.Position = anch.Position + Vector3.new(0,yoff*math.sin(t) + .5,0);
end

game:GetService("RunService").Heartbeat:Connect(bob);

Doing the effect on the client in a LocalScript:

local yoff = .5
local function rotateStars()
	local pows = workspace.Powerups:GetChildren();
	for i,v in pairs(pows) do
		local blackImg = v.BlackStar.SurfaceGui.ImageLabel;
		local yellowImg = v.YellowStar.SurfaceGui.ImageLabel;
		blackImg.Rotation = blackImg.Rotation - 2;
		yellowImg.Rotation = yellowImg.Rotation + 2;
		local t = v.ImageAnchor:FindFirstChild("t");
		local img = v.ImageAnchor
		t.Value = t.Value + .05;
		img.Position = v.Position + Vector3.new(0,yoff*math.sin(t.Value) + .5,0); --this line in particular is the offender
                 -- commenting it out stops the bobbing effect but also stops the collision issue. the rest of the lines cause no issues
	end
end

game:GetService("RunService").RenderStepped:Connect(rotateStars)

The interesting difference between this and the problems I was having with the bombs is that unlike the bombs, the powerups have no parts in its hierarchy with CanCollide set to true:
RobloxStudioBeta_Kdakt7Whj4
(BobbingScript is what ran the above code for the server-sided example)
The three welds are what weld BlackStar, ImageAnchor, and YellowStar to the Powerup part.