Spawn Objects

In this lesson, we are going to spawn the hat when the player buys it and equip it.

Spawning an equipment

To spawn any objects in your game, you need an asset reference. This asset reference is a template that you have made.

Create a template

For this example, a new template has been made using a CC called “witch hat model” by the creator, mangoboy. This model was dropped in a Client Context of an empty Equipment object and after changing the color, we have a cool hat that looks like our UI.

Hierarchy of our template with the position and scale of the hat
The Wizard Hat

Once you are happy with your new hat, you can create a new “Template From This” and drag that template as a Custom Property of your ShopServer.

The template inside the Project Content (networked as it will be spawned from a server-side script)
The Asset Reference of the Hat as a Custom Property of the ShopServer script

SpawnAsset and Equip

To spawn an object, you can use the function World.SpawnAsset. This can be done on the server if the object is networked, or in the Client Context even if the object is not networked. World.SpawnAsset returns a reference to the spawned object so we can store that in a variable called equipment and use Equip to attach it to the player.

function SpawnAndEquip(player, ref)
    local equipment = World.SpawnAsset(ref)
    equipment:Equip(player)
endCode language: Lua (lua)

This function is going to be called after the Coins are removed from the player. The HAT_REF is the Custom Property that contains the reference to the template we want to spawn. Here is the full script:

local HAT_REF = script:GetCustomProperty("Hat")

function SpawnAndEquip(player, ref)
    local equipment = World.SpawnAsset(ref)
    equipment:Equip(player)
end

function OnBuyHat(player)
    if player:GetResource("Coins") < 3 then
        print("Error, not enough coins")
        return
    end
    player:RemoveResource("Coins", 3)
    SpawnAndEquip(player, HAT_REF)
end

Events.ConnectForPlayer("BuyHat", OnBuyHat)Code language: Lua (lua)
Now the hat is spawned and equipped to the player

Bonus step – Hiding Shop after purchase

As you might have noticed in the previous gif, the UI is hidden when the player buys the hat. To do that, we can use our ToggleShop event that is connected to our UIShop script. This is how you can broadcast an event to a specific player. Here we are sending an event “ToggleShop” to the player with the parameter false to hide the UI.

Events.BroadcastToPlayer(player, "ToggleShop", false)Code language: Lua (lua)

This line can be added at line 15 after calling the SpawnAndEquip function to enhance the experience for the player.

local HAT_REF = script:GetCustomProperty("Hat")

function SpawnAndEquip(player, ref)
    local equipment = World.SpawnAsset(ref)
    equipment:Equip(player)
end

function OnBuyHat(player)
    if player:GetResource("Coins") < 3 then
        print("Error, not enough coins")
        return
    end
    player:RemoveResource("Coins", 3)
    SpawnAndEquip(player, HAT_REF)
    Events.BroadcastToPlayer(player, "ToggleShop", false)
end

Events.ConnectForPlayer("BuyHat", OnBuyHat)
Code language: Lua (lua)

Give a bonus to the player

While making your game, you must give a goal to the player. Why do they want this hat? In this example, we are going to give twice the amount of Coins if the player has the WizardHat.

  1. Open the PickupCoin script in Project Content > My Scripts
  2. Paste the following code

Line 4: this function is returning true if, in all the items in the Equipment of the player, one item is called “WizardHat”.
Line 17: if this condition is true, give 2 coins, else, give 1 coin.

local TRIGGER = script:GetCustomProperty("Trigger"):WaitForObject()
local COIN = script.parent

function PlayerHasHat(player)
    local equipment = player:GetEquipment()
    for _,item in ipairs(equipment) do
        if item.name == "WizardHat" then -- Replace with the name of your template if you changed it
            return true
        end
    end
    return false
end

function OnBeginOverlap(trigger, player)
    if not player:IsA("Player") then return end
	
    if PlayerHasHat(player) then
        player:AddResource("Coins", 2)
    else
        player:AddResource("Coins", 1)
    end
	
    COIN:Destroy()
end

TRIGGER.beginOverlapEvent:Connect(OnBeginOverlap)
Code language: Lua (lua)

You can now add more coins, more items and here are some bonus ideas that you could implement:

New items that could be added to the shop
Lesson Content
2 Comments
Collapse Comments

After about 4 weeks of trying to fix this ourselves it is time for help (if anyone is looking at these comments…)

When running this lesson (Spawn Objects) with the code looking exactly like it shows in the lesson and the script that should be placed at the top of the script to access the custom properties being… local HAT = script:GetCustomProperty(“Hat”) … we are getting the following error instead of equipping and obtaining the hat.

Error running Lua task: [6C2795901343C52B] ShopServer:4: stack index 1, expected string, received nil: (bad argument into ‘CoreObject(string, table)’)

Is there any help available?

Hi, you should post your questions in Discord. You’ll get faster responses over there. 😀 Also, I don’t know how to make code formatted in these comments, so it might look a little messy. Sorry.

I’m going through this certification as well, and I had the same problem. It appears your ShopServer script and custom properties may not be matching. Example, your local variable should be HAT and your Custom Properties for ShopServer should also be Hat.

Check your Custom Properties:
1) Select your ShopServer file in the hierarchy
2) Did you drag and drop the WizardHat into your Custom Properties?
— WizardHat can be found in Project Content (Window > Project Content)
3) Once you drag and drop the WizardHat into your Custom Properties, you’ll need to **change the name** to Hat (or if you want to use WizardHat as the name, fine — but in this example, we will change to Hat)

Check your ShopServer script, and make sure it matches exactly:

— you will need to change your variable to local HAT because that’s the name we entered in Custom Properties
local HAT = script:GetCustomProperty(“Hat”)

function SpawnAndEquip(player, ref)
local equipment = World.SpawnAsset(ref)
equipment:Equip(player)
end

function OnBuyHat(player)
if player:GetResource(“Coins”) < 3 then
print("Error, not enough coins")
return
end
player:RemoveResource("Coins", 3)
— You will need to change the next line to read HAT as well
SpawnAndEquip(player, HAT)
end

Events.ConnectForPlayer("BuyHat", OnBuyHat)

Leave a Comment

Scroll to Top