#どのようなものを作っているか
今、unityの3Dでカップシャッフルゲームを作っています。
カップが三つありそれをシャッフルするのですが、ランダムにシャッフルするのでランダムに設定した変数によって移動させます。
#実現したいこと
その時、右端と左端にあるカップの位置を交換する場合、その場所にあるオブジェクトを移動させるオブジェクトとして取得してから、移動させたいです。なぜならば、数回移動させたのちに正解のしるしを入れたカップを取得したいからです。
カップはそれぞれ1,2,3と分けて区別してあります。
#試したこと
これまでには、オブジェクトをランダムに移動させるとき、移動させたのちに元居た位置に初期化し、それを移動させたと錯覚させて処理してきました。しかし、それだと正解のしるしを入れたカップを取得することができません。初期化してしまうために、正解のカップがどこに行ったのかわからなくなってしまうからです。
#####最後に
ネットで調べてみたのですが、自分のようなことをしている人が見つからず、解決することができませんでした。
指定した場所に存在するオブジェクトを取得するやり方でなくても構わないので、どのような処理にすれば目的が達成できるか教えていただきたいです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
カップオブジェクトは現状の「実際に移動させたかのように錯覚させる」という方式のままにしておき、正解のカップがどれであるかはスクリプト上で別途追跡するというのはどうでしょう?
初期状態での正解カップ番号を変数に保持しておき、カップの交換が発生するたびに
- 交換対象の番号がいずれも現在の正解カップ番号と異なる場合は、正解カップ番号を変更しない...たとえば現在の正解カップ番号が2の状態で、カップ1とカップ3の交換が行われた時には、正解カップ番号は2のまま維持する。
- 交換対象の番号のいずれかが現在の正解カップ番号と一致する場合は正解カップ番号も入れ替える...たとえば現在の正解カップ番号が2の状態で、カップ1とカップ2の交換が行われた時には、正解カップ番号は1に変更する。現在の正解カップ番号が1の状態で、カップ1とカップ3の交換が行われた時には、正解カップ番号は3に変更する。
というルールで正解カップ番号を入れ替えていけば、シャッフルが終わった時点で何番目のカップが正解であるか分かるのではないでしょうか。
##追記
何かご参考になれば...と思いまして、下図のような実験シーンを作ってみました。
3つのカップは空のオブジェクトの子オブジェクトとしてカップのモデルと景品のモデルを配置したものです。今回の実験ではカップ内に最初から景品を仕込んでおき、ハズレのカップは景品を非表示にすることで当たりのカップだけに景品が入っているように見せることにしました。
また、カップの動きを画面上で確認しやすくするため、各カップにはそれぞれ別々の色を付けました。実際のゲームだと、カップの見た目が違うと当たりカップを簡単に見破られてしまってまずいでしょうね。
これに下記のようなカップを開閉して景品を見せる動きをさせるためのスクリプトをアタッチしています。
C#
1using System.Collections; 2using UnityEngine; 3 4public class Mug : MonoBehaviour 5{ 6 [SerializeField] private float openHeight = 2.0f; 7 [SerializeField] private float animationLength = 1.0f; 8 9 private Coroutine currentAnimation; 10 private bool hasPrize; 11 private Transform mugModel; 12 private Transform prize; 13 14 public bool HasPrize 15 { 16 get => this.hasPrize; 17 set 18 { 19 this.prize.gameObject.SetActive(value); 20 this.hasPrize = value; 21 } 22 } 23 24 private void Awake() 25 { 26 this.mugModel = this.transform.Find("MugModel"); 27 this.prize = this.transform.Find("Prize"); 28 } 29 30 public void Open() 31 { 32 if (this.currentAnimation != null) 33 { 34 this.StopCoroutine(this.currentAnimation); 35 } 36 37 this.currentAnimation = this.StartCoroutine(this.DoAnimation(this.openHeight)); 38 } 39 40 public void Close() 41 { 42 if (this.currentAnimation != null) 43 { 44 this.StopCoroutine(this.currentAnimation); 45 } 46 47 this.currentAnimation = this.StartCoroutine(this.DoAnimation(0.0f)); 48 } 49 50 private IEnumerator DoAnimation(float destinationHeight) 51 { 52 var initialHeight = this.mugModel.localPosition.y; 53 for (var time = 0.0f; time < this.animationLength; time += Time.deltaTime) 54 { 55 var t = time / this.animationLength; 56 this.mugModel.localPosition = new Vector3( 57 0.0f, 58 Mathf.SmoothStep(initialHeight, destinationHeight, t), 59 0.0f); 60 yield return null; 61 } 62 63 this.mugModel.localPosition = new Vector3(0.0f, destinationHeight, 0.0f); 64 this.currentAnimation = null; 65 } 66}
Operatorがカップのシャッフル役で、下記のようなスクリプトをアタッチしました。インスペクター上でmugs
にシーン上の3つのカップをセットしています。
C#
1using System; 2using System.Collections; 3using System.Collections.Generic; 4using System.Linq; 5using UnityEngine; 6using Random = UnityEngine.Random; 7 8public class Operator : MonoBehaviour 9{ 10 [SerializeField] private float animationLength = 1.0f; 11 [SerializeField] private Mug[] mugs; 12 13 private int bingoIndex; 14 15 private IEnumerator Start() 16 { 17 // まずランダムな当たり番号を決め、その番号のカップに景品を仕込む 18 this.bingoIndex = Random.Range(0, this.mugs.Length); 19 for (var i = 0; i < this.mugs.Length; i++) 20 { 21 this.mugs[i].HasPrize = i == this.bingoIndex; 22 } 23 24 // ここで確認のためにコンソールに当たり番号を出力してみる 25 Debug.Log($"Bingo index: {this.bingoIndex}"); 26 27 yield return new WaitForSeconds(4.0f); 28 29 // カップを全部開き、中身を見せてみる 30 foreach (var mug in this.mugs) 31 { 32 mug.Open(); 33 yield return new WaitForSeconds(0.5f); 34 } 35 yield return new WaitForSeconds(2.0f); 36 37 // カップを全部閉じ... 38 foreach (var mug in this.mugs) 39 { 40 mug.Close(); 41 yield return new WaitForSeconds(0.5f); 42 } 43 yield return new WaitForSeconds(2.0f); 44 45 // ランダムに選んだ2つの番号を入れ替える操作を10回行う 46 var randomIndices = new List<int>(); 47 for (var i = 0; i < 10; i++) 48 { 49 randomIndices.Clear(); 50 randomIndices.AddRange( 51 Enumerable.Range(0, this.mugs.Length) 52 .Select(i => (i, guid: Guid.NewGuid())) 53 .OrderBy(p => p.guid) 54 .Select(p => p.i).Take(2)); 55 yield return this.Swap(randomIndices[0], randomIndices[1]); 56 57 // 1回交換するたびにコンソールに当たり番号を出力してみる 58 Debug.Log($"Bingo index: {this.bingoIndex}"); 59 } 60 yield return new WaitForSeconds(2.0f); 61 62 // カップを全部開き、中身を見せてみる 63 foreach (var mug in this.mugs) 64 { 65 mug.Open(); 66 yield return new WaitForSeconds(0.5f); 67 } 68 } 69 70 private IEnumerator Swap(int indexA, int indexB) 71 { 72 // 2つのカップが半円を描くようにアニメーションさせ... 73 var mugA = this.mugs[indexA]; 74 var mugB = this.mugs[indexB]; 75 var transformA = mugA.transform; 76 var transformB = mugB.transform; 77 var positionA = transformA.position; 78 var positionB = transformB.position; 79 var center = (positionA + positionB) * 0.5f; 80 var vectorA = positionA - center; 81 var vectorB = positionB - center; 82 for (var time = 0.0f; time < this.animationLength; time += Time.deltaTime) 83 { 84 var t = time / this.animationLength; 85 var r = Quaternion.Euler(0.0f, Mathf.SmoothStep(0.0f, 180.0f, t), 0.0f); 86 transformA.position = center + (r * vectorA); 87 transformB.position = center + (r * vectorB); 88 yield return null; 89 } 90 transformA.position = center + vectorB; 91 transformB.position = center + vectorA; 92 93 // mugs配列上の2つのカップを入れ替え... 94 this.mugs[indexA] = mugB; 95 this.mugs[indexB] = mugA; 96 97 // 必要に応じ当たり番号を更新する 98 if (this.bingoIndex == indexA) 99 { 100 this.bingoIndex = indexB; 101 } 102 else if (this.bingoIndex == indexB) 103 { 104 this.bingoIndex = indexA; 105 } 106 } 107}
動かしてみると、カップ入れ替え操作によってmugs
配列の順序が変化していき、併せてbingoIndex
の値も変化していきました。
投稿2021/01/10 15:41
編集2021/01/11 14:57総合スコア10811
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/10 23:46
2021/01/11 14:58
2021/01/12 03:29