How to connect/disconnect a function (Camera manipulation)?

So, I am making a Camera animation using Tween that have a different phase.

now I don’t know how to properly disconnect the phase 1 function.

I made this to test but it seems it doesn’t work.

local PHASE_SWITCH = script:WaitForChild("PHASE_SWITCH")

Camera.CameraType = Enum.CameraType.Scriptable

local CONNECTION

local function CAMERA_PHASE_1()
	while wait(.5) do
		print("PHASE_1")
	end
end

local function CAMERA_PHASE_2()
	while wait(.5) do
		print("PHASE_2")
	end
end

PHASE_SWITCH:GetPropertyChangedSignal("Value"):Connect(function()
	
	if CONNECTION then
		CONNECTION:Disconnect()
	end
	
	if PHASE_SWITCH.Value == 1 then
		CONNECTION = PHASE_SWITCH.Changed:Connect(CAMERA_PHASE_1)
	elseif PHASE_SWITCH.Value == 2 then
		CONNECTION = PHASE_SWITCH.Changed:Connect(CAMERA_PHASE_2)
	end
end)

--Outputs:
-- Phase_1 (15x)
-- Phase_2 (2x)
-- Phase_1 (1x)
-- [And now they intercept each other.]

I know I did something wrong with this because I’m just experimenting with it.

Any ideas on how to accomplish my goal?

The goal should look like this:

  • Phase 1 runs the camera manipulation repeatedly until a value changed and disconnects the Phase 1 function to stop the loop.
  • Now Phase 2 should run and make a new camera manipulation without loop as the value changed and ends and disconnect it.
1 Like

They intercept eachother because while loops continue to run even when you disconnect the connection to the event. What the code is basically doing is creating multiple while loops that never end, so you have to add some breaks in the while loop that stop the loop when the phase is over. I also recommend adding something that checks whether a loop has already been made.

Yep, I know that, I’m just testing because I thought by just disconnecting a function it will stop the loop also.

Now, Imagine this because this is the goal that I want:

A game loads and a camera manipulation started (looping) and a UI shows. As the camera loops around in different subjects, I clicked the “Play” button. Now the current camera should stop its looping and move to different phases like moving a different hallway to “simulate” a new mode like for example teleports my character to a different game.

But now my problem is, As the function is already running the loop, how do I stop it at that point (if the script is in the middle area) if my created if-else condition to break it is in the lowest part of the loop. Now that’s my problem,

Add in a break system, like:

local break1 = false
function x(...)
    while true do
        if break1 then
            break1 = false
            break
        end
        --// things here
    end
end

coroutine.resume(coroutine.create(x))
--// when you no longer need the loop:
break = true

(Code written in mobile, apologies for mistakes)

2 Likes

You could use object oriented programming to create a “CameraTween.” In a module script, it would look something like this:

local CameraTween = {}
CameraTween.__index = CameraTween

function CameraTween.new(PhaseFunction, TimeStep)
    local self = setmetatable({}, CameraTween)
    self.Enabled = true
    spawn(function()
        while self.Enabled do
            PhaseFunction()
            wait(TimeStep)
        end
    end)
    return self
end

function CameraTween:Stop()
    self.Enabled = false
end

return CameraTween

Now in the local script:

local PHASE_SWITCH = script:WaitForChild("PHASE_SWITCH")
local CameraTween = require(script:WaitForChild("CameraTween"))
local Phase1CameraTween, Phase2CameraTween = nil, nil

function Phase1Function()
    -- put what you want to happen every time step
end

function Phase2Function()
    -- put what you want to happen every time step
end

PHASE_SWITCH:GetPropertyChangedSignal("Value"):Connect(function()
    if PHASE_SWITCH.Value == 1 and not Phase1CameraTween then
        Phase1CameraTween = CameraTween.new(Phase1Function, 0.5) -- change the time step to whatever
    elseif PHASE_SWITCH.Value == 2 and not Phase2CameraTween then
        if Phase1CameraTween then
            Phase1CameraTween:Stop() -- stops the phase1 loop
            Phase1CameraTween.Enabled = false -- this also stops the phase 1 loop
        end
        Phase2CameraTween = CameraTween.new(Phase2Function, 0.5) -- change the time step to whatever
    end
end)
1 Like