Custom gravity script

Hey, I need help adding custom gravity to my movement script. I tried raycasting but can’t manage it to work correctly. Im running R6 character. I didn’t add deltatime or acceleration yet. Any ideas how to add gravity?

-- Get required services
local userInputService = game:GetService("UserInputService")
local runService = game:GetService("RunService")

-- Get player references
local playerCharacter = script.Parent
local humanoid = playerCharacter:WaitForChild("Humanoid")
local humanoidRootPart = playerCharacter:WaitForChild("HumanoidRootPart")

-- Disable default movement
humanoid.WalkSpeed = 0
humanoid.JumpPower = 0

-- Create and configure BodyVelocity
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
bodyVelocity.Parent = humanoidRootPart
bodyVelocity.Velocity = Vector3.zero

-- Movement configuration
local moveSpeed = 16
local acceleration = 2
local deacceleration = 2

-- Key state tracking table
local keyStates = {
	W = false,
	S = false,
	A = false,
	D = false
}

-- Update key states on key press
userInputService.InputBegan:Connect(function(input)
	if input.KeyCode.Name == "W" then
		keyStates.W = true
	elseif input.KeyCode.Name == "A" then
		keyStates.A = true
	elseif input.KeyCode.Name == "S" then
		keyStates.S = true
	elseif input.KeyCode.Name == "D" then
		keyStates.D = true
	end
end)

-- Update key states on key release
userInputService.InputEnded:Connect(function(input)
	if input.KeyCode.Name == "W" then
		keyStates.W = false
	elseif input.KeyCode.Name == "A" then
		keyStates.A = false
	elseif input.KeyCode.Name == "S" then
		keyStates.S = false
	elseif input.KeyCode.Name == "D" then
		keyStates.D = false
	end
end)


-- Update movement --
runService.Heartbeat:Connect(function(deltaTime: number)
	local moveDirection = Vector3.zero
	
	local wishDir = Vector3.zero
	if keyStates.W then
		wishDir -= Vector3.zAxis
	end
	if keyStates.S then
		wishDir += Vector3.zAxis
	end
	if keyStates.A then
		wishDir -= Vector3.xAxis
	end
	if keyStates.D then
		wishDir += Vector3.xAxis
	end
	
	bodyVelocity.Velocity = wishDir * moveSpeed
	
end)

Im closer to success, but still cant manage how to keep the player on ground

-- ## Services
local userInputService = game:GetService("UserInputService")
local runService = game:GetService("RunService")

-- ## Player References
local playerCharacter = script.Parent
local humanoid = playerCharacter:WaitForChild("Humanoid")
local humanoidRootPart = playerCharacter:WaitForChild("HumanoidRootPart")

-- ## Disable Default Movement
humanoid.WalkSpeed = 0
humanoid.JumpPower = 0

-- ## VectorForce Configuration
local vectorForce = Instance.new("LinearVelocity")
local attachment = Instance.new("Attachment")
attachment.Parent = humanoidRootPart
vectorForce.Attachment0 = attachment
vectorForce.RelativeTo = Enum.ActuatorRelativeTo.Attachment0
vectorForce.Parent = humanoidRootPart
vectorForce.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
vectorForce.MaxForce = math.huge
vectorForce.MaxAxesForce = Vector3.new(math.huge, math.huge, math.huge)
vectorForce.Enabled = true

-- ## Key State Tracking
local keyStates = {
	W = false,
	S = false,
	A = false,
	D = false
}

-- ## Key Press Event Handler
userInputService.InputBegan:Connect(function(input)
	if input.KeyCode.Name == "W" then
		keyStates.W = true
	elseif input.KeyCode.Name == "A" then
		keyStates.A = true
	elseif input.KeyCode.Name == "S" then
		keyStates.S = true
	elseif input.KeyCode.Name == "D" then
		keyStates.D = true
	end
end)

