How can I recreate this tween effect from Flood Escape 2?

Greetings! I’m creating a Flood Escape 2 timeline editor inside of Roblox Studio to more efficiently test maps. However, I’m stuck on one crucial step.

On FE2, when moving a part, you set the properties like a tween. However, if you try to move the part mid tween it’ll play both tweens at the same time somehow. I genuinely cannot find any resources or features matching this mechanic. Any help would be greatly appreciated!

Example: How can I recreate this kind of tween? - Clipped with Medal.tv
(Pay attention to how the Red brick moves. When I hit the button mid tween, it keeps going up and applies that second tween on top of it.)

I’m desprate, help would be amazing. Thank you!

You would probably want to use Lerping instead of tweening? This is just my suggestion, as I am not completely sure what you could do other than either use lerping or an iterator loop where you change the speed.

1 Like

I had thought about Lerping, I tried a few things but couldn’t figure out trying to lerp easing styles and easing directions.

I see AssemblyLinearVelocity could be an option. I don’t know if you could get any tweening easing styles. I’m not going to say it’s impossible, but I have no idea how you could achieve this, sorry.

1 Like

The source code for Timelines V1 is available on GitHub: FloodEscape2/TimelineV1.lua at main · Crazyblox-Games/FloodEscape2 · GitHub

I think this is the function that was used?

--Function that moves parts and models; used primarily for floods
local InternalTweenConfigs = {}
function TimelinePlayer.MovePart(Object, Translation, Duration, IsLocalSpace, EasingStyle, EasingDirection)
	if typeof(Object) ~= "Instance" then
		error("Object: Only an Instance (Model, BasePart) can be provided")
	end
	if not (Object:IsA("Model") or Object:IsA("BasePart")) then
		error("Object: MovePart can only accept a Model with a PrimaryPart or a BasePart")
	end
	if typeof(Translation) ~= "Vector3" then
		error("Translation: Provided invalid data type (" .. typeof(Translation) .. "); please provide a Vector3 Value")
	end
	local EasingStyle, EasingDirection = EasingStyle or "Sine", EasingDirection or "InOut"
	local IsModel = Object:IsA("Model")
	if IsModel then
		if Object.PrimaryPart == nil then
			local ModelDescendants = Object:GetDescendants()
			for _, Descendant in next, ModelDescendants do
				if Descendant:IsA("BasePart") then
					Object.PrimaryPart = Descendant
					warn("PrimaryPart not present; function has automatically assigned a PrimaryPart")
					break
				end
			end
		end
	end
	local InternalCFrameValue = Instance.new("CFrameValue")
	InternalTweenConfigs[Object] = InternalTweenConfigs[Object] or Instance.new("Configuration")
	local AttConfig = InternalTweenConfigs[Object]
	local TweenAttribute = (
		"Tween_"
		.. (IsLocalSpace and "Local" or "Global")
		.. "_"
		.. game:GetService("HttpService"):GenerateGUID(false):sub(1, 8)
	)
	AttConfig:SetAttribute(TweenAttribute, Vector3.new())
	if AttConfig:GetAttribute("OriginalCFrame") == nil then
		local refCFrame = IsModel and Object:GetPrimaryPartCFrame() or Object.CFrame
		AttConfig:SetAttribute("OriginalCFrame", refCFrame)
		AttConfig.AttributeChanged:Connect(function(ChangedAttribute)
			local AppliedCFrame = AttConfig:GetAttribute("OriginalCFrame")
			local Vectors = { ["Local"] = Vector3.new(), ["Global"] = Vector3.new() }
			for AttributeName, AttributeValue in pairs(AttConfig:GetAttributes()) do
				if AttributeName:find("Tween_") then
					for VectorName, VectorValue in pairs(Vectors) do
						if AttributeName:find(VectorName) then
							Vectors[VectorName] = Vectors[VectorName] + AttributeValue
						end
					end
				end
			end
			AppliedCFrame = AppliedCFrame * CFrame.new(Vectors.Local.X, Vectors.Local.Y, Vectors.Local.Z)
			AppliedCFrame = AppliedCFrame + Vectors.Global
			if IsModel then
				Object:PivotTo(AppliedCFrame)
			else
				Object.CFrame = AppliedCFrame
			end
		end)
	end
	InternalCFrameValue.Changed:Connect(function(NewCFrame)
		AttConfig:SetAttribute(TweenAttribute, Vector3.new(NewCFrame.X, NewCFrame.Y, NewCFrame.Z))
	end)
	local TranslationTween = TweenService:Create(
		InternalCFrameValue,
		TweenInfo.new(Duration, Enum.EasingStyle[EasingStyle], Enum.EasingDirection[EasingDirection]),
		{ Value = CFrame.new(Translation.X, Translation.Y, Translation.Z) }
	)
	TranslationTween.Completed:Connect(function()
		InternalCFrameValue:Destroy()
		AttConfig:SetAttribute(TweenAttribute, nil)
		local CompleteCFrame = AttConfig:GetAttribute("OriginalCFrame")
		if IsLocalSpace then
			CompleteCFrame = CompleteCFrame * CFrame.new(Translation.X, Translation.Y, Translation.Z)
		else
			CompleteCFrame = CompleteCFrame + Translation
		end
		if IsModel then
			Object:PivotTo(CompleteCFrame)
		else
			Object.CFrame = CompleteCFrame
		end
		AttConfig:SetAttribute("OriginalCFrame", CompleteCFrame)
		local oldCFrame = IsModel and Object:GetPrimaryPartCFrame() or Object.CFrame
	end)
	TranslationTween:Play()
end
1 Like

WAIT I DIDN’T KNOW THAT! Thank you!!
I’ll check it out and report back if it ended up working!

Thank you so so much, this ended up working exactly how I wanted it to!!

1 Like