How to Actually Use Roblox's Physics Character Controllers

im trying to make climbing work like the climbing state in humanoids with the controller manager’s ClimbController and ClimbSensor but i have no idea how to go about making this. I want to understate how did Humanoids detect ladder parts or truffel parts

local function updateControllerManagerSensor()
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {character} -- Character should not be included within things that the raycast can return
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude

	local raycastToGround = workspace:Raycast(humanoidRootPart.Position, Vector3.new(0, -4.5, 0), raycastParams)

	if raycastToGround then -- Character is on the ground, raycast returned something
		groundSensor.SensedPart = raycastToGround.Instance
		groundSensor.HitNormal = raycastToGround.Normal
		groundSensor.HitFrame = CFrame.new(raycastToGround.Position)

		humanoid:ChangeState(Enum.HumanoidStateType.Running) -- Changing humanoid states so we have animations 
		controllerManager.ActiveController = groundController -- Switch the ActiveController to groundController. 
	else -- Character is midair, raycast didn't return anything
		humanoid:ChangeState(Enum.HumanoidStateType.Freefall) 
		controllerManager.ActiveController = airController
	end
	
	-- Define a constant for the multiplier in the raycast direction calculation
	local CLIMB_RAYCAST_MULTIPLIER = 2

	-- Define a function to calculate the raycast direction
	local function getRaycastDirection(humanoidRootPart)
		return (humanoidRootPart.CFrame.LookVector * CLIMB_RAYCAST_MULTIPLIER) + Vector3.new(0, 7.6, 0)
	end
	
	local raycastToLadder = workspace:Raycast(humanoidRootPart.Position, getRaycastDirection(humanoidRootPart), raycastParams)
	
	if raycastToLadder then -- Character is climbing a ladder, raycast returned something
		-- Handle the case where the raycast hit a ladder
		climbSensor.SensedPart = raycastToLadder.Instance
		climbSensor.HitNormal = raycastToLadder.Normal
		climbSensor.HitFrame = CFrame.new(raycastToLadder.Position)
		humanoid:ChangeState(Enum.HumanoidStateType.Climbing)
		controllerManager.ActiveController = climbController
		return
	else -- Character is not climbing
		climbSensor.SensedPart = nil
		controllerManager.ActiveController = groundController
		if humanoid:GetState() ~= Enum.HumanoidStateType.Jumping then
			humanoid:ChangeState(Enum.HumanoidStateType.Running)
		end

	end
end

basicly i want the climbController to do this:

but it does this:

i also want to add siting functionality as well because when the player sits a seat for VehicleSeat they get stuck and can’t jump out.

image

1 Like

How would you increase jump height? BaseMoveSpeed modifies walk speed, but I can’t figure out a way to change the jump height.

You can increase the jump height by increasing the Y value of the jumpImpulse Vector3.

In this part of the code:

local function doJump(actionName, inputState)
    if actionName == "JUMP_ACTION" and inputState == Enum.UserInputState.Begin and humanoid:GetState() ~= Enum.HumanoidStateType.Ragdoll then
        local jumpImpulse = Vector3.new(0, 750, 0) -- Y is jump power. Change as you see fit.  

        controllerManager.RootPart:ApplyImpulse(jumpImpulse)
        
        humanoid:ChangeState(Enum.HumanoidStateType.Jumping) 
        
        local floor = controllerManager.GroundSensor.SensedPart
        if floor then -- Character's on the floor?  
            floor:ApplyImpulseAtPosition(-jumpImpulse, controllerManager.GroundSensor.HitNormal) -- Equal and opposite force  
        end
    end
end

The relevant part would be:

local jumpImpulse = Vector3.new(0, 750, 0)

This is where the jump force is being applied.

1 Like

How about swimming? how do i activate swimming functionality

Hello, good tutorial.

Have you made any reliable methods for the “Landed” HumanoidStateType to work when character actually has landed, if yes would you mind sharing?

1 Like

Hello! When I was coding landing animations for my game, I used Humanoid.StateChanged. In particular, I checked for when the oldState was Freefall and the newState was Running. Then I simply changed the state to Landed.

Wonderful tutorial! I haven’t found alot like this in a while. I was just wondering:

Somebody already said how to detect player deaths and such previously on this thread. How can I respawn the player and stop the player from moving/controlling the character after death?

Made a full game which was only possible if this topic existed.

1 Like

You can do that by using the asset in roblox’s topic.

Now this is crazy impressive! Glad this topic was helpful

1 Like

One hundred likes! :face_holding_back_tears: Thanks for all of the support

Has something changed with roblox’s character controllers? The file doesn’t seem to work anymore as my character just half clips to the ground and isn’t able to move. The character can jump and then move but it’s not what I’m looking for. I tried re-installing the file but to no avail I got the same results.
Is anyone else also experiencing this?
image

Yeah me 2 they seemed to have broken them my game doesn’t use humanoids but uses the controllers and it was working before especially annoying for me because my game requires them.

cc @voidguyDev Posted bug report, this previously worked.

I had that problem, my solution was to put the PartSensor’ parent in the HumanoidRootPart

1 Like

That works! Thanks a little annoying we have to do that though and nothing was said about the change hopefully it gets reverted.

since someone else tested before me and said it works I’ll try it out for myself too.
As of my now my “fix” was to just to use the scripts given from the introduction post of character controller and edit them myself.

I suppose the reason for that change is how SensorUpdateType works in OnRead mode, since that mode requires a BasePart to detect objects. However, in Manual mode, that’s not necessary. So, I agree with you.

for some reason, my character just ragdolls itself whenever it hits a wall at a fast speed. any help?

EDIT: the character only seems to do this when you jump right after slamming into a wall. still stumped.