Ethereum Unity3D Boilerplate Questions

@SamR, @vivraan, @YosephKS, @enoonmai, @K00N, @IndeepParth, @Epica, @Hero909, @0xprof

The WebGL / Metamask Integration Pre-Release Package has been published.


This has been tested as desktop and WebGL using Unity 2020.3.26 & 2020.3.29.
NOTE: A new step upon import - in Player Setting when build is set to WebGL, under Resolution and Presentation select the Moralis WebGL template (see the Readme in the features/webgl-metamask branch (https://github.com/ethereum-boilerplate/ethereum-unity-boilerplate/tree/features/webgl-metamask)

The WebGL/Metamask integration is done. Still need to synchronize the interface to Wallet Connect / Nethereum function calls to match the new interface.

Please use the following thread for issues and questions about the community: Unity WebGL / Browser Wallet Interface Questions

5 Likes

I was waiting for this, thank you so much!

1 Like

Hi. Is there a way to update an existing data row for a custom object? For example, Iā€™d like to find the row associated with a matching wallet address in a custom PlayerData object and then save data to that row (e.g., TokensCollected). Thanks!

var user = await MoralisInterface.GetUserAsync();
var walletAddress = user.authData[ā€œmoralisEthā€][ā€œidā€].ToString();

MoralisQuery player = await MoralisInterface.GetClient().Query();

var dataRow = player.WhereEqualTo(ā€œWalletAddressā€, walletAddress);

//Update TokenBalance for this specific rowā€¦

1 Like

Yes, this is possible.

You want to query a custom table, not the user table correct?

Say you have this object:

class PlayerStats : MoralisObject
{
    public PlayerStats() : base("PlayerStats") {}

    public string Name {get; set; }
    public string WalletAddress {get; set; }
}

To query an existing player by WalletAddres:

        user = await MoralisInterface.GetUserAsync();
        var walletAddress = user.authData["moralisEth"]["id"].ToString();

        // Create query
#if UNITY_WEBGL
        MoralisQuery<PlayerStats> playerStatsQuery = await MoralisInterface.GetClient().Query<PlayerStats>();
        playerStatsQuery = playerStatsQuery.WhereEqualTo("WalletAddress", walletAddress);
#else
        MoralisQuery<PlayerStats> playerStatsQuery = MoralisInterface.GetClient().Query<PlayerStats>().WhereEqualTo("WalletAddress", walletAddress);
#endif
        // Run query
        IEnumerable<PlayerStats> result = await playerStatsQuery.FindAsync();

        // Assunig there shou8ld only be a single row returned.
        PlayerStats ps = result.FirstOrDefault();

        // Change row data
        ps.Name = "Clem the bold";

        // Save changes
        await ps.SaveAsync();

Happy coding,
David

2 Likes

Worked perfectly. Thanks so much!

1 Like

Hi @dgoodrich

I have tested the pre-release with Unity v2020.3.27 and it is working fine. But with Unity v2021.2.5 iā€™m getting this error on Metamask wallet connect:

MRLW.framework.js.gz:3 NotSupportedException: /Applications/Unity/Hub/Editor/2021.2.5f1/Unity.app/Contents/il2cpp/libil2cpp/icalls/mscorlib/System.Runtime.InteropServices/RuntimeInformation.cpp(34) : Unsupported internal call for IL2CPP:RuntimeInformation::GetRuntimeArchitecture - "This icall is not supported by il2cpp on this architecture."
Rethrow as TypeInitializationException: The type initializer for 'System.Runtime.InteropServices.RuntimeInformation' threw an exception.

Here the screenshot:

1 Like

Thanks for posting. We have some up coming changes for all the jslib packages for Unity version > 2021.

I will add the ā€œSystem.Runtime.InteropServices.RuntimeInformationā€ as well.

@IndeepParth copied to the WebGL / Wallet Browser pre-release thread for proper tracking.

Hi there,

I am sorry i donā€™t understand, even with the readme :slight_smile:
I donā€™t want to set custom gas fees and I canā€™t find which one of your scripts is responsible for that.

Maybe something I am missing in the whole logic of it but its the network that sets the gas fee no ?

Thanks again for your time.

Hi @dgoodrich,

I canā€™t seem to make the AwardableController.cs works.
I am simply trying to send a NFT minted with an ERC1155 between two players.
I try to use the SafeTransferFrom function like this:

public string ABINft;

    public async void NftTransfer()
    {
        MoralisInterface.InsertContractInstance("NFT", ABINft, "mumbai", nftAddress);
        Function f = MoralisInterface.EvmContractFunctionInstance("NFT", "mumbai", "safeTransferFrom");
        Debug.Log(f);

        string jsonresult = await f.SendTransactionAsync(senderAccount, receiverAccount, 2, 1, 0);
        print(jsonresult);

    }

Where the ā€œsenderAccountā€ owns the ID number 2 from the nftAddress (ERC1155 contract address).

The transfer fails like shown here:

What am I missing ?
Thanks a lot for your time and support!

you dont want to set custom gas ? then what are you looking for ?
i didnt set custom gas in any of my script, but i am still updating it,
and send the contract code for the erc 1155

Hello ! thanks for the reply !

since it was a demo, i have to manually place the gas

sorry maybe I misunderstood, I donā€™t want the players to have to change the gas limit on metamask everytime they want to transact. If I donā€™t significantly increase this value the transaction fails

And this is the contract code for the erc1155:

// SPDX-License-Identifier: MIT
// contracts/NftTrader.sol

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol";

contract YTTokens is ERC1155PresetMinterPauser {
    
    uint256 public gameIDCounter;
    
    mapping(string => uint256) public idmap;
    mapping(uint256 => string) public lookupmap;


    constructor() ERC1155PresetMinterPauser("") { //base URI
        
    }
    
    function addGameID( string memory gameID, uint256 initialSupply ) external {
        require(hasRole(MINTER_ROLE, _msgSender()), "YTTokens: must have minter role to mint");
        
        require(idmap[gameID] == 0, "YTTokens: This gameID already exists");
        
        gameIDCounter = gameIDCounter + 1;
        idmap[gameID] = gameIDCounter;
        lookupmap[gameIDCounter] = gameID;

        _mint(msg.sender, gameIDCounter, initialSupply, "");        
    }
    
    function uri(uint256 id) public view virtual override returns (string memory) {
        return string( abi.encodePacked( super.uri(id), lookupmap[id]));
    }
    
    function getAllTokens(address account) public view returns (uint256[] memory){
        uint256 numTokens = 0;
        for (uint i = 0; i <= gameIDCounter; i++) {
            if ( balanceOf(account, i) > 0) {
                numTokens++;
            }
        }
        
        uint256[] memory ret = new uint256[](numTokens);
        uint256 counter = 0;
        for (uint i = 0; i <= gameIDCounter; i++) {
            if ( balanceOf(account, i) > 0) {
                ret[counter] = i;
                counter++;
            }
        }
        
        return ret;
    }
}

yes, you can set custom gas in code and add them to the parameters, so the user dont have to touch the gass and go straight to accepting the transaction.
you can look at this from the readme

Nethereum.Hex.HexTypes.HexBigInteger g = new Nethereum.Hex.HexTypes.HexBigInteger(80);
Nethereum.Hex.HexTypes.HexBigInteger wei = new Nethereum.Hex.HexTypes.HexBigInteger(1000);
string jsonResult = await func.CallAsync(playerAddress, new Nethereum.Hex.HexTypes.HexBigInteger(80), new Nethereum.Hex.HexTypes.HexBigInteger(1000), pars);

you can also take a look at the nethereum docs
(http://docs.nethereum.com/en/latest/)

can you show me what the SafeTransferFrom function look like ?
you may need to use this method

string playerAddress = "0x37bd48252f4dcE15C7147eA82b31978a00750f81";
object[] pars = {2, 1,0};
Nethereum.Hex.HexTypes.HexBigInteger g = new Nethereum.Hex.HexTypes.HexBigInteger(80);
Nethereum.Hex.HexTypes.HexBigInteger wei = new Nethereum.Hex.HexTypes.HexBigInteger(1000);
string jsonResult = await func.CallAsync(senderAccount, new Nethereum.Hex.HexTypes.HexBigInteger(80), new Nethereum.Hex.HexTypes.HexBigInteger(1000), pars);

or try

string jsonresult = await f.SendTransactionAsync(senderAccount, new Nethereum.Hex.HexTypes.HexBigInteger(80), new Nethereum.Hex.HexTypes.HexBigInteger(1000), pars);
        print(jsonresult);

if this doesnā€™t work, no worries, i am writing a demo right now and will update you when i am done :slightly_smiling_face:

3 Likes

Hello everyone,

I am using Moralis SDK for Unity. I am trying to fetch my NFTs using :

async void Fun()
{
NftOwnerCollection balance = await MoralisInterface.GetClient().Web3Api.Account.GetNFTsForContract(address.ToLower(), tokenAddress, ChainList.eth);
}

Ref : https://github.com/ethereum-boilerplate/ethereum-unity-boilerplate#getnftsforcontract

The above code is working fine on PC, but returning null on Android. Please help.

@Hero909


i made some updates, take a look at this
you can then be able to send custom erc20 and call smart contract functions and specify the gas
i am still working on the nft snippets and will update it later on.
2 Likes

@Hero909 you should be able to call any smart contract function with gas from the code i sent above, i will try to check how this can be sent from ones balance

1 Like

hey, it is difficult for any one to help if there is no errors or anything ?
have you tried using unity remote ?
This function is supposed to work on all devices, it has been tested on android, ios and on pc ?
@dgoodrich maybe you have seen this before ?

1 Like

Wow thanks a lot !! thats amazing
Testing this now ! :slight_smile:
:raised_hands:t3:

OMG this works perfectly !!!
Canā€™t wait for the nft snippets