🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Unity

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

Q&A

解決済

1回答

1714閲覧

参照渡しの仕方が分からない

CPU

総合スコア13

C#

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

Unity

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

0グッド

0クリップ

投稿2021/01/23 09:48

編集2021/01/23 12:42

ガチャシステムを作るために下のようなスクリプトを書いたのですが、
参照渡しをしないと、GManager.instance.〜が増えないと言われましたが、どうするのかが分かりません。
Dataの形を維持したいです。
参照渡しの基本は分かっています。
https://teratail.com/questions/316883
ここで質問した物と同じです。

c#

1using System; 2using System.Collections; 3using System.Collections.Generic; 4using UnityEngine; 5using UnityEngine.UI; 6using System.Linq; 7 8class Data 9{ 10 public string name; 11 public int rarity; 12 public int id; 13 public int numbers; 14} 15 16public class gacha : MonoBehaviour 17{ 18 public void itiren() 19 { 20 List<Data> myData = new List<Data> 21 { 22 new Data 23 { 24 name = "kaze", 25 rarity = 1, 26 id = 1001, 27 numbers = GManager.instance.kazeint 28 }, 29 30 new Data 31 { 32 name = "bomu", 33 rarity = 1, 34 id = 1002, 35 numbers = GManager.instance.bomuint 36 }, 37 38 new Data 39 { 40 name = "speeddown", 41 rarity = 1, 42 id = 1003, 43 numbers = GManager.instance.speeddownint 44 }, 45 46 new Data 47 { 48 name = "mpkotei", 49 rarity = 1, 50 id = 1004, 51 numbers = GManager.instance.mpkoteiint 52 }, 53 54 new Data 55 { 56 name = "mpzouka", 57 rarity = 1, 58 id = 1005, 59 numbers = GManager.instance.mpzoukaint 60 }, 61 62 new Data 63 { 64 name = "mpkyuushuu", 65 rarity = 1, 66 id = 1006, 67 numbers = GManager.instance.mpkyuushuuint 68 }, 69 70 new Data 71 { 72 name = "hpkaifuku", 73 rarity = 1, 74 id = 1007, 75 numbers = GManager.instance.hpkaifukuint 76 }, 77 78 new Data 79 { 80 name = "hpzouka", 81 rarity = 1, 82 id = 1008, 83 numbers = GManager.instance.hpzoukaint 84 } 85 }; 86 87 int gachane = 50; 88 if (GManager.instance.coin >= gachane) 89 { 90 GManager.instance.coin = GManager.instance.coin - gachane; 91 92 93 float gint = UnityEngine.Random.Range(0f, 100f); 94 if (gint < 50f) 95 { 96 var iti = 97 from x in myData 98 where x.rarity == 1 99 orderby x.id ascending 100 select x; 101 102 System.Random r1 = new System.Random(); 103 int r2 = r1.Next(0, 8); 104 105 Debug.Log(myData[r2].numbers); 106 107 foreach (Data a in iti) 108 { 109 ++ myData[r2].numbers; 110 Debug.Log(r2 + "+1"); 111 } 112 } 113 114 else if (gint < 90f) 115 { 116 Debug.Log("2"); 117 } 118 119 else if (gint < 97f) 120 { 121 Debug.Log("3"); 122 } 123 124 else 125 { 126 Debug.Log("4"); 127 } 128 } 129 } 130} 131 132using System.Collections; 133using System.Collections.Generic; 134using UnityEngine; 135 136public class GManager : MonoBehaviour 137{ 138 public static GManager instance = null; 139 140 //hosiiti 141 public int kazeint; 142 public int bomuint; 143 public int speeddownint; 144 public int mpkoteiint; 145 public int mpzoukaint; 146 public int mpkyuushuuint; 147 public int hpkaifukuint; 148 public int hpzoukaint; 149 //hosiitiowari 150 151 152 private void Awake() 153 { 154 if (instance == null) 155 { 156 instance = this; 157 DontDestroyOnLoad(this.gameObject); 158 } 159 else 160 { 161 Destroy(this.gameObject); 162 } 163 } 164}

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

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

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

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

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

Zuishin

2021/01/23 09:51

> 参照渡しをしないと、GManager.instance.〜が増えないと言われましたが 誰に言われたのか知りませんが、言葉の表面だけでなく、何を言われたのか最後まで聞いてみては?
CPU

2021/01/23 12:18

Teratailの質問の回答で言われました。 僕は質問しましたが返事が返ってこないためここでまた質問することにしました。
Zuishin

2021/01/23 12:35

そういう場合は話の流れがわかるよう URL をリンクするものです。質問を編集し、他人に話がわかるよう説明してください。
Zuishin

2021/01/23 13:39 編集

ベストアンサーに選ばれている回答が意味不明だったので低評価してきました。解決してからベストアンサーを選ぶのが良いと思います。参照渡しがどうこういう問題には思えません。どこで参照渡しを使おうとしているのかも理解できません。 if がたくさん使われているため、条件が満たされていない可能性があります。 > Debug.Log(r2 + "+1"); これが実行されているかどうかをまず確かめるのが良いと思います。 元の質問も読みにくくわかりにくいので、回答がつきにくかったのでしょう。どこの Debug.Log でどのような出力になったが、期待していたのはどのような出力だったと、コード中の具体的な場所とその部分での変数の実際の値と期待する値を明示するとわかりやすくなると思います。 一度ベストアンサーを外し、「回答者が実行してみればわかる」という考えを捨てて、何も知らない人に丁寧に説明するよう質問を編集しなおせば新しく回答がつくのではないでしょうか。質問を編集しなおすと質問がアクティブになり、回答者の目につきやすくなります。
CPU

2021/01/23 14:29

質問の仕方教えて下さりありがとうございます! Debug.Log(r2 + "+1");では、 r2が1の場合、1+1が8個出力されました。 しかし、GManager.instance.kazeintの数は増えませんでした。 これはr2が他の数字の場合でも、GManager.instance.〜intの数は増えませんでした。 どのようなスクリプトを書けばGManager.instance.〜intの数が増えるのか教えていただきたいです。
dodox86

2021/01/23 18:53

質問がどうもよく分からないのですが、 CPUさんの[2021/01/23 23:29]のコメント: > Debug.Log(r2 + "+1");では、 > r2が1の場合、1+1が8個出力されました。 > しかし、GManager.instance.kazeintの数は増えませんでした。 とは、コードの以下の部分を言っていますか? > foreach (Data a in iti) > { > ++ myData[r2].numbers; > Debug.Log(r2 + "+1"); > } もしかすると、Dataクラスをnewしたときに numbers = GManager.instance.kazeint のようにしているので、GManager.instance.~~ も同時に値が増えるはずと思っていますか?
CPU

2021/01/24 00:55

そうです。 初心者であまり良く分からなかったので、そうだと思っていました。 参照渡しの説明を読むとnumbersを増やしても、GManager.instance.〜intは同時に値が増えない事が分かりました。
退会済みユーザー

退会済みユーザー

2021/01/24 02:57

DataをGManager側に持たせてみては。
退会済みユーザー

退会済みユーザー

2021/01/24 09:36

この状態をListとforeachで何とかしようと思ったら、 List内のnumbersを System.Action<int> numbers; 生成時のnewで numbers = (value) => GManager.Instance.変数名 + value; foreachの中は numbers(加算値); ぐらいしか思い浮かばなかった。 foreachもよくわからない事になってますよ?itiからaを取り出して使わないとか、何の為に回してるのか?
CPU

2021/01/24 12:30

あまり良く分からないので、詳しく教えて欲しいです。
退会済みユーザー

退会済みユーザー

2021/01/24 19:40

どこがですか? ラムダ式?foreach?
CPU

2021/01/25 07:07

System.Action<int> numbers; スクリプトのどこに書くのかが分からないです。 listの中の new data の中の numbersをSystem.Action<int> numbersにするのですか? numbers = (value) => GManager.Instance.変数名 + value; valueとは何かが分からないです。 numbers(加算値); の加算値をどのように書くのかが分からないです。 初心者過ぎる質問だと思いますがすいません。 お答えいただきたいです。
退会済みユーザー

退会済みユーザー

2021/01/25 08:49

書いててなんですが、上記コードについてはとりあえず無視してください。 初心者にこんなおかしなコードを教えたらダメだと思いますので、、、 一応、やってる事はデリゲート、ラムダ式、Linq、メソッドチェーンとか調べたら分かるかもしれませんし、難しいかもしれません。物凄い長文でイヤになるぐらい丁寧(濃過ぎる)で理解できない解説が沢山でてくると思います。まぁ、使うだけなら、、、 で、質問の命題部分ですがコードを見るとGManagerがstaticなインスタンスでシングルトン仕様で、それの参照が~って言われると???そもそも参照を持つ必要がない、持たなくてもアクセス出来るpubic staticに???ってお話なのです。 そもそもなんですけど、gachaクラスの中でGManager.Instance.変数名 = 数値;ってコードを書けば直接変更出来るって事は分かってますか?
退会済みユーザー

退会済みユーザー

2021/01/25 09:12

説明ですが、変更したいのはGManagerはint型変数でDataクラスで作っているのはintなので代入してもGManager.Instance.変数の数値が入ります。 Dataクラスはint型の入れ物を作っているだけです。intの入れ物にint型の参照を入れる事は出来ません。 なので、GMamagerの変数の参照ではなくその変数が持っていた値をコピーしてDataクラスで作ったintの入れ物に入れているんです。DataクラスのintがGManagerのintを指している訳ではありません。 int型を参照にする事は基本出来ません、、、直接的だとrefを使ったメソッドとか、intの値を持っただけのクラスを作るとかすればそういう振る舞いをする、は出来るんですけども、意味が変わってくるので普通に書いたら無いと思います。 言葉で説明すると、 intを直接に参照には出来ないのでintを処理する匿名メソッドを作って、そのメソッドの中で強引に変更するって事をしたのが上記のコードです。
退会済みユーザー

退会済みユーザー

2021/01/25 10:34

ここが分かっているのかの回答を頂けますか? そもそもなんですけど、gachaクラスの中でGManager.Instance.変数名 = 数値;ってコードを書けば直接変更出来るって事は分かってますか? 言い換えると、この状況、コードにおいて参照が必要ない(言い換えるとGManager.Instanceと記述したら、それがGManagerの参照)って事です。
CPU

2021/01/25 13:01

そもそもなんですけど、gachaクラスの中でGManager.Instance.変数名 = 数値;ってコードを書けば直接変更出来るって事は分かってますか? →分かっています。ただlistで簡単に書けるなら、簡単に書きたいです。 (ランダムで場合分けがめんどくさいから) スクリプトがどのような事をやっているのかは分かりました。 ただ、スクリプトをどのように書くのかが分かりません。 元のスクリプトの何行目を何に変える、付け足すを教えて欲しいです。
退会済みユーザー

退会済みユーザー

2021/01/25 15:49

もしかしてですが、回したいのはこっちですか? public int kazeint; public int bomuint; public int speeddownint; public int mpkoteiint; public int mpzoukaint; public int mpkyuushuuint; public int hpkaifukuint; public int hpzoukaint; これらのベタ書きのintに対応する値をDataに入れてforeachで回したいって事ですか? でしたら、Dataがnameを持ってますのでこちらの値を変更する方が楽かと思います。 GManagerの変数の方を下記に変更します。 Dictionry<string,int> dict = new Dictionary<string, int>() { { "kaze", 0 }, { "bomu", 0 }, { "speeddown", 0 }, { "mpkotei", 0 }, { "hpkyuusyuu", 0 }, { "hpzouka", 0 }, }; これならListと同じ感じで使えます。 使う時(foreachの部分) foreach(Data a in iti) { GManager.Instance.dict[a.name] += 足したい値; } そっちも変更したくないってなるとやはり過去の回答になるとして、 Dataクラスのpublic int numbersを下記に変更します。 System.Action<int> numbers; new Dataの中を書き換える numbers = (_) => GManager.Instance.変数名 += _; foreachの中で a.numbers(足したい数字); 正直こっちはオススメ出来ないですが、、、
CPU

2021/01/29 14:55

返信遅くなり申し訳ありません。 ありがとうございます。 僕はdictionaryのやり方でやる事にしました。 ですが、 ++GManager.instance.dict[a.name]; の部分でerror CS0122が出てしまいました。 どうすれば良いのでしょうか?
退会済みユーザー

退会済みユーザー

2021/01/29 23:56

外部のクラスからアクセスする場合はdictをpublicにしてください public Dictionary<string, int> dict = ~ です
CPU

2021/01/31 13:19

ありがとうございます。 僕は 、、、c# System.Random r1 = new System.Random(); int r2 = r1.Next(0, 8); foreach (Data a in iti) { ++GManager.instance.dict[a.name]; } foreach (int Value in GManager.instance.dict.Values) { Debug.Log(Value); } public Dictionary<string, int> dict = new Dictionary<string, int>() { {"kaze",0}, {"bomu",0}, {"speeddown",0}, {"mpkotei",0}, {"mpzouka",0}, {"mpkyushuu",0}, {"hpkaifuku",0}, {"hpzouka",0}, }; 、、、 というスクリプトに変えたのですが、 ガチャボタンを押した時に KeyNotFoundException: The given key was not present in the dictionary. System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) (at <9577ac7a62ef43179789031239ba8798>:0) というエラーが出てしまいました。 どうしたらこのエラーは消えるのでしょうか?
退会済みユーザー

退会済みユーザー

2021/02/01 06:51

KeyNotFoundException:エラー文 The given key was not present in the dictionary.:説明文 その下、あってるかは知りませんが、呼び出しメソッド、メモリの番地、何の番地を指してるかは知らない、値が無い って感じの意味じゃないでしょうか。Dictionaryに指定したキーの値をくれ、と指示したけどそんなキーは見つからない。って言われてます。 さすがにこれ以上使い方の説明まではしませんよ。自身で理解しないとどうにもならない部分ですし、私程度の知識ではしっかりした解説も出来ません。私自身があいまい、間違った知識も多いです。 少なくともほぼ基本部分なのでネットに優れた解説が山ほどあります。
Tto777

2021/07/26 19:58 編集

こちらでは解決したようで良かったです。
guest

回答1

0

自己解決

質問に答えて頂いた皆さんのおかげで、解決出来ました。
ありがとうございました。

c#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class GManager : MonoBehaviour 6{ 7 public static GManager instance = null; 8 9 public int coin; 10 11 //hosiiti 12 public Dictionary<string, int> dict = new Dictionary<string, int>() 13 { 14 {"kaze",0}, 15 {"bomu",0}, 16 {"speeddown",0}, 17 {"mpkotei",0}, 18 {"mpzouka",0}, 19 {"mpkyushuu",0}, 20 {"hpkaifuku",0}, 21 {"hpzouka",0}, 22 }; 23 //hosiitiowari 24 25 26 private void Awake() 27 { 28 if (instance == null) 29 { 30 instance = this; 31 DontDestroyOnLoad(this.gameObject); 32 } 33 else 34 { 35 Destroy(this.gameObject); 36 } 37 } 38} 39 40using System; 41using System.Collections; 42using System.Collections.Generic; 43using UnityEngine; 44using UnityEngine.UI; 45using System.Linq; 46 47public class gacha : MonoBehaviour 48{ 49int gachane = 50; 50 if (GManager.instance.coin >= gachane) 51 { 52 GManager.instance.coin = GManager.instance.coin - gachane; 53 54 55 float gint = UnityEngine.Random.Range(0f, 100f); 56 if (gint < 50f) 57 { 58 var iti = 59 from x in myData 60 where x.rarity == 1 61 orderby x.id ascending 62 select x; 63 64 string[] itistr = new string[] 65 { 66 "kaze", 67 "bomu", 68 "speeddown", 69 "mpkotei", 70 "mpzouka", 71 "mpkyushuu", 72 "hpkaifuku", 73 "hpzouka", 74 }; 75 76 System.Random r1 = new System.Random(); 77 int r2 = r1.Next(0, 8); 78 79 var hosiiti = GManager.instance.dict.Keys.ToList(); 80 foreach(var key in hosiiti) 81 { 82 if (itistr[r2] == key) 83 { 84 ++GManager.instance.dict[key]; 85 } 86 } 87 88 foreach(var kvp in GManager.instance.dict) 89 { 90 Debug.Log(kvp.Value); 91 } 92 } 93 } 94}

投稿2021/02/05 15:07

CPU

総合スコア13

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問