開発ブログ

株式会社Nextatのスタッフがお送りする技術コラムメインのブログ。

電話でのお問合わせ 075-744-6842 ([月]-[金] 10:00〜17:00)

  1. top >
  2. 開発ブログ >
  3. Rust >
  4. 【Rust】RustでWebAPIを作って、UnityクライアントからAPIコールしてみる【Unity】
【Rust】RustでWebAPIを作って、UnityクライアントからAPIコールしてみる【Unity】

【Rust】RustでWebAPIを作って、UnityクライアントからAPIコールしてみる【Unity】

こんにちは。最近涼しくなってきて嬉しいホンジョウです。
今回はRustでWebAPIを作ってみたくなったので、作っていこうと思います。
Webフレームワークは、Axumを使ってみようと思います。
Axum GitHubリポジトリ

開発環境

  • macOS 13.4 Ventura
  • rustc 1.72.0
  • cargo 1.72.0
  • Unity 2022.2.21
Rustのインストール方法に関しては割愛させていただきます。
インストール方法に関してはこちらをご確認ください。

Cargo.tomlの編集

今回使用していくパッケージをCargo.tomlに記述していきます
​[package]
name = "rust_web_api"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
axum = "0.6.1"
tokio = { version = "1.23.0", features = ["full"] }
serde = { version = "1.0.149", features = ["derive"] }
serde_json = "1.0.89"

Rustプロジェクトのディレクトリ構成


src/
  ├ controller/
  │    ├ mod.rs
  │    └ users.rs
  └ main.rs

mod.rsの記述


pub mod users;

users.rsの記述

users.rsにはレスポンスに含めるUser構造体と、Userを生成してJSONに変換し、IntoResponseにして返す関数を用意します。

use axum::{
    response::Json,
    response::IntoResponse,
    http::StatusCode
};
use serde::Serialize;
use serde_json::json;

#[derive(Serialize)]
struct User {
    name: String,
    hp: u32,
    atk: u32,
    def: u32,
    spd: u32
}

pub async fn get_users() -> impl IntoResponse {
    let user = User {
        name: "test_name".to_string(),
        hp: 100,
        atk: 10,
        def: 20,
        spd: 30,
    };

    (StatusCode::OK, Json(json!(user)))
}

main.rsの記述

今回はGETメソッドのAPIだけを用意します。

use axum::{
    routing::get,
    Router,
    response::Json,
    response::IntoResponse,
    http::StatusCode
};
use serde_json::json;
use std::net::SocketAddr;

mod controller;

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/", get(root))
        .route("/users", get(controller::users::get_users));
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
}

async fn root() -> impl IntoResponse {
    (
        StatusCode::OK,
        Json(json!("OK"))
    )
}
この時点で実行してみて、問題なくJSONが返ってくるようであれば、「RustでWebAPIを作ってみた」はこれにて完成です。 それでは次にUnityクライアント側の処理を書いていきましょう。

Unityプロジェクトのディレクトリ構成


Assets/
  └ Scripts/
        ├ SceneInitializer.cs
        ├ User.cs
        └ UserInfoView.cs

User.csの記述

ここではAPIレスポンスから受け取るUserのデータを格納するUserクラスを書いていきます。

using System;
using UnityEngine;

[Serializable]
public sealed class User
{
    [SerializeField] string name;
    [SerializeField] int hp;
    [SerializeField] int atk;
    [SerializeField] int def;
    [SerializeField] int spd;

    public string Name => name;
    public int Hp => hp;
    public int Atk => atk;
    public int Def => def;
    public int Spd => spd;
}

UserInfoView.cs

こちらはUnityの画面上にUserのデータを表示するUI用のクラスになります。

using UnityEngine;
using UnityEngine.UI;

public sealed class UserInfoView : MonoBehaviour
{
    [SerializeField] Text name;
    [SerializeField] Text hp;
    [SerializeField] Text atk;
    [SerializeField] Text def;
    [SerializeField] Text spd;

    public void UpdateUserInfo(User user)
    {
        name.text = "Name: " + user.Name;
        hp.text = "HP: " + user.Hp.ToString();
        atk.text = "ATK: " + user.Atk.ToString();
        def.text = "DEF: " + user.Def.ToString();
        spd.text = "SPD: " + user.Spd.ToString();
    }
}

SceneInitializer.csの記述

ここでゲームの開始時にAPIからデータを取得して、UIに反映させる処理を書いていきます。
本当はもっと綺麗にクラス分けをして書きたいところですが、一旦動作確認的にMonoBehaviourでベタ書きしてしまいます。

using System;
using System.Net;
using System.Net.Http;
using Cysharp.Threading.Tasks;
using UnityEngine;

public class SceneInitializer : MonoBehaviour
{
    [SerializeField] UserInfoView view;

    readonly HttpClient httpClient = new();

    void Start()
    {
        StartAsync().Forget();
    }

    async UniTaskVoid StartAsync()
    {
        var response = await httpClient.GetAsync("http://127.0.0.1:3000/users");

        var json = await response.Content.ReadAsStringAsync();

        if(response.StatusCode == HttpStatusCode.OK)
        {
            var user = JsonUtility.FromJson(json);
            view.UpdateUserInfo(user);
        }
    }
}

Sceneの作成と実行

スクリーンショット
あとはSceneにUIを作成して、実行できるようにしましょう。APIからUserデータを取得していることを確認できました。
今回はベタ書きのJSONを返すだけのAPIでしたが、DBからデータを取得したりするのも試してみたいと思います。ご覧いただきありがとうございました。

参考資料

TOPに戻る