Not looking for entire scripts or anything–I am curious as to how the smooth transition below between position levels was achieved in untitled boxing game (with text and voice chat bubbles preserved):
It is likely done using a ColorCorrectionEffect
in Lighting
with the TintColor
tweened. This affects only the 3D world, so name tags and voice bubbles stay visible. It’s triggered when the player enters or exits a zone. An alternative is using a black full-screen Frame
in a ScreenGui
and tweening its BackgroundTransparency
for more UI control.
Thanks! I’m also mainly wondering how the positions are elevated so smoothly.
I’m assuming I get lifted up to a client-sided platform in the little span of the blackout, but it seemed too smooth lol. Maybe I’m overthinking it.
You’re getting teleported. It’s as simple as that
Thanks, yeah, that’s what I thought! I was also wondering how the region types loaded so quickly that it almost felt seamless for the first time I opened this area (in the video). It might be my computer, but I normally expected some issues unless it was prerendered somehow lol.
When you step into a certain zone, your screen fades to black for a split second — during that time, you’re probably being teleported to a client-sided duplicate of the arena that’s positioned higher up. Because the fade hides the teleport, it feels like you were smoothly lifted up, even though it’s just a quick position swap. The fight you’re watching is likely synced or mirrored across both levels so it appears seamless. It’s all done locally on the client, which makes it super smooth and fast, with no delay or teleport jitters. You’re not overthinking it — it’s a smart illusion using a bit of visual misdirection and scene duplication!
Precisely. Everything is handled on the client, including the teleportation. Here is a crude teleportation demo I made that creates a near seamless transfer of movement: https://gyazo.com/818e8cc13822482a4e4b46348e398adc
--!strict
local PartA = workspace:WaitForChild("PartA")
local PartB = workspace:WaitForChild("PartB")
local canTeleport = true
local function teleportsTo(part: BasePart, otherPart: BasePart)
part.Touched:Connect(function(otherPart)
if not canTeleport then
return
end
local character = otherPart.Parent :: Model
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid then
return
end
local verticalOffset = Vector3.yAxis * character:GetExtentsSize().Y / 2
local currentCFrame = character:GetPivot()
local newCFrame = CFrame.new(otherPart.Position + verticalOffset) * currentCFrame.Rotation
canTeleport = false
character:PivotTo(newCFrame)
task.wait(0.5)
canTeleport = true
end)
end
teleportsTo(PartA, PartB)
teleportsTo(PartB, PartA)
Another thing I noticed was that other players who wanted to spectate could be seen in both the spectating arena and within the spectating pad (if you were off the pad).
Would it be better to clone players across this among each client who enters the region? My friends could see my character moving like normal on the pad if they were watching me while outside of the pad, but I could see seamless movement in the spectator’s arena.
I came questioning this smooth transition I saw with the pretense that simply moving the character locally would also move it for the server (as if I were cheating).
Sorry for continuing to ponder this:
Two more observations:
- Upon joining the game, you can’t spectate ongoing battles unless they’ve been started after you join.
- There are some players who can be seen on your screen in the spectator’s arena despite not entering the mode.
I have now come to the conclusion that the players fighting have been moved downward on the spectators’ clients.
- This is a limitation introduced by the developer’s scripting. This is something you can implement.
- Could be a bug. It’s much more believable from a design standpoint to have replicated dummies than locally displaced live players. The developer could be doing this for all active battles to reduce initialization delay upon spectation