SkillAgentSearch skills...

Unity3dSampleTemplate

Unity3d sample template to work with Nethereum

Install / Use

/learn @Nethereum/Unity3dSampleTemplate
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Unity3d Sample Template Net472 / Netstandard

Sample template to get started working with Unity3d development using Nethereum, from smart contracts, code generation to Unity integration. Unity Version used is 2022.3.21

Template structure and projects

Sample.Unity

The main unity example project including the following code examples:

  • Output to the log the current BlockNumber using Unity.UI both in Async and coroutines
  • Ether transfer using Unity.UI and coroutines
  • Using 1559 Suggestion strategies or Legacy mode when tranfering Ether
  • Smart contract deployment (ERC20), Transactions (Transfer) and Querying (Balance)
  • Cross Platform architecture for both Coroutines and Task to enable the reuse of your code using different deployments Native /Desktop or Browser using Metamask)
  • Using a Nethereum contract integration project (Sample.DotNet)
  • Metamask connectivity in browser

The example includes the reference to the openupm com.nethereum.unity package which includes the Nethereum main dlls for .net472 and netstandard https://github.com/Nethereum/Nethereum.Unity. Check the package for installation information, or the Package configuration (Manifest.json) section in this document.

Sample.DotNet This folder is the "generic" standalone .net integration project and tests.

Sample.DotNet.Contracts

This is the standard Nethereum integration project, but adapted to work with Unity, including both an .asmdef and package.json files.

The csproj has been modified to output the bin and obj files to a build folder so it can be referenced by the Sample.Unity project.

 	<BaseOutputPath>..\Build\$(MSBuildProjectName)\bin</BaseOutputPath>
        <BaseIntermediateOutputPath>..\Build\$(MSBuildProjectName)\obj</BaseIntermediateOutputPath>

Sample.DotNet.Tests

This the standard test project supported by Nethereum.XUnitEthereumClients and a testchain included in the testchain folder (using geth by default and included)

Sample.Solidity.Contracts

This includes the ERC2O smart contract that is used in the examples.

Important Notes:

  • All the examples are self contained, to simplify them, so when working with the browser you will need "Connect" per example.
  • WebGL: When using Web3 with Tasks this requires something like the WebGLThreadingPatcher https://github.com/VolodymyrBS/WebGLThreadingPatcher, or any other way to enable wasm with Task threading support. Note if you are using Unity V6 you will require to use https://github.com/Nethereum/WebGLThreadingPatcher that includes a fix, not yet available on the main repository.
  • To support AOT and WebGL this sample uses the Nethereum dlls packaged for Net472AOT or NetstandardAOT with the custom Newtonsoft Json.Net by Unity (already added as a package reference)
  • Please remember to remove System.HttpClient and UnityEngine of the Nethereum release package if using the nethereum dlls directly
  • Nethereum.Unity.Metamask is only supported in WebGL at the moment, the Metamask SDK will be supported shortly, currently work in progresss (if you require access to small PoC let me know) image
  • If creating a custom index.html file, or rebuilding webgl in a new folder, the script needs to instantiate nethereumUnityInstance as per the example here: https://github.com/Nethereum/Unity3dSampleTemplate/Sample.Unity/blob/master/webgl/index.html#L107
  • When building to Desktop and other platforms (not web), you will requited to use "https" instead of "http" as the newer versions of Unity validate this.

Desktop demo

Desktop

Browser demo

Webgl WebglEIP

Test Chain

To run a local blockchain you can just use the preconfigured chain includes in Sample.DotNet/testchain. All the examples use the chainId "31337" as default.

Package configuration (Manifest.json)

Here is the example of the packages in manifest.json included in the Sample.Unity/packages folder

