How can I make a ball lose speed as it rolls rather than have it rolling infinitely?

Hi DevForum,

I made a script where you can kick a ball, and it applies a velocity to the ball, however I want it to lose its velocity and stop rolling after a short amount of time.

I read some DevForum articles stating to use BodyGyros, AngularVelocities, etc, but don’t know how to put it into effect. Help is appreciated!

1 Like

Add an AngularVelocity to the ball, leave the AngularVelocity field on all zeros, and set a low MaxTorque. Change this torque based on how quickly you want it to lose the velocity.

2 Likes

Thanks for your reply,

I tried this method however the ball seems to keep infinitely rolling without slowing down.

What I did is once the player spawns the ball in front of them, I then add the AngularVelocity, but nothing seems to have changed.

Here’s what I did:

local AngularVelocity = Instance.new("AngularVelocity", ball)
AngularVelocity.AngularVelocity = Vector3.new(0,0,0)
AngularVelocity.MaxTorque = 0

MaxTorque should be higher than 0, otherwise the constraint won’t do anything.

I also tried using MaxTorques such as 1, 0.1, and others but nothing seemed to have changed. Is it because of my way of adding a velocity to the ball?

I’m using :ApplyImpulse(), but I don’t know if that’s the best way.

Perhaps make sure that the RelativeTo property is set to Enum.ActuatorRelativeTo.World? Your method of applying the velocity shouldn’t affect the constraint.
I haven’t opened studio or used constraints in a while, but I’m sure that should work.

Yes, it’s set to World by default, yet there’s no progress in stopping the ball for some reason. Thank you for your reply!

1 Like

Two caveats with using AngularVelocity; first of all, it also needs an associated attachment (attachment0) to work with RelativeTo = Enum.ActuatorRelativeTo.World; secondly, MaxTorque actually has to be surprisingly high to get the desired effect (100 or more!). Here’s a pretty simple example, using CollectionService so that you can add and remove the RollingFriction “property” easily while testing.

local RunService = game:GetService("RunService")
local CollectionService = game:GetService("CollectionService")
local RollingFrictionConnections = {}
local FrictionConstant = 100

local function AddRollingFriction(part: BasePart)
	local attachment = Instance.new("Attachment")
	attachment.Name = "FrictionAttachment"
	attachment.Parent = part
	local av = Instance.new("AngularVelocity")
	av.Name = "FrictionAngularVelocity"
	av.AngularVelocity = Vector3.new(0, 0, 0)
	av.MaxTorque = FrictionConstant
	av.Attachment0 = attachment
	av.Parent = part
end

CollectionService:GetInstanceAddedSignal("RollingFriction"):Connect(AddRollingFriction)
CollectionService:GetInstanceRemovedSignal("RollingFriction"):Connect(function(part)
	part.FrictionAttachment:Destroy()
	part.FrictionAngularVelocity:Destroy()
end)

local ball = Instance.new("Part")
ball.Shape = Enum.PartType.Ball
ball.Position = Vector3.new(0, 10, 0)
ball.Anchored = false
ball.Parent = workspace
CollectionService:AddTag(ball, "RollingFriction")

Of course, you’ll need to add some logic so that this isn’t active while the part isn’t touching anything, but that should be fairly trivial to implement.

1 Like

Yeeeees
Thanks you very much!!