- Home /
Rotation of a group of cubes, Rubiks style
Hi guys,
I wonder how i can tell a group of cube to rotate (via C# script), like a Rubiks cube. The problem is that each cube should not rotate from his own "center", but exactly like it does when i select them all and use the rotation tool in the editor.
Here, i selected the row that i want to turn (exactly like a Rubik's player would). How can i tell them in C# to rotate correctly, relatively to the new center ? Thanks a lot !
Answer by ArkaneX · Feb 27, 2014 at 10:51 AM
You can create an empty game object at a row center, parent your selected cubes to this object, and then rotate parent instead of individual cubes.
This won't work btw. It's not as simple as that.
I tried to make something similar and gave up after realising it would take a lot more time than I originally planned.
You need to dynamically define your groups after every rotation.
You could do this with a 3 dimensional array and shuffle each cube around in that array.
Then you could write a method that performs the shuffle at the same time as the rotation animation.
The rotation could pull values out of the 3 dimensional array and perform its transform on those objects.
The question was about a way to rotate a group of selected cubes as a whole, not about a way of selecting them. I assume OP is able to select them then. And in this case my answer should be enough to accomplish the task.
Answer by Exalia · Feb 27, 2014 at 11:36 AM
I'll use a 2 x 2 x 2 Array as an example
8 possible locations and 8 unique cubes.
The possible locations are Binary
XYZ is the position of the cube, I is the index
XYZ (I)
000 (0)
100 (1)
010 (2)
110 (3)
001 (4)
101 (5)
011 (6)
111 (7)
If I perform a Right rotation in the clockwise direction
Every cube with an X value of 1 will be rotated clockwise.
This will shift the cubes with index 1,3,5 and 7.
(1) 100 will go up (+Y) -> 110
(3) 110 will go away (+Z) -> 111
(7) 111 will go down (-Y) -> 101
(5) 101 will go towards (-Z) -> 100
Perform this transformation on your array and you get
XYZ (I)
000 (0)
100 (5)
010 (2)
110 (1)
001 (4)
101 (7)
011 (6)
111 (3)
You can use the same method for any rotation
Right, Left, Top, Bottom, Right Inverted, Left Inverted, Top Inverted, Bottom Inverted.
If your cube is of a larger size you have the base to add more rotation methods, but I'll leave that up to you :)
As for the actual visible rotation, inside the same place you call the Array shifting method you can group the game objects that have an X value of 1. Parent them together like ArkaneX suggest to an empty game object and rotate that object.
You must then break the heirarchy if a different rotation is required.
This is just how I would do it, there may be easier ways but I hope this gets you moving in the right direction.
Goodluck!
using UnityEngine;
using System.Collections;
//Class to control rubik's cube rotation
public class RubixScript : MonoBehaviour
{
//Public Variables
public GameObject rubix;
//Private Variables
private GameObject[] cubes;
private GameObject[] face;
private GameObject rightPivot;
private int i;
// Use this for initialisation
void Start ()
{
//All cubes tagged as Cube
cubes = GameObject.FindGameObjectsWithTag("Cube");
//9 cubes per face
face = new GameObject[9];
//Call RotateRight function
RotateRight();
}
//Rotate the right face
void RotateRight()
{
//Reset Counter
i = 0;
//Create new pivot point
rightPivot = new GameObject("rightPivot");
//(2,1,1) is the center of my pivot point, this will change depending on rubiks cube size and individual cube size.
//For this example I used 1 unit per cube
//This point is also not world space relative, you would have to add the word space vector of the entire cube first.
rightPivot.transform.position = new Vector3(2,1,1);
//Set the parent of the transform to the entire cube
//This way if you rotate the entire cube the faces and the cubes inside them will follow this rotation
rightPivot.transform.parent = rubix.transform;
//Find right face cubes and set rightPivot as their parent
foreach(GameObject cube in cubes)
{
if(cube.transform.position.x == 2)
{
cube.transform.parent = rightPivot.transform;
cube.name = "Right Face Cube";
face[i] = cube;
i++;
}
}
}
//Perform rotation gradually (To prove concept)
void Update()
{
rightPivot.transform.RotateAround(rightPivot.transform.position,Vector3.right,Time.deltaTime);
}
}
Answer by Griga123 · Feb 27, 2014 at 02:51 PM
Truly amazing ! This will help a lot for the next part of the development ! Now i have to find a way to accurately find the center of an object, to define it as the pivot.
Griga is clearly new to unity answers so is likely unaware of the practices ;)
Griga if you have an answer it's best to mark the question as answered then people who have the same issue can easily find their answer and those looking to help people don't find already answered questions. :)
Also it's best to only post an Answer if you believe it is an answer otherwise leave your comments under the relevent Answer/Question.
No big deal though, plenty of people who have been using this for a long time still don't do this >.>
Oh well, my bad, i'll keep that in $$anonymous$$d ^^ Thanks for the help Exalia, and one last thing, do you know if there is an easy way to find the center of an object in the Editor (to mark it as pivot) ? THanks a lot !
gameObject.transform.position
will give you the center of the object (Assu$$anonymous$$g the origin is centered correctly to the geometry)
But I'm not sure this will help you, I'd open a new question on this, someone may know or may know a place where you can find out :)
When rotating Pivot the child object position changes according to the Pivot Parent , it is not good to rotate the face another time.
Do you have any idea how to overcome this?
I tried changing the parent after the rotation, but the position is not as expected
Your answer
![](https://koobas.hobune.stream/wayback/20220613134858im_/https://answers.unity.com/themes/thub/images/avi.jpg)