-- ## Key Release Event Handler
userInputService.InputEnded:Connect(function(input)
	if input.KeyCode.Name == "W" then
		keyStates.W = false
	elseif input.KeyCode.Name == "A" then
		keyStates.A = false
	elseif input.KeyCode.Name == "S" then
		keyStates.S = false
	elseif input.KeyCode.Name == "D" then
		keyStates.D = false
	end
end)

-- ## Movement variables
local moveSpeed = 800
local acceleration = 2
local deacceleration = 2

-- ## Movement Direction Variables
local wishDir
local moveDirection
local isGrounded

-- ## Update Movement
runService.Heartbeat:Connect(function(deltaTime: number)
	-- Reset moveDirection for each iteration
	moveDirection = Vector3.zero
	
	-- Get desired movement direction
	wishDir = Vector3.zero
	if keyStates.W then
		wishDir -= Vector3.zAxis
	end
	if keyStates.S then
		wishDir += Vector3.zAxis
	end
	if keyStates.A then
		wishDir -= Vector3.xAxis
	end
	if keyStates.D then
		wishDir += Vector3.xAxis
	end
	
	local rayOrigin = humanoidRootPart.Position
	local rayDirection = Vector3.new(0, -5, 0)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {playerCharacter}
	
	local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
	
	if raycastResult then
		isGrounded = true
		humanoidRootPart.Position = Vector3.new(humanoidRootPart.Position.X, raycastResult.Position.Y +2, humanoidRootPart.Position.Z)
	else
		isGrounded = false
	end
	if not isGrounded then
		vectorForce.VectorVelocity = Vector3.new(0, -25, 0)
	end
	
end)

I did the gravity, its working, the thing is the humanoid.HipHeight is returning 0, so i cant get the proper distance of the raycast. Ideas?

-- ## Services
local userInputService = game:GetService("UserInputService")
local runService = game:GetService("RunService")

-- ## Player References
local playerCharacter = script.Parent
local humanoid = playerCharacter:WaitForChild("Humanoid")
local humanoidRootPart = playerCharacter:WaitForChild("HumanoidRootPart")

-- ## Disable Default Movement
humanoid.WalkSpeed = 0
humanoid.JumpPower = 0

-- ## VectorForce Configuration
local vectorForce = Instance.new("LinearVelocity")
local attachment = Instance.new("Attachment")
attachment.Parent = humanoidRootPart
vectorForce.Attachment0 = attachment
vectorForce.RelativeTo = Enum.ActuatorRelativeTo.Attachment0
vectorForce.Parent = humanoidRootPart
vectorForce.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
vectorForce.MaxForce = math.huge
vectorForce.MaxAxesForce = Vector3.new(math.huge, math.huge, math.huge)
vectorForce.Enabled = true

-- ## Key State Tracking
local keyStates = {
	W = false,
	S = false,
	A = false,
	D = false
}

-- ## Key Press Event Handler
userInputService.InputBegan:Connect(function(input)
	if input.KeyCode.Name == "W" then
		keyStates.W = true
	elseif input.KeyCode.Name == "A" then
		keyStates.A = true
	elseif input.KeyCode.Name == "S" then
		keyStates.S = true
	elseif input.KeyCode.Name == "D" then
		keyStates.D = true
	end
end)

-- ## Key Release Event Handler
userInputService.InputEnded:Connect(function(input)
	if input.KeyCode.Name == "W" then
		keyStates.W = false
	elseif input.KeyCode.Name == "A" then
		keyStates.A = false
	elseif input.KeyCode.Name == "S" then
		keyStates.S = false
	elseif input.KeyCode.Name == "D" then
		keyStates.D = false
	end
end)

-- ## Movement variables
local moveSpeed = 800
local acceleration = 2
local deacceleration = 2

-- ## Movement Direction Variables
local wishDir
local moveDirection
local isGrounded

