Rotating a Transform around another Transform on the X, Y, and Z Axis

I’ve been playing with Unity 5 for about a two weeks now and I’m starting to get the hang of it. The one thing I don’t have a complete understanding of is rotation outside using Euler angles.

So what I built is a way to fracture a cube into many tiny cubes of the same relative scale. I am trying to make the transition between one cube to many as seamless and possible. Here is the code I have.

public class Destructor : MonoBehaviour {
	
	/// <summary>
	/// Creates the same number of cuts on each axis.
	/// </summary>
	/// <returns>The fratured cubes.</returns>
	/// <param name="cube">Cube that will be fractured</param>
	/// <param name="velocity">The speed which the fractures are moving.</param>
	/// <param name="cuts">The amount of fractures per axis there will be.</param>
	public static GameObject[] Fracture(GameObject cube, Vector3 velocity, int cuts){
		GameObject[] fracts = new GameObject[cuts * cuts * cuts];

		// Get parent information
		Rigidbody parent = cube.GetComponent<Rigidbody> ();
		Vector3 scale = cube.transform.localScale;

		// Get information used by all fractures.
		Vector3 fScale = new Vector3 (scale.x / cuts, scale.y / cuts, scale.z / cuts);
		Vector3 shift = new Vector3 ((fScale.x - scale.x) / 2 , (fScale.y - scale.y) / 2, (fScale.z - scale.z) / 2);
		Vector3 angle = cube.transform.eulerAngles;

		// Create  and configure base
		GameObject baseFracture = GameObject.CreatePrimitive (PrimitiveType.Cube);
		baseFracture.transform.localScale = fScale;
		baseFracture.transform.position = cube.transform.position + shift;
		baseFracture.GetComponent<Renderer> ().material = cube.GetComponent<Renderer> ().material;
		baseFracture.GetComponent<BoxCollider> ().material = cube.GetComponent <BoxCollider> ().material;

		// Configure physics.
		Rigidbody body = baseFracture.AddComponent<Rigidbody> ();
		body.mass = parent.mass / fracts.Length;

		int i = 0;
		for (int x = 0; x < cuts; x++) {
			for(int y = 0; y < cuts; y++){
				for(int z = 0; z < cuts; z++){
					// Create fracture and move it to the right position.
					GameObject obj = Instantiate(baseFracture);
					obj.transform.position += new Vector3(fScale.x * x, fScale.y * y, fScale.z * z);

					// Rotate
					obj.transform.RotateAround(cube.transform.position, Vector3.right, angle.x);
					obj.transform.RotateAround(cube.transform.position, Vector3.up, angle.y);
					obj.transform.RotateAround(cube.transform.position, Vector3.forward, angle.z);

					// Apply physics
					obj.GetComponent<Rigidbody> ().velocity = velocity;

					// Add it to the array
					fracts[i++] = obj;
				}
			}
		}

		// Destroy the base and the initial cube.
		Destroy (baseFracture);
		Destroy (cube);

		// Give back all the fractures.
		return fracts;
	}

}

If you need any comprehension, let me know. So my problem is these lines of code here.

obj.transform.RotateAround(cube.transform.position, Vector3.right, angle.x);
obj.transform.RotateAround(cube.transform.position, Vector3.up, angle.y);
obj.transform.RotateAround(cube.transform.position, Vector3.forward, angle.z);

I expected them to rotate all the fragments around the center to look like the original, which it does until I start combining rotations. Such as having the Y at 45 degrees and the Z at 45 degrees for some reason rotates the X at 45 degrees. I could test all the possibilities and see what happens then offset the axis which are wrong, but I feel like there is a better way to go about this.

Any help would be greatly appreciated :slight_smile:

Update
I almost have a solution. I changed the Z axis from Vector.forward to

new Vector3 (Mathf.Sin (Mathf.Deg2Rad * angle.y), -Mathf.Sin (Mathf.Deg2Rad * angle.x), Mathf.Cos (Mathf.Deg2Rad * angle.x) * Mathf.Cos (Mathf.Deg2Rad * angle.y));

This works great when doing two axis at once, like XZ and YZ. But when combining all X, Y and Z rotation it moves slightly. So either I have a completely wrong solution or a math error :).

If you just want the rotation of the fragments to match the rotation of the original cube, replace those three lines with:

obj.transform.rotation = cube.transform.rotation;