Low Gravity + Low Velocity not working properly

  1. I’m making a timescale feature in my game, however, whenever I got to a low timescale, the player doesn’t jump the height it should.

  2. The way I’m going about simulating a really slow jump is by lowering the gravity in the workspace and lowering the velocity at which the player jumps.

For example, I’ve attempted to add a velocity vector of (0,4,0) in a workspace with a gravity of 2. The player should stay in the air for at least 4 seconds, however, all it does is a tiny micro-jump way shorter than what basic kinematics suggests.
robloxapp-20211231-1916185.wmv (239.7 KB)

I’ve tried this with multiple gravities and velocities and usually it works properly until you lower the gravity enough.

  1. I’ve forked the playermodule and removed the control portion so it doesn’t interfere with my script.
    Looking around the devforums hasn’t really helped me that much since I haven’t really found any solutions to my issue. There is a post from a while ago that is also vaguely similar but doesn’t help.

testing with a fixed velocity vector and wks gravity of 2:

-- variables and services
local input = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local abs = math.abs
local wfc = game.WaitForChild
local p = game:GetService('Players').LocalPlayer
p.CharacterAdded:Wait()
local lc = p.Character
local rp = wfc(lc,"HumanoidRootPart")
local start
-- beginning y pos to compare later on
local origin = rp.Position.Y


-- jump function
function jump()
	rp.Velocity = rp.Velocity + Vector3.new(0,4,0)
end

-- determines whether or not it should calculate the height of the jump
local calcheight = false

-- check if space is pressed
input.InputBegan:connect(function(keycode)
	local key=keycode.KeyCode
	if key==Enum.KeyCode.Space then
		jump()
		start = os.time()
		calcdrop = true
	end
end)

RunService.Stepped:Connect(function()
	-- calculates the difference in time between when the player first presses jump and when they begin to fall
	if calcdrop==true and ((rp.Velocity.Y) <= -0.5) then
		print(os.time() - start)
		calcdrop = false
	end
end)

testing with variable velocity depending on gravity to get the same height:

-- variables and services
local input = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local abs = math.abs
local wfc = game.WaitForChild
local p = game:GetService('Players').LocalPlayer
p.CharacterAdded:Wait()
local lc = p.Character
local rp = wfc(lc,"HumanoidRootPart")

-- beginning y pos to compare later on
local origin = rp.Position.Y


-- jump function
function jump(height)
	rp.Velocity = rp.Velocity + Vector3.new(0,(2*workspace.Gravity*height)^0.5,0)
end

-- determines whether or not it should calculate the height of the jump
local calcheight = false

-- check if space is pressed
input.InputBegan:connect(function(keycode)
	local key=keycode.KeyCode
	if key==Enum.KeyCode.Space then
		jump(4)
		calcheight = true
	end
end)

RunService.Stepped:Connect(function()
	-- calculates the difference in height once player starts dropping again after pressing space
	if(calcheight==true and ((rp.Velocity.Y) <= 0.5)) then
		print(rp.Position.Y - origin)
		calcheight = false
	end
end)

Heres where I tested all my code:
Baseplate.rbxl (110.8 KB)

Sorry if I’m missing something obvious, I’m new to roblox lua and its my first time posting here. :smiley:

2 Likes

Nothing I’ve done so far works and I’ve been on this issue for around a week now so since no one seems to have an answer, I might as well send this in as a bug report.

Unfortunately, im unable to post in bug reports and I don’t have the patience or time to meet all the requirements to be upgraded to a regular so for the time being I’m going to have to give up.

I’ve tried a few more things, here’s the updated place file:
Baseplate.rbxl (111.0 KB)

new script that has both functions:

-- variables and services
local input = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local abs = math.abs
local wfc = game.WaitForChild
local p = game:GetService('Players').LocalPlayer
p.CharacterAdded:Wait()
local lc = p.Character
local rp = wfc(lc,"HumanoidRootPart")
local start
-- beginning y pos to compare later on
local origin = rp.Position.Y


-- fixed jump function with (0,4,0) velocity w/ workspacegravity of 2
function fixedjump()
	workspace.Gravity = 2
	rp.Velocity = rp.Velocity + Vector3.new(0,4,0)
end

-- variable jump height function
function jump(height)
	rp.Velocity = rp.Velocity + Vector3.new(0,(2*workspace.Gravity*height)^0.5,0)
end

-- determines whether or not it should calculate the height of the jump/time in the air before dropping
local calcheight = false
local calcdrop = false

