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.
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)
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.
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.
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)
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)
I wrote to the creator of the place from the example and he helped me do it. I changed the player model to r6 and made the player be the owner of the part