How to stop the player from flinging when falling from high height?

I want to make it so when the player falls from a high height they don’t fling all over the place. I want it so when they touch the part on the ground that teleports the player to the lobby of my game the player won’t fling around and can walk to where they might chose to go right after they have been teleported.
I’ve tried many fixes to this by trying to slow the player’s fall but I can’t figure that out so I decided to find some information about stopping the player from flinging.
I found this post and this post but I wasn’t sure what to do.
I made this script:

local Humanoid = game.Players:GetPlayerFromCharacter("Humanoid")

Humanoid:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, false)

However the script didn’t work as intended. I put the code in a normal script under Workspace. I wasn’t sure what to do so I tried to make a script based off of a bit of code. I know I probably made a decent error with my script but I don’t know what to do.

1 Like

You can either loop through the character and set all the bodyparts to Massless = true, or try some scripts that people have provided in this post
How do I stop player’s character from bouncing after landing from a high height - Help and Feedback / Scripting Support - DevForum | Roblox

2 Likes

I tested the script in a local script under StarterCharacterScripts and it worked but also caused a side effect.
I used this script:

local character = script.Parent --character, can grab from CharacterAdded signal / or placing script under character in StarterCharacter
local humanoid = character:WaitForChild("Humanoid")
local primaryPart = character:WaitForChild("HumanoidRootPart")

humanoid.StateChanged:Connect(function(oldState, newState)
	if newState == Enum.HumanoidStateType.Landed then
		-- cancel out existing velocity
		local velo = primaryPart.AssemblyLinearVelocity
		primaryPart.AssemblyLinearVelocity = velo*Vector3.new(1,0,1)

		-- get distance to ground
		local ray = Ray.new(primaryPart.Position, Vector3.new(0,-20,0))
		local hit, pos = game.Workspace:FindPartOnRay(ray, character)

		--apply ground hit position to character at hip height offset
		local hipHeight = humanoid.HipHeight
		local newPos = pos + Vector3.new(0,hipHeight,0)
		character:MoveTo(primaryPart.Position - primaryPart.Position + newPos) -- changed to moveTo and instead of primaryPart.CFrame used primaryPart.Position
	end
end)

And this was the side effect when jumping or when being teleported:
robloxapp-20230227-0927357.wmv (1.2 MB)
Sorry if you can’t play it as I’ve been told by some people. If you can’t the script teleports the player up maybe like 10 studs in a loop over and over when teleported or sometimes when jumping. Good news is that it does do what I want, I just need to somehow make it less sensitive.

1 Like
humanoid:SetStateEnabled(Enum.HumanoidStateType.FallingDown,false)

All you need is to disable FallingDown. The only issue I’ve seen is the potential to clip through short blocks (thin Y axis on size).

Disabled FallingDown

Although from higher heights, there can still be some bouncing.

I changed the script to this but it still didn’t work so I’m guessing I put the code in the wrong spot or I need to make a new script:

local character = script.Parent --character, can grab from CharacterAdded signal / or placing script under character in StarterCharacter
local humanoid = character:WaitForChild("Humanoid")
local primaryPart = character:WaitForChild("HumanoidRootPart")

humanoid:SetStateEnabled(Enum.HumanoidStateType.FallingDown,false)

humanoid.StateChanged:Connect(function(oldState, newState)
	if newState == Enum.HumanoidStateType.Landed then
		-- cancel out existing velocity
		local velo = primaryPart.AssemblyLinearVelocity
		primaryPart.AssemblyLinearVelocity = velo*Vector3.new(1,0,1)

		-- get distance to ground
		local ray = Ray.new(primaryPart.Position, Vector3.new(0,-20,0))
		local hit, pos = game.Workspace:FindPartOnRay(ray, character)

		--apply ground hit position to character at hip height offset
		local hipHeight = humanoid.HipHeight
		local newPos = pos + Vector3.new(0,hipHeight,0)
		character:MoveTo(primaryPart.Position - primaryPart.Position + newPos) -- changed to moveTo and instead of primaryPart.CFrame used primaryPart.Position
	end
end)
1 Like

This needs to be in a LocalScript for one. Also, you don’t need the state changed part unless you’re trying to fix the bouncing, in which case all you need is this:

