25
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【VRChat】ワールドでChatGPTを使う方法

Last updated at Posted at 2023-06-07

2024/3/20追記
Replitのサービス変更によりサーバーを無料で立てることができなくなりました。

何をするか

VRChatのワールドからChatGPTを呼び出せるUdonギミックを作ります。
対象レベルは簡単なギミックが作れる人を想定しています。
U#のコードはコピペでいいので書けなくても大丈夫です。

仕組み

利用するもの

  • U#
  • Node.js
  • Replit
  • ChatGPT API

構成

image.png

Node.jsを使ってAPIサーバーを構築し、UdonのVRCStringDownloaderでサーバーにアクセス
サーバーからChatGPT APIを呼んで結果をVRChatに返しています。
今回はReplitというサービスを使ってサーバーを立てます。

気をつけること

利用料金

ChatGPT APIは従量課金制です。ワールドをpublic化する時は使いすぎに気をつけてください。Usageからリミットをかけておくことをおすすめします。
ちなみに初回登録時に$5程度のお試し枠が配られ、その後は支払い情報登録が必要です。

API Keyの取扱い

Replitは無課金だとソースコードが自動で全て公開されます。
API Keyなどの秘匿情報はソースコード内に絶対に書かずSecretから呼び出すようにしましょう。

Allow Untrusted URL設定

VRChatの外部通信はデフォルトではホワイトリストにある特定のサービスに限られるため、今回のギミックを動かすには設定のAllowUntrustedURLにチェックを入れる必要があります。

手順

実装していきます。

  1. Replitでサーバーを立てる
  2. Udonでサーバーにアクセスする
  3. ChatGPT APIを使えるようにする

Replitでサーバーを立てる

Replit でアカウントを作成し、Create a ReplボタンからNode.jsの環境を作成してください。
image.png

examplesをクリックしServer(Express)を選択すると、サンプルのサーバー用コードが自動で設定されます。
image.png

画面上部の緑色の「Run」ボタンを押すとサーバーが起動します。
(初回は必要なインストールがあるため少し時間がかかります。)

右上にWebViewが追加され、「Hello Express app!」と表示されれば起動済みです。
上部の窓に表示されているのがサーバーのURLになり、これでサーバーへアクセスができます。
image.png

Udonでサーバーにアクセスする

VRCStringDownloaderを使ってサーバーから文字列を読み込みます。
以下のサンプルコードをつかってU#を作成してください。

StringLoader.cs
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
using UnityEngine.UI;
using VRC.SDK3.StringLoading;
using VRC.Udon.Common.Interfaces;

public class StringLoader : UdonSharpBehaviour
{
    [SerializeField] private VRCUrl _url;
    [SerializeField] private Text _text;

    public override void Interact()
    {
        VRCStringDownloader.LoadUrl(_url, (IUdonEventReceiver)this);
        _text.text = "Loading...";
    }
    public override void OnStringLoadSuccess(IVRCStringDownload result)
    {
        _text.text = result.Result;
    }
    public override void OnStringLoadError(IVRCStringDownload result)
    {
        _text.text = "Error.";
        Debug.Log(result.Error);
    }
}

キューブにセットし、URLには先ほど立てたサーバーのURLを設定します。
TextはuGUIのやつをよしなに設定してください。
image.png

VRCでインタラクトして、Textに「Hello Express app!」が表示されたら成功です。
表示されない場合はAllow Untrusted URL設定を見直してみてください。
image.png

ChatGPT APIを使えるようにする

OpenAIアカウントを登録し、ChatGPTのAPIキーを取得してください。
やり方は調べればたくさん出てくると思います。
APIキーは他人に教えないようにしましょう。

Replitに戻ります。
左下のToolsからSecretsを選択し、先ほど取得したAPIキーをOPENAI_API_KEYという名前で設定します。
image.png

左下のToolsからPackagesを選択し、「openai」を検索してインストールします。
image.png
image.png

サンプルのサーバー用コードをChatGPT用に書き換えます。

index.js
const express = require('express');
const app = express();

const { Configuration, OpenAIApi } = require("openai");
const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);


app.get('/', (req, res) => {
  res.send('Hello Express app!');
});

app.get('/OmoshiroikotoItte', async (req, res) => {
  const systemRole = "あなたは超一流コメディアンとしてふるまってください。";
  const message = "何か面白いことを言ってください。";
  const completion = await openai.createChatCompletion({
    model: "gpt-3.5-turbo",
    messages: [{role: "system", content: systemRole},{role: "user", content: message}],
  });
  res.send(completion.data.choices[0].message.content);
});

app.listen(3000, () => {
  console.log('server started');
});

Unity側のURLも末尾に/OmoshiroikotoItteを追加します。
image.png

動作確認してみましょう。
image.png

最後に

VRCStringDownloaderでサーバーにアクセスすることでUdonの制限を超えて遊ぶことができます。
今回使ったJavaScript向けにはChatGPTの他にもDiscord.jsやTwitterAPI、非公式ですがVRChatAPIのようなものも公開されています。
受信したテキストはそのまま表示するだけでなくUdonでさらにほかのギミックに接続したりといった使い方も可能なので、いろいろなギミックを作ってみてください。

作例

いろいろなサービスを組み合わせてこんなのも作れます

おまけ

双方向会話がしたい

VRChatの仕様上データを外に送るのが難しいですが一応クエリパラメータというのが使えます。

25
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?