[ C# ] Randomly rotating square blocks from an array of 90 degree increments.

Heya forumites,

I’m trying to script a bunch of square blocks to instantiate at a random rotation along the y-axis, only at 90 degree increments (so that no matter which rotation value the blocks adopt, they still line up next to each other). When instantiating these blocks, my script draws a random value from an array of 4 values (in degrees): 90, -90, 180, -180, and applies the value to transform.rotation.y.

Here’s the script for reference:

public class BlockSpawn : MonoBehaviour 
{

	public GameObject[] blockPrefab;
	public GameObject blockTemplate; // This is just a visual mesh used so that I can see the object in the editor
	public float[] rotationAngle;
	
	// Use this for initialization
	void Awake () 
	{
		Destroy(blockTemplate); // Destroying the visual reference mesh prior to instantiating square blocks.
		
		// Rotate the BlockSpawner at a random 90 degree angle, before instantiating block.
		Quaternion rotation = transform.rotation;
		rotation.y = Random.Range(0, rotationAngle.Length);
		transform.rotation = rotation;
		
                // Instantiate a random block prefab from a list, inheriting the rotation of the BlockSpawner.
		GameObject block = blockPrefab[Random.Range(1, blockPrefab.Length)];
		Instantiate(block, transform.position, transform.rotation);
	}
}

The problem: Some blocks end up instantiating at a 45 degree angle instead (ie. they end up diagonal and clipping into their square neighbour). It’s as if the engine is trying to rotate the block a full 90 degree increment, but stops at the halfway mark.

The weird thing is, if I reduce the array in the inspector to 2 possible angles (eg. 90, -90), the blocks spawn at the correct angles. However, increasing the array size to 3 possible angles and some blocks end up spawning diagonally (even if the array is, say, 90, 90, 90 ie. all identical angles).

In a nutshell, increasing the array size of possible values above 2 will result in the blocks not rotating fully prior to instantiation.

Anyone have any idea what might be going on here? Possible fixes/workarounds would be much appreciated!

I guess you need to change the value of eulerAngles, not the rotation value. eulerAnges goes from 0 to 360, rotation from 0 to 1. E.g: eulerAngles.y = Random.Range(0, rotationAngle.Length);

Pardon my coding noobness, but isn’t an eulerAngle a Vector3 value? I wouldn’t be able to pass this into an Instantiate’s rotation argument, as this requires a Quaternion?

ie. Instantiate(object, Vector3, Quaternion);

Also, I don’t quite get the concept of rotation only taking values from 0 to 1 - I assumed that setting transform.rotation.y = 90 would just pass the value of 90 to the object’s y rotation. This seems to be the observed behaviour if I leave my rotationAngle[ ] array size to 2. Or am I conceptually wrong about this behaviour?

Yes, a Vector3 value. But you dont need to assign a value to Instantiate. Use MyObjectType my_obj = Instantiate(object) as MyObjectTyp and then setup the transform values after that with my_obj.transform.eulerAngles = new Vector3(90, 0, 0)…e.g.

The rotation values you see in the editor are eulerAngles and represent the rotation in degree. The rotation value represent the rotation in another format…I’m not sure what that is.

Ah, yes, thank you AxelF - I see where my error in thinking was. Thanks for explaining eulerAngles vs. rotation; I’ll remember to use eulerAngles in the future instead.

Fixed my issue - there were two errors in the original script:

  1. eulerAngles fixed the core issue of the blocks rotating at weird angles.

  2. Blocks weren’t necessarily instantiating at random angles as I hadn’t assigned the random numbers to rotationAngle correctly.

Thanks again for pointing me in the right direction AxelF! :smile: