Polygon Collider 2Dの編集ツールのデータを読み書きしたい
ステージ毎に読み込んだデータを元に、Polygon Collider 2Dの形状を変更したかった。
ヒエラルキーで編集したPolygon Collider 2Dの形状データを読み書きするためVector2[]のデータのjson化がうまくいかなかったのでその対処メモ。

エディタ上でPolygon Collider 2Dの形状を変更したのでそのデータを読み書きできるようにしたい。
うまくいかなかった
// Polygon Collider 2Dを持つGameObjectの参照
public GameObject objectWithCollider;
// 保存するデータのキー
private string Vector2ArrayKey = "Vector2ArrayKey";
// Polygon Collider 2Dを取得し、その頂点座標を保存するメソッド
public void SaveColliderData()
{
PolygonCollider2D collider = objectWithCollider.GetComponent<PolygonCollider2D>();
if (collider != null)
{
Vector2[] vectorArray= collider.points;
// Vector2[]を文字列にシリアライズ
string serializedVectorArray = JsonUtility.ToJson(vectorArray);
// なにかしら保存処理…
}
}でいけると思ったんです。だがしかし、JSONが空になる。
JsonUtility.ToJson()メソッドは、標準のUnityシリアライゼーションシステムを使用してオブジェクトをJSON形式にシリアライズします。
ただし、JsonUtility.ToJson()は、配列を直接シリアライズすることができません。
そのため、Vector2[] の配列を直接シリアライズすると、空の文字列が返されます。なるほど、わからん。
試行錯誤で動くようになった
using System;
using UnityEngine;
[System.Serializable]
public class Coordinates
{
public Vector2[] points;
}
public class ColliderEditor : MonoBehaviour
{
// 保存するデータのキー
private const string Vector2ArrayKey = "Vector2ArrayKey";
// Polygon Collider 2Dを持つGameObjectの参照
[SerializeField]
public GameObject objectWithCollider;
// 書き込み
public void SaveColliderData()
{
PolygonCollider2D collider = objectWithCollider.GetComponent<PolygonCollider2D>();
if (collider != null)
{
Vector2[] vectorArray = collider.points;
String coordinateString = string.Join(",", vectorArray);
// PlayerPrefにセット
PlayerPrefs.SetString(Vector2ArrayKey, coordinateString);
// PlayerPrefsの変更を保存
PlayerPrefs.Save();
}
}
// 読み込み
public void LoadColliderData()
{
// 座標の文字列をJSON形式にシリアライズして保存
string json = SerializeCoordinates();
// JSON形式の文字列をデシリアライズしてVector2[]に変換
Vector2[] vertices = DeserializeCoordinates(json);
// 反映させるよ
PolygonCollider2D collider = objectWithCollider.GetComponent<PolygonCollider2D>();
if (collider != null && vertices != null)
{
collider.points = vertices;
}
}
// 座標をJSON形式にシリアライズして返すメソッド
string SerializeCoordinates()
{
// (0.76, 22.51),(-22.92, 8.70),(-20.42, -10.27),(-0.11, -24.03),(17.21, -11.18),(26.12, 2.14) のようなデータ
string coordinateString = PlayerPrefs.GetString(Vector2ArrayKey);
// 座標の文字列をカンマと括弧で分割
string[] coordinatePairs = coordinateString.Split(new char[] { '(', ')', ',' }, System.StringSplitOptions.RemoveEmptyEntries);
// Vector2の配列を作成
Vector2[] vertices = new Vector2[coordinatePairs.Length / 2];
for (int i = 0; i < coordinatePairs.Length; i += 2)
{
float x, y;
// 各座標のxとyを取得してVector2に変換
if (float.TryParse(coordinatePairs[i], out x) && float.TryParse(coordinatePairs[i + 1], out y))
{
vertices[i / 2] = new Vector2(x, y);
}
else
{
// なんかデータがおかしい時の処理
}
}
// 座標をCoordinatesクラスにセット
Coordinates coordinates = new Coordinates();
coordinates.points = vertices;
// CoordinatesオブジェクトをJSON形式にシリアライズして返す
return JsonUtility.ToJson(coordinates);
}
// JSON形式の文字列をデシリアライズしてVector2[]に変換するメソッド
Vector2[] DeserializeCoordinates(string json)
{
// JSON形式の文字列をCoordinatesクラスにデシリアライズ
Coordinates coordinates = JsonUtility.FromJson<Coordinates>(json);
// CoordinatesクラスからVector2[]を取得して返す
return coordinates.points;
}
}
おわりに
ステージごとにCSVから取得したデータを元にPolygon Collider 2Dの形状を動的に変更することができるようになりました。
小数点誤差とか気にしない。そこまで精度を保証する必要がないものを作っているので、これでよし!なんでもよし!
もっと良い方法があると思うので、誰か教えてください。

エディタ上で読み書きできるツール作った。

