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

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

ただいまの
回答率

90.84%

  • C#

    5994questions

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

  • Unity

    3216questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity2D

    624questions

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 138

JectABC

score 20

前提・実現したいこと

一つの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#

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

触われないリストの初期化

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

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

リストのコピー

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

var list1 = new List<string>();
list1.Add("a");

// コンストラクタの引数に複製したいListを渡す
var list2 = new List<string>(list1);
list2[0] = "b";

Debug.Log(list1[0]); //a
Debug.Log(list2[0]); //b

リストのコピーで対応できない場合

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/29 12:57

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

    キャンセル

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;
}
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.84%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    おもしろ・特徴のある Fizz Buzz回答(たくさん)ください。

    数年前に流行して検索すれば死ぬほど出てくるFizzBuzzですが、 ルービックキューブに似て単純なだけにプログラマを惹きつけるのでしょうか。 なので、改めてあげるのもどうか

  • 解決済

    C#

    C#について解決いたしました。本当に助かりました。またどうぞ宜しくお願いいたします。

  • 解決済

    unity 画面内に同じものを表示しない

    unityでランダムでキャラクターを表示していくものなのですが、画面内に同じキャラクターが表示されてしまうのでされないようにしたいです。 キャラクターは一定時間でCloneされ一

  • 解決済

    [Unity]落とすアイテムを増やしたい

    Unityでりんごが落ちてくるゲームを作っています アイテムを2つまでは落とせるようになったのですが3つ目のアイテムをどうすれば落とせるのかがわかりません どうすれば3つ目4つ

  • 解決済

    C# 独自クラスを使ったListから、一つの要素だけ抽出したい

    実現したいこと 以下のリスト D 男 E 男 A 男 C 男 B 男 から D のみを取り出すには、 どうすれば良いでしょうか。 ネットで調べた情報を元に

  • 解決済

    MVC モデルのバリデーションについて

    モデルでアノテーション(Required)を指定しているプロパティが4つあります。 [Required] public string A { get; set;

  • 解決済

    自キャラが向いてる方向に攻撃をしたい

    3Dゲームの自機にビームの様な攻撃をしたいのですが真っすぐ(Z軸)にしか弾が飛んでいきません。 自機が向いてる方向に攻撃を行うにはどの様なコードを記述すればいいのか教えて頂きたいで

  • 解決済

    unity シーン自動遷移

    現在unityにて横スクロールのゲームを作成しています。行き詰まっているので教えて欲しいことがあります。詳しく言うと、 ・最後のステージでゴールに着いたらタイトルに戻る ・穴に落ち

同じタグがついた質問を見る

  • C#

    5994questions

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

  • Unity

    3216questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity2D

    624questions