はじめに
Twiterで、以下のようなツイートを見かけた。
AIにUnityエディタ拡張作ってもらった|るら @Lu_Ra_999 #note https://t.co/6uC29uJkh4
— るら/VRC (@Lu_Ra_999) 2023年1月18日
これが出来るのなら、(ある程度ユーザがUnityを分かっている前提で、)VR実験に必要な種々のスクリプトを実装させられるのでは、と考えた。
要件
そこで、この記事ではChatGPTに「シーン内のオブジェクトの移動記録を記録し、csvファイルに保存する」スクリプトを作らせてみる。
とりあえず書かせてみる。
using UnityEngine;
using System.IO;
using System.Text;
public class SaveTransformData : MonoBehaviour
{
// 保存する対象のゲームオブジェクト
[SerializeField] private GameObject targetObject;
// ファイル名
// コンマ区切りの文字列
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 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に関する実装時間を多く削減できそうだ。