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

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

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

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

Unity

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

Q&A

解決済

1回答

609閲覧

自作したクラスの配列の追加を2回実行すると、二つとも同じ値になってしまう。

MOTOMUR

総合スコア195

C#

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

Unity

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

0グッド

0クリップ

投稿2020/05/31 15:55

編集2020/05/31 16:22

自作したクラスを配列で扱うために、

MasterData.cs

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class MasterData : MonoBehaviour 6{ 7 public static AllyMemberStatus[] AllyMemberStatusArray; //冒険者パーティー。一覧。 8 public static AllyMemberStatus[] AllyMemberSelectedArray;//パーティ選出メンバー管理用。 9 10 11 12 // Start is called before the first frame update 13 void Start() 14 { 15 DontDestroyOnLoad(this); 16 17 bool InitialGame = true; 18 19 var AllyMemberStatusList = new List<AllyMemberStatus>(); 20 if (InitialGame) 21 { 22 AllyStatus a1 = Resources.Load<AllyStatus>("AllyStatus/いち/1"); 23 AllyMemberStatus aa1 = new AllyMemberStatus(); 24 aa1 = a1.GetAllyMemberStatus(); 25 AllyMemberStatusArray = new AllyMemberStatus[1] {aa1}; 26 AllyMemberSelectedArray = new AllyMemberStatus[1] {aa1}; 27 Debug.Log(AllyMemberStatusArray[0].GetCharactorName()); 28 AllyStatus a2 = Resources.Load<AllyStatus>("AllyStatus/に/1"); 29 AllyMemberStatus aa2 = new AllyMemberStatus(); 30 aa2 = a2.GetAllyMemberStatus(); 31 32 System.Array.Resize(ref AllyMemberStatusArray, AllyMemberStatusArray.Length + 1); 33 AllyMemberStatusArray[AllyMemberStatusArray.Length - 1] = aa2; 34 AllyMemberSelectedArray = new AllyMemberStatus[2] { aa1, aa2 }; 35 36 Debug.Log(AllyMemberStatusArray[0].GetCharactorName()); 37 Debug.Log(AllyMemberStatusArray[1].GetCharactorName()); 38 InitialGame = false; 39 } 40 } 41 42 // Update is called once per frame 43 void Update() 44 { 45 46 } 47} 48

AllyStatus.cs

1using System; 2using System.Collections; 3using System.Collections.Generic; 4using System.Linq; 5using UnityEngine; 6using UnityEngine.UI; 7 8[Serializable] 9[CreateAssetMenu(fileName = "AllyStatus" , menuName = "CreateAllyStatus")] 10public class AllyStatus : CharactorsStatus 11{ 12 13 14} 15

CharactorStatus.cs

1using System; 2using System.Collections; 3using System.Collections.Generic; 4using System.Linq; 5using UnityEngine; 6using UnityEngine.UI; 7 8[Serializable] 9public abstract class CharactorsStatus : ScriptableObject 10{ 11 12 [SerializeField] 13 private string charactorName = " "; 14 [SerializeField] 15 private string CharactorID = System.Guid.NewGuid().ToString("N"); 16 [SerializeField] 17 private int level = 1; 18 [SerializeField] 19 private JobType.JobKind jobType =JobType.JobKind.戦士; 20 [SerializeField] 21 private JobType.JobName jobName = JobType.JobName.戦士; 22 [SerializeField] 23 private WeaponEnum.AllWeapon equipWeapon; 24 25 [SerializeField] 26 private int earnedExperience = 0; 27 [SerializeField] 28 private int nextLvUpExperience = 0; 29 30 [SerializeField] 31 private int maxHP = 100; 32 [SerializeField] 33 private int nowHP = 100; 34 [SerializeField] 35 private int maxMP = 30; 36 [SerializeField] 37 private int nowMP = 30; 38 [SerializeField] 39 private int ATK = 20; 40 [SerializeField] 41 private int DEF = 10; 42 [SerializeField] 43 private int INT = 15; 44 [SerializeField] 45 private int MND = 10; 46 [SerializeField] 47 private int DEX = 10; 48 [SerializeField] 49 private int AGI = 10; 50 [SerializeField] 51 private int CRI = 5; 52 53 [SerializeField] 54 private bool isPoisonState = false; 55 [SerializeField] 56 private bool isNumbnessState = false; 57 [SerializeField] 58 private bool isSelected = false; 59 60/*上記の要素すべてのget setは省略。*/ 61 62 public AllyMemberStatus GetAllyMemberStatus() 63 { 64 AllyMemberStatus allyMemberStatus = new AllyMemberStatus(); 65 allyMemberStatus.SetCharactorName(charactorName); 66 allyMemberStatus.SetCharactorID(CharactorID); 67 allyMemberStatus.SetLevel(level); 68 allyMemberStatus.SetJobType(jobType); 69 allyMemberStatus.SetJobName(jobName); 70 allyMemberStatus.SetEquipWeapon(equipWeapon); 71 allyMemberStatus.SetEarnedExperience(earnedExperience); 72 allyMemberStatus.SetNextLvUpExperience(nextLvUpExperience); 73 allyMemberStatus.SetMaxHP(maxHP); 74 allyMemberStatus.SetNowHP(nowHP); 75 allyMemberStatus.SetMaxMP(maxMP); 76 allyMemberStatus.SetNowMP(nowMP); 77 allyMemberStatus.SetATK(ATK); 78 allyMemberStatus.SetDEF(DEF); 79 allyMemberStatus.SetINT(INT); 80 allyMemberStatus.SetMND(MND); 81 allyMemberStatus.SetDEX(DEX); 82 allyMemberStatus.SetAGI(AGI); 83 allyMemberStatus.SetCRI(CRI); 84 return allyMemberStatus; 85 } 86 87 88 89 // Start is called before the first frame update 90 void Start() 91 { 92 DontDestroyOnLoad(this); 93 } 94 95 96} 97 98

AllyMemberStatus

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class AllyMemberStatus : MonoBehaviour 6{ 7 public static string charactorName = " "; 8 public static string CharactorID; 9 public static int level = 1; 10 public static JobType.JobKind jobType = JobType.JobKind.戦士; 11 public static JobType.JobName jobName = JobType.JobName.戦士; 12 public static WeaponEnum.AllWeapon equipWeapon; 13 14 15 public static int earnedExperience = 0; 16 public static int nextLvUpExperience = 0; 17 18 public static int maxHP = 100; 19 public static int nowHP = 100; 20 public static int maxMP = 30; 21 public static int nowMP = 30; 22 public static int ATK = 20; 23 public static int DEF = 10; 24 public static int INT = 15; 25 public static int MND = 10; 26 public static int DEX = 10; 27 public static int AGI = 10; 28 public static int CRI = 5; 29 30 31 public static bool isPoisonState = false; 32 public static bool isNumbnessState = false; 33 public static bool isSelected = false; 34 35 public void SetCharactorName(string CharactorName) 36 { 37 charactorName = CharactorName; 38 } 39 40 public string GetCharactorName() 41 { 42 return charactorName; 43 } 44 public void SetCharactorID(string CharactorId) 45 { 46 CharactorID = CharactorId; 47 } 48 /*上記以外のすべての要素のget setは省略。*/ 49 50 // Start is called before the first frame update 51 void Start() 52 { 53 DontDestroyOnLoad(this); 54 } 55 56} 57

上記のコードを作成しました。AllyMemberStatus.csは実際に使用しているget,set以外略。原因不明の場合は修正で追記します。)

scriptableObjectのallyStatus型を読み込み、GetAllyMemberStatus()して、変換して、AllyMemberStatusArrayに保存しています。

出力結果

このコードを出力すると、配列にaa1を追加時はAllyMemberStatusArray[0].GetCharactorName()はちゃんと、「いち/1」のデータが入っているのですが、
aa2を追加すると、AllyMemberStatusArrayの[0]も[1]も「に/1」のデータになってしまいます。
(ちなみに、リストにしてみたり、同時にArrayにいれて初期宣言しても同様の出力です。)

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

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

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

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

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

BluOxy

2020/05/31 16:21 編集

AllyStatus.csは、C#の構文がおかしいように思います。scriptableObjectではなくScriptableObjectでしょうか。また、GetAllyMemberStatusに戻り値やアクセス修飾子が存在しません。{}の数が合っていません。 実際のコードを見て手打ちで移したのであれば、それは止めましょう。代わりに、実際のコードをコピーし、1字とも違わない実際のコードを質問文にペーストしてください。 でないと「そのコードではコンパイルエラーが起きてしまうので、コンパイルエラーを直してください」が回答になります。それはMOTOMURさんの求めている回答ではないと思うので、質問の編集をお願いします。
BluOxy

2020/05/31 16:18

AllyMemberStatus クラスが怪しいので、添付して頂きたいです。 前回の質問もそうでしたが、static を使っているからな気がします。(あくまで勘) 火傷をしない内に static キーワードについて理解を深めることを推奨します。
MOTOMUR

2020/05/31 16:24

staticの勉強は平日の日中にしようと思ってます。なので同じくstaticが問題であったのであれば、お手数おかけしました。staticは明日の日中より理解に努めます。
MOTOMUR

2020/05/31 16:29

なぜstaticを脳死でつけているかというと、 staticを使うとシーン間で値を保持できると見たからです。 DontDestroyOnLoad(this);のみでもシーン間で同じ値にアクセスできるのであれば、わざわざstaticを使わなくてもいいのですが。。。
BluOxy

2020/05/31 16:42

> staticを脳死でつけている 余計なお世話でしたら申し訳ないですが、脳死でよく知らない構文を書くのは、今回のように後で困ることになるので止めた方が良いと思います。
gentaro

2020/05/31 17:35

どうやったやこんなにマイナス評価貰えるんだと思ったら、回答ついても全部自己解決にしてる人なのか。 一種の荒らしっぽいな。
MOTOMUR

2020/05/31 23:32 編集

分からないことを質問させていただいてる身で反論するのも気が引けますが、「全て自己解決してる」という理解に一体どうやったら辿り着くんでしょうか。。。 マイナス評価に関しては、プログラミングに関しては独学しており「理解の浅い言語を駆使して作りたいものを作ってみたいが、分からないことが多い。聞くしかない」状況が多く。また、わからないことがわからない、という状態での質問が多いからだと私は思ってます。 理解が追いつき抜け出すまではー100スコアを背負って頑張ります。
BluOxy

2020/06/01 03:36 編集

詳細を全て書くのは大変なので、凄くざっくり答えてしまえば「全て自己解決してる」人の真似をすれば良いと思います。その人が何を考えてどう行動して自己解決しているかに着目することが大切です。 あとは、その人がする質問を見てみるのも良いと思います。大体の場合、その質問には検索やデバッグで自己解決できない根拠があると思います。
BluOxy

2020/06/01 00:31

あとは、分からないことが分からない状態になる理由を自己分析することですね。検索しても見つかると思います
guest

回答1

0

ベストアンサー

public static string charactorName = " ";

結論から書いてしまえば、上記のstaticキーワードを外せばその問題は解決します。
下記のメソッドの戻り値が同じなのも 上記メンバーに付与されている static が原因です。

  • AllyMemberStatusArray[0].GetCharactorName();
  • AllyMemberStatusArray[1].GetCharactorName();

しかし、根本原因は static キーワードをよく知らずに使っていることだと思うので、今回と同じような問題を再発させないためには static キーワードについて理解を深める必要があります。

参考になりそうなサイト2選

投稿2020/05/31 16:29

編集2020/05/31 16:49
BluOxy

総合スコア2663

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

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

BluOxy

2020/05/31 16:39

MOTOMURさんの作成されているプログラムがどんなものかは分かりませんが、MasterDataをアタッチしたゲームオブジェクトを別のシーンに移動させれば下記のメンバーがstaticなので「シーン間で値を保持」という目的は達成できるかと思います。 public static AllyMemberStatus[] AllyMemberStatusArray; public static AllyMemberStatus[] AllyMemberSelectedArray; 他のメンバーへ無闇矢鱈にstaticをつけると意図した通りに動かなくなると思います。
MOTOMUR

2020/05/31 16:50

参考サイトありがとうございます。 Staticについて理解してからStatic関連の質問(2つ)に、理解した内容を書きクローズしようと思います。
MOTOMUR

2020/05/31 16:57

ちなみに、staticを勉強するにあたり、なぜ「staticな自作クラスの配列は問題なく動作して、staticな自作クラスの中身がstatic だと問題があるか。」の疑問も上記参考サイトで解消されますか? 「staticは一意な値しか取れず、複数存在しうる自作クラスの中身がStaticだと、最後に設定した値が全ての参照に影響してしまうため」と*予想はしてますが、(*予想はよくないと学びましたが説明のために記述)その辺りの例が見つからそうなので事前に質問させていただきました。
BluOxy

2020/05/31 17:43 編集

> なぜ「staticな自作クラスの配列は問題なく動作して、staticな自作クラスの中身がstatic だと問題があるか。」の疑問も上記参考サイトで解消されますか? 解消されると思います。 ※問題あり/なしで判断するのではなく、MOTOMURさんの目的が達成できるか否かで判断すると良いかと staticの特性を理解した上で、意図通りの動きをする(すなわち、問題ない)と分かっているならば、たとえ全てのメンバーやクラスにstaticを付けても構いません。staticの特性を理解しているなら。 理解していなければ、そもそも意図通りの動きをする/しないの判断は出来ないはずですから、その状態でstaticを用いると今回のような状況に陥ります。 つまり、staticの特性を理解すれば、そこにstaticを付けるべきかの判断ができる訳なので、やはり上記参考サイトで疑問は解消されるのではないかと思います。
BluOxy

2020/05/31 17:21

> 「staticは一意な値しか取れず、複数存在しうる自作クラスの中身がStaticだと、最後に設定した値が全ての参照に影響してしまうため」 Debug.Logを使うか、VisualStudioのブレークポイントの機能を使って実際に値を確認するのが早いと思います。
MOTOMUR

2020/06/01 00:10 編集

非常に丁寧な回答ありがとうございます。 static の理解が終わりましたらここで報告させていただこうと思いますが、こちらの回答はBAに先にさせていただきます。
BluOxy

2020/06/01 03:37 編集

はい。BAを選んでもらえることも嬉しいですが、それよりもstaticの理解を終えて問題と解決策を認識できたかどうかのフィードバックがあると回答した甲斐があると感じられるので嬉しいです。
MOTOMUR

2020/06/01 10:52

static学習についてフィードバック。 ご指摘の通り、staticをAllyMemberStatusのメンバから取り除くと、質問の挙動は起こりませんでした。 staticについて。 staticをつけた変数は静的メンバとなり、コピーを許しません。今回のコードでいうと2度AllyMemberStatusを呼び出すことで、見かけ上AllyMemberStatusのインスタンスを2つ作成しているように見えますが、取り出したいものがAllyMemberStatusの中のstaticなメンバであるため、同じAllyMemberStatusが最初の代入ではaa1に一つ目の値が代入されますが、,aa2に代入された瞬間にaa1 = aa2となり、今回の結果になったと思われます。 staticについて丁寧に教えていただきありがとうございました。これが間違った認識であればご指摘お願いいたします。
BluOxy

2020/06/01 13:50 編集

正否はさておき、ご自身でドキュメントを読んで解釈したのは自己解決力向上の良い一歩です。 > aa2に代入された瞬間にaa1 = aa2となり、今回の結果になったと思われます。 ここは明確に違います。AllyMemberStatusクラスが持つstaticメンバをそれぞれのインスタンスが共有しています。共有しているのはそのメンバがstaticだからです。決してaa1とaa2自体が同じということではありません。aa1とaa2が持つstaticなメンバがそれぞれのインスタンスで共有されているだけです。大事なので、同じ説明を色々な文章にしてみました。aa1とaa2自体が同じかどうかは、比較して試してみると良いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問