このルービック キューブ ゲームの初期の実装では多くのチュートリアルを参照しましたが、コード ロジックはすべて自分で書きました (参考のために元の投稿リンクを示します)。実装のアイデアのみが説明されています。
完了:
ルービック キューブの回転とルービック キューブのアニメーション効果は、ルービック キューブのすべての cfop 式をサポートしており、ボタンを押すとルービック キューブを回転できます。
キーボードの Alt キーを押してマウスを動かすと、ルービック キューブを行き止まりなく 360 度観察できます。
ルービック キューブの中央のブロックには回転プロンプトがあり、ルービック キューブを時計回りまたは反時計回りのどちらに回転させる必要があるかを尋ねます。回転プロンプトをダブルクリックすると、すぐに F 側に設定されます。
ルービック キューブはデフォルトで時計回りに回転します。キーボードの Ctrl キーを押すと、ルービック キューブの回転タイプとプロンプト タイプが反時計回りに切り替わります。
最初のビルドが中断され、ルービック キューブの状態が保存および復元され、ルービック キューブの復元の検出がサポートされました。復元されたルービック キューブ、白い下の 2 つの層と黄色の一番上の層に分けられます。裏返すと(同様の5種類あり)、下が白い2段(同様の5種類)、下が白いクロス(5種類と同様)
ルービック キューブ CFOP 式の検出と復元アルゴリズムが完成し (オリジナル)、Enlu の実現が完了しました。詳細については、次を参照してください: (メッセージ数 14 件) ルービック キューブ CFOP 式マッチング アルゴリズム_qq_39858654 のブログ - CSDNブログ
テストチャート:
ルービック キューブ ゲームを回転させるというアイデアは、もともとステーション b のビデオ「Meng Xinxue Unity はルービック キューブを作成できますか?」から生まれました。
良いアイデアを提供してくれました。私がやりたいのは、3 次のルービック キューブです。ルービック キューブの回転が最大の問題です。ビデオの中の大男のアイデアは次のとおりです。
1. まず 27 個のキューブを配置してルービック キューブを形成し、次に 6 つの薄いキューブをルービック キューブのコントローラーとして使用し、ルービック キューブの 6 つの側面に配置します。各ルービック キューブ コントローラーは 9 個のキューブに触れます。
2. ルービック キューブの特定の面が回転しようとしているとき、それは特定のルービック キューブ コントローラを選択することと同等であり、その後、選択されたルービック キューブ コントローラはそれ自体に触れているオブジェクトを検出し、それを独自のサブオブジェクトに変換し、コントロール デバイスを再度回転すると、ルービック キューブの特定の面の回転が完了します。
3. ルービック キューブ コントローラが選択されている場合、残りの 5 つのルービック キューブ コントローラはサブオブジェクトを持つことができません。サブオブジェクトがある場合は、形成されたルービック キューブ コントローラによって得られる不完全なキューブ表面を避けるために、前のサブオブジェクトを解放する必要があります。 . .
このアイデアは実現可能ですが、大きな欠点があります。ルービック キューブの特定の面のみを回転させることができます。ルービック キューブの中央 (E、M、S) を回転させたい場合は回転できません。これには、ユニティタッチの判定メカニズムが関係します。
A オブジェクトと B オブジェクトが接触したとき、C オブジェクトが A オブジェクトに触れると、Unity は C オブジェクトが A オブジェクトと B オブジェクトに触れたとみなします。
より適切なたとえを使用すると、2 人が感電した場合、どちらに触れても感電します。
上記の考え方を使用してルービック キューブの E、M、S の中間回転を実行すると、回転されるのは中央のブロックではなく、ルービック キューブ全体です。
したがって、27 個の小さな正方形で構成されるルービック キューブを自由に回転できるようにしたい場合、最初に解決すべき問題は、コントローラーをどのように生成するかということです。
私が考えた方法は、3次元座標で判定するというものですが、この方法は非常に有効であることが実証されており、3段目だけでなく、ルービックキューブのコントローラー判定にも応用できると感じています第 4 レベルや第 5 レベルなどのゲーム。
まず、3次ルービックキューブの軸を(0,0,0)、白を底面とすると、次のような法則を見つけます。
(a,a,-1)F (1,a,a)R (a,1,a)U
(a,a,1)B (-1,a,a)L (a,-1,a)D
F 面上のマス目を判定したい場合は、27 個のマス目にそれぞれ 3 次元座標の Z 軸が -1 に等しいかどうかを判定させるだけで、9 個の適格なマス目が得られます。
(a,0,a) E (0,a,a) M (a,0,a) S
E 面上のマス目を判定したい場合、27 個のマス目にそれぞれ 3 次元座標の y 軸が 0 に等しいかどうかを判定させるだけで、条件を満たす中央の 9 個のマス目が得られます。
f=S(条件)+F(条件) r=M(条件)+R(条件) u=E(条件)+U(条件)
b=S(条件)+B(条件) l=M(条件)+L(条件) d=E(条件)+D(条件)
f 平面上のマス目を判定したい場合は、27 個のマス目にそれぞれ 3 次元座標の y 軸が 0 か、z 軸が -1 かどうかを判定させるだけで済みます。 18 個の適格な正方形を取得します。
実装後、小さな問題が見つかりました。つまり、回転後のルービック キューブの座標に小さな誤差が発生し、それが 1 または 0 に等しくなるのではなく、1.001 または 0.0082 などになる可能性があります。そのため、判断する前に Mathf.Round() を使用してエラーをチェックしてください。正しい数のキューブを取得するには削除する必要があります。そうしないと、ルービック キューブが回転するとキューブが失われます。
ルービック キューブの回転はゲーム全体の中核部分であり、それを実現するための手順は次のとおりです。
1. 27 個のルービック キューブの作成については、主な参考資料は次のとおりです: Unity チュートリアル | 3D "ルービック キューブ" をステップごとに綴ることを教えます。モデルのみが生成され、移動することはできません。
2. 6 つの表面コントローラーと 6 つの中央ブロック コントローラーを含む 12 個のルービック キューブ コントローラーが作成され、27 個のキューブを制御するために使用されます。
3. 18 個のボタンがスクリプトで定義および初期化されます。主な参考資料は次のとおりです: Unity: 配列を使用して複数のボタンを管理する
4. ルービックキューブの回転アニメーションの実現:
1. クォータニオン補間によって実現されるルービック キューブ アニメーションはユニバーサル ロックの問題を回避しますが、クォータニオンの回転は 1 回しかなくなるため、回転値を保存し、角度の連続性を維持する必要があります。これは完璧な解決策です。は角度重ね合わせ法(私のオリジナル)です。
角度重ね合わせ法: 最初の回転方向を定義し、時計回りに回転する場合は 90 を加算し、反時計回りに回転する場合は 90 を減算し、角度を -360 度から 360 度の間で制限するこの方法で回転の原理を理解し、最後の回転を記録することができます。時間角度、時計回りに90を加算して時計回りの目標値を取得し、反時計回りから90を減算して反時計回りの目標値を取得します。
2. ルービック キューブ コントローラの値は相互に影響を与えることはできません 私の調査の結果、12 個のルービック キューブ コントローラのアニメーションはたまたま相互に影響を受けないことがわかりました。
3. ルービック キューブの回転アニメーションは時間通りに完了し、所定の位置にあることを確認する必要がありますが、コルーチンを使用すると、この問題をうまく解決できます。
マジック キューブのアニメーション効果コードは次のとおりです。
private IEnumerator RotateOverTime(Transform transformToRotate, Quaternion targetRotation, float duration)
{
var timePassed = 0f;
while (timePassed < duration)
{
var factor = timePassed / duration;
transformToRotate.rotation = Quaternion.Slerp(transformToRotate.rotation, targetRotation, factor);
// 增加自上一帧起经过的时间
timePassed += Time.deltaTime;
// 重要的这告诉Unity在这里中断,渲染这个帧
// 在下一帧中从这里继续
yield return null;
}
// 要确保以精确值结束,请在完成时设置目标旋转修复
transformToRotate.rotation = targetRotation;
}
アニメーションコルーチンの呼び出し方法は次のとおりです。
StartCoroutine(RotateOverTime(mofanControlList[mofanConNum].transform,Quaternion.Euler(mofan_rotate * n1), 0.3f));
ルービック キューブの実装を自由に観察してください。
ランダムな観察効果を実現するためにルービック キューブの周りをカメラが回転できるようにするスクリプトがメイン カメラに関連付けられていますが、これも問題を引き起こします。ボタンを使用してルービック キューブの各面を制御しますが、どれがどれであるかを区別するのは困難です。 face はどの face からのものなので、ルービック キューブの中央のブロックにルービック キューブの回転インジケーターを追加しました。
ルービック キューブの状態の保存と復元:
2 つの Vector3 が構造体で定義されており、27 個のルービック キューブの座標とオイラー角を保存するために使用されます。ルービック キューブの対応する座標とオイラー角を保存した後、ルービック キューブの状態を保存できます。後で座標を保存します。のルービック キューブが見つかります。また、オイラー角によってルービック キューブの色を反転できます。具体的には、「ルービック キューブ状態検出 2_qq_39858654 のブログ」-CSDN ブログを参照してください。
480件のレコードをリストアップしたところ、約1週間で見つかりました。
ルービックキューブの縮小の検出:
1. まず、27 個のルービック キューブが復元されているかどうかを判断します。
ルービックキューブが復元されたかどうかを検出する必要がある場合、それはルービックキューブの座標と回転角度が正しいかどうかを検出することである。
エッジブロック座標復元検出:
たとえば、赤と白のエッジを検出するには、赤い立方体の中心ブロックの座標を白い立方体の中心の座標に加算して、赤と白のエッジの座標を取得します。
コーナーブロック座標復元検出:
たとえば、赤、白、緑のエッジを検出するには、赤い立方体の中心ブロックの座標を白い立方体の中心の座標と緑の立方体の中心の座標に加算して、次の座標を取得します。赤、白、緑のエッジ。
エッジブロック、コーナーブロック回転角度減少検出:
エッジブロックまたはコーナーブロックの回転角度が、一番中央のルービックキューブの回転角度と同じであれば復元されます。
上記の 2 つのテストに合格すると、ルービック キューブの復元が成功したことになり、20 個のルービック キューブのリアルタイム復元をリアルタイムで検出できます。
2. 次に、復元されたルービック キューブの数を 4、8、12、20 に分けて判断します。さまざまな復元段階で、黄色の最上層がうまく回転するかどうかは、黄色の中央ブロックが他のブロックと同じ側にあるかどうかによって決まります。 。
ゲームの完全なコードは gitee にアップロードされています。アドレスは次のとおりです。