-- ## Update Movement
runService.Heartbeat:Connect(function(deltaTime: number)
	-- Reset moveDirection for each iteration
	vectorForce.VectorVelocity = Vector3.zero
	
	-- Get desired movement direction
	wishDir = Vector3.zero
	if keyStates.W then
		wishDir -= Vector3.zAxis
	end
	if keyStates.S then
		wishDir += Vector3.zAxis
	end
	if keyStates.A then
		wishDir -= Vector3.xAxis
	end
	if keyStates.D then
		wishDir += Vector3.xAxis
	end
	
	local rayOrigin = humanoidRootPart.Position
	local rayDirection = Vector3.new(0, (humanoid.HipHeight + humanoid.LeftLeg.Size.Y)* -1, 0)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {playerCharacter}
	
	local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
	
	if raycastResult then
		isGrounded = true
		print(raycastResult)
	else
		isGrounded = false
	end
	if not isGrounded then
		vectorForce.VectorVelocity = Vector3.new(0, -25, 0)
	end
	
end)

What are you trying to achieve?
By default, the Humanoid.HipHeight is set to 0. So if you haven’t changed it thats why.

If you are trying to shoot the ray beneath the player then you can set the direction like this

local rayDirection = Vector3.new(0, -1, 0) * 3

does this apply to all scales of people avatars?
edit: nevermind r6 avatars dont scale

This is my code now, but when i set gravity to something high, my player goes into ground, i tried this:

if raycastResult then
		isGrounded = true
		humanoidRootPart.Position = raycastResult.Position + Vector3.new(0, 3, 0)
	else

but the character keeps bouncing

-- ## Services
local userInputService = game:GetService("UserInputService")
local runService = game:GetService("RunService")

-- ## Player References
local playerCharacter = script.Parent
local humanoid = playerCharacter:WaitForChild("Humanoid")
local humanoidRootPart = playerCharacter:WaitForChild("HumanoidRootPart")

-- ## Disable Default Movement
humanoid.WalkSpeed = 0
humanoid.JumpPower = 0

-- ## VectorForce Configuration
local vectorForce = Instance.new("LinearVelocity")
local attachment = Instance.new("Attachment")
attachment.Parent = humanoidRootPart
vectorForce.Attachment0 = attachment
vectorForce.RelativeTo = Enum.ActuatorRelativeTo.Attachment0
vectorForce.Parent = humanoidRootPart
vectorForce.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
vectorForce.MaxForce = math.huge
vectorForce.MaxAxesForce = Vector3.new(math.huge, math.huge, math.huge)
vectorForce.Enabled = true

-- ## Key State Tracking
local keyStates = {
	W = false,
	S = false,
	A = false,
	D = false
}

-- ## Key Press Event Handler
userInputService.InputBegan:Connect(function(input)
	if input.KeyCode.Name == "W" then
		keyStates.W = true
	elseif input.KeyCode.Name == "A" then
		keyStates.A = true
	elseif input.KeyCode.Name == "S" then
		keyStates.S = true
	elseif input.KeyCode.Name == "D" then
		keyStates.D = true
	end
end)

-- ## Key Release Event Handler
userInputService.InputEnded:Connect(function(input)
	if input.KeyCode.Name == "W" then
		keyStates.W = false
	elseif input.KeyCode.Name == "A" then
		keyStates.A = false
	elseif input.KeyCode.Name == "S" then
		keyStates.S = false
	elseif input.KeyCode.Name == "D" then
		keyStates.D = false
	end
end)

-- ## Movement variables
local moveSpeed = 800
local acceleration = 2
local deacceleration = 2

-- ## Movement Direction Variables
local wishDir
local moveDirection
local isGrounded

-- ## Update Movement
runService.Heartbeat:Connect(function(deltaTime: number)
	-- Reset moveDirection for each iteration
	vectorForce.VectorVelocity = Vector3.zero
	
	-- Get desired movement direction
	wishDir = Vector3.zero
	if keyStates.W then
		wishDir -= Vector3.zAxis
	end
	if keyStates.S then
		wishDir += Vector3.zAxis
	end
	if keyStates.A then
		wishDir -= Vector3.xAxis
	end
	if keyStates.D then
		wishDir += Vector3.xAxis
	end
	
	local rayOrigin = humanoidRootPart.Position
	local rayDirection = Vector3.new(0, -1, 0) * 3
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {playerCharacter}
	
	local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
	
	if raycastResult then
		isGrounded = true
		humanoidRootPart.Position = raycastResult.Position + Vector3.new(0, 3, 0)
	else
		isGrounded = false
	end
	if not isGrounded then vectorForce.VectorVelocity = Vector3.new(0, -75, 0) end
	
end)

