Break not working?

For some reason, my break doesn’t seem to be working.

I apologize for the messy-coding, I’ll organize it soon :sweat_smile:

Output:

image

  • these prints are from the LocalScript from FireAllClients()

  • randomly, it fires false twice then it goes back to true. (Which isn’t what’s supposed to happen)

  • also near the end of the LocalScript, the break doesn’t seem to, of course break, which is what I assume the main culprit behind the error.

Server-Script:

local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage.Events
local Assets = ReplicatedStorage.Assets
local VFX = ReplicatedStorage.VFX
local SFX = ReplicatedStorage.SFX

local NukeRE = Events:FindFirstChild("Nuke")
local CameraShakeRE = Events:FindFirstChild("CameraShake")

NukeRE.OnServerEvent:Connect(function(Player, Tool)
	local Character = Player.Character
	Tool.Handle:Destroy()
	Tool.Enabled = false
	Tool.Parent = workspace
	
	local NukeActivated = false
	
	local Nuke = Assets.Nuke:Clone()
	local NukeVFX = VFX.NukeVFX:Clone()
	Nuke.PrimaryPart.Position = Tool.Main.Position + Vector3.new(0,1000,0)
	
NukeVFX.InnerNuke.Touched:Connect(function(HitPart)
		local success, errormsg = pcall(function()
			if HitPart then
				local Character = HitPart.Parent
				if Character:IsA("Model") then
					local Humanoid = Character.Humanoid
					if Humanoid:IsA("Humanoid") then
						Humanoid.Health = 0
						for _, bodypart in pairs(Character:GetDescendants()) do
							if bodypart:IsA("BasePart") then
								bodypart.BrickColor = BrickColor.new("Really black")
							elseif bodypart:IsA("Accessory") then
								bodypart.Handle.BrickColor = BrickColor.new("Really black")
							end
						end
					end
				end
			end
		end)
end)
	Nuke.Parent = workspace
	Nuke.PrimaryPart.Touched:Connect(function(HitPart)
		if HitPart then
			NukeActivated = true
			warn("Nuke Unleashed, plr="..Player.Name)
			NukeVFX:SetPrimaryPartCFrame(Nuke.PrimaryPart.CFrame)
			CameraShakeRE:FireAllClients(true)
			Nuke:Destroy()
			NukeVFX.Parent = workspace
			local NukeSound = SFX:WaitForChild("NukeSound"):Clone()
			NukeSound.Parent = NukeVFX.PrimaryPart
			NukeSound:Play()
			for i = 1, 225, 1 do
				task.wait()
				NukeVFX:ScaleTo(i)
			end
			for i = 225, 250, .5 do
				task.wait()
				NukeVFX:ScaleTo(i)
			end
			for i = 0, 1, 0.01 do
				task.wait(0.025)
				for _, part in pairs(NukeVFX:GetDescendants()) do
					if part:IsA("BasePart") then
						part.Transparency = i
					end
				end
			end
			NukeVFX:Destroy()
			CameraShakeRE:FireAllClients(false)
		end
	end)
end)

LocalScript:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local Events = ReplicatedStorage:WaitForChild("Events")

local CameraShakeRE = Events:WaitForChild("CameraShake")

local LocalPlayer = Players.LocalPlayer
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")

CameraShakeRE.OnClientEvent:Connect(function(Activated)
		print(Activated)
	
	while true do
		if Activated == true then
			print(Activated)
			task.wait()

			local xoffset = math.random(-100,100) / 500
			local yoffset = math.random(-100,100) / 500
			local zoffset = math.random(-100,100) / 500

			Humanoid.CameraOffset = Vector3.new(xoffset,yoffset,zoffset)
		else
			print(Activated)
			task.wait()
			Humanoid.CameraOffset = Vector3.new(0,0,0)
			break
		end
	end
end)

From a cursory glance, it’s because you’re using the local variable Activated which is never modified inside of the context of the callback. The solution would be to put an Activated variable outside of the callback and modify that when the callback is executed.

If I’m understanding how your script is intended to work correctly, this is how I would modify it while maintaining your current structure

-- All the other stuff in your LocalScript...
local Activated = false

CameraShakeRE.OnClientEvent:Connect(function(activate)
	-- Ignore the case where you're sending an activate signal when already activated,
	-- so that you don't start another while loop
	if Activated and activate then return end
	Activated = activate

	-- Each callback is self-contained, so we need to make sure we don't run the code
	-- after this line so that the CameraOffset doesn't get set to (0, 0, 0) briefly
	if not Activated then return end

	while Activated do
		task.wait()
		local xoffset = math.random(-100,100) / 500
		local yoffset = math.random(-100,100) / 500
		local zoffset = math.random(-100,100) / 500

		Humanoid.CameraOffset = Vector3.new(xoffset,yoffset,zoffset)
	end
	Humanoid.CameraOffset = Vector3.new(0,0,0)
end)
Additional Details

If the code above is working perfectly fine for you, then you can disregard what I’m writing here.

I would probably write the following code instead of what you have to ensure that it works as I would intend.
Essentially what it’s doing is if the camera isn’t shaking and the server tells the client to start shaking, it will bind the relevant shaking code to Heartbeat, which emits every frame. When the server tells the client to stop shaking and we’re currently binded to Heartbeat, it unbinds it.

-- At the top
local RunService = game:GetService("RunService")
--
-- Your other LocalScript code
--

local CurrentShake = nil

CameraShakeRE.OnClientEvent:Connect(function(activate)
    if CurrentShake == nil and activate then
        CurrentShake = RunService.Heartbeat:Connect(function(_deltaTime)
            local xoffset = math.random(-100,100) / 500
            local yoffset = math.random(-100,100) / 500
            local zoffset = math.random(-100,100) / 500
            
            Humanoid.CameraOffset = Vector3.new(xoffset, yoffset, zoffset)
        end)
    elseif CurrentShake ~= nil and not activate then
        CurrentShake:Disconnect()
        CurrentShake = nil
    end
end)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.