{
  "scopedRegistries": [
        {
            "name": "package.openupm.com",
            "url": "https://package.openupm.com",
            "scopes": [
                "com.nethereum.unity"
            ]
        }
  ],
  "dependencies": {
	"com.nethereum.unity": "4.19.2",
    	"com.tools.webglthreadingpatcher": "file:../../WebGLThreadingPatcher",
	"com.contracts.dotnet.sample": "file:../../Sample.DotNet/Sample.DotNet.Contracts",
	"com.unity.nuget.newtonsoft-json": "3.2.1",
      ...

  • Scoped registries that uses openupm to include "com.nethereum.unity".
  • Webglthreadingpatcher has been downloaded from its github repository and added as folder dependency.
  • Sample dotnet integration project: "com.contracts.dotnet.sample": "file:../../Sample.DotNet/Sample.DotNet.Contracts"
  • Newtonsoft json: "com.unity.nuget.newtonsoft-json": "3.2.1"

Code examples

BlockNumber query Async (vanilla Nethereum)

using System;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using UnityEngine;
using UnityEngine.UI;
using Nethereum.Web3;
using System.Threading.Tasks;
using Nethereum.Unity.Rpc;

public class GetLatestBlockVanillaNethereum : MonoBehaviour {

    private static bool TrustCertificate(object sender, X509Certificate x509Certificate, X509Chain x509Chain, SslPolicyErrors sslPolicyErrors)
    {
        // all certificates are accepted
        return true;
    }

    public string Url = "http://localhost:8545";
    public InputField ResultBlockNumber;
    public InputField ResultBlockNumberConstant;
    
    public InputField InputUrl;

    // Use this for initialization
    async void Start()
    {
        InputUrl.text = Url;
        await CheckBlockNumberPeriodically();
    }
    public async Task CheckBlockNumberPeriodically()
    {
        var wait = 1000;
        while (true)
        {
           await Task.Delay(wait);
           wait = 1000;
           var web3 = new Web3(new UnityWebRequestRpcTaskClient(new Uri(InputUrl.text)));
            
           var blockNumber = await web3.Eth.Blocks.GetBlockNumber.SendRequestAsync();
           ResultBlockNumberConstant.text = blockNumber.Value.ToString();
        }
    }

    public async void GetBlockNumber()
	{
        Url = InputUrl.text;
        //This is to workaround issue with certificates https://forum.unity.com/threads/how-to-allow-self-signed-certificate.522183/
        //Uncomment if needed
        //ServicePointManager.ServerCertificateValidationCallback = TrustCertificate;
        var web3 = new Web3(new UnityWebRequestRpcTaskClient(new Uri(InputUrl.text)));
        var blockNumber = await web3.Eth.Blocks.GetBlockNumber.SendRequestAsync();
        ResultBlockNumber.text = blockNumber.Value.ToString();
    }
}

BlockNumber query Coroutines

using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using Nethereum.Unity.Rpc;

public class GetLatestBlockCoroutine : MonoBehaviour
{
    public string Url = "http://localhost:8545";

    public InputField ResultBlockNumber;
    public InputField InputUrl;

    // Use this for initialization
    void Start()
    {
        InputUrl.text = Url;
    }

    public void GetBlockNumberRequest()
    {
        Url = InputUrl.text;
        StartCoroutine(GetBlockNumber());
    }

    public IEnumerator GetBlockNumber()
    {

       var blockNumberRequest = new EthBlockNumberUnityRequest(InputUrl.text);
 
       yield return blockNumberRequest.SendRequest();

        if (blockNumberRequest.Exception != null)
        {
            UnityEngine.Debug.Log(blockNumberRequest.Exception.Message);
        }
        else
        {
            ResultBlockNumber.text = blockNumberRequest.Result.Value.ToString();
        }
        
    }
 }

Simple Ether transfer using Coroutines

To transfer Ether Nethereum provides a specific Unity Request, the EthTransferUnityRequest.

The EthTransferUnityRequest it is instantiated with the "url" of our Ethereum client, the private key to be able to sign transactions and our account address (the same of the private key).

var url = "http://localhost:8545";
var privateKey = "0xb5b1870957d373ef0eeffecc6e4812c0fd08f554b37b233526acc331bf1544f7"; 
var ethTransfer = new EthTransferUnityRequest(url, privateKey, "YOURCHAINID");

Once our unity request is instantiated it we can initiate the transfer as follows using Legacy Mode providing 2 Gwei as the gas price

var receivingAddress = "0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe";
yield return ethTransfer.TransferEther(receivingAddress, 1.1m, 2);

Here we have specified the receivingAddress, the amount to send and the optional gas price in Gwei. The request will automatically convert the gas price to Wei.

We can validate afterwards if we have had any exception as following:

if (ethTransfer.Exception != null)
{
    Debug.Log(ethTransfer.Exception.Message);
    yield break;
}

If no errors have occurred we can retrieve the transaction hash from the Request and Poll every 2 seconds to wait for the transaction to be mined.

 var transactionHash = ethTransfer.Result;
//create a poll to get the receipt when mined
var transactionReceiptPolling = new TransactionReceiptPollingRequest(url);
//checking every 2 seconds for the receipt
yield return transactionReceiptPolling.PollForReceipt(transactionHash, 2);

Finally we can check the balance of our recieving account, using EthGetBalanceUnityRequest. Note that we specify we want the balance for the latest Block when doing the request.

var balanceRequest = new EthGetBalanceUnityRequest(url);
yield return balanceRequest.SendRequest(receivingAddress, BlockParameter.CreateLatest());

We can convert the result in Wei to Eth using the default Wei

Related Skills

View on GitHub
GitHub Stars87
CategoryDevelopment
Updated4mo ago
Forks41

Languages

C#

Security Score

92/100

Audited on Nov 16, 2025

No findings