Purchase NFT loot box Pack NFTs from a Marketplace and open them to reveal and receive a randomly selected NFT; either a common red gem, or a rare purple gem!
Assets in this repository are created by Gabriel Aguiar.
Gabriel's YouTube • Gabriel's Twitter • Purchase these assets ($10 USD)
See the live demo or view the preview below:
Install Blender and follow our guide to Setting Up Unity
View the full guide on our blog!
Below, we'll explore key areas of the codebase that enable the web3 functionality of this project using our GamingKit.
For information on the visual effects and animations, please see Gabriel's video: How To Create A Loot Box.
The logic for all of the web3 functionality is contained in the Lootbox.cs
script.
Three smart contracts make up this project:
Contract | URL |
---|---|
Edition (NFT Items) | View Smart Contract |
Pack (Loot boxes) | View Smart Contract |
Marketplace | View Smart Contract |
The NFTs are bundled into the Pack
NFTs, which are then sold on the Marketplace
.
To begin, we need to instantiate the SDK.
using Thirdweb; // 1. Import the ThirdwebSDK
public class LootBox : MonoBehaviour
{
// 2. Create a ThirdwebSDK instance for us to use throughout the class
private ThirdwebSDK sdk;
void Start()
{
// 3. When the game starts, set up the ThirdwebSDK
sdk = new ThirdwebSDK("optimism-goerli");
}
}
Now we can use the sdk
instance throughout this class; allowing us to connect to user wallets, and interact with smart contracts.
We need users to connect their wallets to our game.
We achieve this by:
- Requesting the user to connect their wallet
- Requesting the user to switch to the correct network (
Optimism Goerli
):
async Task<string> EnsureCorrectWalletState()
{
string address = await sdk.wallet.Connect();
await sdk.wallet.SwitchNetwork(420);
return address;
}
We use the Marketplace contract to purchase loot boxes from the connected wallet.
We achieve this by:
- Connecting to the marketplace contract
- Calling the
BuyListing
function.
async Task<TransactionResult> BuyPackFromMarketplace()
{
await EnsureCorrectWalletState();
Marketplace marketplace =
sdk
.GetContract("0x8ecE57a92ea312D5f31E39E5F6f3E6fC02507D7B")
.marketplace;
var result = await marketplace.BuyListing("0", 1);
return result;
}
The Pack contract is used to open loot boxes with the Open
function. First, the user buys the pack, and then they can open it:
async Task<ERC1155Reward> OpenPack()
{
await EnsureCorrectWalletState();
await BuyPackFromMarketplace();
Pack packContract = await GetPackContract();
// Here, 0 is the pack ID, and 1 is the amount of packs to open
var result = await packContract.Open("0", "1");
openedLootItem = result.erc1155Rewards[0];
return result.erc1155Rewards[0];
}
The Update
function listens for Input.GetMouseButtonDown(0)
and calls the OpenPack
function when the user clicks the mouse.
if (Input.GetMouseButtonDown(0))
{
var openedPack = await OpenPack();
if (openedLootItem != null)
{
animator.SetBool("Open", true);
cameraAnimator.SetBool("Open", true);
}
}
Based on the token ID opened, we Instantiate
the correct item (from red or purple):
if (openedLootItem.tokenId == "0")
{
loot = Instantiate(redGem);
}
if (openedLootItem.tokenId == "1")
{
loot = Instantiate(purpleGem);
}
Jump into our Discord to speak with the team directly!