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

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

ただいまの
回答率

91.23%

  • C#

    5017questions

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

  • Unity

    2472questions

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

Unity C# Listの使い方

解決済

回答 3

投稿

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

gozi200

score 2

前提・実現したいこと

Listを使ってゲームで使用する、ステータスを持ったプレイヤーを作成したいです

発生している問題・エラーメッセージ

PlayerクラスでListを作り、他のクラスでListにAddしています。
そうするとPlayerクラスの方でAddしたものが反映されず困っています。
csvで行っているのですが、値を入れるところは問題なくできているので、コードを省略します。
Addしているところにブレークポイントを立てて確認したところ、そこではきちんと値が入っていました。

該当のソースコード

public class Player : MonoBehaviour {
    private Player_Data player_data;
    private Player_Status player_status;

    public List<Player_Status> players = new List<Player_Status>();

    void Start() {
        player_data = GetComponent<Player_Data>();
        player_data.Set_Parameter();
    } 
}

public struct Player_Status {
    public int ID;      // 番号
    public string name; // 名前
}

public class Player_Data : MonoBehaviour {
    Player player = new Player();

    public void Set_Parameter() {
        Player_Status player_status;
        for(int i = 0; i < 2; ++i) { // TODO: マジックナンバー 
        player_status.ID   = int.Parse(player_data[i][0]);  // 番号
        player_status.name = player_data[i][1];             // 名前

    player.players.Add(player_status); // ここでプレイヤーの持っているListに格納
    }

試したこと

newのタイミングを変えてみたがダメだった。調べてもクラスを分けて行っているところが見つからない。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

check解決した方法

0

Player_Dataのnew Player();がいらなかった

GameObjectがいるという前提を抜かして言いました。
どこの情報が大切なのかが分かっていなかったためのミスでした。

参考にさせていただく部分が多くあったので学ばせていただきます。

ありがとうございました。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

C言語でいう構造体とかJavaとかでいうクラスのオブジェクトって、

基本的には staticじゃないから、同じクラスから生成していても、

public class Test{
             public method1(){ Test2 t = new Test2(); }
             public method2(){ Test2 t = new Test2(); }
}

public Test2{
       ... 何らかのメンバ ( メソッドやフィールド )
}

だと method1と method2 にあるt は別物です。

int型のローカル変数と同じです。

これのクラスレベルじゃないかなと。

Player_Dataクラスを見ると Playerクラスをコンポジションしているけど、

これだと、例えば yusha( 勇者 ), wizard ( 魔法使い )... とあったとき、

yushaは yusha用の Player playerにアクセスします。

よって、全体のやつには反映されない。

クラスって"ある意味" 変数と一緒。

単なる型。

だから複数個作れますよね。

同じクラスから作れば(持っているデータも)共通しているなら、意味がない。

逆にめんどくさくなるし。

勇者用にYushaクラス, Wizardクラス...って少しでも違えばクラスを生成しないといけなくなる。


[返信1]

変数で考えてみてください。

int method1(){
    int a;
  a = 100;
}

int method2(){
    int a;
    a = 32;
}

さて、上記の場合、int a はそれぞれ同じものでしょうか?

実際には method1はmethod1内にあるint aを, method2は method2内にある int aを参照します。

よって、別物になります。

これのオブジェクト版。

なので、例えばmainメソッド内で、

Player player1 = new Player( "player1" );
Player enemy1 = new Player( "ememy1" );
CharaManager manager = new CharaManager();

manager.add( palyer1 );
manager.add( enemy1 );

みたいになると思う。

この一つのmanagerがListを持っていて、管理する...みたいな。

あと、基本的にオブジェクト指向の言語はフィールドはprivateです。

そうじゃないとC言語でいうグローバル変数と同じになってしまいますから。

で、そのアクセスはアクセサと呼ばれるget/setで。

C# なら プロパティって呼ばれるもの。

Listを持つのは一つに限定したほうがいいはず。

( 複数個あってもいいが、完全に独立しているから今回は不向き。 )


[ 返信2 ]

えーと、返信1 で挙がっているmanager をC++で書くと

class PlayerManager{
      public:
             void add( Player *player ){ players.push_back( player ); }
             ... // その他メンバ
      private:
             List<Player> players;
};

みたいに持っていて、管理者として存在します。

別にこれはなくてもいいですが、あくまで考え方。

返信にある ( 20になった... ) のコードでは

main関数で player が生成されていますね。

このplayerオブジェクトが持つので player::x には 20が入っている。

が、これを別のクラスや関数でさらに生成して使用しても player自体がまったく違う物質になっていますから、もっているデータも違ってくる。

同じ"太郎"でも山田太郎と東京太郎では違いますよね。

それと同じです。

最初の質問では、流れを考えるといいと思います。

まず、

Playerのほうで生成するとしても、player_dataを生成 -> player_data::Set_Parameterで設定 -> ( Set_Parameterの呼び出し ) -> Player playerが生成される -> Set_Parameterが動く ...

という感じで考えると、( Player_Data の方の ) Player player とかがわかりにくくなる。

というか、なぜこういう風に複雑にしたのかが疑問。

( 私が馬鹿なだけかもしれないが。 )


[ 返信3 ]

例えば、上記のPlayerManager クラスがあるとして、

void func( PlayerManager *manager ){
     Player player; // プレイヤーを生成 ( 本来は引数が必要だと思うが、例なので省略 )
     manger->add( player );
}

みたいにしておけば、

// main関数内
PlayerManager manager; // これも本当は引数が必要だろうけど、例なので省略。
func( &manager );

みたいに管理者を渡せばOkだと思う。

オブジェクト指向だからって、複雑に捉えすぎると意味がわからなくなり、余計アレになる。

関係性をUMLとかで洗い出して考えてみては?

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/26 14:16

    値を触るところでListを作らなくてはいけないという事ですか?

    根本から勘違いしているかもしれません。(私が)
    例えばPlayerのHPを変動させたいときに例: class Battleでplayer.HPの値の計算は、Battle用に作られたPlayer playerのHPを計算するのであって、PlayerクラスのHPの値を変えているわけではないという事ですか?
    これが分かれば理解がしやすくなるのかなと感じます。

    キャンセル

  • 2017/12/26 14:25

    ちょっと、本編? の方で追加しますね。

    キャンセル

  • 2017/12/26 14:54

    class Hoge {
    public:
    int x = 10;

    void hoge() {
    std::cout << x << std::endl;
    }
    };


    void main() {
    Hoge hoge;

    hoge.x = 20;

    std::cout << hoge.x << std::endl;

    hoge.hoge();

    system("pause");
    }
    実行結果はとに20でした。
    mainで作成したmain用のhoge.xとHogeの持っているxは連動しているのですか?
    なのにListの内容が別物になってしまう違いがよくわからないです><

    書いてくださったmanagerはListですか?
    そうでないならAddできないですし、そうなのでしたら最初に私が試していたPlayerに入れるのとどう違うのでしょう?

    記入漏れがありました。C++でしたらまだC#よりは分かるので良い例があるのでしたらC++で挙げていただけたら理解は早まるかもしれません

    キャンセル

  • 2017/12/26 15:09

    追記します

    キャンセル

  • 2017/12/26 15:47

    なるほど、クラス別で呼ぶとわかりやすかったのですね。

    やはり複雑ですよねorz
    一つのクラスで処理をまとめるのは設計上よくないと技術が足りていないのにも関わらず変に分けようとしているからですね…

    ManagerのListに格納したとしても、他所で使おうとするとまた値が違うのでつかえなくないですか?
    Managerで値をいじることが前提なのでしょうか

    キャンセル

  • 2017/12/28 11:15

    そうですね。Managerで値をいじることが前提です。

    が、main関数 ( Javaだとmainメソッドですが。 ) みたいに必ず呼ばれるものならいいですが、

    普通の関数やメソッド等は呼び出さないと動きません。

    よって、呼び出す必要がありますが、例えばmain関数内でmanagerを生成して、

    managerに命令する関数やメソッド等 ( main関数以外 ) も生成すると別のものになるので

    引数で渡します。

    例は本体に記述しますね。

    キャンセル

0

PlayerのHPを変動させたいときに

あなたが書いたPlayerは型です。例えばintstring,int[]なども型です。
型に対してその型のデータ(実体、インスタンス)は複数存在できます。
複数存在できるということは、データを操作するときは、当然どのデータに対して操作するかを書く必要があります。
ですので、

class Battleでplayer.HPの値の計算は、Battle用に作られたPlayer playerのHPを計算するのであって、PlayerクラスのHPの値を変えているわけではないという事ですか?

その通りです。そもそも、あなたが考えているであろう「PlayerクラスのHP」というものはありません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/26 15:22

    ごめんなさい、HPは例で挙げさせていただきました。説明不足でした。
    ですが、BeatStar様の返事に書いたコードではクラスの関数を呼び出してみると、Playerで呼んだ値しか変えてないのにクラスの値まで変わっています。
    #include<iostream>

    class Player {
    public:
    int HP = 10; // Playerクラス内ではノータッチ

    void HP_Check() {
    std::cout << HP << std::endl;
    }
    };


    void main() {
    Player player;

    player.HP = 20; // mainの持っているPlayer playerであってPlayerのHPではない?

    std::cout << player.HP << std::endl;

    player.HP_Check(); // mainのPlayer playerにしか値を入れていないのに、PlayerクラスのHPの値が変わっている

    system("pause");
    }

    キャンセル

  • 2017/12/26 16:38 編集

    言い方が悪かったようですが、例だとかそういうの関係なく
    あなたの言う「クラスの値」(クラスが持っている値)というのは存在しません。
    初心者によくある勘違いです。

    class Player{...}であなたが書いているのは
    「こういう内容のデータの実態があります。」ではなく
    「こういう性質をもつデータの種類(型)があります。」です。

    Player p1;
    Player p2;
    とかけばp1,p2がそれぞれ個別にHPを持っていますが、
    Playerは、「この型のデータが作られたら、そいつはHPという名前のint型のデータを内包していて、初期値は10である」と定義しているだけです。

    キャンセル

  • 2017/12/26 16:45

    なるほど。
    プレイヤーにステータスだけを設定してあるものを委譲させて、それをプレイヤーのステータスとして扱おうと思っています。
    なのでプレイヤー自体は持っていなくても問題ないのかと思っていますがどうなのでしょう?
    全部手探りなので書き方がおかしいのかもしれませんが、そうしているつもりです。
    質問にも不慣れなもので必要な情報が少なく申し訳ございません。

    キャンセル

  • 2017/12/26 17:00

    > プレイヤーにステータスだけを設定してあるものを委譲させて、それをプレイヤーのステータスとして扱おうと思っています。

    どういう意味ですか?

    > プレイヤー自体は持っていなくても

    * (何かが)プレイヤー自体は持っていなくても
    * プレイヤー自体は(ステータスを)持っていなくても

    どっちですか?

    キャンセル

  • 2017/12/26 17:08

    後者です

    キャンセル

  • 2017/12/26 17:10

    なぜプレイヤーとプレイヤーのステータスを分けたいんですか?

    キャンセル

  • 2017/12/26 17:13

    私の参考にしている本での書き方がそうであったため、そうするものだと思っています。

    キャンセル

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

ただいまの回答率

91.23%

関連した質問

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

  • C#

    5017questions

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

  • Unity

    2472questions

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