📑

[Astar] Get the contract address from Unity!

2023/03/31に公開

Today I'll look at how to link Unity and Astar's WASM.

The general structure is to set up a websocket server and link it to the blockchain using polkadot.js.

On top of that, we link unity and websocket.

1 About the WebSocket server

Let's take a look at the code.

We configure the server to listen on port 8080 in WebSocket.Server().

Then, in server.on, we define a callback function that is executed when a connection is established with a client.

Specifically, this callback function is executed when the connection event occurs.


Slightly modified. The revised code is at the bottom of this article.

Then, the connect function is executed as the actual process.

As shown below, the contract has been obtained.
I omit the explanation here.

2 Unity side code (C#)

Now let's look at the Unity code.

This time, to use websocket, we use "NativeWebSocket".

1) Importing NativeWebSockets

We will use this Github.
https://github.com/endel/NativeWebSocket

We will follow the procedure here.

Select "Package Manager" from the "Window" menu.

From "+" here, select "Add Package From Git URL".

Paste the Github URL and "Add" to complete.

2) Let's look at what's in the code

Now let's look at what's in the code.

An instance of WebSocket is created, and processing is described when a connection is made or an error occurs.

Now, let's press this button.

When this button is pressed, the "connect" function here is set to execute. (We omit the configuration method and other details this time.)

Then, as you can see, the contents of "websocket.OnOpen" were executed.

Now, let's also look at the websocket server process.

As you can see, it is set to return the contract address this time.

This is the Unity side processing.

When a message is received, it is converted to a string and displayed.

It could be displayed like this.

That's all for this time.

The code used this time is shown below.

server.js
const WebSocket = require("ws");

const { ApiPromise, WsProvider } = require("@polkadot/api");
const { ContractPromise } = require("@polkadot/api-contract");

const metadata = require("./metadata.json");

async function connect() {
  // Connect to the local development network
  const provider = new WsProvider("wss://rpc.shibuya.astar.network");
  const api = await ApiPromise.create({ provider });

  const contract = new ContractPromise(
    api,
    metadata,
    "a1MvMiL1VPNKHc6pb8XNAw6fcwh85fc8V3wgocpmJjYK1Tm"
  );

  console.log(contract.address.toHuman());

  return contract.address.toHuman();
}

const server = new WebSocket.Server({ port: 8080 });

server.on("connection", async (socket) => {
  console.log("Connect");
  const contract = await connect();

  console.log("Client connected.");

  socket.send(`Contract Address: ${contract}`);

  socket.on("message", (message) => {
    console.log(`Received message: ${message}`);
    socket.send(`Server received: ${message}`);
  });

  socket.on("close", () => {
    console.log("Client disconnected.");
  });
});

(unityのコード)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using NativeWebSocket;

public class StartMenuManager : MonoBehaviour
{

    WebSocket websocket;
    // Start is called before the first frame update
    void Start()
    {
        // WebSocketクライアントのインスタンスを生成
        websocket = new WebSocket("ws://localhost:8080");

        websocket.OnOpen += () =>
        {
        Debug.Log("Connection open!");
        };

        websocket.OnError += (e) =>
        {
        Debug.Log("Error! " + e);
        };

        websocket.OnClose += (e) =>
        {
        Debug.Log("Connection closed!");
        };

        websocket.OnMessage += (bytes) =>
        {
            Debug.Log("OnMessage!");
            Debug.Log(bytes);

            // getting the message as a string
            var message = System.Text.Encoding.UTF8.GetString(bytes);
            Debug.Log("OnMessage! " + message);
        };

        // Keep sending messages at every 0.3s
        // InvokeRepeating("SendWebSocketMessage", 0.0f, 0.3f);

    }

    // Update is called once per frame
    void Update()
    {
        #if !UNITY_WEBGL || UNITY_EDITOR
        websocket.DispatchMessageQueue();
        #endif
    }

    async void SendWebSocketMessage()
    {
        if (websocket.State == WebSocketState.Open)
        {
        // Sending bytes
        await websocket.Send(new byte[] { 10, 20, 30 });

        // Sending plain text
        await websocket.SendText("plain text message");
        }
    }
    public async void connect(){
        
        // waiting for messages
        await websocket.Connect();
  
    }
}

Discussion