using { /Fortnite.com/Devices } using { /Fortnite.com/UI } using { /Verse.org/Simulation } using { /Verse.org/Colors } using { /UnrealEngine.com/Temporary/UI } using { /UnrealEngine.com/Temporary/SpatialMath } # This is our main "Actor" (like a Player or a Prop). # It holds the logic for our timer. PanicTimerLogic := class(creative_device): # 1. BINDINGS: Connect this script to the devices in your level. # Think of this as plugging a cable from the Timer Device into our script. @editable TimerDevice: timer_device = timer_device{} # 2. BINDINGS: Connect to the HUD Message Device that shows our countdown. # We use a hud_message_device because Verse cannot directly bind to a # widget text-block at runtime; the hud_message_device is the supported # path for displaying updating text to all players. # note: If your project uses a custom widget, drive it from a Verse # `button_device` or `hud_message_device` as shown here. @editable HUDMessage: hud_message_device = hud_message_device{} # 3. VARIABLES: The "Health Bar" of our logic. # This holds the current time. It changes every second. var CurrentTime: float = 0.0 # 4. CONSTANTS: The "Rules of the Game." # These never change. They are the thresholds for panic. PanicThreshold: float = 10.0 CalmThreshold: float = 30.0 # This function runs ONCE when the game starts. # Like the "Pre-Round" phase. OnBegin(): void = # Start the timer device TimerDevice.Start() # Subscribe to the timer's "Success" event, which fires when the # countdown ends, and drive our per-second loop separately. TimerDevice.SuccessEvent.Subscribe(OnTimerEnd) # Spin up our own update loop so we can poll time each second. spawn { RunUpdateLoop() } # Polls the timer device once per second and refreshes the UI. RunUpdateLoop(): void = loop: Sleep(1.0) UpdateUI() # Fires when the timer device reaches zero. OnTimerEnd(Agent: ?agent): void = HUDMessage.Hide() # This function runs EVERY second inside RunUpdateLoop. # This is the "Game Loop" for our logic. UpdateUI(): void = # Get the current time from the device. # Think of this as checking the scoreboard. # note: timer_device exposes GetActiveDuration() which returns elapsed time; # subtract from the configured duration to get time remaining. # Here we read the elapsed time and label it clearly. ElapsedSeconds := TimerDevice.GetActiveDuration() # Format the time as a plain integer string (whole seconds elapsed). # Int() truncates toward zero, which is correct for a countdown display. ElapsedInt: int = if (V := Int[ElapsedSeconds]) then V else 0 TimeString: message = "{ElapsedInt}s" # Show the string through the HUD Message device. HUDMessage.SetText(TimeString) HUDMessage.Show() # Store for state checks below. set CurrentTime = ElapsedSeconds # DECIDE THE STATE (The "Panic" Logic) # note: timer_device does not expose a direct GetTimeRemaining(); we # track urgency by comparing elapsed time against the 60 s total # set on the device (60 - elapsed gives remaining). TimeRemaining: float = 60.0 - CurrentTime if (TimeRemaining <= PanicThreshold): # PANIC MODE: Time is low. # Show an urgent prefix so the player knows to hurry. HUDMessage.SetText("!! {ElapsedInt}s !!") else if (TimeRemaining <= CalmThreshold): # WARNING MODE: Time is getting tight. HUDMessage.SetText("> {ElapsedInt}s <") else: # CALM MODE: Plenty of time. Plain display. HUDMessage.SetText(TimeString)