I can't figure out how to slow down the player when they fall

I want the player to fall at a normal speed but then when they player touches a part (or anything else that works) the player either stops falling for a second to stop the downwards momentum or the player’s momentum downwards is changed to be a lot smaller so the player falls slower.
I can’t seem to figure out how to get the player to slow down/stop falling. My only other option would be stopping the player from flinging all over the place when they hit the ground which is my goal from this.
I first tried a script that was supposed to do what I’m trying to do but it didn’t do that. When the player reached the bottom the script did nothing, but when they player got teleported back to the lobby (there is a part at the bottom that does that) the player got pushed up towards the roof of the lobby for forever or a very long time.
This is the script:

local part = script.Parent-- Get the part that the player will touch
local RunService = game:GetService("RunService")

part.Touched:Connect(function(otherpart) -- Connect to the part's touched event
	local hrp = otherpart.Parent:FindFirstChild("HumanoidRootPart") -- Find the player's HumanoidRootPart

	local bodyvelocity = hrp:FindFirstChildWhichIsA("BodyVelocity")	-- Check if the player has a body velocity attached
	if hrp and not bodyvelocity then
		local newvalue = Instance.new("BodyVelocity") -- Attach a body velocity to the player's humanoid root part to give them an upward push
		newvalue.Velocity = Vector3.new(0, 10000, 0) -- give an upward velocity of 10000 in the Y-axis
		newvalue.MaxForce = Vector3.new(10000, 10000, 10000) -- Set the max force to be able to apply to the player's humanoid rootpart
		newvalue.P = 5000 -- Set the damping property of the body velocity to 5000
		newvalue.Parent = hrp -- Parent the body velocity to the player's humanoid root part

		-- Function to be run every render step to check if the player is within 100 studs of the ground
		local function onHeartbeat()
			if hrp.Position.Y <= 100 then -- Check if the player's humanoid root part is within 100 studs of the ground
				hrp.BodyVelocity.Velocity = Vector3.new(0,0,0) -- Set the player's velocity to (0,0,0)
				hrp.BodyVelocity.MaxForce = Vector3.new(0,0,0) -- Set the max force to (0,0,0) to stop applying the upward force
				newvalue:Destroy() -- Remove the bodyvelocity
				RunService:RemoveHeartbeat(onHeartbeat) -- Remove the heartbeat event
			end
		end

		-- Bind the heart beat function to the render step
		RunService:BindToRenderStep("slowFall", Enum.RenderPriority.First.Value, onHeartbeat)
	end
end)

--This will effectively slow down their fall as they get closer to the ground.

I also tried anchoring the player’s HumanoidRootPart but that didn’t work to slow the player down. I’m not sure what to do here because as far as I can tell I can only a few options to get the effect of what I am trying to do. The player is falling from 10K studs off the ground by the way.
TLDR: I can’t figure out how to stop the player from flinging all over the place and I only have 3 options being stop the player from flinging all over the place with some sort of script, stopping the player from falling for a split second, or slowing down the player’s fall speed.

I got no replies on my first topic about this.

2 Likes

If you set the velocity positive your player is going to start moving upward. You should change your velocity to negative to slow the player down but greater than the -9.8 which is default. Try this:

newvalue.Velocity = Vector3.new(0, -5, 0)

2 Likes

As a player lands, their Humanoid changes state from “Falling” to “Landing”. You can follow this state change event and an a velocity to slow the player, or add an opposing force to the downward force under gravity.

https://create.roblox.com/docs/reference/engine/classes/Humanoid#StateChanged

I changed the script to this now:

local part = script.Parent-- Get the part that the player will touch
local RunService = game:GetService("RunService")

part.Touched:Connect(function(otherpart) -- Connect to the part's touched event
	local hrp = otherpart.Parent:FindFirstChild("HumanoidRootPart") -- Find the player's HumanoidRootPart

	local bodyvelocity = hrp:FindFirstChildWhichIsA("BodyVelocity")	-- Check if the player has a body velocity attached
	if hrp and not bodyvelocity then
		local newvalue = Instance.new("BodyVelocity") -- Attach a body velocity to the player's humanoid root part to give them an upward push
		newvalue.Velocity = Vector3.new(0, -25, 0) -- give an upward velocity of 10000 in the Y-axis
		newvalue.MaxForce = Vector3.new(10000, 10000, 10000) -- Set the max force to be able to apply to the player's humanoid rootpart
		newvalue.P = 5000 -- Set the damping property of the body velocity to 5000
		newvalue.Parent = hrp -- Parent the body velocity to the player's humanoid root part
		-- Function to be run every render step to check if the player is within 100 studs of the ground
		
		local function onHeartbeat()
			if hrp.Position.Y <= 100 then -- Check if the player's humanoid root part is within 100 studs of the ground
				hrp.BodyVelocity.Velocity = Vector3.new(0,0,0) -- Set the player's velocity to (0,0,0)
				hrp.BodyVelocity.MaxForce = Vector3.new(0,0,0) -- Set the max force to (0,0,0) to stop applying the upward force
				newvalue:Destroy() -- Remove the bodyvelocity
				RunService:RemoveHeartbeat(onHeartbeat) -- Remove the heartbeat event
			end
		end

		-- Bind the heart beat function to the render step
		RunService:BindToRenderStep("slowFall", Enum.RenderPriority.First.Value, onHeartbeat)
	end
end)

