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

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

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

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

Unity

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

Q&A

解決済

2回答

2079閲覧

Unity 一つのListをデータ一覧としてアクセスしたい

JectABC

総合スコア34

C#

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

Unity

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

0グッド

1クリップ

投稿2017/12/28 15:16

編集2017/12/29 04:40

###前提・実現したいこと
一つのListをデータ一覧として使いそれらを参照して別々に使用・加工(変更)。参照と言いますが実際に参照でデータをとってしまうと使用はできますがデータを加工する時に元のデータ一覧も変わってしまいます。何か解決策はないでしょうか?
また、もしListで実現できないなら別の方法が何かあるでしょうか?
お願いします。
###発生している問題・エラーメッセージ

エラーメッセージはありません

###該当のソースコード

using System.Collections; using System.Collections.Generic; using UnityEngine; public class CharPrefab { public int id; public int rear; public int efectnumber; public string name; public int[] move = new int[8]; public string efect; public bool efect_onoff = false; public CharPrefab(int i,int r,int en ,string n,int N,int NE,int E,int SE,int S,int SW,int W,int NW){ id = i; rear = r; efectnumber = en; name = n; move[0] = N; move[1] = NE; move[2] = E; move[3] = SE; move[4] = S; move[5] = SW; move[6] = W; move[7] = NW; } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Decktest { //データ一覧用。値は固定させたい public List<CharPrefab> chars = new List<CharPrefab>(); public void AllAdd(){ chars.Add (new CharPrefab (0,1,4,"歩",1,0,0,0,0,0,0,0)); chars.Add (new CharPrefab (1,2,4,"香",8,0,0,0,0,0,0,0)); chars.Add (new CharPrefab (2,2,4,"馬",0,2,0,0,0,0,0,2)); chars.Add (new CharPrefab (3,3,4,"銀",1,1,0,1,0,1,0,1)); chars.Add (new CharPrefab (4,3,4,"金",1,1,1,0,1,0,1,1)); chars.Add (new CharPrefab (5,4,7,"飛",8,0,8,0,8,0,8,0)); chars.Add (new CharPrefab (6,4,7,"角",0,8,0,8,0,8,0,8)); chars.Add (new CharPrefab (7,5,0,"王",1,1,1,1,1,1,1,1)); } }
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; public class GameManager : MonoBehaviour {   public Decktest deck = new Decktest();   public CharTemplate tempA; public CharTemplate tempB; public List<CharPrefab> ListA = new List<CharPrefab>(); public List<CharPrefab> ListB = new List<CharPrefab>(); void Start () { deck.AllAdd(); //データ一覧読み込み //※今回はListA,Bと同じデータを入れていますが違うこともあります。つまりコピーなどでは対応できません。 for(int i=0;i<9;i++){ ListA.Add(deck.chars[i]); } for(int i=0;i<9;i++){ ListA.Add(deck.chars[i]); } tempA.InitStatus(ListA[0]); tempB.InitStatus(ListB[0]);      tempA.Move_skills(deck.chars[tempA.efectnumber].move); Debug.Log(tempA.move[0]); Debug.Log(tempB.move[0]); } // Update is called once per frame void Update () {} }
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class CharTemplete :MonoBehaviour{ //アタッチするクラス public int id; public int rear; public int efectnumber; public string name; public int[] move = new int[8]; public bool efect_onoff = false; //ステータスを付与 public void InitStatus(CharPrefab t){ this.id = t.id; this.rear = t.rear; this.efectnumber = t.efectnumber; this.name = t.name; this.move = t.move; efect_onoff = false; } public void Move_skills(int[] m){ for(int y = 0;y<8;y++){ this.move[y] = this.move[y] + m[y]; if(move[y]>8) move[y] = 8; } } void Start() { } void Update() { } }

###試したこと
・回答にならって
GameManagerのStart()に
ListB = new List<CharPrefab>(listA); を追加
⇨変化なし

・chars自体をコピーして2つにして別々のデータ一覧からListA,Bに格納する
charsをコンストラクタで2つにコピーする方法
⇨変化なし
charsの内容をforeachで、新しく作ったListに格納していく
⇨変化なし

後者の2つでもできないとは...
まだどこかで同じところを参照しているということでしょうか

・Deckクラス,CharPrefabクラスは変化させたくないため構造体に
⇨変化なし

###補足情報(言語/FW/ツール等のバージョンなど)
unity2017.2.0f3
C#

最悪自分用と敵用のデータ一覧を作ればよさそうですが、できればやりたくはないです。

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

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

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

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

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

guest

回答2

0

ベストアンサー

###触われないリストの初期化
変更を加えようとした時、エラーが出るので触って欲しくないものに有効です。
UnityでしたらScriptableObjectも検討してみてください。

C#

1public static readonly List<CharPrefab> chars = new List<CharPrefab>(){ 2 new CharPrefab (0,1,4,"歩",1,0,0,0,0,0,0,0), 3 new CharPrefab (1,2,4,"香",8,0,0,0,0,0,0,0) 4 // 略 5};

###リストのコピー
Listのコンストラクタを使うのが一番楽です。

C#

1var list1 = new List<string>(); 2list1.Add("a"); 3 4// コンストラクタの引数に複製したいListを渡す 5var list2 = new List<string>(list1); 6list2[0] = "b"; 7 8Debug.Log(list1[0]); //a 9Debug.Log(list2[0]); //b

###リストのコピーで対応できない場合
初期値になるデータと動的に変化するデータを混在していませんか?
もし混在されているのでしたらそれを分けるところから始めてみてはいかがでしょうか

投稿2017/12/28 18:19

IShix

総合スコア1724

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

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

JectABC

2017/12/29 03:57

いつもありがとうございます。 list1,2に違うものを入れることはできます。その入れたものの内容(CharPrefabのメンバ変数)などが共有されてしまいます。 おそらく原因はlist1,2の値をdeck.charsという一つのリストから持ってきていることです。 リストのコピーに対応できない場合に該当するのではないかと思います。 List1,2は動的に、deck.charsは初期値にしたいのですが、結局変化させてしまっているのはdeck.charsなためList1,2のCharPrefabの内容も共有されてしまいます。 ”試したこと”を追加しておきます。
guest

0

いろいろやってみましたがこれが自分が思っていたものに一番近いかなと思いました.
前回の質問でも同じような質問をして、そこでの回答を参考にしてみました。

<前回の回答>
newで新たにクラスを作る方法(下のコード)。これならListA,Bがそれぞれ違う値を持ててなお、その内容も変化できてデータを共有しなくて済みます。
しかしこの方法では問題がありました。
問題1.データ一覧を作っている意味がなくなるため
問題2.ListA,Bに同じデータを入れるとは限らないため。例えば下のコードでは分かりやすく同じCharPrefab型をいくつも入れているためforでコードが簡単に済みます。しかし実際はDecktestの一覧から内容が違う様々なCharPrefabをListに入れます。そのためコードが長くなるという点。

//自分用 for(int i=0;i<8;i++){ ListA.Add(new CharPrefab(0,1,4,"歩",1,0,0,0,0,0,0,0)); } for(int i=0;i<8;i++){ ListB.Add(new CharPrefab(0,1,4,"歩",1,0,0,0,0,0,0,0)); }

この問題を解決するためにDecktestクラスにcharLoad()を加えてみました。
上のコードと

using System.Collections; using System.Collections.Generic; using UnityEngine; public struct Decktest { //データ一覧用。値は固定させたい public List<t0> chars; //public List<t0> charse = new List<t0>(); public void AllAdd(){ chars = new List<t0>(); chars.Add (new t0 (0,1,4,"歩",1,0,0,0,0,0,0,0)); chars.Add (new t0 (1,2,4,"香",8,0,0,0,0,0,0,0)); chars.Add (new t0 (2,2,4,"馬",0,2,0,0,0,0,0,2)); chars.Add (new t0 (3,3,4,"銀",1,1,0,1,0,1,0,1)); chars.Add (new t0 (4,3,4,"金",1,1,1,0,1,0,1,1)); chars.Add (new t0 (5,4,7,"飛",8,0,8,0,8,0,8,0)); chars.Add (new t0 (6,4,7,"角",0,8,0,8,0,8,0,8)); chars.Add (new t0 (7,5,0,"王",1,1,1,1,1,1,1,1)); } public CharPrefab charLoad(int i){ CharPrefab tt = new t0(chars[i].id,chars[i].rear,chars[i].efectnumber,chars[i].name,chars[i].move[0],chars[i].move[1],chars[i].move[2],chars[i].move[3],chars[i].move[4],chars[i].move[5],chars[i].move[6],chars[i].move[7]); return tt; } }

投稿2017/12/29 07:30

JectABC

総合スコア34

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問