😺

Unity EditorからOpenAI APIを叩く

に公開

概要


OpenAIのAPIをUnity Editor上から叩いて画像生成とシェーダーを作成するEditor拡張を作成しました
また、Github上にPackageとして公開することで手軽にインストールできるようにしています

完成品

完成品が見たい方はこちらから
https://github.com/tkada/unity_openai_texture
https://github.com/tkada/unity_openai_shader

Editor拡張からAPIを叩く

事前にOpenAIのAPI KEYを取得しておきます
Editor拡張からAPIを叩く場合、非同期にした方がウインドウがフリーズしないので操作性が良くなります。
Editor拡張の中で非同期処理を行うためにEditorCoroutineを利用しました。

EditorCoutineはPackage ManagerのUnity Repositoryからインストールできます

private void CreateTexture(string prompt)
{
    // Placeholder for texture creation logic
    Debug.Log("Texture creation logic goes here.");
    //Coroutineの始動の仕方
    this.StartCoroutine(GenerateImageCoroutine(prompt));
}

//Coroutineの書き方はMonoBehaviourと同じ
IEnumerator GenerateImageCoroutine(string prompt)
{
    this.isLoading = true;

    //Note:https://platform.openai.com/docs/api-reference/images/create
    string url = "https://api.openai.com/v1/images/generations";

    // JSONボディ
    string json = JsonUtility.ToJson(new ImageGenerationRequest
    {
        model = this.modelOptions[this.selectedModelIndex],
        prompt = prompt,
        n = this.generateNumber,
        size = this.SizeStr[this.selectedSizeIndex],
    });

    Debug.Log("Request JSON: " + json);

    byte[] bodyRaw = Encoding.UTF8.GetBytes(json);

    UnityWebRequest request = new UnityWebRequest(url, "POST");
    request.uploadHandler = new UploadHandlerRaw(bodyRaw);
    request.downloadHandler = new DownloadHandlerBuffer();
    request.SetRequestHeader("Content-Type", "application/json");
    request.SetRequestHeader("Authorization", "Bearer " + apiKey);

    yield return request.SendWebRequest();

    if (request.result != UnityWebRequest.Result.Success)
    {
        Debug.LogError("OpenAI API Error: " + request.error);
        this.isLoading = false;
    }
    else
    {
        var result = JsonUtility.FromJson<ImageGenerationResponse>(request.downloadHandler.text);
        //CoroutineからさらにCoroutineを呼ぶこともできる
        this.StartCoroutine(DownloadImage(result.data.Select(data => data.url).ToArray()));
    }
}

https://github.com/tkada/unity_openai_texture/blob/main/Editor/OpenAITextureCreator.cs

基本的な流れとしては、ドキュメントに記載のJsonを作成し、そのJsonをAPI KEYとともにEND POINTにPOSTします。ここら辺はMonoBehaviourでAPIを叩く場合と変わりありません。

PackageとしてGithubに公開する

PackageとしてGithubに公開するのに必要な要素としては主に2つです

  • ルートにpackage.jsonを置く
  • Assembly Definition(.asmdefファイル)を作成する

ファイル構成はこのようになっています
(ここで.metaファイルは省略してますがGithub上には必要になります)

unity_openai_texture
│  LICENSE
│  README.md
│  README_JP.md
│  package.json
│
└─Editor
        OpenAITextureCreator.asmdef
        OpenAITextureCreator.cs

今回package.jsonはこのようにしました

{
    "name": "jp.tkada.unityopenaitexture",
    "version": "1.0.0",
    "displayName": "OpenAI Texture Creator",
    "description": "OpenAI Texture Creator for Unity",
    "unity": "2020.1",
    "keywords": [
      "editor"
    ],
    "author": {
      "name": "tkada"
    },
    "dependencies": {
        "com.unity.editorcoroutines": "1.0.0"
    }
}

ここで大事になるのはdependenciesの項目です。ここに依存パッケージを設定しておくと、PackageManagerからインストールしたときに依存パッケージも一緒にインストールしてくれます

次にAssembly Definitionを作成します。
Create->Scripting->Assembly Definitionから作成ができます。
今回作ったものはEditor拡張であり、EditorCoroutineに依存しているので下記の設定にしました。

これでセットアップは完了です。
Githubにアップロード後、別プロジェクトからインストールして正しくインストールされるか確認してください。
注意点としてmetaファイルもGithub内にアップロードしておかないと、インストール時に警告が出てしまいます。README.mdのmetaファイルも存在しないと警告が出てしまうので、ちゃんと作っておくのが良いでしょう。

まとめ

OpenAIのAPIを叩くEditor拡張の紹介しました。
また、Packageとしての公開の仕方についても紹介しました

Discussion