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?
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.
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.
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?
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.
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
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
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
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.