Touched Event Affecting Function

I have a function that is called by the characters torso being touched - Torso.Touched - I also have a while true loop that prints the output of a boolean called ClimbingWall - It checks for when the player is climbing the wall.

When the player is not climbing the wall, it correctly prints false. But for some reason, whenever the player is climbing the wall, it will bounce between true and false, and the output will look something like this >>> true, false, true, false, true, false, false, true, false

function EnableClimb()
    if not ClimbingWall and Humanoid:GetState() == Enum.HumanoidStateType.Freefall then  
        local raycastParams = RaycastParams.new()
        local raycast = workspace:Raycast(HumRootPart.Position, HumRootPart.CFrame.LookVector * 1.38, raycastParams)
        ClimbingWall = true

        if raycast and raycast.Instance.Size.Y > 5 then
         FocusPart = raycast.Instance
            local firstTick = tick()
            print(raycast.Normal)
            
            if climbSideValue or climbValue or climbPower then
                climbSideValue, climbValue, climbPower = 0, 2, 1
            end

            HumRootPart.AssemblyLinearVelocity = Vector3.new(0,0,0)

            TweenService:Create(Humanoid, TweenInfo.new(0.4, Enum.EasingStyle.Exponential), { CameraOffset = Vector3.new(0,0,0) }):Play()
            TweenService:Create(camera, TweenInfo.new(0.4, Enum.EasingStyle.Exponential), { FieldOfView = 120 }):Play()

            ClimbConnect = RunService.RenderStepped:Connect(function()
                
                if not ClimbingWall then return end
                
                if FocusPart and Head.Position.Y > (FocusPart.Position.Y + FocusPart.Size.Y / 2) + 0.7 then
                    HumRootPart.AssemblyLinearVelocity = Vector3.new(0, 50, 0)

                    if Sprinting == false then
                        Humanoid.WalkSpeed = 16
                    else
                        Humanoid.WalkSpeed = 27
                    end

                    IdleClimbTrack:Stop()
                    MoveClimbTrack:Stop()
                    DownFOVTween:Play()
                    ClimbingWall = false
                    ClimbConnect:Disconnect()

                    return
                end

                Humanoid.WalkSpeed = 0
                local checkRaycast = workspace:Raycast(HumRootPart.Position, HumRootPart.CFrame.LookVector * 1.38, raycastParams)
                
                if not checkRaycast or checkRaycast.Instance ~= FocusPart then
                    print("TOO BAD")
                    DownFOVTween:Play()
                    
                    task.delay(0.1, function()
                        if not workspace:Raycast(HumRootPart.Position, HumRootPart.CFrame.LookVector * 1.38, raycastParams) then
                            ClimbingWall = false
                            ClimbConnect:Disconnect()
                        end
                    end)
                    return
                end

                if CurrentInputW and not MoveClimbTrack.IsPlaying then
                    IdleClimbTrack:Stop()
                    MoveClimbTrack:Play()
                elseif not CurrentInputW then
                    MoveClimbTrack:Stop()
                    IdleClimbTrack:Play()
                end

                HumRootPart.AssemblyLinearVelocity = CFrame.lookAlong(Vector3.zero, checkRaycast.Normal, Vector3.yAxis):VectorToWorldSpace(Vector3.new(climbSideValue, climbValue * climbPower, 0))
            end)

            while task.wait(0.1) and FocusPart and ClimbingWall do

                if tick() - firstTick > 4 then
                    ClimbConnect:Disconnect()
                    MoveClimbTrack:Stop()
                    IdleClimbTrack:Play()
                    ClimbingWall = false
                    break
                end

                climbPower = CurrentInputW and 5 or -1
                climbSideValue = CurrentInputA and 15 or (CurrentInputD and -15 or 0)

            end
        end
    end
end

How could i fix this?

The Raycast may be failing intermittently, maybe consider using a module like ZonePlus?

3 Likes

Not this biggest fan of using plugins, would there be any other way to fix this problem? Its okay if not, i could probably still manage to get something working.

bumping for any other solutions

While I highly suggest using the ZonePlus module (it would also eliminate needing both Touched and Raycast), the issue might be that you should use Enum.RaycastFilterType.Include so it only detects parts of the ladder.

I came across a way of using tables some time ago to solve the toggle problem.

Here is a sound zone file I created using it:

SoundZones.rbxl (57.6 KB)

You can get the idea of how to use tables.

Here is the code:




--==============
-- RANDOM SOUND
--==============

local NewSound = nil
local LastSound = nil

function SelectRandomSound(source)
	while not NewSound or NewSound == LastSound do
		NewSound = source:GetChildren()[math.random(1, #source:GetChildren())]
	end
	LastSound = NewSound
	return NewSound
end



--=============
-- PLAY SOUNDS
--=============

local Players = game:GetService("Players")
local Player = Players.LocalPlayer or Players.PlayerAdded:Wait()
local Zones = game.Workspace:WaitForChild("Zones")
local Sounds = game:GetService("SoundService"):WaitForChild("Zones")

local PartsTouching = {}
local IsPlaying = false
local CurrentZone

for _, zone in pairs(Zones:GetChildren()) do
	if zone:IsA("BasePart") then

		zone.Touched:Connect(function(otherPart)
			
			if otherPart.Parent.Name == Player.Name then
				
				-- add toucing parts to table
				
				if not table.find(PartsTouching, otherPart) then
					table.insert(PartsTouching, otherPart)
				end
				
				-- track bool
				
				if IsPlaying == false then
					IsPlaying = true
					
					-- stop sounds
					
					for _, sound in pairs(Sounds:GetChildren()) do
						if sound:IsA("Sound") then
							sound:Stop()
						end
					end
					
					-- play sound
					
					local function PlaySound()
						local RandomSound = nil
						RandomSound = SelectRandomSound(Sounds[zone.Name])
						if not RandomSound.IsPlaying then
							RandomSound:Play()
							RandomSound.Ended:Wait()
							PlaySound() -- play next random sound
						end
					end
					PlaySound()

				end

			end
		end)
		
		zone.TouchEnded:Connect(function(otherPart)

			if otherPart.Parent.Name == Player.Name then

				-- remove toucing parts from table

				if table.find(PartsTouching, otherPart) then
					table.remove(PartsTouching, table.find(PartsTouching, otherPart))

					-- parts table empty

					if #PartsTouching == 0 then

						-- reset bool
						
						IsPlaying = false

						-- stop sound

						if Sounds:FindFirstChild(zone.Name) then
							for _, sound in pairs(Sounds:GetDescendants()) do
								if sound:IsA("Sound") then
									sound:Stop()
									sound.TimePosition = 0
								end
							end
						else
							warn("SOUNDS | ERROR: Sound Zone Not Found", zone.Name)
						end
					end
				end
			end
		end)

	end
end
1 Like

this might be it, ill try this out and give you the solution if it works!

So I’ve removed every instance where it sets climbingWall to false from the script but if the variable is set to true in the function, it’ll still print true,false,true,false and bounce between in the boolean.

But if i set it to true outside the function, it stays as true, and doesnt bounce between true and false.

at this point I have no clue whats happening?

This has been solved by @mc7oof in another topic you can find her

[Problem With Boolean Inside Of Touched Function - #6 by WindyTundra]