How to rotate columns of a Rubik's cube?

Hi! I’m working on my master’s project which is about a rubik’s cube. I’m pretty new to unity and c#, I’ve been studying it since January and I’m facing some problems with the structure of the movements. I’ve find some ideas on other questions but they are not so clear since I’m a newbie. At the moment I’ve created my cube (I’ve got all my little cubes as children to an empty object set as parent). I would like each columns and rows to rotate on click but at the moment I’ve just managed to rotate a face setting an empty object as a rotation center of that face and making it parent of the 9 cubes forming it (inside the cube parent). This was just a test and I know it’s not the right way. So, I was wondering what it would be the most rightful way to write the script in order to rotate columns and rows.

This is what I’ve done up to now.

sing System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CubeRotation : MonoBehaviour {

public GameObject rotationFaceA;
private float speed = 2f;

// Use this for initialization
void Start () {
	
}

// Update is called once per frame
void Update () {

    rotationFaceA.transform.Rotate(0, 0, 1+90 * speed);
}

}

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

I think the best way is to create EmptyObjects as pivots, and then make parent and unparent each cube to the correct pivot for each movement.