Tweening pausing, playing help

I have a capture the point with flag system, but i am clueless to find a way that i want the tween to work.



The function “Animate” gets called in a while true do loop with 1s delay, The issue i am having atm is that when i leave the area it starts going down as it should but when i go back it doesn’t stop and doesn’t start going up as intended. Any solution?

2 Likes

Sorry this may not be the issue, but I do see that you put flagNeutralDown:Pause() in both RiseTheFlag() and DownTheFlag(). Sorry if this isn’t any help.

1 Like

Yeah to make sure it isn’t tweening at the same time i pause it

1 Like

What is the “Holder” variable?

From what I can see; when you try to raise the flag, you check if Holder ~= playerInBounds[1], however, you also check is #playerInBounds == 1 (No more or no less than 1 player). Meaning these if statements contradict each other.

Should you even be checking if `Holder ~= playerInBounds[1]?

Thats what I’m understanding from the pictures you sent.

1 Like

Yes, it’s correct holder is the one who captured it, it’s nil by default and when the flag gets risen it’s the one and only playerInBounds[1]

1 Like

Alright, so you’re saying that when the player try’s to capture the flag, the holder variable is set to them, right?

But then your checking if Holder ~= playerInBounds[1]. Wouldn’t playerInBounds[1] be the holder? Which would return a false value, therefore, not rising the flag.

Wouldn’t you want to say if Holder == playerInBounds[1] then?

1 Like

Nooo, the holder is set after the capture is done, so the holder cannot repacture his flag

hmm alright, do some debugging by adding:

print(playerInBounds[1], Captured, Holder)

Put this at the beginning of the Animate() function

1 Like

It prints everything well i am just asking how to tween play tween when value is let’s say 1 and when 2 to stop and when 0 to go down

1 Like

Is it because your setting Rising = true but never setting it back to false when the flag begins to go down or stay as Neutral?

1 Like

The problem is that you are stopping the tween while it’s not complete which causes the rising variable to never be set back to false because the code that should do it is wrapped in a Completed callback that is never called if the tween is stopped before completion.

1 Like

What should i do then? I tried this but didn’t work

Using tweens will probably cause inconsistencies in rising/lowering speeds if their processes are started/stopped before they are complete, so changing the flag’s CFrame is more effective and will produce uniform results. Try this:

local flag = -- Reference your flag
local upPos: Vector3 = --Your flag's fully up position
local downPos: Vector3 = -- Your flag's fully down position
local neutralPos: Vector3 = -- Your flag's neutral position
local captured: boolean = false
local playersInBounds = {} -- Array of players in bounds
local speedAlpha = 1 / 13 -- Lerp argument alpha should be between 0 and 1, since you use 13 as the tweening speed, 1 / 13 = 0.07 will rise/lower the flag in 13 seconds

function Animate()
    -- Require 1 player to go up or down
    if #playersInBounds == 1 then
        -- Go up or down depending on wheter the flag is captured or not
        if not captured then
            -- Rise the flag

            local targetCFrame = flag.CFrame:Lerp(CFrame.new(upPos), speedAlpha)
            
            -- If the flag is not completely up continue rising else set captured to true
            if (upPos - targetCFrame.Position).Magnitude > 0 then
                flag.CFrame = targetCFrame
            else
                captured = true
            end
        else
            -- Lower the flag

            local targetCFrame = flag.CFrame:Lerp(CFrame.new(downPos), speedAlpha)
            
            -- If the flag is not completely down continue lowering else set captured to false
            if (downPos - targetCFrame.Position).Magnitude > 0 then
                flag.CFrame = targetCFrame
            else
                captured = false
            end
        end
    elseif #playersInBounds < 1 then
        -- No one is conquering the flag, lerp to neutral position and set captured to false because it belongs to no one

        flag.CFrame = flag.CFrame:Lerp(CFrame.new(neutralPos), speedAlpha)
        captured = false
    end
end

I mean it rotates for some reason but yeah, it works!
image

My bad, it rotates because it’s setting the CFrame which also includes rotation. To keep it unchanged you want to set the targetCFrame’s rotation to the flag’s by adding the flag’s rotation and the targetCFrame’s position.

Here’s the updated Animate() function:

function Animate()
    -- Require 1 player to go up or down
    if #playersInBounds == 1 then
        -- Go up or down depending on wheter the flag is captured or not
        if not captured then
            -- Rise the flag

            local targetCFrame = flag.CFrame:Lerp(CFrame.new(upPos), speedAlpha)
            
            -- If the flag is not completely up continue rising else set captured to true
            if (upPos - targetCFrame.Position).Magnitude > 0 then
                flag.CFrame = targetCFrame.Position + flag.CFrame.Rotation
            else
                captured = true
            end
        else
            -- Lower the flag

            local targetCFrame = flag.CFrame:Lerp(CFrame.new(downPos), speedAlpha)
            
            -- If the flag is not completely down continue lowering else set captured to false
            if (downPos - targetCFrame.Position).Magnitude > 0 then
                flag.CFrame = targetCFrame.Position + flag.CFrame.Rotation
            else
                captured = false
            end
        end
    elseif #playersInBounds < 1 then
        -- No one is conquering the flag, lerp to neutral position and set captured to false because it belongs to no one
        local targetCFrame = flag.CFrame:Lerp(CFrame.new(neutralPos), speedAlpha)

        flag.CFrame = targetCFrame.Position + flag.CFrame.Rotation
        captured = false
    end
end

I am still getting this

Oversight, I couldn’t test the code. Anyway the target position CFrame needs to be multiplied by the original flag’s rotation before lerping.

function Animate()
    -- Require 1 player to go up or down
    if #playersInBounds == 1 then
        -- Go up or down depending on wheter the flag is captured or not
        if not captured then
            -- Rise the flag

            local targetCFrame = flag.CFrame:Lerp(CFrame.new(upPos) * flag.CFrame.Rotation, speedAlpha)
            
            -- If the flag is not completely up continue rising else set captured to true
            if (upPos - targetCFrame.Position).Magnitude > 0 then
                flag.CFrame = targetCFrame
            else
                captured = true
            end
        else
            -- Lower the flag

            local targetCFrame = flag.CFrame:Lerp(CFrame.new(downPos) * flag.CFrame.Rotation, speedAlpha)
            
            -- If the flag is not completely down continue lowering else set captured to false
            if (downPos - targetCFrame.Position).Magnitude > 0 then
                flag.CFrame = targetCFrame
            else
                captured = false
            end
        end
    elseif #playersInBounds < 1 then
        -- No one is conquering the flag, lerp to neutral position and set captured to false because it belongs to no one
        local targetCFrame = flag.CFrame:Lerp(CFrame.new(neutralPos) * flag.CFrame.Rotation, speedAlpha)

        flag.CFrame = targetCFrame
        captured = false
    end
end
1 Like

Great tysm for help, after days of searching for help only you helped correctly, massive W for you!

1 Like

The only thing that is kinda strange is the Magnitude because it’s never 0
image

Right, the :Lerp() method interpolates two CFrames which means it finds a point between them according to the alpha factor which as a result will never be completely 0.

What you can do is checking if magnitude is greater than 0.01 since the lowest value is will reach will be lesser than 0.01.