I’m currently creating my own controller for a game, and was working on the swimming part of the controller. I have the swimming part and state handling done, but the transition is very odd. Here’s how i want it to behave:
When the character walks into water, as long as it touches the ground beneath the water (near the shore or just very shallow) it doesn’t switch to the swimming state. since i made the density of the character lower than the water, as it goes into deeper into the water it will float, and once it gets into the point where it no longer touches the ground, thats when it switches to the swimming state, and will stay there until it touches ground again.
heres the code snippet in the state machine that handles the swimming/running state (it runs every frame):
local rootPart = character:WaitForChild("HumanoidRootPart")
local currentState = humanoid:GetState()
local isGrounded = groundSensor.SensedPart
local isInWater = buoyancySensor.TouchingSurface
-- Handle sitting first
if humanoid.Sit then
humanoid:ChangeState(Enum.HumanoidStateType.Seated)
return
end
--print(b)
-- Swimming logic - only enter swimming if in water AND not touching ground
if isInWater and not isGrounded then
if currentState ~= Enum.HumanoidStateType.Swimming then
humanoid:ChangeState(Enum.HumanoidStateType.Swimming)
end
return
end
-- Exit swimming if touching ground (even if still in water)
if currentState == Enum.HumanoidStateType.Swimming and isGrounded then
humanoid:ChangeState(Enum.HumanoidStateType.Running)
return
end
heres the code snippet that handles the controller:
humanoid.StateChanged:Connect(function(old, new)
if old == Enum.HumanoidStateType.Seated then
self:SetBehavior("Ground")
Inputs.EnableSeatExit(false)
end
if new == Enum.HumanoidStateType.Running then
self:SetBehavior("Ground")
controller.ActiveController = controller.GroundController
elseif new == Enum.HumanoidStateType.Freefall then
-- self:SetBehavior("Air")
controller.ActiveController = controller.AirController
elseif new == Enum.HumanoidStateType.Seated then
self:DisableCurrentBehavior()
Player.Character:SetAttribute("Sprinting", false)
Player.Character:SetAttribute("Aiming", false)
Inputs.EnableSeatExit(true)
elseif new == Enum.HumanoidStateType.Swimming then
self:SetBehavior("Water")
controller.ActiveController = controller.SwimController
end
end)
the SetBehavior() function just switches how the player inputs are converted into movement.
my issue is that when the player walks into water, at a point it just stops moving and stays stuck in position. the state is still in the running state and only switches to swimming when i jump. also when im swimming and go back to shore, when i switch back to running, my character’s moves very slowly and speeds up as the water gets shallower.
heres a video showcasing this:
how do i fix this so that it transitions smoothly, and also fix that speed issue when walking out of water?
Im using the controller manager/physics-based controller instead of the old controller btw.