How do i stop a function with an another function inside that function

the title may be a bit confusing, but what i am trying to say is that i have a function, lets call it function1, and inside function1 there is an another function, lets call it function2. what i want to achieve is to stop function1 with function2. how would i do that?

You could do something like this

local function1 = function()
	print'start of function1'
	local function2 = function()
		print'function2'
		return false
	end
	
	local result = function2()
	if result == false then
		return print'stopped function'
	end
	print'end of function1'
end

function1()

image

3 Likes

ah, i think thats the solution… mostly it is

thanks that would probably work, but is there any way i could do that with userinputservice.InputBegan:Connect(function(), since return doesnt work on that

You could disconnect the InputBegan connection (not sure if that’s what you want)

this is what my script looks like:

module.function = function()
    --some script
    userinputservice.InputBegan:Connect(function(input)
        if input.KeyCode == Enum.KeyCode.X then
            --some code
            this is where i want the entire function to stop
        end
    end)
end

Can you explain why you want to stop the function? The whole module.function function would run before you would be able to stop it with UserInput

its a placement system and i want “X” to be the cancel key. here is the entire script
basically im getting lots of errors when i press x because the function is still running so i have to stop it

local module = {}
local RR3 = require(game.ReplicatedStorage.RotatedRegion3)

module.place = function(plr,item,itemtype)
	local placeitem = game.ReplicatedStorage.Remotes.PlaceItem
	local canPlace = false
	local itemTransparent = item:Clone()
	itemTransparent.Parent = workspace.Placing
	local function refreshcolor()
		if canPlace == true then
			for i,v in pairs(itemTransparent.Parts:GetChildren()) do
				if v.Name == "Hitbox" then
					v.Transparency = 0.5
					v.Color = Color3.fromRGB(0, 214, 0)
					v.CanCollide = false
				else
					v.Transparency = 0.5
					v.CanCollide = false
				end
			end
		else
			for i,v in pairs(itemTransparent.Parts:GetChildren()) do
				if v.Name == "Hitbox" then
					v.Transparency = 0.5
					v.Color = Color3.fromRGB(200, 0, 0)
					v.CanCollide = false
				else
					v.Transparency = 0.5
					v.CanCollide = false
				end
			end
		end
	end
	refreshcolor()
	local plot
	for i,v in pairs(game.Workspace.Plots:GetChildren()) do
		if v.Owner.Value == plr.Name then
			plot = v
			for i,b in pairs(v.BaseParts:GetChildren()) do
				b.Grid.Transparency = 0
			end
		end
	end
	local mouse = plr:GetMouse()
	local hitbox = itemTransparent.Parts.PrimaryPart
	local function getsurface(surfacenormal)
		local normal = plot.Middle.CFrame:VectorToObjectSpace(surfacenormal)
		local nx,ny,nz = normal.X,normal.Y,normal.Z
		if nx ~= 0 and (ny == 0 and nz == 0) then
			if nx > 0 then
				return("Front")
			else
				return("Back")
			end
		elseif ny ~= 0 and (nx == 0 and nz == 0) then
			if ny > 0 then
				return("Top")
			else
				return("Bottom")
			end
		elseif nz ~= 0 and (nx == 0 and ny == 0) then
			if nz > 0 then
				return("Left")
			else
				return("Right")
			end
		end
	end
	local function snapToGrid(vector3,middle,folder,posx,posy,posz,normal,hit,SN1,SN2,SN3)
		local x = math.floor(vector3.X+0.5)
		local y = math.floor(vector3.Y+0.5)
		local z = math.floor(vector3.Z+0.5)
		local S1 = getsurface(SN1)
		local S2 = getsurface(SN2)
		local S3 = getsurface(SN3)
		wait()
		local nx,ny,nz = normal.X,normal.Y,normal.Z
		if nx ~= 0 and (ny == 0 and nz == 0) then
			if nx > 0 then
				--Front
				if S1 == "Front" or S1 == "Back" then
					x -= hitbox.Size.X/2
				elseif S1 == "Top" or S1 == "Bottom" then
					x -= hitbox.Size.Y/2
				elseif S1 == "Right" or S1 == "Left" then
					x -= hitbox.Size.Z/2
				end		
			else
				--Back
				if S1 == "Front" or S1 == "Back" then
					x += hitbox.Size.X/2
				elseif S1 == "Top" or S1 == "Bottom" then
					x += hitbox.Size.Y/2
				elseif S1 == "Right" or S1 == "Left" then
					x += hitbox.Size.Z/2
				end	
			end
		elseif ny ~= 0 and (nx == 0 and nz == 0) then
			if ny > 0 then
				--Top
				if S2 == "Front" or S2 == "Back" then
					y += hitbox.Size.X/2
				elseif S2 == "Top" or S2 == "Bottom" then
					y += hitbox.Size.Y/2
				elseif S2 == "Right" or S2 == "Left" then
					y += hitbox.Size.Z/2
				end	
			else
				--Bottom
				if S2 == "Front" or S2 == "Back" then
					y -= hitbox.Size.X/2
				elseif S2 == "Top" or S2 == "Bottom" then
					y -= hitbox.Size.Y/2
				elseif S2 == "Right" or S2 == "Left" then
					y -= hitbox.Size.Z/2
				end	
			end
		elseif nz ~= 0 and (nx == 0 and ny == 0) then
			if nz > 0 then
				--Left
				if S3 == "Front" or S3 == "Back" then
					z -= hitbox.Size.X/2
				elseif S3 == "Top" or S3 == "Bottom" then
					z -= hitbox.Size.Y/2
				elseif S3 == "Right" or S3 == "Left" then
					z -= hitbox.Size.Z/2
				end	
			else
				--Right
				if S3 == "Front" or S3 == "Back" then
					z += hitbox.Size.X/2
				elseif S3 == "Top" or S3 == "Bottom" then
					z += hitbox.Size.Y/2
				elseif S3 == "Right" or S3 == "Left" then
					z += hitbox.Size.Z/2
				end	
			end
		end
		x = math.floor(x+0.5)
		y = math.floor(y+0.5)
		z = math.floor(z+0.5)
		local posx2 = middle.Position.X + x
		local posy2 = middle.Position.Y + y
		local posz2 = middle.Position.Z + z
		if S1 == "Front" or S1 == "Back" then
			if itemTransparent.Parts.PrimaryPart.Size.X % 2 ~= 0 then
				if math.floor(posx+0.5) > posx2 then
					x += 0.5
				else
					x -= 0.5
				end
			end
		elseif S1 == "Top" or S1 == "Bottom" then
			if itemTransparent.Parts.PrimaryPart.Size.Y % 2 ~= 0 then
				if math.floor(posx+0.5) > posx2 then
					x += 0.5
				else
					x -= 0.5
				end
			end
		elseif S1 == "Right" or S1 == "Left" then
			if itemTransparent.Parts.PrimaryPart.Size.Z % 2 ~= 0 then
				if math.floor(posx+0.5) > posx2 then
					x += 0.5
				else
					x -= 0.5
				end
			end
		end
		
		if S2 == "Right" or S2 == "Left" then
			if itemTransparent.Parts.PrimaryPart.Size.X % 2 ~= 0 then
				if math.floor(posy+0.5) > posy2 then
					y += 0.5
				else
					y -= 0.5
				end
			end
		elseif S2 == "Top" or S2 == "Bottom" then
			if itemTransparent.Parts.PrimaryPart.Size.Y % 2 ~= 0 then
				if math.floor(posy+0.5) > posy2 then
					y += 0.5
				else
					y -= 0.5
				end
			end
		elseif S2 == "Front" or S2 == "Back" then
			if itemTransparent.Parts.PrimaryPart.Size.Z % 2 ~= 0 then
				if math.floor(posy+0.5) > posy2 then
					y += 0.5
				else
					y -= 0.5
				end
			end
		end
		
		if S3 == "Right" or S3 == "Left" then
			if itemTransparent.Parts.PrimaryPart.Size.X % 2 ~= 0 then
				if math.floor(posz+0.5) > posz2 then
					z += 0.5
				else
					z -= 0.5
				end
			end
		elseif S3 == "Top" or S3 == "Bottom" then
			if itemTransparent.Parts.PrimaryPart.Size.Y % 2 ~= 0 then
				if math.floor(posz+0.5) > posz2 then
					z += 0.5
				else
					z -= 0.5
				end
			end
		elseif S3 == "Front" or S3 == "Back" then
			if itemTransparent.Parts.PrimaryPart.Size.Z % 2 ~= 0 then
				if math.floor(posz+0.5) > posz2 then
					z += 0.5
				else
					z -= 0.5
				end
			end
		end
		folder.Parts:SetPrimaryPartCFrame(middle+Vector3.new(-x,y,-z))
		local rogi = {
			{1, 1, -1},  --top front right
			{1, -1, -1}, --bottom front right
			{-1, -1, -1},--bottom front left
			{-1, 1, -1}, --top front left

			{1, 1, 1},  --top back right
			{1, -1, 1}, --bottom back right
			{-1, -1, 1},--bottom back left
			{-1, 1, 1}  --top back left
		}
		local buildareas = plot.BuildAreas:GetChildren()
		local boolTable = {}
		for i,v in pairs(rogi) do
			local CornerPos = hitbox.CFrame * CFrame.new(hitbox.Size.X/2 * v[1], hitbox.Size.Y/2 * v[2], hitbox.Size.Z/2 * v[3])
			local region = RR3.new(CornerPos,Vector3.new(0,0,0))
			local partsfound = region:FindPartsInRegion3WithWhiteList(buildareas)
			if #partsfound == 0 then
				table.insert(boolTable,false)
			else
				table.insert(boolTable,true)
			end
		end
		local region2 = RR3.new(hitbox.CFrame,hitbox.Size - Vector3.new(0.25,0.25,0.25))
		local parts2 = region2:FindPartsInRegion3()
		for i,v in pairs(parts2) do
			if v.Name == "Hitbox" and v ~= hitbox then
				table.insert(boolTable,false)
			end
		end
		if not table.find(boolTable,false) then
			canPlace = true
		else
			canPlace = false
		end
		refreshcolor()
	end
	local RS = game:GetService("RunService")
	local UIS = game:GetService("UserInputService")
	itemTransparent.Parent = workspace.Placing
	RS.RenderStepped:connect(function()
		local Whitelist = {}
		for i,v in pairs(plot.BaseParts:GetChildren()) do
			table.insert(Whitelist,v)
		end
		for i,v in pairs(plot.Structures:GetChildren()) do
			table.insert(Whitelist,v.Parts.Hitbox)
		end
		local ray = Ray.new(mouse.UnitRay.Origin,mouse.UnitRay.Direction*1000)
		local params = RaycastParams.new()
		params.FilterType = Enum.RaycastFilterType.Whitelist
		params.FilterDescendantsInstances = Whitelist
		local results = workspace:Raycast(ray.Origin,ray.Direction,params)
		if results ~= nil then
			local posX = plot.Middle.Position.X - results.Position.X
			local posY = results.Position.Y - plot.Middle.Position.Y
			local posZ = plot.Middle.Position.Z - results.Position.Z
			local largestsize
			local sizes = {}
			table.insert(sizes,plot.Middle.Size.X)
			table.insert(sizes,plot.Middle.Size.Y)
			table.insert(sizes,plot.Middle.Size.Z)
			for i,v in pairs(sizes) do
				if largestsize == nil then
					largestsize = v
				else
					if largestsize < v then
						largestsize = v
					end
				end
			end
			local whitelist2 = {}
			table.insert(whitelist2,plot.Middle)
			local rayparams2 = RaycastParams.new()
			rayparams2.FilterType = Enum.RaycastFilterType.Whitelist
			rayparams2.FilterDescendantsInstances = whitelist2
			local pos1 = plot.Middle.Position+Vector3.new(largestsize,0,0)
			local pos2 = plot.Middle.Position+Vector3.new(0,largestsize,0)
			local pos3 = plot.Middle.Position+Vector3.new(0,0,largestsize)
			local res1 = workspace:Raycast(pos1, plot.Middle.Position - pos1, rayparams2)
			local res2 = workspace:Raycast(pos2, plot.Middle.Position - pos2, rayparams2)
			local res3 = workspace:Raycast(pos3, plot.Middle.Position - pos3, rayparams2)
			local pos = Vector3.new(posX,posY,posZ)
			snapToGrid(pos,plot.Middle.CFrame,itemTransparent,results.Position.X,results.Position.Y,results.Position.Z,results.Normal,results.Instance,res1.Normal,res2.Normal,res3.Normal)
		end
		wait()
	end)
	UIS.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			if canPlace == true then
				if plr.PlaceCooldown.Value == false then
					if itemtype == "Structures" then
						if plr.Inventory.Structures:FindFirstChild(item.Name) ~= nil then
							placeitem:FireServer(item.Name,itemTransparent.Parts.PrimaryPart.CFrame,itemtype)
						end
					elseif itemtype == "Blueprints" then
						if plr.Inventory.Blueprints:FindFirstChild(item.Name) ~= nil then
							placeitem:FireServer(item.Name,itemTransparent.Parts.PrimaryPart.CFrame,itemtype)
						end
					end
				end
			end
		elseif input.KeyCode == Enum.KeyCode.R then
			game.ReplicatedStorage.Remotes.RotatePart:FireServer(plot.Middle,Vector3.new(90,0,0))
		elseif input.KeyCode == Enum.KeyCode.T then
			game.ReplicatedStorage.Remotes.RotatePart:FireServer(plot.Middle,Vector3.new(0,90,0))
		elseif input.KeyCode == Enum.KeyCode.Y then
			game.ReplicatedStorage.Remotes.RotatePart:FireServer(plot.Middle,Vector3.new(0,0,90))
		elseif input.KeyCode == Enum.KeyCode.X then
			workspace.Placing:ClearAllChildren()
			plr.PlayerGui.Buttons.Main.Visible = true
			plr.PlayerGui.PlacingGui.Main.Visible = false
			game.ReplicatedStorage.Remotes.ChangeValue:FireServer(plr.IsPlacing,false)
			for i,b in pairs(plot.BaseParts:GetChildren()) do
				b.Grid.Transparency = 0
			end
		end
	end)
end

return module

You can do this by having a run stepped event for that function then check for a certain bool value and if its true then you can return or break it or disconnect that event.Use the desired key to obviously changed the bool value to true

You could do

local RenderStepped = RS.RenderStepped:connect(function()
local InputBegan
InputBegan = UIS.InputBegan:Connect(function(input)

and then when X is pressed you would just do

RenderStepped:Disconnect()
InputBegan:Disconnect()

(Also you don’t need a wait() inside of RenderStepped, and connect is deprecated in favor of Connect)

oh ok ill try that i guess and let you know if it worked

you mean like

RunService.RenderStepped:Disconnect()

?

Its the same thing you are just indexing it for the other function to access it

local RenderStepped = RS.RenderStepped:Connect(function()

returns the connection that you just connected, so “RenderStepped” would be the connection
So to disconnect the connection you do

RenderStepped:Disconnect()

Just change the line where it says

RS.RenderStepped:connect(function()

with

local RenderStepped = RS.RenderStepped:Connect(function()

and the same with InputBegan

1 Like

yeah thats working. sorry for the late answer