回答編集履歴

1

実験結果を追記

2021/01/11 14:57

投稿

Bongo
Bongo

スコア10807

test CHANGED
@@ -11,3 +11,393 @@
11
11
 
12
12
 
13
13
  というルールで正解カップ番号を入れ替えていけば、シャッフルが終わった時点で何番目のカップが正解であるか分かるのではないでしょうか。
14
+
15
+
16
+
17
+ ##追記
18
+
19
+
20
+
21
+ 何かご参考になれば...と思いまして、下図のような実験シーンを作ってみました。
22
+
23
+
24
+
25
+ ![図1](29a4107c7e37202d01e8fd363588dc7b.gif)
26
+
27
+
28
+
29
+ 3つのカップは空のオブジェクトの子オブジェクトとしてカップのモデルと景品のモデルを配置したものです。今回の実験ではカップ内に最初から景品を仕込んでおき、ハズレのカップは景品を非表示にすることで当たりのカップだけに景品が入っているように見せることにしました。
30
+
31
+ また、カップの動きを画面上で確認しやすくするため、各カップにはそれぞれ別々の色を付けました。実際のゲームだと、カップの見た目が違うと当たりカップを簡単に見破られてしまってまずいでしょうね。
32
+
33
+ これに下記のようなカップを開閉して景品を見せる動きをさせるためのスクリプトをアタッチしています。
34
+
35
+
36
+
37
+ ```C#
38
+
39
+ using System.Collections;
40
+
41
+ using UnityEngine;
42
+
43
+
44
+
45
+ public class Mug : MonoBehaviour
46
+
47
+ {
48
+
49
+ [SerializeField] private float openHeight = 2.0f;
50
+
51
+ [SerializeField] private float animationLength = 1.0f;
52
+
53
+
54
+
55
+ private Coroutine currentAnimation;
56
+
57
+ private bool hasPrize;
58
+
59
+ private Transform mugModel;
60
+
61
+ private Transform prize;
62
+
63
+
64
+
65
+ public bool HasPrize
66
+
67
+ {
68
+
69
+ get => this.hasPrize;
70
+
71
+ set
72
+
73
+ {
74
+
75
+ this.prize.gameObject.SetActive(value);
76
+
77
+ this.hasPrize = value;
78
+
79
+ }
80
+
81
+ }
82
+
83
+
84
+
85
+ private void Awake()
86
+
87
+ {
88
+
89
+ this.mugModel = this.transform.Find("MugModel");
90
+
91
+ this.prize = this.transform.Find("Prize");
92
+
93
+ }
94
+
95
+
96
+
97
+ public void Open()
98
+
99
+ {
100
+
101
+ if (this.currentAnimation != null)
102
+
103
+ {
104
+
105
+ this.StopCoroutine(this.currentAnimation);
106
+
107
+ }
108
+
109
+
110
+
111
+ this.currentAnimation = this.StartCoroutine(this.DoAnimation(this.openHeight));
112
+
113
+ }
114
+
115
+
116
+
117
+ public void Close()
118
+
119
+ {
120
+
121
+ if (this.currentAnimation != null)
122
+
123
+ {
124
+
125
+ this.StopCoroutine(this.currentAnimation);
126
+
127
+ }
128
+
129
+
130
+
131
+ this.currentAnimation = this.StartCoroutine(this.DoAnimation(0.0f));
132
+
133
+ }
134
+
135
+
136
+
137
+ private IEnumerator DoAnimation(float destinationHeight)
138
+
139
+ {
140
+
141
+ var initialHeight = this.mugModel.localPosition.y;
142
+
143
+ for (var time = 0.0f; time < this.animationLength; time += Time.deltaTime)
144
+
145
+ {
146
+
147
+ var t = time / this.animationLength;
148
+
149
+ this.mugModel.localPosition = new Vector3(
150
+
151
+ 0.0f,
152
+
153
+ Mathf.SmoothStep(initialHeight, destinationHeight, t),
154
+
155
+ 0.0f);
156
+
157
+ yield return null;
158
+
159
+ }
160
+
161
+
162
+
163
+ this.mugModel.localPosition = new Vector3(0.0f, destinationHeight, 0.0f);
164
+
165
+ this.currentAnimation = null;
166
+
167
+ }
168
+
169
+ }
170
+
171
+ ```
172
+
173
+
174
+
175
+ Operatorがカップのシャッフル役で、下記のようなスクリプトをアタッチしました。インスペクター上で`mugs`にシーン上の3つのカップをセットしています。
176
+
177
+
178
+
179
+ ```C#
180
+
181
+ using System;
182
+
183
+ using System.Collections;
184
+
185
+ using System.Collections.Generic;
186
+
187
+ using System.Linq;
188
+
189
+ using UnityEngine;
190
+
191
+ using Random = UnityEngine.Random;
192
+
193
+
194
+
195
+ public class Operator : MonoBehaviour
196
+
197
+ {
198
+
199
+ [SerializeField] private float animationLength = 1.0f;
200
+
201
+ [SerializeField] private Mug[] mugs;
202
+
203
+
204
+
205
+ private int bingoIndex;
206
+
207
+
208
+
209
+ private IEnumerator Start()
210
+
211
+ {
212
+
213
+ // まずランダムな当たり番号を決め、その番号のカップに景品を仕込む
214
+
215
+ this.bingoIndex = Random.Range(0, this.mugs.Length);
216
+
217
+ for (var i = 0; i < this.mugs.Length; i++)
218
+
219
+ {
220
+
221
+ this.mugs[i].HasPrize = i == this.bingoIndex;
222
+
223
+ }
224
+
225
+
226
+
227
+ // ここで確認のためにコンソールに当たり番号を出力してみる
228
+
229
+ Debug.Log($"Bingo index: {this.bingoIndex}");
230
+
231
+
232
+
233
+ yield return new WaitForSeconds(4.0f);
234
+
235
+
236
+
237
+ // カップを全部開き、中身を見せてみる
238
+
239
+ foreach (var mug in this.mugs)
240
+
241
+ {
242
+
243
+ mug.Open();
244
+
245
+ yield return new WaitForSeconds(0.5f);
246
+
247
+ }
248
+
249
+ yield return new WaitForSeconds(2.0f);
250
+
251
+
252
+
253
+ // カップを全部閉じ...
254
+
255
+ foreach (var mug in this.mugs)
256
+
257
+ {
258
+
259
+ mug.Close();
260
+
261
+ yield return new WaitForSeconds(0.5f);
262
+
263
+ }
264
+
265
+ yield return new WaitForSeconds(2.0f);
266
+
267
+
268
+
269
+ // ランダムに選んだ2つの番号を入れ替える操作を10回行う
270
+
271
+ var randomIndices = new List<int>();
272
+
273
+ for (var i = 0; i < 10; i++)
274
+
275
+ {
276
+
277
+ randomIndices.Clear();
278
+
279
+ randomIndices.AddRange(
280
+
281
+ Enumerable.Range(0, this.mugs.Length)
282
+
283
+ .Select(i => (i, guid: Guid.NewGuid()))
284
+
285
+ .OrderBy(p => p.guid)
286
+
287
+ .Select(p => p.i).Take(2));
288
+
289
+ yield return this.Swap(randomIndices[0], randomIndices[1]);
290
+
291
+
292
+
293
+ // 1回交換するたびにコンソールに当たり番号を出力してみる
294
+
295
+ Debug.Log($"Bingo index: {this.bingoIndex}");
296
+
297
+ }
298
+
299
+ yield return new WaitForSeconds(2.0f);
300
+
301
+
302
+
303
+ // カップを全部開き、中身を見せてみる
304
+
305
+ foreach (var mug in this.mugs)
306
+
307
+ {
308
+
309
+ mug.Open();
310
+
311
+ yield return new WaitForSeconds(0.5f);
312
+
313
+ }
314
+
315
+ }
316
+
317
+
318
+
319
+ private IEnumerator Swap(int indexA, int indexB)
320
+
321
+ {
322
+
323
+ // 2つのカップが半円を描くようにアニメーションさせ...
324
+
325
+ var mugA = this.mugs[indexA];
326
+
327
+ var mugB = this.mugs[indexB];
328
+
329
+ var transformA = mugA.transform;
330
+
331
+ var transformB = mugB.transform;
332
+
333
+ var positionA = transformA.position;
334
+
335
+ var positionB = transformB.position;
336
+
337
+ var center = (positionA + positionB) * 0.5f;
338
+
339
+ var vectorA = positionA - center;
340
+
341
+ var vectorB = positionB - center;
342
+
343
+ for (var time = 0.0f; time < this.animationLength; time += Time.deltaTime)
344
+
345
+ {
346
+
347
+ var t = time / this.animationLength;
348
+
349
+ var r = Quaternion.Euler(0.0f, Mathf.SmoothStep(0.0f, 180.0f, t), 0.0f);
350
+
351
+ transformA.position = center + (r * vectorA);
352
+
353
+ transformB.position = center + (r * vectorB);
354
+
355
+ yield return null;
356
+
357
+ }
358
+
359
+ transformA.position = center + vectorB;
360
+
361
+ transformB.position = center + vectorA;
362
+
363
+
364
+
365
+ // mugs配列上の2つのカップを入れ替え...
366
+
367
+ this.mugs[indexA] = mugB;
368
+
369
+ this.mugs[indexB] = mugA;
370
+
371
+
372
+
373
+ // 必要に応じ当たり番号を更新する
374
+
375
+ if (this.bingoIndex == indexA)
376
+
377
+ {
378
+
379
+ this.bingoIndex = indexB;
380
+
381
+ }
382
+
383
+ else if (this.bingoIndex == indexB)
384
+
385
+ {
386
+
387
+ this.bingoIndex = indexA;
388
+
389
+ }
390
+
391
+ }
392
+
393
+ }
394
+
395
+ ```
396
+
397
+
398
+
399
+ 動かしてみると、カップ入れ替え操作によって`mugs`配列の順序が変化していき、併せて`bingoIndex`の値も変化していきました。
400
+
401
+
402
+
403
+ ![図2](4e4b3f25bfe9dea4f8d40b6cece9d5d4.gif)