Rubik's cube game (with game open source code)

The early implementation of this Rubik's Cube game referred to many tutorials, but all the code logic was written by myself (the original post link will be given for reference), and only the idea of ​​​​the implementation is discussed.

completed:

The rotation of the Rubik's Cube and the animation effect of the Rubik's Cube support all the cfop formulas of the Rubik's Cube, and the Rubik's Cube can be rotated by pressing the button

Press the alt key on the keyboard to move the mouse to observe the Rubik's Cube in 360 degrees without dead ends

The center block of the Rubik's Cube has a rotation prompt, which prompts whether the Rubik's Cube needs to rotate clockwise or counterclockwise. Double-click the rotation prompt to quickly set it to the F side

The Rubik's Cube rotates clockwise by default. Press the ctrl key on the keyboard to switch the Rubik's Cube's rotation type and prompt type to counterclockwise rotation.

The first build is disrupted, the Rubik's cube state is saved and restored, and the detection of the Rubik's cube restoration has been supported. It is divided into the Rubik's cube has been restored, the white bottom two layers and the yellow top layer have been turned over (there are 5 similar types), and the white bottom two layers ( Similar to 5 types), white bottom cross (similar to 5 types)

Rubik's cube cfop formula detection and restoration algorithm has been completed (original), and the realization of Enlu has been completed. For details, please see: (14 messages) Rubik's cube CFOP formula matching algorithm_qq_39858654's blog-CSDN blog

Test chart:

The idea of ​​turning the Rubik's Cube game originally came from a video at station b: Can Meng Xinxue Unity make a Rubik's Cube?

Provided me with a good idea. What I want to do is a third-order Rubik's cube. The rotation of the Rubik's cube is the biggest problem. The big guy's idea in the video is:

1. First place 27 cubes to form a Rubik's Cube, and then use 6 thin cubes as the controllers of the Rubik's Cube, which are placed on the six sides of the Rubik's Cube, and each Rubik's Cube controller touches 9 cubes.

2. When a certain surface of the Rubik's Cube is about to rotate, it is equivalent to selecting a certain Rubik's Cube controller, and then the selected Rubik's Cube controller detects the object that touches itself, turns it into its own sub-object, and controls If the device is rotated again, the rotation of a certain face of the Rubik's Cube is completed.

3. If a Rubik’s Cube controller is selected, then the remaining 5 Rubik’s Cube controllers cannot have sub-objects. If there are, the previous sub-objects must be released, so as to avoid the incomplete cube surface obtained by the formed Rubik’s Cube controller. .

Although this idea is feasible, it has a big disadvantage. It can only rotate a certain face of the Rubik's cube. When I want to rotate (E, M, S) in the middle of the Rubik's cube, it can't do it. This involves To the judgment mechanism of unity touch:

When the A object and the B object touch each other, if the C object touches the A object, unity will think that the C object touches the A object and the B object.

To use a more appropriate analogy, if two people get an electric shock, you will get an electric shock no matter which one you touch.

If I use the above-mentioned ideas to perform any intermediate rotation of E, M, and S on the Rubik's Cube, what is rotated is the entire Rubik's Cube, not the middle block!

So if we want the Rubik's Cube formed by 27 small squares to be able to rotate at will, the first problem to be solved is: how to generate a controller?

The way I came up with is to use three-dimensional coordinates to judge. Facts have proved that this method is very effective. I feel that it can be used not only for the third level, but also for the controller judgment of the Rubik’s Cube games such as the fourth and fifth levels.

First, I put the axis of the third-order Rubik's Cube at (0, 0, 0), and white is the bottom surface, and I will find such a rule:

(a,a,-1)F         (1,a,a)R        (a,1,a)U

(a,a,1)B          (-1,a,a)L        (a,-1,a)D

If you want to judge the squares on the F surface, you only need to let the 27 squares respectively judge whether the z-axis of the three-dimensional coordinates is equal to -1, and you get 9 qualified squares.

(a,0,a) E        (0,a,a) M        (a,0,a) S

If you want to judge the squares on the E surface, you only need to let the 27 squares respectively judge whether the y-axis of the three-dimensional coordinates is equal to 0, and you get 9 middle squares that meet the conditions.

f=S(condition)+F(condition) r=M(condition)+R(condition) u=E(condition)+U(condition)

b=S(condition)+ B(condition) l=M(condition)+L(condition) d=E(condition)+D(condition)

