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

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

新規登録して質問してみよう
ただいま回答率
85.47%
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Unity

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

1047閲覧

ボタンを押したタイミングを記録した配列が、Jsonファイルへ出力されない

tuna-uniko

総合スコア10

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Unity

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/05/02 13:47

編集2020/05/09 02:50

Jsonに配列を出力する方法について質問です。
以下のコードではOnClick()でtapのタグが付いたボタンを押すたびに配列内へそのタイミングを記録し、配列の大きさを1つ増やすリサイズの処理をしています。そしてFinishのタグが付いたボタンを押すとタイミングが"soundscore"に配列形式で記録されたJsonファイルが出力される仕組みです。これを譜面データとして利用したいのですが、試しに31回tapボタンを押してから出力したところ以下の結果になりました。

Json

1{"soundscore":[0.0,0.0]}

何度か修正を繰り返したところ、Makerクラス内で宣言した配列soundscore[2]が値が入っていない状態そのままで書き出しに使用され、mk.soundscore[i]そのものを参照できていないのではないかという考えにたどり着きました。そこで、i回分クリックしたタイミングのデータを格納したmk.soundscore[i]のデータをどのような処理を使えばJsonファイルへ書き出せるか知りたいです。

目指していること
Jsonファイルを出力した時、ボタンを押したタイミングが回数分きちんとファイル内に反映される(以下の状態が理想の出力で、mk.soundscore[0]などにそれぞれ格納されているfloat型の数値が入ります)

Json

1{"soundscore":[mk.soundscore[0],mk.soundscore[1]・・・mk.soundscore[i]]}

C#

