ChatGPTにUnityシーン内のオブジェクトの移動を記録するスクリプトを書かせてみた

はじめに

Twiterで、以下のようなツイートを見かけた。

これが出来るのなら、(ある程度ユーザがUnityを分かっている前提で、)VR実験に必要な種々のスクリプトを実装させられるのでは、と考えた。

 

要件

そこで、この記事ではChatGPTに「シーン内のオブジェクトの移動記録を記録し、csvファイルに保存する」スクリプトを作らせてみる。

 

とりあえず書かせてみる。

 

 

using UnityEngine;
using System.IO;
using System.Text;

public class SaveTransformData : MonoBehaviour
{
    // 保存する対象のゲームオブジェクト
    [SerializeField] private GameObject targetObject;

    // ファイル名
    [SerializeField] private string fileName = "TransformData.csv";

    // コンマ区切りの文字列
    private readonly string DELIMITER = ",";

    // 一行目のパラメータ名
    private readonly string PARAMETERS = { "Name", "Position.x", "Position.y", "Position.z", "Rotation.x", "Rotation.y", "Rotation.z", "Rotation.w" };

    // ファイルに書き込む文字列
    private StringBuilder csvContent;

    private void Start()
    {
        // 一行目のパラメータ名を追加
        csvContent = new StringBuilder();
        for (int i = 0; i < PARAMETERS.Length; i++)
        {
            csvContent.Append(PARAMETERS[i]);
            if (i < PARAMETERS.Length - 1)
            {
                csvContent.Append(DELIMITER);
            }
        }
        csvContent.AppendLine();
    }

    private void Update()
    {
        if (targetObject == null)
        {
            return;
        }

        // オブジェクトの名前、座標、回転を取得
        string name = targetObject.name;
        Vector3 position = targetObject.transform.position;
        Quaternion rotation = targetObject.transform.rotation;

        // 文字列に追加
        csvContent.Append(name);
        csvContent.Append(DELIMITER);
        csvContent.Append(position.x);
        csvContent.Append(DELIMITER);
        csvContent.Append(position.y);
        csvContent.Append(DELIMITER);
        csvContent.Append(position.z);
        csvContent.Append(DELIMITER);
        csvContent.Append(rotation.x);
        csvContent.Append(DELIMITER);
        csvContent.Append(rotation.y);
        csvContent.Append(DELIMITER);
        csvContent.Append(rotation.z);
        csvContent.Append(DELIMITER);
        csvContent.Append(rotation.w);
        csvContent.AppendLine();
    }

    private void OnApplicationQuit()
    {
        // ファイルに書き込み
        File.WriteAllText(fileName, csvContent.ToString());
    }
}

 

この時点で、それなりのものが出来上がった。出来上がったスクリプトをアタッチしてみると、エラーもなくcsvに出力され、きちんと保存された。

 

このスクリプトには以下のような不満点があった。

・一つのオブジェクトしかtransformを保存できない

・保存場所をAssets/Log 以下にしたい

・rotationがquaternion形式になっている

・csvContentが結構重くなりそう。 File.AppendAllTextを用い、毎フレーム保存してほしい。

 

これらを直させてみる。

 

 

何回かに指示を分けて、対話的にスクリプトを修正させた結果が以下である。

完成したスクリプト

using UnityEngine;
using System.IO;
using System.Text;
using System;

public class SaveMultipleTransformData : MonoBehaviour
{
    // 保存する対象のゲームオブジェクト
    [SerializeField] private GameObject targetObjects;
    // ファイル名
    [SerializeField] private string fileName = "TransformData.csv";

    // 保存先のフォルダパス
    [SerializeField] private string folderPath = "/Assets/LogTest";

    // コンマ区切りの文字列
    private readonly string DELIMITER = ",";

    // ファイルに書き込む文字列
    private StringBuilder csvContent;

    private string filePath;

    private void Start()
    {
        if (targetObjects.Length == 0)
        {
            return;
        }
        filePath = Environment.CurrentDirectory + folderPath + "/" + fileName;

        // フォルダが存在しなければ作成
        if (!Directory.Exists(Environment.CurrentDirectory + folderPath))
        {
            Directory.CreateDirectory(Environment.CurrentDirectory + folderPath);
        }

        // 一行目のパラメータ名を追加
        csvContent = new StringBuilder();
        for (int i = 0; i < targetObjects.Length; i++)
        {
           
            string objectName = targetObjects[i].name;
            csvContent.Append(objectName + "_Position_x" + DELIMITER);
            csvContent.Append(objectName + "_Position_y" + DELIMITER);
            csvContent.Append(objectName + "_Position_z" + DELIMITER);
            csvContent.Append(objectName + "_Rotation_x" + DELIMITER);
            csvContent.Append(objectName + "_Rotation_y" + DELIMITER);
            csvContent.Append(objectName + "_Rotation_z" + DELIMITER);
        }
        csvContent.AppendLine();
    }

    private void Update()
    {
        for (int i = 0; i < targetObjects.Length; i++)
        {
            if (targetObjects[i] == null)
            {
                continue;
            }

            // オブジェクトの座標、回転を取得
            Vector3 position = targetObjects[i].transform.position;
            Vector3 rotation = targetObjects[i].transform.eulerAngles;

            // 文字列に追加
            csvContent.Append(position.x + DELIMITER);
            csvContent.Append(position.y + DELIMITER);
            csvContent.Append(position.z + DELIMITER
            );
            csvContent.Append(rotation.x + DELIMITER);
            csvContent.Append(rotation.y + DELIMITER);
            csvContent.Append(rotation.z + DELIMITER);
        }
        csvContent.AppendLine();

        File.AppendAllText(filePath, csvContent.ToString());
        csvContent.Clear();

    }
}
このスクリプトで、良い感じに動いた。

ありがてえ........
 

感想

まだタイムスタンプなどの細かい機能は付けていないが、一先ずChatGPTさんが実用に耐えることを確認できた。
また、上のコードのDELIMITER = ",";とした部分や、StringBuilderを用いた実装などは自分には考えつかない部分だった。学びが多い。
これからは、ChatGPTを活用することで実験Utilityに関する実装時間を多く削減できそうだ。