If you want to judge the squares on the f plane, you only need to let 27 squares respectively judge whether the y-axis of the three-dimensional coordinates is equal to 0 or whether the z-axis is equal to -1, and you get 18 qualified squares.

After the implementation, I found a small problem, that is, there will be a small error in the coordinates of the Rubik's Cube after rotation, it will not be just equal to 1 or 0, it may be 1.001 or 0.0082, etc., so use Mathf.Round() to check the error before judging Only by removing can the correct number of cubes be obtained, otherwise the Rubik's Cube will lose cubes if it turns around.

Rubik's cube rotation is the core part of the whole game, and the steps to realize it are:

1. For the creation of 27 Rubik's Cubes, the main reference is: Unity Tutorial | Teach you to spell a 3D "Rubik's Cube" step by step , and only a model is generated and cannot be moved.

2. 12 Rubik's cube controllers are created, with 6 surface controllers and 6 central block controllers, used to control 27 cubes.

3. 18 buttons are defined and initialized with a script. The main reference is: Unity: Use an array to manage multiple Buttons

4. Realization of Rubik's cube rotation animation:

  1. The Rubik’s Cube animation realized by quaternion interpolation avoids the problem of universal lock, but the quaternion rotation is gone only once, so it is necessary to save the rotation value and maintain the continuity of the angle, which is a perfect solution The method is the angle superposition method (my original).

Angle superposition method: first define an initial direction of rotation, add 90 when turning clockwise, subtract 90 when turning counterclockwise, and limit the angle between -360 degrees and 360 degrees. You can understand the principle of rotation in this way and record the last time Angle, turn clockwise and add 90 to get the target value of clockwise rotation, and subtract 90 from counterclockwise to get the target value of counterclockwise rotation.

2. The values ​​of the Rubik's Cube controllers cannot affect each other. After my exploration, the animations of the 12 Rubik's Cube controllers just happen to be unaffected by each other.

3. The Rubik's Cube rotation animation must be completed on time and ensure that it is in place. Using coroutines can solve this problem very well.

The magic cube animation effect code is:

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;
    }

The method of calling the animation coroutine:

StartCoroutine(RotateOverTime(mofanControlList[mofanConNum].transform,Quaternion.Euler(mofan_rotate * n1), 0.3f));

Freely observe Rubik's Cube implementation:

A script is tied to the main camera to let the camera rotate around the Rubik's Cube to achieve a random observation effect, but this also leads to a problem, using buttons to control each face of the Rubik's Cube, but it is hard to tell which face is from which face , so I added a Rubik's Cube rotation indicator on the center block of the Rubik's Cube.

Rubik's Cube State Saving and Restoration:

Two Vector3s are defined with the structure, which are used to save the coordinates and Euler angles of 27 Rubik's cubes. After saving the corresponding coordinates and Euler angles of the Rubik's cube, the state of the Rubik's cube can be saved. Later, the coordinates of the Rubik's cube are found And the Euler angle can reverse the color of the Rubik's Cube, see specifically: Rubik's Cube State Detection 2_qq_39858654's Blog-CSDN Blog

I listed 480 records and found it in about a week.

Detection of Rubik's cube reduction:

1. First judge whether the 27 Rubik's Cubes are restored:

When it is necessary to detect whether a Rubik's Cube is restored, it is to detect whether the coordinates and rotation angle of the Rubik's Cube are correct.

Edge block coordinate restoration detection:

For example: to detect red and white edges, you can add the coordinates of the central block of the red cube to the coordinates of the center of the white cube to obtain the coordinates of the red and white edges.

Corner block coordinate restoration detection:

For example: to detect red, white and green edges, you can add the coordinates of the central block of the red cube to the coordinates of the center of the white cube and the coordinates of the center of the green cube to obtain the coordinates of the red, white, and green edges.

Edge block, corner block rotation angle reduction detection:

As long as the rotation angle of the edge block or corner block is the same as the rotation angle of the most central Rubik's cube, it is restored.

When the above two tests pass, it means that a Rubik's Cube has been restored successfully, so that the real-time restoration of 20 Rubik's Cubes can be detected in real time.
 

2. Then judge the number of Rubik’s Cubes restored, divided into 4, 8, 12, and 20. For different restoration stages, whether the yellow top layer is successfully turned depends on whether the yellow center block is on the same side as other blocks.

The complete code of the game has been uploaded on gitee, the address is:

Smart Rubik's Cube

Guess you like

Origin blog.csdn.net/qq_39858654/article/details/124038491