質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.34%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

3回答

78閲覧

Jsonから構造体を取得したい

Tsubaki2358

総合スコア2

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2025/01/18 05:07

実現したいこと

Json上にあるnotesのwaitFrameの取得したい。

最終的にはInitializeStructListにJsonDataを引数で渡して、使用するノーツの全データを構造体を持つリストとして受け取り、その中からwaitFrameなどの要素を必要に応じて取得したい。

発生している問題・分からないこと

Json上にあるnotesのwaitFrameの取得方法がわからない。
というよりJsonで構造体を記述して、それをC#で受け取る方法を理解できていない。

該当のソースコード

Json

1{ 2 "title": "sample", 3 "notes": [ 4 { "waitFrame": "60", "posX": "1", "posY": "1" }, 5 { "waitFrame": "70", "posX": "2", "posY": "2" }, 6 { "waitFrame": "80", "posX": "3", "posY": "3" } 7 ] 8} 9

C#

1using System.Collections.Generic; 2using System.Threading.Tasks; 3using System.Threading; 4using System; 5using UnityEngine; 6using System.Collections; 7 8public class NotesGenerator : MonoBehaviour 9{ 10 public GameObject notePrefab; 11 private List<Notes> Data; 12 [SerializeField] public TextAsset jsonTextAsset; 13 14 private GameObject mainCamera; 15 private float cameraPosX, cameraPosY; 16 17 //JsonData json; 18 19 // JSONの情報 20 [Serializable] 21 private class JsonData 22 { 23 public string title; 24 public Notes notes; 25 } 26 27 [Serializable] 28 // 構造体の定義 29 private struct Notes 30 { 31 public float waitFrame; 32 public float posX; 33 public float posY; 34 } 35 36 // 生成されたオブジェクトのカウント用(テスト用) 37 // この値を基にDataリストのインデックスが取得できた 38 int objectCounter = 0; 39 40 private void Start() 41 { 42 Debug.Log("NotesGenerator booted"); 43 44 // メインカメラの座標を取得 45 mainCamera = Camera.main.gameObject; 46 cameraPosX = mainCamera.transform.position.x; 47 cameraPosY = mainCamera.transform.position.y; 48 49 // 文字列に変換 50 string inputString = jsonTextAsset.text; 51 52 // JsonUtility.FromJsonを使用して読み込み 53 // JsonUtility.FromJson<格納するクラス>(JSONの文字列 54 JsonData json = JsonUtility.FromJson<JsonData>(inputString); 55 Debug.Log("Title is : " + json.title); 56 57 Debug.Log(json.notes); 58 59 Debug.Log("Wait-frame is " + json.notes.waitFrame); 60 61 62 // Dataリストを初期化 63 Data = InitializeStructList(json); 64 65 Debug.Log("DataList length is " + Data.Count); 66 } 67 68 // 構造体の初期化 69 private List<Notes> InitializeStructList(JsonData json) 70 { 71 Debug.Log("InitializeStructList booted"); 72 List<Notes> Data = new List<Notes>(); 73 74 //foreach (Notes note in json) 75 //{ 76 // //string type = note["type"].Get<string>(); 77 // //float timing = float.Parse(note["timing"].Get<string>()); 78 //} 79 80 81 // ここの繰り返し回数については、Jsonのデータ数に依存させたい 82 for (int i = 1; i <= 3; i++) 83 { 84 for (int j = 1; j <= 5; j++) 85 { 86 // 毎回構造体を生成して場所を指定する 87 Notes sp = new Notes(); 88 89 // ここを変更してJsonからの情報に依存するようにする 90 // カメラに映るように調整している 91 sp.posX = j + cameraPosX; 92 sp.posY = i + cameraPosY; 93 94 // 設定された構造体をリストに追加する 95 Data.Add(sp); 96 } 97 } 98 99 return Data; 100 } 101 102 /*---------------------------------------ここからUpdate()------------------------------------------------- */ 103 private void Update() 104 { 105 // スペースが押されたら実行 106 // ボタンが押されたら~とかの処理に流用できそう 107 if (Input.GetKeyDown(KeyCode.Space)) 108 { 109 Debug.Log("Get key down the Space Key"); 110 _ = DelayAsync(destroyCancellationToken); 111 } 112 } 113 114 115 116 private async ValueTask DelayAsync(CancellationToken token) 117 { 118 Debug.Log("ValueTask DelayAsync booted"); 119 120 // ここで設定しているフレーム数を配列に置き換えるのも出来そう 121 // awaitする対象が異なる 122 //for (int i = 0; i < 10; i++) 123 Debug.Log("Use Data length is " + Data.Count); 124 for (int i = 0; i < Data.Count; i++) 125 { 126 // 毎60フレーム後に実行 127 // 前回の実行後から60フレーム後に動いている 128 // ここもJsonから取得したタイミングに依存させたい 129 int waitFrame = 60; 130 for (int frame = 0; frame < waitFrame; frame++) 131 { 132 frame++; 133 // ここで非同期で動いてたメソッドが回収される 134 await Awaitable.NextFrameAsync(token); 135 } 136 137 CreateArrow(); 138 objectCounter++; 139 } 140 Debug.Log("<br>Created arrow " + objectCounter + "times<br>"); 141 142 Debug.Log("ValueTask DelayAsync ended"); 143 } 144 145 /* 146 * Notesゲームオブジェクトを生成する 147 * 任意のアニメーションにゲームオブジェクトを渡して 148 * アニメーションしてもらう 149 */ 150 private void CreateArrow() 151 { 152 Debug.Log("CreateArrow booted"); 153 154 // インスタンス生成 155 GameObject go = Instantiate(notePrefab); 156 157 // 大きさ設定 158 SetArrowScale(go); 159 160 // ポジション設定 161 SetArrowPosition(go, objectCounter); 162 163 Debug.Log("CreateArrow ended"); 164 } 165 166 167 private void SetArrowScale(GameObject go) 168 { 169 go.transform.localScale = new Vector3(0, 0, 1); 170 } 171 172 173 /* 174 * Dataリストから構造体を取得し 175 * 取得した構造体から設定する場所を取得する 176 */ 177 private void SetArrowPosition(GameObject go, int index) 178 { 179 Notes sp = Data[index]; 180 float px = sp.posX; 181 float py = sp.posY; 182 go.transform.position = new Vector3(px, py, 0); 183 } 184}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

https://note.com/takamo1220/n/nbcdd55d36c66#a240f4c2-8ca5-495e-80b3-4d6eb03e2952
上記サイトを参考にしてJson作成からコードの記載を実施しました。

補足

〇環境
Unity6

試行錯誤しているのでコメントで省いているものが多く見づらい状態で申し訳ありませんが、ご助力いただけますと幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tsubaki2358

2025/01/18 06:43

https://qiita.com/mittan1330/items/80c4ed4c392710caebf6 の内容の方がさらに参考になりそうなのでメモ コメントアウトしているforEach文で出ていたエラーの内容を解決できる可能性が高い。 また、JsonNode.cs等のライブラリの取り込み方は分かっていないので、帰宅後に調査、実装を試みる事
guest

回答3

0

質問の要点がJSONに対応するクラスの定義方法を知りたいという事かなと思うのでそこに絞って回答します。
すでに指摘がありますが、floatで受け取りたい場合はJSON側も文字列ではなく数値(""で囲まない)で表記したほうが良いです。

json

1{ 2 "title": "sample", 3 "notes": [ 4 { "waitFrame": 60, "posX": 1, "posY": 1 }, 5 { "waitFrame": 70, "posX": 2, "posY": 2 }, 6 { "waitFrame": 80, "posX": 3, "posY": 3 } 7 ] 8}

上記のJSONをJsonUtilityで受け取る場合はこういう形で定義します。
JSONの配列はListでも受け取れます。
配列よりListのほうが扱いやすいので自分は常にListにしてます。

cs

1[Serializable] 2public class Note 3{ 4 public float waitFrame; 5 public float posX; 6 public float posY; 7} 8 9[Serializable] 10public JsonData 11{ 12 public string title; 13 List<Note> notes; 14} 15 16// JSON文字列をJsonDataに変換 17JsonData jsonData = JsonUtility.FromJson<JsonData>(inputString); 18 19Debug.Log($"title={jsonData.title}"); 20foreach(var note in jsonData.notes) 21{ 22 Debug.Log($"waitFrame={note.waiteFrame}, posX={note.posX}, posY={note.posY}"); 23}

投稿2025/01/18 07:24

mingos

総合スコア4213

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

参考にしているページからはjsonの構造を変更していますよね?
そしたらc#側のデータ構造を変更していないのはなぜですか?

json

1{ 2 "title": "sample", 3 "notes": [ 4 { "waitFrame": "60", "posX": "1", "posY": "1" }, 5 { "waitFrame": "70", "posX": "2", "posY": "2" }, 6 { "waitFrame": "80", "posX": "3", "posY": "3" } 7 ] 8}

具体的には「notes」は元ページの「character」に相当する扱いだとは思いますが、配列(もしくはリスト)に変更していますよね?
でも、JsonDataクラスの定義ではpublic Notes notes;と単一データしか格納しないように定義されていますよね?この理由はなぜですか?
単一データが正しいのか複数データが正しいのかは判断できるまでの情報が提示されていないので分かりません。
まずはjsonと暮らす悌吾を正しい方にそろえて試してみてください。

投稿2025/01/18 05:40

len_souko

総合スコア1365

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tsubaki2358

2025/01/18 06:26

ご回答ありがとうございます。 現在外に居るので帰宅後に作業でき次第試してみます! (多分24行目の事を言っているはず…!)
guest

0

この場合、数値が""で囲まれているので、数値ではなく文字列で扱われています。
Jsonを以下のようにするのがいいのではないでしょうか。

Json

1{ 2 "title": "sample", 3 "notes": [ 4 { "waitFrame": 60, "posX": 1, "posY": 1 }, 5 { "waitFrame": 70, "posX": 2, "posY": 2 }, 6 { "waitFrame": 80, "posX": 3, "posY": 3 } 7 ] 8}

投稿2025/01/18 05:20

fiveHundred

総合スコア10177

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tsubaki2358

2025/01/18 05:27 編集

回答ありがとうございます。試してみましたが解決できませんでした。(テンプレ) 原因がやはりわからんのです... デバッグログには文字列で書いていた時も含めて以下のように表示されます。 Wait-frame is 0
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.34%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問