Skateboard stuck in air

I want to make a skateboard dodgeball game.
But bugs always keep appearing. I have already created a post about a problem I had on this system, here this is:
:ApplyImpulse() only works after some time

My new problem: player stuck in air for no good reason. Here’s a video:
Player stuck in air (1.5 MB)

I also have a problem with the dodgeball. Videos explain more than words, here you go:
Hand position not updating (138.2 KB)

Here is all my code:

Skateboard script:

local Players = game:GetService("Players")
local InputServ = game:GetService("UserInputService")
local plr = Players.LocalPlayer
local playerModule = require(plr.PlayerScripts:WaitForChild("PlayerModule"))
local controls = playerModule:GetControls()
rootPartChanged = nil
local skate = workspace.Skateboard

controls:Disable()

plr.CharacterAdded:Wait()

local humanoid = plr.Character:WaitForChild("Humanoid")
local skateAnim = humanoid.Animator:LoadAnimation(plr.Character.Animate.SkateBoost)

local function loadCharacter()
	if typeof(rootPartChanged) == "RBXScriptConnection" then
		rootPartChanged:Disconnect()
	end

	local character = plr.Character
	local humanoid = character:WaitForChild("Humanoid")
	local rootPart = humanoid.RootPart

	rootPartChanged = humanoid:GetPropertyChangedSignal("RootPart"):Connect(function()
		rootPart = humanoid.RootPart
	end)
	
end

pcall(loadCharacter)
plr.CharacterAdded:Connect(loadCharacter)

local function weld(part0 : BasePart, part1 : BasePart)
	if (not part0:IsA("BasePart")) or (not part1:IsA("BasePart")) then --NOTE: I used brackets just because I don't know the operator priority
		error("Can't weld non BasePart objects")
	end
	
	local weld = Instance.new("Weld")
	
	weld.Part0 = part0
	weld.Part1 = part1
	
	weld.C0 = part0.CFrame:Inverse()
	weld.C1 = part1.CFrame:Inverse()
	
	weld.Parent = part0
	return weld
end

local function attachSkate(plrChar : Model, skate : Model)
	local rightLeg = plrChar:FindFirstChild("RightLeg") or plrChar:FindFirstChild("RightLowerLeg")
	print(rightLeg)
	
	plrChar:MoveTo(plrChar.HumanoidRootPart.Position + Vector3.new(0, 3, 0))
	skate:MoveTo(rightLeg.Position - Vector3.new(0, 0.75, 0))
	
	weld(rightLeg, skate.Cube)
	plrChar.Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
	
	for i, v in pairs(plrChar:GetChildren()) do
		if v:IsA("BasePart") and v.Name ~= "head" then
			v.Massless = true
		end
	end
end

local function moveSkate(plrChar)
	local root = workspace.Skateboard.PrimaryPart
	local rightLeg = plrChar:FindFirstChild("RightLeg") or plrChar:FindFirstChild("RightLowerLeg")

	if rightLeg and not rightLeg:FindFirstChild("Weld") then
		attachSkate(plrChar, workspace.Skateboard)
	end
	-- Calculate the direction based on the left leg's orientation
	local direction = root.CFrame.LookVector * 80 -- Adjust the speed as needed

	-- Set the velocity of the skateboard's PrimaryPart
	root.AssemblyLinearVelocity += Vector3.new(direction.X, 0, direction.Z)
	
	skateAnim:Play()
end

--[[local function moveSkate(plrChar : Model)
	local root = workspace.Skateboard.PrimaryPart
	root:ApplyImpulse((CFrame.new(root.AssemblyLinearVelocity) * CFrame.new(0, 0, -5 * workspace.Gravity)).Position)
	local rightLeg = plrChar:FindFirstChild("LeftLeg") or plrChar:FindFirstChild("LeftLowerLeg")
	if rightLeg and not rightLeg:FindFirstChild("Weld") then
		attachSkate(plrChar, workspace.Skateboard)
	end
end]]

InputServ.InputBegan:Connect(function(key)
	print(key.KeyCode.Name)
	local rad = math.rad
	if key.KeyCode.Name == "W" then
		moveSkate(plr.Character)
	elseif key.KeyCode.Name == "A" then
		skate.PrimaryPart:ApplyAngularImpulse(skate.PrimaryPart.AssemblyAngularVelocity + Vector3.new(0, 700, 0))
	elseif key.KeyCode.Name == "D" then
		skate.PrimaryPart:ApplyAngularImpulse(skate.PrimaryPart.AssemblyAngularVelocity + Vector3.new(0, -700, 0))
	end
end)

Dodgeball server script:

local Players = game:GetService("Players")

local tool = script.Parent
local onClick = tool.OnClick.OnServerEvent
local char = tool.Parent.Parent.Character

local function destroyAfterX(object : Instance, x : number) --I hate code sugar, and debris is code sugar, so thats why I implemented this
	task.delay(x, function()
		if object and object.Parent then
			object:Destroy()
		end
	end)
end

local function throwBall(player, mousePos : Vector3)
	if not mousePos then
		return
	end
	print("threw")
	local hand = char:FindFirstChild("RightArm") or char:FindFirstChild("RightHand")
	local direction = CFrame.lookAt(Vector3.new(), mousePos - hand.Position)
	local ball = tool.Handle:Clone()
	ball.Position = hand.Position
	local ballsFol = workspace:FindFirstChild("Dodgeballs folder")
	if not ballsFol then
		ballsFol = Instance.new("Folder")
		ballsFol.Parent = workspace
		ballsFol.Name = "Dodgeballs folder"
	end
	ball.Parent = ballsFol
	ball.AssemblyLinearVelocity = (direction * CFrame.new(0, 50, -90)).Position
	print(ball.AssemblyLinearVelocity)
	ball.Boing:Play()
	task.wait(0.15)
	ball.CanCollide = true
end

onClick:Connect(throwBall)

Dodgeball client script

local tool = script.Parent
local onClick = tool.OnClick
local player = game:GetService("Players").LocalPlayer
local mouse = player:GetMouse()

tool.Activated:Connect(function()
	onClick:FireServer(mouse.Hit.Position)
end)

Any help appreciated. Thanks!

What happens when you wait a bit before testing?

I’m not sure it’ll work in your case, but I’ve found that physics seems to load in last, sometimes taking 10-15 seconds when testing.
I spent about half an hour trying to get swinging doors to work properly when a player pushed against them, only to find out if I’d waited a few seconds more when testing they would have worked perfectly the first time.

It works after after around 1 minute(didn’t measure). However, I want it to work immediately.

And I want to know why this happens.

Like I said, physics takes a little while to load but only at the beginning. Once the game is loaded then everything should work fine.

Or do you wait a couple minutes, spawn the board, and then it takes a few seconds to drop? Why not create the weld to the parts as soon as the player is added but leave it disabled, then instead of calling the entire weld function just enable the weld?

As for your ball throwing, as far as I know animations only work on hte client.

It welds only once. After that it detects that there is a weld and doesn’t weld it anymore.

About the dodgeball, animation is not an issue. I haven’t created animations for that yet. The issue is that it shoots from spawn position, not the players hand position.

Is it because you set ball.Position = hand.Position but then Parent it to the ballsFol Folder in the workspace? Would that reset it’s Position in the workspace to 0,0,0?