ガチャシステムを作るために下のようなスクリプトを書いたのですが、
参照渡しをしないと、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}
> 参照渡しをしないと、GManager.instance.〜が増えないと言われましたが
誰に言われたのか知りませんが、言葉の表面だけでなく、何を言われたのか最後まで聞いてみては?
Teratailの質問の回答で言われました。
僕は質問しましたが返事が返ってこないためここでまた質問することにしました。
そういう場合は話の流れがわかるよう URL をリンクするものです。質問を編集し、他人に話がわかるよう説明してください。
なるほど。分かりました!
https://teratail.com/questions/316883
これです。
ベストアンサーに選ばれている回答が意味不明だったので低評価してきました。解決してからベストアンサーを選ぶのが良いと思います。参照渡しがどうこういう問題には思えません。どこで参照渡しを使おうとしているのかも理解できません。
if がたくさん使われているため、条件が満たされていない可能性があります。
> Debug.Log(r2 + "+1");
これが実行されているかどうかをまず確かめるのが良いと思います。
元の質問も読みにくくわかりにくいので、回答がつきにくかったのでしょう。どこの Debug.Log でどのような出力になったが、期待していたのはどのような出力だったと、コード中の具体的な場所とその部分での変数の実際の値と期待する値を明示するとわかりやすくなると思います。
一度ベストアンサーを外し、「回答者が実行してみればわかる」という考えを捨てて、何も知らない人に丁寧に説明するよう質問を編集しなおせば新しく回答がつくのではないでしょうか。質問を編集しなおすと質問がアクティブになり、回答者の目につきやすくなります。
質問の仕方教えて下さりありがとうございます!
Debug.Log(r2 + "+1");では、
r2が1の場合、1+1が8個出力されました。
しかし、GManager.instance.kazeintの数は増えませんでした。
これはr2が他の数字の場合でも、GManager.instance.〜intの数は増えませんでした。
どのようなスクリプトを書けばGManager.instance.〜intの数が増えるのか教えていただきたいです。
質問がどうもよく分からないのですが、
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.~~ も同時に値が増えるはずと思っていますか?
そうです。
初心者であまり良く分からなかったので、そうだと思っていました。
参照渡しの説明を読むとnumbersを増やしても、GManager.instance.〜intは同時に値が増えない事が分かりました。
DataをGManager側に持たせてみては。
この状態をListとforeachで何とかしようと思ったら、
List内のnumbersを
System.Action<int> numbers;
生成時のnewで
numbers = (value) => GManager.Instance.変数名 + value;
foreachの中は
numbers(加算値);
ぐらいしか思い浮かばなかった。
foreachもよくわからない事になってますよ?itiからaを取り出して使わないとか、何の為に回してるのか?
あまり良く分からないので、詳しく教えて欲しいです。
どこがですか?
ラムダ式?foreach?
System.Action<int> numbers;
スクリプトのどこに書くのかが分からないです。
listの中の new data の中の numbersをSystem.Action<int> numbersにするのですか?
numbers = (value) => GManager.Instance.変数名 + value;
valueとは何かが分からないです。
numbers(加算値);
の加算値をどのように書くのかが分からないです。
初心者過ぎる質問だと思いますがすいません。
お答えいただきたいです。
書いててなんですが、上記コードについてはとりあえず無視してください。
初心者にこんなおかしなコードを教えたらダメだと思いますので、、、
一応、やってる事はデリゲート、ラムダ式、Linq、メソッドチェーンとか調べたら分かるかもしれませんし、難しいかもしれません。物凄い長文でイヤになるぐらい丁寧(濃過ぎる)で理解できない解説が沢山でてくると思います。まぁ、使うだけなら、、、
で、質問の命題部分ですがコードを見るとGManagerがstaticなインスタンスでシングルトン仕様で、それの参照が~って言われると???そもそも参照を持つ必要がない、持たなくてもアクセス出来るpubic staticに???ってお話なのです。
そもそもなんですけど、gachaクラスの中でGManager.Instance.変数名 = 数値;ってコードを書けば直接変更出来るって事は分かってますか?
説明ですが、変更したいのはGManagerはint型変数でDataクラスで作っているのはintなので代入してもGManager.Instance.変数の数値が入ります。
Dataクラスはint型の入れ物を作っているだけです。intの入れ物にint型の参照を入れる事は出来ません。
なので、GMamagerの変数の参照ではなくその変数が持っていた値をコピーしてDataクラスで作ったintの入れ物に入れているんです。DataクラスのintがGManagerのintを指している訳ではありません。
int型を参照にする事は基本出来ません、、、直接的だとrefを使ったメソッドとか、intの値を持っただけのクラスを作るとかすればそういう振る舞いをする、は出来るんですけども、意味が変わってくるので普通に書いたら無いと思います。
言葉で説明すると、
intを直接に参照には出来ないのでintを処理する匿名メソッドを作って、そのメソッドの中で強引に変更するって事をしたのが上記のコードです。
ここが分かっているのかの回答を頂けますか?
そもそもなんですけど、gachaクラスの中でGManager.Instance.変数名 = 数値;ってコードを書けば直接変更出来るって事は分かってますか?
言い換えると、この状況、コードにおいて参照が必要ない(言い換えるとGManager.Instanceと記述したら、それがGManagerの参照)って事です。
そもそもなんですけど、gachaクラスの中でGManager.Instance.変数名 = 数値;ってコードを書けば直接変更出来るって事は分かってますか?
→分かっています。ただlistで簡単に書けるなら、簡単に書きたいです。
(ランダムで場合分けがめんどくさいから)
スクリプトがどのような事をやっているのかは分かりました。
ただ、スクリプトをどのように書くのかが分かりません。
元のスクリプトの何行目を何に変える、付け足すを教えて欲しいです。
もしかしてですが、回したいのはこっちですか?
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(足したい数字);
正直こっちはオススメ出来ないですが、、、
返信遅くなり申し訳ありません。
ありがとうございます。
僕はdictionaryのやり方でやる事にしました。
ですが、
++GManager.instance.dict[a.name];
の部分でerror CS0122が出てしまいました。
どうすれば良いのでしょうか?
外部のクラスからアクセスする場合はdictをpublicにしてください
public Dictionary<string, int> dict = ~
です
ありがとうございます。
僕は
、、、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)
というエラーが出てしまいました。
どうしたらこのエラーは消えるのでしょうか?
KeyNotFoundException:エラー文
The given key was not present in the dictionary.:説明文
その下、あってるかは知りませんが、呼び出しメソッド、メモリの番地、何の番地を指してるかは知らない、値が無い
って感じの意味じゃないでしょうか。Dictionaryに指定したキーの値をくれ、と指示したけどそんなキーは見つからない。って言われてます。
さすがにこれ以上使い方の説明まではしませんよ。自身で理解しないとどうにもならない部分ですし、私程度の知識ではしっかりした解説も出来ません。私自身があいまい、間違った知識も多いです。
少なくともほぼ基本部分なのでネットに優れた解説が山ほどあります。
こちらでは解決したようで良かったです。
回答1件
あなたの回答
tips
プレビュー