1using UnityEngine; 2using System.IO; 3using System; 4using UnityEngine.UI; 5 6[Serializable] 7public class Maker 8{ 9 public float[] soundscore = new float[2]; 10 //public int[] Notekind; 11} 12 13public class timing : MonoBehaviour 14{ 15 16 float TimeCount = 0; 17 //インスタンス作成 18 Maker mk = new Maker(); 19 public GameObject ko; 20 public GameObject lp; 21 int i=1; 22 23 // Start is called before the first frame update 24 void Start() 25 { 26    // 配列を初期化 27 mk.soundscore[0] = 0; 28 ko = GameObject.FindWithTag("tap"); 29 lp = GameObject.FindWithTag("Finish"); 30 } 31 32 // Update is called once per frame 33 void Update() 34 { 35 //開始からの時間を計測 36 TimeCount += Time.deltaTime; 37 } 38 39 public void OnClick() 40 { 41 if (tag == "tap") 42 { 43 //ボタンを押したタイミングを記録し、配列の要素数を増やしつつ 44 //配列に代入 45 mk.soundscore[i] = TimeCount; 46 Array.Resize(ref mk.soundscore, i + 1); 47 Debug.Log(mk.soundscore[i]); 48 } 49 50 if (tag == "Finish") 51 { 52 //Jsonファイルで出力 53 string json = JsonUtility.ToJson(mk); 54 File.WriteAllText("Assets\testj", json); 55 //読み込みの確認用 start()内で指定した数値しか返らない 56 int u; 57 for (u = 0; u < i; u++) 58 { 59 Debug.Log(mk.soundscore[u]); 60 } 61 } 62 } 63}

参考サイト様
https://sawalemounity.hatenablog.com/entry/2017/09/23/223000
ー>こちらのサイト様にあるソースコードの一部分たちを試行錯誤して組み込んだものが上のコードになります。

使用環境
Unity2019,1,5f1 C#のみ使用しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは。
OnClick()にてtagが"tap"だった場合の処理にて
配列の要素数は増えていますが、iの変数の値は増えていないようです。
iをインクリメントすることで解決できると思います。

cs

1public void OnClick() 2{ 3 if (tag == "tap") 4 { 5 //ボタンを押したタイミングを記録し、配列の要素数を増やしつつ 6 //配列に代入 7 mk.soundscore[i] = TimeCount; 8 9 // iの値を更新する 10 i++; 11 12 // 現在の配列数に +1 する 13 Array.Resize(ref mk.soundscore, mk.soundscore.Length + 1); 14 Debug.Log(TimeCount); 15 } 16}

余談ですが、このような場合は配列を使うよりListを使ったほうがいいかもしれません。
Listでしたら、'Add()'関数を使うことで最後尾に要素を追加できるので、
インデックス用の変数を所持しなくてすみます。
ご参考までに。

cs

1using UnityEngine; 2using System; 3using System.Collections.Generic; // Listを使う際の名前空間 4 5[Serializable] 6public class Maker 7{ 8 public List<float> soundscore = new List<float>(); 9} 10 11public class timing : MonoBehaviour 12{ 13 Maker mk = new Maker(); 14 15 // Start is called before the first frame update 16 void Start() 17 { 18 // 配列を初期化 19 mk.soundscore.Add(0); 20 } 21 public void OnClick() 22 { 23 if (tag == "tap") 24 { 25 mk.soundscore.Add(TimeCount) 26 Debug.Log(TimeCount); 27 } 28 29 if (tag == "Finish") 30 { 31 string json = JsonUtility.ToJson(mk); 32 File.WriteAllText("Assets\testj", json); 33 for (int u = 0; u < mk.soundscore.Count; u++) 34 { 35 Debug.Log(mk.soundscore[u]); 36 } 37 } 38 } 39}

投稿2020/05/11 04:10

編集2020/05/11 06:22
YASU_jrt

総合スコア33

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

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

tuna-uniko

2020/05/11 06:04

YASU_jrt様 ありがとうございます。Listを利用するとよいことは初めて知りました。 実際にあれこれ試してみましたが、前者では「範囲外やぞお前」とエラーが出る他、エラーが消えても出力は変わりませんでした。Listを使った書き方では、エラーこそ一度も出なかったですが出力は初期化で加えた0のみでした(コンソールには要素数1、値0が出力)。 このことから、初期化された状態のmkがなぜかOnClick()内 tag=="tap"の処理で上書きされずそのままになっていると考えているのですが、なぜなのでしょうか。
YASU_jrt

2020/05/11 06:29

前者の「範囲外やぞお前」エラーの件は修正しました。 OnClick()処理内の tag で判定している件について質問があるのですが、 tag が "tap" か "Finish" かで判定していますが、 もしかして tap用のGameObjectと、finish用のGameObject それぞれにこの timing コンポーネントはアタッチされていますか? Hierarchy上に timing コンポーネントは複数存在していますか?
tuna-uniko

2020/05/11 06:55

tapとFinishのタグが付いたGameObjectそれぞれにtiming.csがアタッチされています。 実は先ほど思い切ってOnClick()のtagがFinishの時の処理でiのみ表示するよう書き換えるとiが0のままでした。またUpdate()内から新しく作ったTes()とEnd()をキー入力で呼び出す仕組みに変えたところ、iが増加していることも確認できました。 こうなったのはtimingが処理を担当する複数のGameObjectにアタッチされているために、tapとFinishそれぞれのGameObjectが参照するiの値が増加後のiの値と初期化処理をされただけのi=0とで異なっていたからですか?
YASU_jrt

2020/05/11 07:32

はい、その通りです。 tapのGameObjectにアタッチされている timing コンポーネントと finishのGameObjectにアタッチされている timing コンポーネントは 別々のもの扱いになっています。 そのため、tap の timing コンポーネントは OnClick()が呼ばれるたびに soundscore は増えていきますが、 finish の timing コンポーネント の soundscore は増えていません。 そのため finish の timing コンポーネント の OnClick() が呼ばれても soundscore は初期化されたままのため、 json に書き込んでも数値が増えていないということになります。
tuna-uniko

2020/05/11 07:52

回答ありがとうございます。ずっと上手くいかず頭を悩ませていたのでスッキリしました。Listについても教えていただき感謝しております。これからはコンポーネントが別々になることにも注意してプログラムを組んでいこうと思います。 YASU_jrt様、本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問