-- check if space is pressed
input.InputBegan:connect(function(keycode)
	local key=keycode.KeyCode
	if key==Enum.KeyCode.E then
		fixedjump()
	end
	if key==Enum.KeyCode.Q then
		jump(4)
	end
	start = os.time()
	calcheight = true
	calcdrop = true
end)

RunService.Stepped:Connect(function()
	-- calculates the difference in time between when the player first presses jump and when they begin to fall and the height at which they begin to fall
	if (calcdrop==true or calcheight==true) and ((rp.Velocity.Y) <= -0.5) then
		print(os.time() - start)
		print(rp.Position.Y - origin)
		print("\n")
		calcdrop = false
		calcheight = false
	end
end)

I think if you change jump power or jump height for the humanoid as opposed to trying to add velocity directly i think you could use it as a workaround.
Im not sure why, but it does seem that humanoids like “snapping” to the floor as shown by this video: (Sorry for any poor angles)
robloxapp-20220102-1450288.wmv (489.7 KB)
I suspect what the roblox engine is doing is having what ever “snapping” effect occur while the velocity is being added, which results in a very temporary increase in Y velocity but then the humanoid “snaps” back into place. It could be because of animations, but I am not really too sure.

1 Like

I’m working on a game that I didn’t fully write so re-adding the playercontrol module would probably cause a lot of issues, especially with custom jump mechanics. I’ll probably consider just re-writing it in the future but the issue still remains and using a bandaid fix probably won’t help in the long run especially if what I’ve written isn’t doing what it should.

Thanks for you input though, ill definitely try removing the animations and see how it works! :smiley:

Apparently the velocity on rootparts just likes to randomly reverse in low gravity situations.

I ran a bunch of tests and it turns out that adding velocity to create a jump worked just fine on regular baseparts despite the code being the exact same for both humanoids and baseparts.

humanoid test output:
image

vs

basepart test output:
image

the entire script:

-- variables and services
local input = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local abs = math.abs
local wfc = game.WaitForChild
local p = game:GetService('Players').LocalPlayer
p.CharacterAdded:Wait()
local lc = p.Character
local rp = wfc(lc,"HumanoidRootPart")
local nonh = wfc(workspace,"nonhumanoid")
nonh.Parent = workspace

local samethreshold = 2

-- fixed velocity jump function
function fixedjump(v)
	workspace.Gravity = 2
	rp.AssemblyLinearVelocity = 	rp.AssemblyLinearVelocity + 	Vector3.new(0,v,0)
end

-- variable jump height function
function jump(height)
	rp.AssemblyLinearVelocity = 	rp.AssemblyLinearVelocity + 	Vector3.new(0,(2*workspace.Gravity*height)^0.5,0)
	--[[
	-- confirming that all body parts are getting their velocity changed(they do)
	for _, i in pairs(rp.Parent:GetChildren()) do
		if i:IsA("BasePart") then
			print(i.AssemblyLinearVelocity)
		end
	end]]
end

function nonhumjump(height)
	nonh.AssemblyLinearVelocity = 	nonh.AssemblyLinearVelocity + 	Vector3.new(0,(2*workspace.Gravity*height)^0.5,0)
end

-- check if space is pressed
input.InputBegan:connect(function(keycode)
	local key=keycode.KeyCode
	if key==Enum.KeyCode.E then
		--fixedjump(4)
	end
	if key==Enum.KeyCode.Q then
		jump(4)
	end
	if key==Enum.KeyCode.P then
		nonhumjump(4)
	end
end)

local prevvelrp = rp.AssemblyLinearVelocity
local samecountrp = 0

local prevvelnonh = nonh.AssemblyLinearVelocity
local samecountnonh = 0

RunService.Stepped:Connect(function()
	if prevvelrp ~= rp.AssemblyLinearVelocity then
		samecountrp = 0
		print("rootpart velocity: "..tostring(rp.AssemblyLinearVelocity))
		print("			dif: "..tostring(rp.AssemblyLinearVelocity - prevvelrp))
		prevvelrp = rp.AssemblyLinearVelocity
	else
		samecountrp = samecountrp + 1
	end
	if prevvelnonh ~= nonh.AssemblyLinearVelocity then
		samecountnonh = 0
		print("part velo: "..tostring(nonh.AssemblyLinearVelocity))
		print("			dif: "..tostring(nonh.AssemblyLinearVelocity - prevvelnonh))
		prevvelnonh = nonh.AssemblyLinearVelocity
	else
		samecountnonh = samecountnonh + 1
	end
	if samecountnonh == 3 or samecountrp == 3 then
		print("end\n\n")
	end
end)

any help you can provide would be much appreciated, Thanks!

Baseplate.rbxl (112.4 KB)