Players can move a moving object whilst welded to it after jumping

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I want the player to be able to get stuck in the rolling snowball if they touch it (Already done).

Want to ALWAYS have this
Streamable

  1. What is the issue? Include screenshots / videos if possible!
    Players can time a jump to be able to move a snowball whilst they are welded to it.

The issue
Streamable

  1. What solutions have you tried so far? Did you look for solutions on the Creator Hub?
    Couldn’t really think of anything and I couldn’t find any solutions/situations on the devforum that related to my problem.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

Players have the “Player” collision group so they can go through snowballs (to avoid snowballs from bouncing)
Snowballs have the “Snowball” collision group so they can go through players

Hope my code isn’t that bad :grimacing:

local players = game:GetService("Players")
local debris = game:GetService("Debris")
local sizeAdd = 0.275

while true do
	local ball = Instance.new("Part")
	ball.Shape = Enum.PartType.Ball
	ball.Size = Vector3.new(2, 2, 2)
	ball.Material = Enum.Material.Snow
	ball.Color = Color3.fromRGB(255, 255, 255)
	ball.Position = script.Parent.Position
	ball.CollisionGroup = "Snowball"
	ball.Parent = workspace
	
	task.spawn(function()
		while (ball.Parent == workspace) do
			ball.Size = Vector3.new(ball.Size.X + sizeAdd, ball.Size.Y + sizeAdd, ball.Size.Z + sizeAdd)
			task.wait(0.05)
		end
	end)
	
	ball.Touched:Connect(function(part)
		if players:GetPlayerFromCharacter(part.Parent) then
			local player = players:GetPlayerFromCharacter(part.Parent)
			local hum = player.Character:FindFirstChildOfClass("Humanoid")
			
			local charParts = {}
			
			for _, part in player.Character:GetDescendants() do
				if part:IsA("BasePart") and part.CanCollide == true then
					table.insert(charParts, part)
					part.CanCollide = false
					part.CanTouch = false
				end
			end
			
			warn(part.Parent, charParts)
			
			local weld = Instance.new("WeldConstraint")
			weld.Part0 = ball
			weld.Part1 = hum.RootPart
			weld.Parent = ball

			hum.PlatformStand = true
			hum:ChangeState(Enum.HumanoidStateType.PlatformStanding)
			
			weld.Destroying:Once(function()

				hum.PlatformStand = false
				hum:ChangeState(Enum.HumanoidStateType.GettingUp)
				weld:Destroy()

				for _, part in pairs(charParts) do
					part.CanCollide = true
					part.CanTouch = true
				end

				table.clear(charParts)
			end)
		end
	end)
	
	debris:AddItem(ball, 5)
	task.wait(1.5)
end

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

I’ve not touched Roblox scripting for a long time now, so I apologise if my suggestion doesn’t help your problem.

What I believe is the root cause of this issue is network ownerships. Roblox servers handle physics calculations in-game at all times, and sometimes it can lag the server (for example when many parts fall at once). To solve this issue, the server will regularly assign “physics ownership” to nearby players of an unanchored part so that the player’s computer becomes responsible for the said unanchored part’s physics calculations.

I think the reason why the snowball gets “controlled” by the player when they jump and get hit by it is due to the network ownership being assigned to the player, hence the player has full control of the snowball and can somewhat control the snowball’s movement. To solve this, you may check out this article about network onwership:

1 Like

Tried every method and example that Roblox had showed on that article (such as ball:SetNetworkOwner(nil) to have the ownership of the ball to be the server) and none of seem to work. Maybe I could be doing something wrong or not reading the article correctly, no clue.

Will look more into it in the morning, thanks!

I would try changing the Humanoid’s state to HumanoidStateType.Physics instead
or maybe changing their state before welding them

Neither of them worked. I even tried running a repeat loop and a while loop (not both of them at the same time, just one of them in other tests), but neither of them worked either.

Additionally, I added some debug printing to get the humanoid’s state and it prints out PlatformStanding (which is pretty much what I want) but the character still looks like they’re freefalling and sometimes, the player can run (only for a split second) while they’re in the snowball.

well if youre setting the humanoids state to Physics then shouldnt the humanoid’s state be Physics and not PlatformStand..?
could you send a video of it?

Video
Streamable

What the code looks like right now (removed setting the humanoid to PlatformStand after you replied):

