Physics problem of spheres rising upwards

  1. I need the player to push a boulder up a slope and if the player does not push it, it should roll back down.
    We have got one script that located “serverscriptservice”.
    i need the stone should roll at the speed of player.

  2. Rock dosen’t roll with the player speed and this point “self.direction = humanoidRootPart.CFrame.LookVector” velocity stone bad work.
    My rock following the player even he is not pushing the rock.
    I wrote in the code that if the speed of the stone is less than a certain value it should roll down, but I have it rolling down sharply

local RunService = game:GetService("RunService")

local RollingStone = {}
RollingStone.__index = RollingStone

local function getPlayerSpeed(player)
	if player and player.Character then
		local humanoidRootPart = player.Character:FindFirstChild("HumanoidRootPart")
		if humanoidRootPart then
			local velocity = humanoidRootPart.Velocity
			return Vector3.new(velocity.X, 0, velocity.Z).Magnitude 
		end
	end
	return 0
end

function RollingStone.new(part)
	local self = setmetatable({}, RollingStone)
	self.stone = part 
	self.currentVelocity = Vector3.zero 
	self.direction = Vector3.zero
	self.speed = 0
	self.active = true 

	self.stone.Touched:Connect(function(otherPart)
		self:OnTouched(otherPart)
	end)


	RunService.Heartbeat:Connect(function(deltaTime)
		self:Update(deltaTime)
	end)

	return self
end

function RollingStone:OnTouched(otherPart)
	local character = otherPart.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	local player = game.Players:GetPlayerFromCharacter(character)

	if humanoid and player then
		local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
		if humanoidRootPart then
			self.speed = getPlayerSpeed(player) 
			self.direction = humanoidRootPart.CFrame.LookVector

			self.currentVelocity = self.direction * self.speed 
			self.active = true 
		end
	end
end

function RollingStone:Update(deltaTime)
	if not self.active then return end 

	local newVelocity = Vector3.new(self.currentVelocity.X, self.stone.AssemblyLinearVelocity.Y, self.currentVelocity.Z)

	
	self.stone.AssemblyLinearVelocity = newVelocity 

	
	self.currentVelocity = self.currentVelocity * (1 - 0.2 * deltaTime)

	
	if self.stone.AssemblyLinearVelocity.Magnitude < 10 then
		self.stone.AssemblyLinearVelocity = Vector3.zero
		self.active = false
	end
end


local stonePart = workspace:WaitForChild("Stone") 
local rollingStone = RollingStone.new(stonePart)

My problems in video:

The example I’m referring to:

Have you tried letting physics handle the sphere, and then using ApplyImpulse to push it when the player comes into contact?

1 Like

applyImpulse used to work very poorly. applyImpulse pushes the stone in jerks, but I need it to roll at the speed of the game, as in the example

decrease the amount of impulse and increase the rate

And @PANDASonNOOB ApplyImpulse provides a sudden quick force (like hitting a baseball with a bat) to an object. You probably would want to use a VectorForce on the ball while the player is pushing it.

1 Like

I understand that, however, considering the existance of raycast cars and the idea that an impulse is just a force multiplied by time, I find it reasonable to believe that it may be possible to achieve a smoother movement simply by increasing the amount of impulses applied and decreasing the magnitude of each to achieve something similar to a constant force.

A vectorForce does make more sense

1 Like
local RunService = game:GetService("RunService")

local RollingStone = {}
RollingStone.__index = RollingStone

local function getPlayerSpeed(player)
	if player and player.Character then
		local humanoidRootPart = player.Character:FindFirstChild("HumanoidRootPart")
		if humanoidRootPart then
			local velocity = humanoidRootPart.Velocity
			return Vector3.new(velocity.X, 0, velocity.Z).Magnitude 
		end
	end
	return 0
end

function RollingStone.new(part)
	local self = setmetatable({}, RollingStone)
	self.stone = part 
	self.currentVelocity = Vector3.zero 
	self.direction = Vector3.zero
	self.speed = 0
	self.active = false 

	self.stone.Touched:Connect(function(otherPart)
		self:OnTouched(otherPart)
	end)

	RunService.Heartbeat:Connect(function(deltaTime)
		self:Update(deltaTime)
	end)

	return self
end

function RollingStone:OnTouched(otherPart)
	local character = otherPart.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	local player = game.Players:GetPlayerFromCharacter(character)

	if humanoid and player then
		local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
		if humanoidRootPart then
			self.speed = getPlayerSpeed(player) 
			self.direction = humanoidRootPart.CFrame.LookVector
			self.active = true 
		end
	end
end

function RollingStone:Update(deltaTime)
	if not self.active then return end 

	local impulseStrength = 9000000 
	local friction = 0.98 

	
	local impulse = self.direction * impulseStrength * deltaTime
	self.stone:ApplyImpulse(impulse)

	
	self.currentVelocity = self.currentVelocity * friction

	
	if self.stone.AssemblyLinearVelocity.Magnitude < 20 then
		self.active = false
	end
end


local stonePart = workspace:WaitForChild("Stone") 
local rollingStone = RollingStone.new(stonePart)

Like that? But now it’s going uphill

Like that? But now it’s going downhill

Wdym its going uphill?

I would personally suggest using a slightly larger hitbox than the sphere itself, so that you dont actually get stopped by the sphere when you try to push it.
That, or disable the collision between the sphere and the character.
(Allows you to push it up way more smoothly)

You also dont seem to set self.active to false unless the sphere becomes too fast, when in reality it should always be set to false if you’re not touching the sphere.

(Sorry for the later reply was having some trouble myself with other stuff)

1 Like

I wrote to the creator of the place from the example and he helped me do it. :slight_smile: I changed the player model to r6 and made the player be the owner of the part

1 Like

Elegant solution, I totally forgot about network ownership!

1 Like