You have to think about two things at the same time. First when you rotate any layer / face two things happen:
- First of all each of the 9 sub-cubes in a layer / face get rotated 90°. So their orientation changes as well as their physcal location within the 3x3x3 cube
- Second the logical positions of those 9 sub cubes change as well so the composition of the orthogonal layers change.
Usually it’s the easiest approach to organise the 27 (26 + center) cubes in an array in a logical manner. Then you basically have 18 different rotations a user can perform (3 cardinal directions x 3 layers in each direction x 2 rotation directions). If you don’t want to write out the “swapping logic” for all 18 cases, just do the 9 cases. The opposite rotation direction is just 3x the other way.
Another way would be to define an indexer (getter / setter) for each layer and just apply the same rotation algorithm to a selected layer. This would also simplifying the rotation part as it would be easier to collect all cubes that need to be rotated.
I would recommend to just use a flattended array with 27 elements. So for example element 0-8 are the bottom layer, 9-17 is the middle layer and 18-26 is the top layer. (0,1,2) (9,10,11) (18,19,20) would be the front face while (6,7,8) (15,16,17) (24,25,26) would be the back side face
I would probably use a struct like this
public struct CubeLayer
{
public Transform center;
public Transform c0,c1,c2,c3,c4,c5,c6,c7;
}
to represent a single layer where “center” is the center piece of that layer and c0 - c7 are the surrounding pieces in clockwise order. That way you can apply a simple rotation swapping algorithm. For example a clockwise rotation would swap like this:
c0 = source.c2;
c1 = source.c3;
c2 = source.c4;
c3 = source.c5;
c4 = source.c6;
c5 = source.c7;
c6 = source.c0;
c7 = source.c1;
All you need with that struct is a get layer and set layer method that takes in a parameter what layer you want to access. You may want to use the “official notaion”
public enum ELayer
{
F, // front face (around z axis)
R, // right face (around x axis)
U, // upper face (around y axis)
L, // left face (around x axis)
B, // back face (around z axis)
D, // down face (around y axis)
M, // middle layer around x-axis
E, // middle layer around y-axis
S // middle layer around z-axis
}
Since i was a bit bored i just implemented a rubik cube script. All you need are 27 unity default cubes as a child of an empty gameobject. Attach the script to the empty parent and Just drag all the children onto the cubes array (can be done at once when you lock the inspector ). Create a new material and use the UnlitVertexColor shader. Assign the material to all cubes and you’re done ^^
At runtime you can press one of the layer buttons (L R U D F B M E S) to rotate that face counter clockwise. Hold shift to rotate clockwise. This follows the common notation of capital letters for clockwise and lower case letters for counter clockwise rotations.
Example Image