facebook twitter hatena line email

Unity/ChatGPT

提供: 初心者エンジニアの簡易メモ
2023年2月8日 (水) 00:04時点におけるAdmin (トーク | 投稿記録)による版

移動: 案内検索

apiを取得する

  1. https://beta.openai.com/ でアカウントを作成
  2. "create new secret key"を押してAPIキーを作成する

参考

https://techblog.kayac.com/2022-group-calendar-unity-openapi

料金確認

https://platform.openai.com/account/usage

unityサンプル

Main.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Main : MonoBehaviour
{
    [SerializeField] GptView gptView;
    GptUseCase gptUseCase = null;
    void Awake()
    {
        if (ReferenceEquals(gptUseCase, null))
        {
            GptRepository gptRepository = new GptRepository();
            GptPresenter gptPresenter = new GptPresenter(gptView);
            gptUseCase = new GptUseCase(
                gptPresenter,
                gptRepository
                );
            gptUseCase.Begin();
        }
    }
    void OnDestroy()
    {
        if (!ReferenceEquals(gptUseCase, null))
        {
            gptUseCase.Finish();
        }
    }
}

GptUseCase.cs

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using Newtonsoft.Json;
using System;
using System.Linq;
using Cysharp.Threading.Tasks;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UniRx;
using UniRx.Triggers;
using UnityEngine.EventSystems;

public class GptUseCase
{
    GptPresenter gptPresenter;
    GptRepository gptRepository;
    CompositeDisposable disposable = null;
    public GptUseCase(
        GptPresenter gptPresenter,
        GptRepository gptRepository
        )
    {
        this.gptPresenter = gptPresenter;
        this.gptRepository = gptRepository;
    }
    /// <summary> 初回処理 </summary>
    public void Begin()
    {
        disposable = new CompositeDisposable();
        gptPresenter.Bind();
        gptPresenter.ExecOnClickAsObservable
            .Subscribe(async _ => {
                TMP_InputField input = gptPresenter.GptView.Input;
                string prompt = input.text;
                if (!string.IsNullOrEmpty(prompt))
                {
                    var response = await gptRepository.GetAPIResponse(prompt);
                    string outputText = response.Choices.FirstOrDefault().Text;
                    string outputText = prompt;
                    outputText = outputText.TrimStart('\n');
                }
            })
            .AddTo(disposable);
    }
    /// <summary> 終了処理 </summary>
    public void Finish()
    {
        disposable.Dispose();
        disposable = null;
    }
}

GptDefine.cs

public class GptDefine
{
    /// <summary>
    /// APIエンドポイント
    /// </summary>
    public const string API_END_POINT = "https://api.openai.com/v1/completions";
    /// <summary>
    /// API KEY
    /// </summary>
    public const string API_KEY = "API_KEY";
    /// <summary>
}

GptPresenter.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UniRx;
using UniRx.Triggers;
using System;

public class GptPresenter
{
    GptView gptView = null;
    public GptView GptView { get => gptView; set => value = gptView; }
    /// <summary> 実行Observable </summary>
    IObservable<Unit> execOnClickAsObservable = null;
    public IObservable<Unit> ExecOnClickAsObservable { get => execOnClickAsObservable; }
    public GptPresenter(GptView gptView)
    {
        this.gptView = gptView;
    }
    public void Bind()
    {
        execOnClickAsObservable = gptView.ExecButton.OnClickAsObservable();
    }
}

GptRepository.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using Newtonsoft.Json;
using System;
using System.Linq;
using Cysharp.Threading.Tasks;
using UnityEngine.EventSystems;

public class GptRepository
{
    /// <summary>
    /// APIからレスポンス取得
    /// </summary>
    /// <param name="prompt"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentOutOfRangeException"></exception>
    public async UniTask<GptAPIResponseEntity> GetAPIResponse(string prompt)
    {
        GptAPIRequestEntity requestEntity = new()
        {
            Prompt = prompt,
            MaxTokens = 200
        };
        string requestJson = JsonConvert.SerializeObject(requestEntity, Formatting.Indented);
        byte[] data = System.Text.Encoding.UTF8.GetBytes(requestJson);
        string jsonString = null;
        using (UnityWebRequest request = UnityWebRequest.Post(GptDefine.API_END_POINT, "POST"))
        {
            request.uploadHandler = new UploadHandlerRaw(data);
            request.downloadHandler = new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");
            request.SetRequestHeader("Authorization", "Bearer " + GptDefine.API_KEY);
            await request.SendWebRequest();
            switch (request.result)
            {
                case UnityWebRequest.Result.InProgress:
                    break;
                case UnityWebRequest.Result.Success:
                    jsonString = request.downloadHandler.text;
                    Debug.Log(jsonString);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
        return JsonConvert.DeserializeObject<GptAPIResponseEntity>(jsonString);
    }
}

GptView.cs

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using Newtonsoft.Json;
using System;
using System.Linq;
using Cysharp.Threading.Tasks;
using System.Collections.Generic;
using TMPro;

public class GptView : MonoBehaviour
{
    /// 入力欄
    [SerializeField]
    private TMP_InputField input;
    public TMP_InputField Input { get => input; }
    /// 出力欄
    [SerializeField]
    private TextMeshProUGUI output;
    public TextMeshProUGUI Output { get => output; }
    /// 実行ボタン
    [SerializeField]
    private Button execButton;
    public Button ExecButton { get => execButton; }
}