Need help with humanoids

Need help with script. When you touch the part for the second time you’re supposed to return to the “running” state or “getting up” state however that is NOT working plz help :sob:

If quality is bad wait a sec cause i just uploaded it

1 Like

You :Destroy() the Swim BodyVelocity, then immediately after :Destroy() Root.BodyVelocity. Are these not the same thing? The error seems to be suggesting that it can’t find the BodyVelocity, and that may be because you’ve already destroyed it the line before.

Maybe replace both lines with:

if Swim then
    Swim:Destroy()
end
1 Like

I’ll fix this, thank you. However my issue is when touching the part for the SECOND time it already removes the velocity with output spam but doesn’t change the state from swimming to standing. Instead it keeps swimming.

Fix what I suggested and see if the issue persists. When that line errors, the code after it (where you set ‘Swimming’ to false and ‘GettingUp’ to true) won’t run. That may be the issue.

Also it’s quite difficult to read your code as you’re repeating the same code multiple times over and over again:

Your TouchEnded function sets ‘GettingUp’ to true 3 times, and does the same with ‘Swimming’ to false. Also you’re dividing Root.Size.Y by 1 in your Touched function, and adding a Vector3.new(0, 0, 0) to your Velocity. Also in your ‘elseif Swim then’ conditional you’re setting ‘Swimming’ to false, then attempt to set it to false 3 lines later in the next conditional.

1 Like

Lol most of the errors you pointed out were me tweaking to try and fix my issue. Y/1 used to be Y/2, the repeated code was me tweaking out.

No worries haha. Are the issues still persisting after the changes?

1 Like

Yeah they still are.


My output isn’t getting spammed (thank you by the way) but when I touch the part again it still doesn’t change the humanoid state.

1 Like

The heartbeat connection is an interesting choice. What was the intention with it?

It won’t get disconnected, so every time you touch the ‘Sea’ part (which will likely be hundreds/thousands of times) it will create a new loop that runs after every physics frame indefinitely.

Also maybe worth going into a bit more depth about what you’re actually hoping this script will do. I assume you just want the character to swim when they’re touching the sea part (with a BodyVelocity to make them swim faster?), and to stop swimming after they leave the water?

1 Like

Yes this is my what I was going for, heartbeat was what came to my mind at the time so I’ll probably be changing the script. Right now I’m redoing most of it to turn it to functions.

Devforum is not the best IDE so no idea how many errors I’ve made on this, but I think this has the same functionality as your code with significantly less text. See if this works?

local function setSwimmingState(isSwimming)
    Humanoid:ChangeState(Enum.HumanoidStateType.Swimming, isSwimming);
    Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, not isSwimming);
end

Root.Touched:Connect(function(Hit) -- Maybe bind to 'Root' instead of 'Sea'?
    if (Hit ~= Sea) then return; end -- If not touching 'Sea', do nothing

    local Swim = Root:FindFirstChild('Swim');
    
    if (Root.Position.Y < Sea.Position.Y - Root.Size.Y) then
        if (not Swim) then
            Swim = Instance.new('BodyVelocity', Root);
            Swim.Name = 'Swim';
        end
        
        Swim.Velocity = Humanoid.MoveDirection *Humanoid.WalkSpeed
        Humanoid.JumpPower = 8;

        if (Humanoid:GetState() ~= Enum.HumanoidStateType.Swimming) then
            setSwimmingState(true);
        end
    else
        if (Swim) then Swim:Destroy(): end
        
        if (Humanoid:GetState() == Enum.HumanoidStateType.Swimming) then
            setSwimmingState(false);
        end
    end
end)

Root.TouchEnded:Connect(function(hit)
    if (Hit ~= Sea) then return; end -- If not touching 'Sea', do nothing

    if (Root:FindFirstChild('Swim')) then
        Root.Swim:Destroy();
    end

    setSwimmingState(false);
end);
1 Like

It’s just occurred to me why you used the Heartbeat, you need a way of updating the velocity each physics step.

local runFunction;

local function setSwimmingState(isSwimming)
    Humanoid:ChangeState(Enum.HumanoidStateType.Swimming, isSwimming);
    Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, not isSwimming);
end

Root.Touched:Connect(function(Hit) -- Maybe bind to 'Root' instead of 'Sea'?
    if (Hit ~= Sea) then return; end -- If not touching 'Sea', do nothing

    local Swim = Root:FindFirstChild('Swim');
    
    if (Root.Position.Y < Sea.Position.Y - Root.Size.Y) then
        if (not Swim) then
            Swim = Instance.new('BodyVelocity', Root);
            Swim.Name = 'Swim';
        end
        
        if (not runFunction) then
            runFunction = RS.Stepped:Connect(function()
                Swim.Velocity = Humanoid.MoveDirection *Humanoid.WalkSpeed
            end);
        end

        Humanoid.JumpPower = 8;

        if (Humanoid:GetState() ~= Enum.HumanoidStateType.Swimming) then
            setSwimmingState(true);
        end
    else
        if (Swim) then Swim:Destroy(): end
        if (runFunction) then runFunction:Disconnect(); end
        
        if (Humanoid:GetState() == Enum.HumanoidStateType.Swimming) then
            setSwimmingState(false);
        end
    end
end)

Root.TouchEnded:Connect(function(Hit)
    if (Hit ~= Sea) then return; end -- If not touching 'Sea', do nothing

    if (Root:FindFirstChild('Swim')) then
        Root.Swim:Destroy();
    end

    if (runFunction) then runFunction:Disconnect(); end

    setSwimmingState(false);
end);
1 Like

It’s 2AM here and I need to sleep. If it’s not working then hopefully someone else can poke their head in and give you a hand.

1 Like

Lol tysm for your help. It has a couple bugs but I’ll fix them. Get some rest.

1 Like