No, i changed it a bit and this might work for every player scale.

if humanoid.BodyHeightScale.Value then
   local rayDirection = Vector3.new(0, -1, 0) * (3.5 * humanoid.BodyHeightScale.Value)
else
   local rayDirection = Vector3.new(0, -1, 0) * 3.5
end

I put the if statement because if the player is r6 then humanoid.BodyHeightScale.Value errors

Edit:
Oh, i didn’t see you change your reply, lol.

1 Like

Found the solution, had to increase raycast by a bit

-- ## Services
local userInputService = game:GetService("UserInputService")
local runService = game:GetService("RunService")

-- ## Player References
local playerCharacter = script.Parent
local humanoid = playerCharacter:WaitForChild("Humanoid")
local humanoidRootPart = playerCharacter:WaitForChild("HumanoidRootPart")

-- ## Disable Default Movement
humanoid.WalkSpeed = 0
humanoid.JumpPower = 0

-- ## VectorForce Configuration
local vectorForce = Instance.new("LinearVelocity")
local attachment = Instance.new("Attachment")
attachment.Parent = humanoidRootPart
vectorForce.Attachment0 = attachment
vectorForce.RelativeTo = Enum.ActuatorRelativeTo.Attachment0
vectorForce.Parent = humanoidRootPart
vectorForce.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
vectorForce.MaxForce = math.huge
vectorForce.MaxAxesForce = Vector3.new(math.huge, math.huge, math.huge)
vectorForce.Enabled = true

-- ## Key State Tracking
local keyStates = {
	W = false,
	S = false,
	A = false,
	D = false
}

-- ## Key Press Event Handler
userInputService.InputBegan:Connect(function(input)
	if input.KeyCode.Name == "W" then
		keyStates.W = true
	elseif input.KeyCode.Name == "A" then
		keyStates.A = true
	elseif input.KeyCode.Name == "S" then
		keyStates.S = true
	elseif input.KeyCode.Name == "D" then
		keyStates.D = true
	end
end)

-- ## Key Release Event Handler
userInputService.InputEnded:Connect(function(input)
	if input.KeyCode.Name == "W" then
		keyStates.W = false
	elseif input.KeyCode.Name == "A" then
		keyStates.A = false
	elseif input.KeyCode.Name == "S" then
		keyStates.S = false
	elseif input.KeyCode.Name == "D" then
		keyStates.D = false
	end
end)

-- ## Movement variables
local moveSpeed = 800
local acceleration = 2
local deacceleration = 2

-- ## Movement Direction Variables
local wishDir
local moveDirection
local isGrounded

-- ## Update Movement
runService.Heartbeat:Connect(function(deltaTime: number)
	-- Reset moveDirection for each iteration
	vectorForce.VectorVelocity = Vector3.zero
	
	-- Get desired movement direction
	wishDir = Vector3.zero
	if keyStates.W then
		wishDir -= Vector3.zAxis
	end
	if keyStates.S then
		wishDir += Vector3.zAxis
	end
	if keyStates.A then
		wishDir -= Vector3.xAxis
	end
	if keyStates.D then
		wishDir += Vector3.xAxis
	end
	
	local rayOrigin = humanoidRootPart.Position
	local rayDirection = Vector3.new(0, -1, 0) * 3.1
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {playerCharacter}
	
	local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
	
	if raycastResult then
		isGrounded = true
		humanoidRootPart.Position = Vector3.new(humanoidRootPart.Position.X, raycastResult.Position.Y + 3, humanoidRootPart.Position.Z)
	else
		isGrounded = false
	end
	if not isGrounded then vectorForce.VectorVelocity = Vector3.new(0, -75, 0) end
	
end)
1 Like

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