Okay So basically I’m making a ROBLOX game that has swimming similar to flood escape 2. The only catch is that the touch event fires multiple times and for some reason my body velocity doesn’t work. Here is the script:
local Character = script.Parent
local Head = Character:WaitForChild("Head")
local Humanoid = Character:WaitForChild("Humanoid")
local Root = Character:WaitForChild("HumanoidRootPart")
local UIS = game:GetService("UserInputService")
local InWater = false
local function InTheWater()
if not InWater then
InWater = true
Humanoid:ChangeState(Enum.HumanoidStateType.FallingDown)
local Velocity = Instance.new("BodyVelocity")
Velocity.Parent = Root
Velocity.MaxForce = Vector3.new(0,1,0) * math.huge
Velocity.Velocity = Vector3.new(0,0,0)
UIS.InputBegan:Connect(function(Input,Process)
if Process then return end
if Input.KeyCode == Enum.KeyCode.Space then
Velocity.Velocity = Vector3.new(0,1,0) * 50
end
end)
UIS.InputEnded:Connect(function(Input,Process)
if Process then return end
if Input.KeyCode == Enum.KeyCode.Space then
Velocity.Velocity = Vector3.new(0,0,0)
end
end)
UIS.InputBegan:Connect(function(Input,Process)
if Process then return end
if Input.KeyCode == Enum.KeyCode.LeftShift then
Velocity.Velocity = Vector3.new(0,1,0) * -50
end
end)
UIS.InputEnded:Connect(function(Input,Process)
if Process then return end
if Input.KeyCode == Enum.KeyCode.LeftShift then
Velocity.Velocity = Vector3.new(0,0,0)
end
end)
end
end
local function OutTheWater()
if InWater then
InWater = false
if Root.BodyVelocity then
Root.BodyVelocity:Destroy()
end
Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
end
while wait() do
Head.Touched:Connect(function(Hit)
if Hit.Name == "Water" then
InTheWater()
end
end)
Head.TouchEnded:Connect(function(Hit)
if Hit.Name == "Water" then
OutTheWater()
end
end)
end
Can you please help me? I’m not sure why it’s doing this
local Character = script.Parent
local Head = Character:WaitForChild("Head")
local Humanoid = Character:WaitForChild("Humanoid")
local Root = Character:WaitForChild("HumanoidRootPart")
local UIS = game:GetService("UserInputService")
local InWater = false
local Up = 0
UIS.InputBegan:Connect(function(Input,Process)
if Process then return end
if Input.KeyCode == Enum.KeyCode.Space then
Up = 1
elseif Input.KeyCode == Enum.KeyCode.LeftShift then
Up = -1
end
end)
UIS.InputEnded:Connect(function(Input,Process)
if Process then return end
if Input.KeyCode == Enum.KeyCode.Space then
Up = 0
elseif Input.KeyCode == Enum.KeyCode.LeftShift then
Up = 0
end
end)
local function InTheWater()
if not InWater then
InWater = true
Humanoid:ChangeState(Enum.HumanoidStateType.FallingDown)
local Velocity = Instance.new("BodyVelocity")
Velocity.MaxForce = Vector3.new(0,1,0) * math.huge
Velocity.Velocity = Vector3.new(0,0,0)
Velocity.Parent = Root
repeat
if Up > 0 then
Velocity.Velocity = Vector3.new(0,1,0) * 50
elseif Up < 0 then
Velocity.Velocity = Vector3.new(0,1,0) * -50
else
Velocity.Velocity = Vector3.new(0,0,0)
end
wait(0.1)
until not InWater
end
end
local function OutTheWater()
if InWater then
InWater = false
if Root.BodyVelocity then
Root.BodyVelocity:Destroy()
end
Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
end
Head.Touched:Connect(function(Hit)
if Hit.Name == "Water" then
InTheWater()
end
end)
Head.TouchEnded:Connect(function(Hit)
if Hit.Name == "Water" then
OutTheWater()
end
end)
Unfortunately it didnt work and the same issue from before happend. Im sorry that i didnt tell you this from before but my roblox avatar inputs become delayed when im in the water part and my avatar keeps flashing
You keep making a new connection every single time you call your InTheWater() function. You should either disconnect your connections OR keep them outside the function.
You also have a while loop thats constantly connection touch events:
while wait() do
Head.Touched:Connect(function(Hit)
if Hit.Name == "Water" then
InTheWater()
end
end)
Head.TouchEnded:Connect(function(Hit)
if Hit.Name == "Water" then
OutTheWater()
end
end)
end
Just keep all your connections outside of any functions/loops or disconnect them when needed.
Connection = Head.Touched:Connect(function(Hit)
if Hit.Name == "Water" then
InTheWater()
end
end)
Connection:Disconnect(); -- Now we disconnect it (which means it won't get triggered, etc)
However, I don’t think this is the right approach for your issue. You should just remove the touch events out of the while loop (just delete the while loop altogether) and move all your userInput connections outside the InTheWater() function.
I took out the UIS inputs out of the function and I Removed the while loop and the same thing happened. I also tried adding The disconnect thing you said and it just didn’t fire the function at all
local Character = script.Parent
local Head = Character:WaitForChild("Head")
local Root = Character:WaitForChild("HumanoidRootPart")
local Humanoid = Character:WaitForChild("Humanoid")
local UIS = game:GetService("UserInputService")
local InWater = false
local Up = 0
UIS.InputBegan:Connect(function(Input,Process)
if Process then return end
if Input.KeyCode == Enum.KeyCode.Space then
Up = 1
end
end)
UIS.InputBegan:Connect(function(Input,Process)
if Process then return end
if Input.KeyCode == Enum.KeyCode.LeftShift then
Up = -1
end
end)
UIS.InputEnded:Connect(function(Input,Process)
if Process then return end
if Input.KeyCode == Enum.KeyCode.Space then
Up = 0
end
end)
UIS.InputEnded:Connect(function(Input,Process)
if Process then return end
if Input.KeyCode == Enum.KeyCode.LeftShift then
Up = 0
end
end)
local function InTheWater()
if InWater == false then
InWater = true
Humanoid:ChangeState(Enum.HumanoidStateType.FallingDown)
local Velocity = Instance.new("BodyVelocity")
Velocity.Parent = Root
Velocity.MaxForce = Vector3.new(0,1,0) * math.huge
Velocity.Velocity = Vector3.new(0,0,0)
if Up == 1 then
Velocity.Velocity = Vector3.new(0,50,0)
elseif Up == 2 then
Velocity.Velocity = Vector3.new(0,-50,0)
else
Velocity.Velocity = Vector3.new(0,0,0)
end
end
end
local function OutTheWater()
if InWater == true then
InWater = false
Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
if Root.BodyVelocity then
Root.BodyVelocity:Destroy()
end
end
end
Head.Touched:Connt(function(Hit)
if Hit.Name == "Water" then
InTheWater()
end
end)
Head.TouchEnded:Connt(function(Hit)
if Hit.Name == "Water" then
OutTheWater()
end
end)