Help with character starting to fling when moving

  1. What do you want to achieve? Keep it simple and clear!
    I want to make a juggling mechanic, that will spawn a ball and start an animation every time the player clicks.
  1. What is the issue? Include screenshots / videos if possible!
    The issue is that every time I begin to move my character, it will sometimes depend on the balls. It mostly starts to fling when there are many balls at once.
  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have tried using Motor6D and Welds. I also tried making a script that would refresh the position of the balls, so they depend on the character, but that seemed too laggy and inconsistent for players with worse connection.
    Furthermore, I tried looking for solutions on here, but I couldn’t find anything that seemed to be an answer to this situation

Imgur

My code:

-- Script Remotes
function Juggle(plr)
	if not  JDebounce then
		JDebounce = true
		local char = plr.Character
		local hum = char:WaitForChild("Humanoid")

		local animationTrack = hum:LoadAnimation(Throw1Animation) -- Start throw animation
		animationTrack:Play()
		
		local Ball = CreateBall(char)
		local ballHum = Ball.Humanoid
		local animationTrack = ballHum:LoadAnimation(BallMoveAnimation) -- Start ball animation
		animationTrack:Play()
		
		spawn(function() -- Throw back animation
			wait(.5)
			local animationTrack = hum:LoadAnimation(Throw2Animation)
			animationTrack:Play()
		end)
		spawn(function() -- Destroy ball when finshed
			wait(1)
			Ball:Destroy()
		end)
		wait(JTime) -- wait for debounce time
		JDebounce = false
	end
end

-- CreateBall Function
return function(char)
	local Ball = game:GetService("ServerStorage").GreenBall:Clone()
	Ball.Parent = char
	
	Ball.HumanoidRootPart.WeldToRoot.Part0 = char.HumanoidRootPart
	
	return Ball
end

I hope this is enough information.

Also, this is my first post on here, so feel free to correct me! :slight_smile:

Seems like those balls are clipping to the character, do they have CanCollide off?

1 Like

Yeah they do have it off, also not anchored.

You seem to be welding the ball to the HumanoidRootPart (hrp) which I speculate drags the character with it as it goes up, you can try anchoring the hrp and if the character doesn’t fling then your problem are those welds.
Also, couple of things about your script, avoid using spawn() as it starts a new thread when ran and has “a built in wait()” which basically yields your script for the period of a wait() when exiting the spawn(). Another note is to not use Humanoid:LoadAnimation() but instead use Animator:LoadAnimation() because the latter is more recommended than the former, and you also don’t want to load the animation each time you want to play it, just have the variable that holds that AnimationTrack at the beginning and each time you need to play the animation just take that variable and slap a :Play() next to it. Because you can only load 256 animations per Animator.

1 Like

I can’t use Roblox Studio right now but ill definitely test those out later, and thanks for the tips. I will definitely change the animation code.
Also whats an alternative to using spawn()?

For example sometimes i would want to wait before doing something meanwhile not delaying the rest of the code.

I would normally try and find ways around it first, test all my possibilities and if I have to run in parallel then I’ll use coroutines, they are slightly trickier to set-up but are much better and smoother. But I recommend finding other ways before using coroutine just because you will rarely need to run code in parallel in the same script. Nothing’s bad with coroutines tho, feel free to use them however you like.

https://gyazo.com/8c2278ec57040ae21d231287490c294c
https://gyazo.com/b5935afc9dc7c616ed560735cadd86aa

Here is my code.
local balls = {}

local replicatedStorage = game:GetService("ReplicatedStorage")
local BallTemplate = replicatedStorage:WaitForChild("Ball")

script.Parent.Activated:Connect(function()
	-- Get Character
	local character = script.Parent:FindFirstAncestorOfClass("Model")
	if not character then return end
	local root = character.PrimaryPart
	if not root then return end
	local hum = character:FindFirstChildOfClass("Humanoid")
	if not hum or hum.Health <= 0 then return end
	
	-- Create ball
	local ball = BallTemplate:Clone()

	-- Weld Ball
	local weld = Instance.new("Weld")
	weld.Part0 = ball
	weld.Part1 = root
	weld.C0 = CFrame.new()
	weld.Parent = ball

	-- Parent Ball
	ball.Parent = workspace

	-- Animate Ball
	table.insert(balls, {
		_object = ball,
		_weld = weld,
		_spawnedAt = time(),
		_speed = 1,
	})
end)

local yStrength = 2
local xStrength = 1
game["Run Service"].Heartbeat:Connect(function()
	for index, ball in pairs(balls) do
		-- Check Ball
		if (not ball._object or not ball._object:IsDescendantOf(workspace) or not ball._weld) then
			if ball._object then
				ball._object:Destroy()
			end
			
			balls[index] = nil
			continue
		end
		
		-- Get Numbers
		local t = math.min((time() - ball._spawnedAt) / ball._speed, 1)
		local rot = math.pi * 2 * t
		
		-- Animate
		local y = -math.abs( math.sin(rot) * yStrength )
		local x = -math.cos(rot) * xStrength
		ball._weld.C0 = CFrame.new(x, y, 2)
		
		-- Check Time
		if t == 1 then
			if ball._object then
				ball._object:Destroy()
			end

			balls[index] = nil
		end
	end
end)

Yeah, I have done some testing now. When the character is anchored, nothing happens, and the character will only start flinging when there are multiple balls welded to the character.