humanoid.StateChanged:Connect(function(_,state)
	if state == Enum.HumanoidStateType.Landed then
		humanoidRootPart.AssemblyLinearVelocity = Vector3.zero
	end
end)

Although you might want to preserve some downward momentum so it doesn’t look weird.

1 Like

So I put that under a new local script under the same thing?

You can put it wherever a local script can run. I would recommend putting it inside the player’s character though with this:

local character = script.Parent
local humanoid = character:WaitForChild('Humanoid')
local humanoidRootPart = character:WaitForChild('HumanoidRootPart')
humanoid:SetStateEnabled(Enum.HumanoidStateType.FallingDown,false)

local stateChanged = humanoid.StateChanged:Connect(function(oldState,state)
	if state == Enum.HumanoidStateType.Landed then
		local velocity = humanoidRootPart.AssemblyLinearVelocity
		humanoidRootPart.AssemblyLinearVelocity = Vector3.new(velocity.X,-workspace.Gravity,velocity.Z)
	end
end)

local destroying
destroying = character.Destroying:Connect(function()
	stateChanged:Disconnect()
	destroying:Disconnect()
	character,humanoid,humanoidRootPart = nil,nil,nil
end)

task.wait()
character:WaitForChild('HumanoidRootPart').CFrame = CFrame.new(0,5000,0)

Disable FallDown With Bounce Fixed

1 Like

Still does the same thing. I did notice that it only happens where parts you teleport to are.

Can you explain in more detail? As you can see in the gif in my previous reply, it works fine for me.

I have scripts in parts that make it so that when you touch that part, it teleports you to another part that is invisible and has CanCollide off. The loop of going up over and over again only seems to happen when the player is inside those parts.

Could you record a visual of that? Also make sure the workspace.Gravity part is actually -workspace.Gravity. I forgot to put the minus sign before I edited it.

Here is what it looks like. I made the parts visible.
robloxapp-20230227-1010458.wmv (2.2 MB)
robloxapp-20230227-1011477.wmv (1.6 MB)

That looks like something that some other script is doing. I have no issues with non-CanCollide parts whatsoever.

I changed the teleport script a bit. Before it teleported the player 5 studs above the part, now it teleports the player 5 studs below and the script isn’t triggered. It still will trigger if the player jumps though, which I will try to figure out.

That would be a different issue than what this topic was made for. But that will happen if you have a touch event without a debounce of some kind. You’re basically having it trigger itself.

You can do something like this:

local debounce = {}
script.Parent.Touched:Connect(function(humanoidRootPart)
	if humanoidRootPart.Name == 'HumanoidRootPart' and not table.find(debounce,humanoidRootPart) then
		table.insert(debounce,humanoidRootPart)
		humanoidRootPart.CFrame *= CFrame.new(0,5,0) --Whatever movement you want to do
		task.wait(5) --debounce time
		table.remove(debounce,table.find(debounce,humanoidRootPart))
	end
end)

My script does have a debounce already:

local teleport1 = script.Parent	
local teleport2 = game.Workspace.SpeedChanger --Speed Changer is the part you teleport to, it also changes you speed.
local db = true

script.Parent.Touched:Connect(function(hit)

	if hit.Parent:FindFirstChild("Humanoid") then
		if db == true then
			db = false
			hit.Parent.HumanoidRootPart.CFrame = teleport2.CFrame*CFrame.new(0, -5, 0)
			task.wait(0.1)
			db = true
		end
	end
end)

0.1 seconds isn’t going to do anything in this case. The event is triggering itself because you’re moving the character to a point that is still touching the part. You need a debounce that will prevent that from happening, or to have the event move the character in a way where it wouldn’t be continuously touching the part.

Also using a global debounce isn’t good as the debounce will work for every player, unless this is a LocalScript, which it doesn’t appear to be. You should use a table debounce instead.

Also, unrelated, but it’s a good practice to use GetService() when referencing a service like Workspace (game:GetService('Workspace')), however Workspace has its own global reference, which is just lowercase workspace.

1 Like

Once the player gets teleported they no longer touch the part that teleported them.

The videos you provided do not reflect that. It teleports the player to a position still within the part.