Unity&C言語の初心者がUnity上でのルービックキューブ再現に挑戦してみたというお話の第三弾です。
キューブの回転方法
前回、キューブを回転させられるようになりました。でも、自動的にくるくる回るだけでは、ルービックキューブになりません。ですので今回は、ボタン操作でキューブを90度ずつ回転させることに挑戦します。
90度だけ回転させる
まずは90度だけ回転させてみます。
ルービックキューブを構成する全てのキューブに、以下のRotationScriptをセットしています。
public class RotationScript : MonoBehaviour { void Start() { StartCoroutine("Delay"); } void Update() { } IEnumerator Delay() { for (int i = 0; i < 90; i++) { yield return new WaitForSeconds(0.01f); transform.RotateAround(new Vector3(0, 0, 0), new Vector3(0, 0, 1), 1); } } }
どうやら無事に90度だけ回転させられました。
動作内容としては、0.01秒毎に1度ずつ回していくイメージだと思います。「WaitForSeconds(0.01f)の0.01fの部分が0.01秒毎に」、「i<90の部分で90回に分けて」、「new Vector3(0, 0, 1), 1)の最後の1で1度毎に」、といった感じだと思います。
Unityはインターネット上に様々な情報があるので、初心者でも切った貼ったで何とか動かせてしまいますね。
ボタン操作と連動させてみる
失敗事例
こんな感じでボタンを設置してみました。
ボタンの方には、以下のStartScriptをセットしました。
public class StartScript : MonoBehaviour { public bool RotationFlag = false; public void OnClick() { RotationFlag = true; } }
キューブの方には、以下のRotationScriptをセットしました。Startボタンをクリックしたら、RotationFlagがtrueになり、90度回転させるプログラムを一度だけ読み込む、ということを意図しました。
public class RotationScript : MonoBehaviour { public StartScript Script; void Start() { } void Update() { Script = GameObject.Find("StartButton").GetComponent<StartScript>(); if (Script.RotationFlag == true) { Script.RotationFlag = false; StartCoroutine("Delay"); } } IEnumerator Delay() { for (int i = 0; i < 90; i++) { yield return new WaitForSeconds(0.01f); transform.RotateAround(new Vector3(0, 0, 0), new Vector3(0, 0, 1), 1); } } }
結果としては失敗です。どういうわけか、数あるキューブの内、1つだけしか動いてくれませんでした。見辛いのですが、ボタンを2回クリックしています。1回目のクリックで中央下段にキューブが移動して、2回目のクリックで中央下段のキューブが中央上段に移動する様子を観察できます。
UnityとC言語の初心者である僕には、何が起こっているのか良く分かりません。ですがひょっとすると、キューブそれぞれにセットしたScriptは1つ1つ順番に実行されていくのではいかという疑念が生じました。1つ目のキューブでフラグを切ってしまっているから、キューブが1つだけしか移動しなかったのではないか、と。
成功事例
ということで、回転動作中かどうかを確認するフラグを追加してみました。
public class RotationScript : MonoBehaviour { public bool RotationCheckFlag=false; public StartScript Script; void Start() { } void Update() { Script = GameObject.Find("StartButton").GetComponent<StartScript>(); if (RotationCheckFlag == false) { if (Script.RotationFlag == true) { RotationCheckFlag = true; StartCoroutine("Delay"); } } } IEnumerator Delay() { for (int i = 0; i < 15; i++) { yield return new WaitForSeconds(0.01f); transform.RotateAround(new Vector3(0, 0, 0), new Vector3(0, 0, 1), 6); } Script.RotationFlag = false; RotationCheckFlag = false; } }
回転動作中の確認フラグを追加することで、ボタン操作でキューブを90度回転させられるようになりました。失敗の真因が何だったのか、未だに消化不良の状態ですが、知識をつけていけば理由を推測できるようになるだろうと前向きに考え、現時点では真因追求を諦めてしまいました。
まだ回転方向は一方向分しか作っていませんが、ボタンを増やしていけば、キューブ全体を任意の方向に回転させることはできそうです。
次のステップは、一面ずつ回していく動作になります。