🧭

Unity--世界百万人規模都市の緯度経度を三次元座標に変換し、CSVfileとしてimportして、一括表示する with chatGPT

2023/01/14に公開

自力で進めないのでchatGPTに頼ってみる。

大きな目標

Unityの空間で検索結果を三次元的に表示し、例えば開架の図書館内を歩きながらときどき本を手に取るような閲覧の仕方を可能にする。

中期的な目標

検索情報をC#でUnityに送り込む。

今日の目標

CSVfileにした500件の都市情報を読み込んで表示する。

世界百万人都市の位置データ

こちらからいただきました。
https://amano-tec.com/data/megacities.html

緯度経度(ラジアンに変換)を三次元座標に変換

  • x=cos緯度×cos経度
  • y=sin緯度
  • z=cos緯度×sin経度
  • 扱いやすいように百倍し、なおかつ整数にした。

教えてchatGPT

https://chat.openai.com/chat
読み込み・表示codeがあまりにうまくかけないので、噂のAI、chatGPTを試してみることにした。
AIに状況を理解してもらうために、どう表現すればいいかかなり悩んだが、以下のように質問した。

Unityでvilles.csvをimportし、ville列をキー、座標列をヴァリューとしてListを作り、そのListからGameobjectを指定された座標に設定するコードを書いてください。

この日本語を理解したことにも驚くが、フランス語で名づけたvilles(都市)という名称のfileに対して、以下のように、cityと英単語で命名をし、しかも「都市の位置」と日本語でコメントしている。状況を推測している感じに、すごい、としか言いようがない。

chatGPTが書いてくれたcodeは以下の通り

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

public class CSVImporter : MonoBehaviour
{
    public GameObject prefab;
    public string fileName = "villes.csv";
    private Dictionary<string, Vector3> cityPositions;

    void Start()
    {
        cityPositions = new Dictionary<string, Vector3>();
        // CSVファイルを読み込み、行ごとに分割する
        string[] lines = File.ReadAllLines(fileName);
        for (int i = 1; i < lines.Length; i++)
        {
            string[] parts = lines[i].Split(',');
            string cityName = parts[0];
            float x = float.Parse(parts[1]);
            float y = float.Parse(parts[2]);
            float z = float.Parse(parts[3]);
            // リストに都市名と座標を追加する
            cityPositions.Add(cityName, new Vector3(x, y, z));
        }
        // ゲームオブジェクトを作成し、都市の位置に配置する
        foreach (KeyValuePair<string, Vector3> city in cityPositions)
        {
            GameObject cityObject = Instantiate(prefab);
            cityObject.transform.position = city.Value;
            cityObject.name = city.Key;
        }
    }
}

ResourcesもAddressableも使わなかった。

UnityでCSVfileをimportする記事を探すと、多いのはResourcesを使うもの、でも今はそれが非推奨だということで、新しい記事はAddressableになっている。

それでとりあえずAddressableの情報とchatGPTのcodeを合成する方法を散々考えたが、なかなかうまくいかない。表示されるエラーを見ていると、assets/CSVに入れてあるvilles.csvをプロジェクト直下で探して「ない」と言っている。

pathを設定し直せばよいのだろうけれども、めんどうくさいので、fileのほうをプロジェクト直下に移した。最終的にはFlutterとのmessenger機能でデータとして送り込むわけだから、今のところfileがどこにあっても動けば良い。そしてこうすれば、addressableの設定は全く不要だということがわかったので、外してしまった。

chatGPTのcodeを微調整する。

変更したのは、Gameobjectの設定のみ。chatGPT様々。

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

public class CSVImporter : MonoBehaviour
{
    public GameObject pointer;
    public string fileName = "villes";
    private Dictionary<string, Vector3> cityPositions;

    void Start()
    {

        cityPositions = new Dictionary<string, Vector3>();
        // CSVファイルを読み込み、行ごとに分割する
        string[] lines = File.ReadAllLines(fileName);
        for (int i = 1; i < lines.Length; i++)
        {
            string[] parts = lines[i].Split(',');
            string cityName = parts[0];
            float x = float.Parse(parts[1]);
            float y = float.Parse(parts[2]);
            float z = float.Parse(parts[3]);
            // リストに都市名と座標を追加する
            cityPositions.Add(cityName, new Vector3(x, y, z));
        }
        // ゲームオブジェクトを作成し、都市の位置に配置する
        foreach (KeyValuePair<string, Vector3> city in cityPositions)
        {
            //pointerを取得
	    GameObject cityObjectBase = GameObject.Find("pointer");
	    //pointerを複製・配置
            GameObject cityObject = Instantiate(cityObjectBase);
            cityObject.transform.position = city.Value;
            cityObject.name = city.Key;
        }
    }
}

まとめ

Listや多元配列の扱い方がわかっていなくて難渋していたが、見事に解決。
chatGPTはすごかった。少なくとも私のような初学者が沼って時間をムダにするぐらいなら、さっさと聞いたほうがよい。ただし、AIにわかってもらいやすい日本語を書くという意識は必要と思う。

Discussion