SeatWeld:destroy() Breaking Animation Locally

My game allows players to carry around smaller players. I created a seat on top of the player’s head so that the smaller player sits in it and gets carried around. I’ve discovered a bug where if the smaller player gets off in any manner (being put down, clicking a button to get off, or jumping off), their animations all break locally for all other players.

There are a few things I have discovered:

  • The animations still work on the server
  • The animations still work locally for the smaller player
  • The animations break for all players locally who are nearby
  • The animations do not break if other players are far enough away when the small player gets off the head of the other player
  • The smaller player can still walk around and do things as normal. Nothing else breaks.
  • The animations of players do not break in normal seats – just the one on the player’s head
  • If one of the players teleports really far away and then back, the animations are working again, which tells me that once a player is far enough away and removed from other players’ sphere of existence, then the animations are reset and work fine.

I’ve look around for a solution and I am really stumped. I’ve checked that the player is shown as removed from the seat, and they are. There isn’t anything tying them to the seat once they are no longer sitting on the player’s head.

I’ve tried commenting out the RemoveActions event code to see if that was doing it, but it didn’t make a difference.

Here is the script that runs when the small player hits the button to accept being picked up:

local Players = game:GetService("Players")
local toddler = script.Parent.Parent.Parent.Parent.Parent

script.Parent.MouseButton1Click:Connect(function()
	
	toddler.Character:FindFirstChild("HumanoidRootPart").Anchored = false
	game.ReplicatedStorage.RemoveActions:FireClient(toddler)
    -- Removes anchoring and animations from toddler if they are picked up when sleeping or sitting
	
	for i, player in pairs(Players:GetPlayers()) do
		if player.Name == script.Parent.Parent.PickupRequester.Value then
			
			player:FindFirstChild("PlayerGui").ScreenGui.Waiting.Visible = false
			player:FindFirstChild("PlayerGui").ScreenGui.Timer.Visible = false
			
			local toddlerH = toddler.Character:FindFirstChild("Humanoid")
			if toddlerH.Sit == true then
				toddlerH.Sit = false
			end
			player.Character.Head:FindFirstChild("Seat"):Sit(toddlerH)
			
			script.Parent.Parent.Visible = false
			script.Parent.Parent.Parent.GetOff.Visible = true
			player.PlayerGui.ScreenGui.PutDown.Visible = true
			
		end
	end
	
end)

After the toddler accepts and is sitting, they can click a button to get off, or they can jump off. The adult has the option to click a button to put the toddler down.

Here is the Get Off script for the toddler:

local Players = game:GetService("Players")
local toddler = script.Parent.Parent.Parent.Parent

script.Parent.MouseButton1Click:Connect(function()
	
	for i, player in pairs(Players:GetPlayers()) do
		if player.Name == script.Parent.Parent.Pickup.PickupRequester.Value then
			
			script.Parent.Parent.Pickup.PickupRequester.Value = ""
			
			player.Character.Head.Seat:FindFirstChild("SeatWeld"):Destroy()
			player.PlayerGui.ScreenGui.PickupPlayerPrompt.PickupPlayer.Value = ""
			player.PlayerGui.ScreenGui.PutDown.Visible = false
			
			script.Parent.Visible = false
			
		end
	end
	
end)

Here are a couple clips showing the issue:

1 Like

Use Animator:GetPlayingAnimationTracks and stop each AnimationTrack with a delay time of 0.
I wrote code for you to check out.

local players = game:GetService("Players")
local toddler = script.Parent.Parent.Parent.Parent -- I suggest FindFirstAncestor/FindFirstAncestorWhichIsA

script.Parent.MouseButton1Up:Connect(function()
	local player = select(2, pcall(function()
		return players:FindFirstChild(script.Parent.Parent.Pickup.PickupRequester.Value)
	end))
	if typeof(player) == 'Instance' and player:IsA("Player") then
		local character = player.Character
		if typeof(character) == 'Instance' and character:IsA("Model") then
			local head = character:FindFirstChild("Head")
			local seat = typeof(head) == 'Instance' and head:FindFirstChild("Seat")
			if typeof(seat) == 'Instance' then
				for _, seatweld in pairs(seat:GetChildren()) do
					if seatweld.Name == 'SeatWeld' then
						seatweld:Destroy()
					end
				end
				local humanoid = character:FindFirstChildWhichIsA("Humanoid")
				local animator = typeof(humanoid) == 'Instance' and humanoid:FindFirstChildWhichIsA("Animator")
				if typeof(animator) == 'Instance' and animator:IsA("Animator") then
					for _, animationTrack in pairs(animator:GetPlayingAnimationTracks()) do
						animationTrack:Stop(0)
					end
				end
				local playergui = player:FindFirstChildWhichIsA("PlayerGui")
				local screengui = typeof(playergui) == 'Instance' and playergui:FindFirstChild("ScreenGui")
				if typeof(screengui) == 'Instance' then
					pcall(function()
						screengui.PickupPlayerPrompt.PickupPlayer.Value = ''
						screengui.PutDown.Visible = false
					end)
				end
				script.Parent.Visible = false
			end
		end
	end
end)
2 Likes

Thanks Sussy!

In the end, the animations were still broken, so I decided to scrap the seat method and attach the players together using a WeldConstraint and updating the network owner to the player holding the other player. Your code helped me with the animations when refactoring this! I appreciate it so much!

1 Like