local players = game:GetService("Players")
local debris = game:GetService("Debris")
local sizeAdd = 0.275

while true do
	local ball = Instance.new("Part")
	ball.Shape = Enum.PartType.Ball
	ball.Size = Vector3.new(2, 2, 2)
	ball.Material = Enum.Material.Snow
	ball.Color = Color3.fromRGB(255, 255, 255)
	ball.Position = script.Parent.Position
	ball.CollisionGroup = "Snowball"
	ball.Parent = workspace

	task.spawn(function()
		while (ball.Parent == workspace) do
			ball.Size = Vector3.new(ball.Size.X + sizeAdd, ball.Size.Y + sizeAdd, ball.Size.Z + sizeAdd)
			task.wait(0.05)
		end
	end)

	ball.Touched:Connect(function(part)
		if players:GetPlayerFromCharacter(part.Parent) then
			local player = players:GetPlayerFromCharacter(part.Parent)
			local hum = player.Character:FindFirstChildOfClass("Humanoid")

			hum:ChangeState(Enum.HumanoidStateType.Physics)
			print(hum:GetState())
			
			local charParts = {}

			for _, part in player.Character:GetDescendants() do
				if part:IsA("BasePart") and part.CanCollide == true then
					table.insert(charParts, part)
					part.CanCollide = false
					part.CanTouch = false
				end
			end

			local weld = Instance.new("WeldConstraint")
			weld.Part0 = ball
			weld.Part1 = hum.RootPart
			weld.Parent = ball

			weld.Destroying:Once(function()
				hum:ChangeState(Enum.HumanoidStateType.GettingUp)
				weld:Destroy()

				for _, part in pairs(charParts) do
					part.CanCollide = true
					part.CanTouch = true
				end

				table.clear(charParts)
			end)
		end
	end)

	debris:AddItem(ball, 5)
	task.wait(1.5)
end

It seems to me that setting the humanoid’s state to Physics had the bug occur more often where sometimes the issue would happen when I’m not moving.

Try setting the network owner of the character to the server before changing states, since humanoid states cannot be set without being the network owner of the character.

1 Like

Works great now! Thank you! Sorry it took me a bit to respond back because I was testing many times, and I was confused on why the ownership of the snowballs become the client after a few minutes. Had the ownership of the ball be the server upon a player touching, but NOT upon being created (hope that made sense) which looks smoother now. Thanks again!

local players = game:GetService("Players")
local debris = game:GetService("Debris")
local sizeAdd = 0.275

while true do
	local ball = Instance.new("Part")
	ball.Shape = Enum.PartType.Ball
	ball.Size = Vector3.new(2, 2, 2)
	ball.Material = Enum.Material.Snow
	ball.Color = Color3.fromRGB(255, 255, 255)
	ball.Position = script.Parent.Position
	ball.CollisionGroup = "Snowball"
	ball.Parent = workspace
	
	ball:SetNetworkOwner(nil)

	task.spawn(function()
		while (ball.Parent == workspace) do
			ball.Size = Vector3.new(ball.Size.X + sizeAdd, ball.Size.Y + sizeAdd, ball.Size.Z + sizeAdd)
			task.wait(0.05)
		end
	end)

	ball.Touched:Connect(function(part)
		if players:GetPlayerFromCharacter(part.Parent) then
			local player = players:GetPlayerFromCharacter(part.Parent)
			local hum = player.Character:FindFirstChildOfClass("Humanoid")
			hum.RootPart:SetNetworkOwner(nil)
			hum:ChangeState(Enum.HumanoidStateType.Physics)
			print(hum:GetState())
			
			local charParts = {}

			for _, part in player.Character:GetDescendants() do
				if part:IsA("BasePart") and part.CanCollide == true then
					table.insert(charParts, part)
					part.CanCollide = false
					part.CanTouch = false
				end
			end

			local weld = Instance.new("WeldConstraint")
			weld.Part0 = ball
			weld.Part1 = hum.RootPart
			weld.Parent = ball

			weld.Destroying:Once(function()
				hum:ChangeState(Enum.HumanoidStateType.GettingUp)
				hum.RootPart:SetNetworkOwner(player)
				weld:Destroy()

				for _, part in pairs(charParts) do
					part.CanCollide = true
					part.CanTouch = true
				end

				table.clear(charParts)
			end)
		end
	end)

	debris:AddItem(ball, 5)
	task.wait(1.5)
end
1 Like

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