--This will effectively slow down their fall as they get closer to the ground.

It works, however I have another problem now. I can’t get the new value to get removed/destroyed once the player reaches a certain point. I’m glad I can at least slow the player’s fall though.

I can't figure out how to slow down the player when they fall - #2 by quakage

(Also when this issue get’s fixed entirely I will mark your reply as the solution.)

*If this does get fixed entirely in this one topic…

1 Like

This isn’t getting anymore replies so I’m going to just mark it as the solution.

I was a little under the weather yesterday so I couldn’t respond. If you are using a server script you are not able to use RunService:BindToRenderStep as it must be used in a local script. Try changing your code to use Heartbeat instead. Try this:

local part = script.Parent-- Get the part that the player will touch
local RunService = game:GetService("RunService")
local connection

part.Touched:Connect(function(otherpart) -- Connect to the part's touched event
	local hrp = otherpart.Parent:FindFirstChild("HumanoidRootPart") -- Find the player's HumanoidRootPart

	local bodyvelocity = hrp and hrp:FindFirstChildWhichIsA("BodyVelocity")	-- Check if the player has a body velocity attached
	local newvalue
	if hrp and not bodyvelocity then
		newvalue = Instance.new("BodyVelocity") -- Attach a body velocity to the player's humanoid root part to give them an upward push
		newvalue.Velocity = Vector3.new(0, -25, 0) -- give an upward velocity of 10000 in the Y-axis
		newvalue.MaxForce = Vector3.new(10000, 10000, 10000) -- Set the max force to be able to apply to the player's humanoid rootpart
		newvalue.P = 5000 -- Set the damping property of the body velocity to 5000
		newvalue.Parent = hrp -- Parent the body velocity to the player's humanoid root part
		-- Function to be run every render step to check if the player is within 100 studs of the ground
		
		local function onHeartbeat(step)
			if hrp.Position.Y <= 100 and hrp:FindFirstChild("BodyVelocity") then -- Check if the player's humanoid root part is within 100 studs of the ground
				hrp.BodyVelocity.Velocity = Vector3.new(0,0,0) -- Set the player's velocity to (0,0,0)
				hrp.BodyVelocity.MaxForce = Vector3.new(0,0,0) -- Set the max force to (0,0,0) to stop applying the upward force
				newvalue:Destroy() -- Remove the bodyvelocity
				connection:Disconnect()
			end
		end
		
		connection = RunService.Heartbeat:Connect(onHeartbeat)
	end
end)

Good to know. I did end up finding a working solution using Touched and TouchEnded. Hopefully you’re feeling better though. Now I’m just trying to figure out how to completely stop the player in mid air for a split second or getting the effect of the player slowing down to apply right when the time is right without the player flinging all over the place. If the player doesn’t stop mid air then they have too much of a downward force for anything to really take effect.

One last thing that may help…here is another post that sounds like what you are after as well. There may be more ideas in here for you.

It’s a bit confusing what I should use and what I should not. The replies are separated so I’m not sure where I would put each part in the script. Somebody got a script that makes the player massless but I don’t know where to put that. I also don’t know how I would make this work for me.

It is true things can get a bit confusing with many replies. Something in there that may help you is to set your MaxForce = Vector3.new(math.huge, math.huge, math.huge). That way whatever you set for your Velocity should take effect right away. It also does take quite a while to get comfortable with where you put what scripts to get the effects you are looking for. I’m still learning every day.

I tried that and it did not do exactly what I wanted. The player didn’t fling all over the place but at the same time they didn’t slow down. They just got stuck on the ground when they got teleported.

I could use this but make the new value get destroyed when the player gets teleported. I would do that by linking it up to when the player touches the part they teleport to. The only problem is that I don’t know how to do that.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.