Create a Coin Collection Mechanic


Now that you have a 3D world, this section of the tutorial teaches you how to add your first script to define a coin collecting mechanic. This mechanic allows players to collect coins, and disables the collection of a coin if it's been recently collected.

Create the Coins

Before you can script anything, you need to have placeholder objects in the world to use as your coins. Like the sea stack platforms you made in the previous section, the coins can be simple Part objects.

To create the coins:

  1. In the Explorer window, add a new folder into the World folder, then rename it Coins.

  2. Insert a cylinder part into the Coins folder, then rename the part to Coin.

    Studio's Explorer window with the Coin part highlighted. The hierarchy of the Workspace to World folder to Coins folder to Coin part is also highlighted.
  3. Select the part, then in the Properties window,

    • Set BrickColor to Gold.
    • Set Material to Metal.
    • Set Size to 0.6, 8, 4.
    • Disable CanCollide. This tells the engine that other parts can pass through the coin, meaning players can walk through the coins in order to collect them.
    • Enable Anchored. This tells the engine to never change the position of the coin due to any physics-related simulation, meaning players can touch the coin without affecting its location.
    A close up view of a gold coin next to two gray cylinder sea stacks on the island.
  4. Duplicate a few more coins and position them around the map for testing purposes.

    Studio's Explorer window with multiple Coin parts highlighted under the Coins folder. A view of multiple coins on the island and two gray cylinder sea stacks.

Your cylinder parts now look like coins and prevent physics simulation, but you need to add logic to the coins so players can collect them.

Create the Script

To have the coins be collectable, you want to react to players touching them. The Roblox engine can notify you when something touches a coin, but you need to declare that in a script. To create a script:

  1. In the Explorer window, hover over ServerScriptService and click the button. A contextual menu displays.

  2. From the contextual menu, select Script. A new script displays under ServerScriptService, which tells the engine to run the script on the server, and prevents clients from accessing the code.

    Studio's Explorer window with both ServerScriptService's plus icon and Script object highlighted.
  3. Rename the script to CoinService.

    Studio's Explorer window with the CoinService script highlighted under ServerScriptService.
  4. Replace the default code with the following code:


    -- Initializing services and variables
    local Workspace = game:GetService("Workspace")
    local Players = game:GetService("Players")
    local coinsFolder = Workspace.World.Coins
    local coins = coinsFolder:GetChildren()
    local COOLDOWN = 10
    -- Defining the event handler
    local function onCoinTouched(otherPart, coin)
    if coin:GetAttribute("Enabled") then
    local character = otherPart.Parent
    local player = Players:GetPlayerFromCharacter(character)
    if player then
    -- Player touched a coin
    coin.Transparency = 1
    coin:SetAttribute("Enabled", false)
    print("Player collected coin")
    task.wait(COOLDOWN)
    coin.Transparency = 0
    coin:SetAttribute("Enabled", true)
    end
    end
    end
    -- Setting up event listeners
    for _, coin in coins do
    coin:SetAttribute("Enabled", true)
    coin.Touched:Connect(function(otherPart)
    onCoinTouched(otherPart, coin)
    end)
    end

    Now, whenever a player touches a coin, the coin disappears for 10 seconds, and the output log prints Player collected coin.

    The following sections describe how the script works in more detail.

    Initializing Services and Variables

    Like with a lot of the code you've probably written in other languages, you define variables that you need later at the top of the script. Our code does the following:

    • Obtain service instances - Roblox services provide built-in functionality for common features. The script first obtains instances of the Workspace service, which contains every object in the 3D world, and the Player service, which manages and contains all players connected to your experience.

    • Obtain references to all coins - The script then queries the 3D workspace for all references to coin objects with the GetChildren() method. This method returns an array containing everything parented to the object it's associated with, which in this case is the Workspace.World.Coins folder you created previously.

    • Defines a global variable - The COOLDOWN variable is used later to define how long to disable a coin after it's collected.

      Initializing Services and Variables

      local Workspace = game:GetService("Workspace")
      local Players = game:GetService("Players")
      local coinsFolder = Workspace.World.Coins
      local coins = coinsFolder:GetChildren()
      local COOLDOWN = 10
      ...

    Defining the Event Handler

    The Roblox engine physically simulates the 3D world and handles a lot of the logic to handle events related to rendering, physics, and networking. When you're interested in scripting your own logic during some of these events, you can listen for and handle them, while letting the engine do the rest. In this case, you listen for and handle events related to coins being touched. The script defines the logic for handling this event in the onCoinTouched() method, which does the following:

    • Detects whether the coin is enabled - Every Instance has an Enabled boolean attribute that defines whether or not the object exists in the 3D world. You can get instance attributes with the GetAttribute() method.

    • Detects whether a player touched the coin - If a coin is enabled, the method uses the player service to check if the object that touched the coin was indeed a player. When a touch event occurs, the Roblox engine passes the object that touched the coin as an otherPart parameter. The script checks to see if the parent of otherPart belongs to a player.

    • Disables the coin if a player touched it, and re-enables it after 10 seconds - Finally, if a player touched the coin, the method disables the coin, waits for 10 seconds, and then re-enables the coin for collection. task.wait() is used instead of wait() because it provides better performance by not pausing code execution entirely, allowing tasks in other threads to run concurrently.

      Defining the Event Handler

      local function onCoinTouched(otherPart, coin)
      if coin:GetAttribute("Enabled") then
      local character = otherPart.Parent
      local player = Players:GetPlayerFromCharacter(character)
      if player then
      -- Player touched a coin
      coin.Transparency = 1
      coin:SetAttribute("Enabled", false)
      print("Player collected coin")
      task.wait(COOLDOWN)
      coin.Transparency = 0
      coin:SetAttribute("Enabled", true)
      end
      end
      end

    Connecting the Event Handler

    All simulated 3D objects inherit from BasePart and therefore have a Touched() event. The following loop connects the onTouchedEvent() handler to every coin's touch event by doing the following:

    • Loop through all the coins - Loop through each of the coins using general iteration.

    • Connect the handler to the event - In each iteration of the loop, the coin is enabled by default, so it's visible in the 3D world during the initial start of the experience. The onCoinTouched() handler method is also connected to the Touched event of the coin so that it runs every time the event occurs. When the engine detects a touch, it also passes in the object that touched the object, otherPart.

      Connecting the Event Handler

      for _, coin in coins do
      coin:SetAttribute("Enabled", true)
      coin.Touched:Connect(function(otherPart)
      onCoinTouched(otherPart, coin)
      end)
      end

Playtest the Mechanic

It's time to see if the coin collection mechanic works as intended. To playtest your experience:

  1. In the menu bar, click the Play button. Studio enters playtest mode.

    Studio's Home tab with the Play button highlighted in the menu bar.
  2. Move your character to touch a coin. If your scripts are working correctly, the Output window displays Player collected coin, and the coin disappears for 10 seconds before re-appearing.

    Studio's Output window that displays confirmation that the player collected a coin.