How to determine how fast a player is falling and apply to bodyVelocity?

This should help a bit, read through it.
Modeling a projectile’s motion - Resources / Community Tutorials - DevForum | Roblox

They just fall slower esssentially.

Can i see an example of that??

1 Like

I think the a BasePart’s property, Velocity, the value of it will change when it experiences physics. Try that.

1 Like

It’s really easy to code it yourself, I gave you the logic already. Also you can refer to these:

RenderStepped
AssemblyAngularVelocity
Humanoid:GetState
HumanoidStateType

Ok so I have determined how fast the player is falling. Now how can I take that info and insert it into the bodyForce so the player slows down immediately?

local workspacePlr = game.Players.LocalPlayer.Character
local humanoid = workspacePlr.Humanoid
local state = humanoid:GetState()
print(state)
		
			
local rootPart = workspacePlr.HumanoidRootPart
rootPart.Anchored = true
			
if state == Enum.HumanoidStateType.Freefall or state == Enum.HumanoidStateType.PlatformStanding then
	local fallSpeed = rootPart.AssemblyLinearVelocity.Y
	print(fallSpeed)
				
	local bodyForce = Instance.new("BodyForce")
	bodyForce.Parent = rootPart
	--bodyForce.MaxForce = Vector3.new(0, 3500, 0)
	bodyForce.Force = Vector3.new(0, ?, 0) --Slow player down immediately
end

Yoy have not taken into account the fact that other bodyparts have mass and velocity besides the HumanoidRootPart.

So how can I fix? Provide me some code?

I would actually use a Body velocity because falling can be a long state (might take lots of time to leave the state) so you want to constantly apply the velocity.

But try with VectorForce too, and just use what works.

Your Force/Velocity is the current Velocity, and the Y set to how much you want to slow the falling down.

For example:
You want 50% Slower:

Vector3.new(0, -0.5 * fallSpeed, 0)

75% slower:

Vector3.new(0, -0.75 * fallSpeed, 0)

The reason why I use - (minus/negative operation) is because you are falling down, which means the Y velocity is negative. So you want the velocity to apply to upwards and not downwards.

Also, do you use RunService/loops(not suggested)/Events on this? It’ll only run once if you don’t.

Are you trying to make a skydive? I would use a bodyvelocity and set them to a static max speed.

I mean, you could try to come up with a formula to simulate wind resistance and include the falling velocity into the opposing(wind resistance) force, but at the end of the day, if you do all that right, you’ll end up with a static speed (terminal velocity) anyway.

1 Like
game.Workspace.Part.Touched:Connect(function(hit)
local workspacePlr = game.Players.LocalPlayer.Character
local humanoid = workspacePlr.Humanoid
local state = humanoid:GetState()
print(state)
			
				
local rootPart = workspacePlr.HumanoidRootPart
rootPart.Anchored = true
			
if state == Enum.HumanoidStateType.Freefall or state == Enum.HumanoidStateType.PlatformStanding then
	local fallSpeed = rootPart.AssemblyLinearVelocity.Y
	print(fallSpeed)
					
	local bodyForce = Instance.new("BodyVelocity")
	bodyForce.Parent = rootPart
	--bodyForce.MaxForce = Vector3.new(0, 3500, 0)
	bodyForce.MaxForce = Vector3.new(0, (0.75 * fallSpeed), 0) --Slow player down immediately
end
end)

I think the Y number in the bodyForce needs to be higher because I still fall down very fast if the player falls from a higher distance?

I can’t figure out the math equation to apply for the bodyVelocity. IF I fall from a low distance, I will float down slowly like I am supposed too. However, If I fall from a high distance I keep falling down fast af. I want it to determine my bodyVelocity so that I can immediately slow down after touching the part no matter what height I am at. Maybe I am not using other bodyVelocity properties to combine the force of what I need. But Idk what else to change.

you need to update the Velocity property of the BodyVelocity for it to change the parent’s velocity.

BodyVelocity.MaxForce only sets how much force the BodyVelocity is allowed to use to reach it’s Velocity property. You’re treating the BodyVelocity as if it’s a BodyForce and you’re updating BodyForce.Force

Use the BodyVelocity. But also make your character massless. This will allow the BodyVelocity to move your character at exactly the speed you set the Y vector to.

for _, part in pairs(Character:GetDescendants()) do
	if part:IsA("BasePart") and (not part.Massless) then
		part.Massless = true
	end
end

Once your character is massless you can simply set the Y velocity of your BodyVelocity to a negative number to have your character fall downwards but at a constant speed in studs/second

BodyVelocity.Velocity = Vector3.new(0, -10, 0)

In the example above, your character will fall down at exactly 10 studs per second. This should force your character to slow down immediately even if you’re already falling super fast.

1 Like

You don’t want to make an entire physics assembly massless. That property is for situations like welding an accessory part off to the side of an assembly and you don’t want it to move the center of mass.

Set the MaxForce to Vector3.new(math.huge, math.huge, math.huge). This gives the BodyVelocity an infinite amount of force to use to hit it’s target Velocity, so it will move at that Velocity regardless of the assembly’s mass.

2 Likes

I don’t see an issue with doing this as long as you set Massless back to false. But yup, doing this would have the same effect!

It’s impossible for a physics object to have 0 mass. The physics engine finds acceleration with the formula acceleration = net force / mass, if mass is 0 then this kicks a divide by 0 exception. they’re probably handling the divide by 0 exception already but you still shouldn’t get comfortable with having massless physics objects.

Here’s a concept you can use to slow down the fall of a character to whatever speed you want, the script I’m going to provide may not be in the format or type you want, but you can use the concept to achieve what you are looking for I think. (the cool part is that this does not effect how players jump or go up, it only affects falling or going down)

Here’s the script:

-- example script limiting fall speed of a character
-- this script is intended as a local script inside StarterPlayerScripts
local RunService = game:GetService("RunService")

local player = game.Players.LocalPlayer
local fallSpeedMaximum = -1 -- this is studs per second

function getHumanoidRoot()
	local character = player.Character
	if character then
		local humanoidRoot = character:FindFirstChild("HumanoidRootPart")
		return humanoidRoot
	end
end

function getLimitedSpeed(oldVelocity)
	local fallSpeed = math.max(oldVelocity.Y, fallSpeedMaximum)
	return Vector3.new(oldVelocity.X, fallSpeed, oldVelocity.Z)
end

local connection = RunService.Heartbeat:Connect(function()
	local humanoidRoot = getHumanoidRoot()
	if humanoidRoot then
		humanoidRoot.Velocity = getLimitedSpeed(humanoidRoot.Velocity)
	end
end)

This script put inside StarterPlayerScripts would limit the speed of characters fall to one stud per second. You could change fallSpeedMaximum to change the fall speed of a specific character when the character hits a certain block.

This is also used as a local script but it could work with a server script I believe, if you had the character and don’t mind the added latency.

Then if eventually the fall speed limit wasn’t needed anymore for some reason, you can call connection:Disconnect() and then the heartbeat function won’t be called.

Many ways this could be done, but this is the way I would try first.

1 Like

HumanoidRootPart.AssemblyLinearVelocity.Y

Need there any more be said?

Thanks. This method works well. I could just set the mass back when i’m done. Also the Method @InfinityDesign stated works just as well. Thanks for the help

1 Like