Quest: Cloning Colors Quest
Challenge: Spawn A Random Colored Block
Feel free to share your solutions, ideas and creations below. If you get stuck, you can find some ideas here for completing this challenge.
Quest: Cloning Colors Quest
Challenge: Spawn A Random Colored Block
Feel free to share your solutions, ideas and creations below. If you get stuck, you can find some ideas here for completing this challenge.
Ok so I spent almost an entire day tring to figure the solution for this challenge, and when I did found the solution I was very happy.
I also had to change the ColorChanger class from the first challenge a bit.
So this is my solution
That’s the new ColorChanger class
using UnityEngine;
public class ColorChanger : MonoBehaviour
{
public SpriteRenderer mySpriteRenderer;
[HideInInspector] public Color color;
public colorChangeEnum colors;
void Awake()
{
mySpriteRenderer = GetComponent<SpriteRenderer>();
}
private void Start()
{
switch (colors)
{
case colorChangeEnum.red:
color = Color.red;
break;
case colorChangeEnum.blue:
color = Color.blue;
break;
case colorChangeEnum.yellow:
color = Color.yellow;
break;
}
mySpriteRenderer.color = color;
}
}
public enum colorChangeEnum
{
red, yellow, blue
}
And this is the SpawnNewBlock class. After I Instantiate the block game object I find the ColorChanger class, and then I randomize the colors for the block
Edit: I changed the SpawnNewBlock because I had a bug where if there are no active blocks and you spawn a new one, it will not be active, so I added an if statement
using UnityEngine;
public class SpawnNewBlock : MonoBehaviour
{
[SerializeField] Transform spawnPosition;
private ColorChanger colorChanger;
[SerializeField] private GameHandler gameHandler;
private BlockMovement blockMovement;
public void SpawnBlock(GameObject block)
{
block = Instantiate(block, spawnPosition.position, Quaternion.identity) as GameObject;
colorChanger = FindObjectOfType<ColorChanger>();
if(gameHandler.allPlayerBlocks.Length == 0)
{
blockMovement = FindObjectOfType<BlockMovement>();
blockMovement.isActiveBool = true;
}
block.gameObject.GetComponent<SpriteRenderer>().color = colorChanger.color;
colorChanger.colors = (colorChangeEnum)Random.Range(0, 3);
}
}
It took me some time to find out how to link all available colors to the instantiated gameObject.
Because i am using a slider, which gives me “int” but a fast way to change colors with the inspector, I had to link the int values to the corresponding colors.
We have a prefab to be instantiated and a spawnposition.
[SerializeField] GameObject blockPrefab;
[SerializeField] Transform spawnPosition;
private Color[] _colors;
The Color Changer has all available colors, we are getting them aswell.
private void Awake()
{
// get all colors, to chose from
_colors = blockPrefab.GetComponent<ColorChanger>().GetAvailableColor;
}
The new Block used our own Method to change its color
public void SpawnBlock()
{
ChangeColor();
Instantiate(blockPrefab, spawnPosition.position, Quaternion.identity);
}
Because we have an int value (used for Random), we can choose any and use it for the “setter” to change ChosenColor.
private void ChangeColor()
{
// we know the size of our available colors
var index = Random.Range(0, _colors.Length);
// the setter inside the prefab, lets us change its value
blockPrefab.GetComponent<ColorChanger>().SetChosenColor = index;
}
Reference to : ColorChanger Script
public int SetChosenColor { set => chosenColor = value; }
Another refactor and this is a big one with a lot of changes from the old code.
Every time I click on the spawn button I create a random int and it’s assigned to one of the colors in the enum
using UnityEngine;
public class SpawnNewBlock : MonoBehaviour
{
[SerializeField] GameObject blockPrefab;
[SerializeField] Transform spawnPosition;
private int randColor;
public void SpawnBlock()
{
randColor = Random.Range(0, 3);
// assigning random int that represent the enum index
blockPrefab.GetComponent<ColorChanger>().colors = (ColorSelect)randColor;
Instantiate(blockPrefab, spawnPosition.position, Quaternion.identity);
}
}
I usually change the variables of the gameobject after it has been instantiated rather than the prefab itself but I assume yours is working OK though not sure what happens if other things are using the prefab…
Instead of hardcoding 3 try using
System.Enum.GetValues(typeof(ColorSelect)).Length
which gets the number of colors in the Enum so if you add colors to the Enum you wont need to change the code.
Yep you’re correct. I acctualy changed this class after I post it and created a new gameobject before instantiate it
Quick one for me. Created a public method for assigning a random colour in ColorChanger:
public void SetRandomColour()
{
mySpriteRenderer.color = colours[Random.Range(0, 3)];
}
Then modified the spawnblock method to call it.
public void SpawnBlock()
{
GameObject newBlock = Instantiate(blockPrefab, spawnPosition.position, Quaternion.identity);
newBlock.GetComponent<ColorChanger>().SetRandomColour();
}
SpriteColors is a public enum in the ColorChanger.
In SpawnBlock:
public void SpawnBlock()
{
GameObject block = Instantiate(blockPrefab, spawnPosition.position, Quaternion.identity);
int randomColor = Random.Range(0, System.Enum.GetNames(typeof(SpriteColors)).Length);
block.GetComponent<ColorChanger>().colorSelection = (SpriteColors)randomColor;
}