Keeping Time
Keeping Time
Almost all games will need to keep track of time in some way. On Roblox, there’s a variety of methods that scripts can measure time and wait, also known as yielding.
Simple Yielding
The simplest form of yielding can be done using the wait
function, which pauses for a given number of seconds. Its usage is straightforward:
When wait
is called, Roblox’s internal scheduler yields the thread for an amount of time that is close as possible to the given time, then signals for the thread to resume again.
Comparison to Unity’s StartCoroutine/IEnumerator
The sample below is taken from Unity Scripting API: WaitForSeconds.
using UnityEngine;
using System.Collections;
public class WaitForSecondsExample : MonoBehaviour
{
void Start()
{
StartCoroutine(Example());
}
IEnumerator Example()
{
print(Time.time);
yield return new WaitForSeconds(5);
print(Time.time);
}
}
In Roblox, a similar piece of code would look like this:
Yielding Using A Function
Sometimes it is easier to define a function and run it after a given number of seconds. For this, the delay
function works perfectly: provide it an amount of time in seconds to wait, and a function to run after that time elapses:
Comparison to MonoBehavior’s Invoke in Unity
Below is an example of a Unity C# script which runs a method, Explode
, after two seconds. It is provided to showcase the similarity between MonoBehavior’s Invoke in Unity to the delay
function in Roblox.
using UnityEngine;
public class ExampleScript : MonoBehaviour
{
void Start()
{
Invoke("Explode", 2);
}
void Explode()
{
print("Kaboom!");
}
}
The example above is similar to the following code in Roblox:
Neither Invoke
nor delay
will pause the current thread. In other words, the script will immediately continue after the provided function call was scheduled.
Frame-by-Frame Time
More commonly, scripts will have logic that must be run as often as possible. The RunService/Stepped
event will fire each frame that the game is running, around 60 frames per second. In Studio, this is after “Run” or “Play Solo” is clicked. This event fires with the current game time followed by the time since the last frame (delta time).
Sometimes it is no longer useful to run such a function every frame. For this, save a reference to the Connection object returned by Connect
, then call Disconnect
on it later. The example below is an event-based implementation of the example from “Simple Yielding”.
Event-based approaches are generally good for keeping code clean. For more information on Events, see the article on Events.
Comparison to MonoBehavior’s Update in Unity C#
Connecting to RunService/Stepped
in Roblox is very similar to defining an Update
function within a MonoBehaviour in Unity.
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
void Update()
{
print(Time.time);
}
}
The above example is similar to the following code in Roblox:
local RunService = game:GetService("RunService")
local function Update(t, dt)
print(time())
end
RunService.Stepped:Connect(Update)
Render Step
Sometimes a LocalScript
is responsible for visual effects. For example, pointing an arrow towards some object. Such visual effects ought to be updated right before the screen is rendered. In Roblox, you can use the RunService/BindToRenderStep
function to accomplish this: