Unityでcsvファイルに従ってObjectを動かす方法
Unityで、csvファイルに書かれたXYZ座標に関する情報に従ってオブジェクトを動かすにはどうすれば良いのでしょう?
この記事では、時間と位置についての情報が書かれたcsvファイルを読み込み、それに基づいてUnityでオブジェクトを動かすスクリプトをご紹介していきます。
筆者はイギリスで博士号取得を目指す学生です。複合現実(Mixed Reality)ヘッドセットであるMicrosoft HoloLens2から抽出したアイトラッキングデータがcsvファイルであるのですが、それをもとにユーザーの視線を再現する際にこのスクリプトが必要になりました。
シンプルなスクリプトですが、探しても条件に合うものが見つからなかったので、他の方のためにもメモを共有しておきたいと思います。
csvファイルでオブジェクトを動かす
Unityにオブジェクトを追加する
まず、Unityでオブジェクトを追加します。このオブジェクトがcsvファイルに沿って動くオブジェクトになります。
コードをオブジェクトに添付する
動かしたいオブジェクトに以下のコードを添付します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using UnityEngine.UI;
public class CSVFileReader: MonoBehaviour
{
public TextAsset csvFile;
[SerializeField] public float startTime;
void Start()
{
}
void Update()
{
ReadTxt();
}
void ReadTxt()
{
string[] records = csvFile.text.Split('\n');
for (int i = 1; i < records.Length; i++)
{
string[] fields = records[i].Split(',');
float timeElapsed = Time.time * 1000;
if(timeElapsed > float.Parse(fields[0]) - startTime)
{
transform.position = new Vector3(float.Parse(fields[1]), float.Parse(fields[2]), float.Parse(fields[3]));
}
}
}
}
csvファイルのデータの確認
csvファイルの構成を確認
まず、時間と位置情報が書かれたcsvファイルのフォーマットについて見てみましょう。筆者の手元にあるのは、ある実験で使ったアイトラッキングのデータで以下のようなものです。Unix Timestampで記録された各時刻における、XYZ座標での位置が示されています。このデータに基づく動きを、Unityで再現したいというわけです。
time | X | Y | Z |
---|---|---|---|
1676284349972 | 1.68805 | -0.24508 | 1.41258 |
1676284350006 | 1.69297 | -0.24562 | 1.4173 |
1676284350039 | 1.68969 | -0.24486 | 1.42162 |
1676284350072 | 1.68180 | -0.24308 | 1.43013 |
1676284350106 | 1.66869 | -0.24059 | 1.43029 |
1676284350139 | 1.67010 | -0.24113 | 1.4218 |
1676284350172 | 1.66897 | -0.24074 | 1.42725 |
1676284350206 | 1.67063 | -0.24096 | 1.4303 |
このコードは、時刻を1つ目のカラムに、X軸の情報を2つ目、Y軸の情報を3つ目、Z軸の情報を4つ目のカラムに入っていることをもとに作成していますので、読み込むcsvファイルがこのような構成になっているかを確認してください。
もしそうでない場合は、fields[1]
の括弧内の数字を変えて該当のカラムを読み取るように指定してください。
csvファイルを指定する
まず最初に、オブジェクトの動きが書かれたcsvファイルを指定します。Unityのフィールドに、csvファイルの名前を記入します。この際エクステンションは無しで大丈夫です。
public TextAsset csvFile;
スタート時間を指定する
続いて、csvファイルの記録がスタートした時刻を指定します。上記のデータ例では、Unix Timestampが1000分の1秒(Millisecond)の単位で記録されています。ここでは、最初の行にある時刻「1676284349972」をstartTime
としてUnityのフィールドに入力します。
[SerializeField] public float startTime;
このコードではスタート時間を基準に、どれくらいの時間が経過したかを計算し、再生から同じ時間が経過したところでの該当の位置にオブジェクトが動くようにしています。
また、筆者が動かしたいファイルの時刻が1000分の1秒で記録されていたので、スタートからの経過時間の算出をfloat timeElapsed = Time.time * 1000
としていますが、csvファイルの記録が秒単位の場合は* 1000
の部分を削除してください。
オブジェクトを動かす
再生ボタンを押すと、オブジェクトが動き出します。とてもシンプルなコードですが、XYZ座標の情報と経過時間の両方を考慮したものが見つからなかったため、この記事を書きました。参考になれば幸いです。