[Astar]コントラクト備忘録51(Unityからコントラクトアドレスを取得しよう!)
本日は、UnityとAstarのWASMの連結方法について見ていきます。
大まかな構成としては、websocketのサーバーを立て、polkadot.jsを使って、ブロックチェーンに連携します。
その上で、unityとwebsocketを連結しています。
1 WebSocketサーバーについて
では、コードを見てみましょう。
WebSocket.Server()でポート8080でサーバーをリッスンするようにサーバーを構成しています。
そして、server.onでクライアントとの接続が確立された時に実行されるコールバック関数を定義しています。
具体的にはconnectionイベントが発生した場合に、このコールバック関数が実行されます。
若干修正しました。修正後はこの記事の一番下にコードを載せています。
そして、実際の処理として、connect関数が実行されています。
下のように、コントラクトが取得されていますが、ここでは説明を省略いたします。
2 Unity側のコードについて(C#)
では、次にUnityのコードを見てみましょう。
今回、websocketを使うために、「NativeWebSocket」を使っています。
1) NativeWebSocketのインポートについて
こちらのGithubを使っていきます。
こちらの手順に沿ってやっていきます。
「Window」から「Package Manager」を選択します。
こちらの「+」から、「Add Package From Git URL」を選択します。
GithubのURLを貼り付けて、「Add」で完了です。
2) コードの中身について
では、コードの中身を見てみましょう。
下にあるように、WebSocketのインスタンスを作成し、接続時やエラー発生時などの処理を記述しています。
では、こちらのボタンを押してみます。
このボタンを押すと、こちらの「connect」関数を実行するように設定しています。(設定方法などは今回省略します。)
すると、このように、「websocket.OnOpen」の中身が実行されたことがわかりました。
では、websocketのサーバーの処理も見てみます。
このように、今回コントラクトアドレスを返すように設定しています。
こちらがUnity側の処理です。
メッセージを受け取った場合、文字列に変換し、表示させるようにしています。
このように表示することができました。
今回は以上です。
なお、今回使ったコードは下のものになります。
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.");
});
});
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