I’m making a simple game where you click to remove blocks and try to find the correct block to move to the next level. what I would like it to do is at the start of the game, select a random cube to assign the “redBlock” script to. I’m thinking I’m going to have to use FindWithTag.
heres what I have so far…
public Color red = Color.red;
public Renderer rend;
void Start ()
{
rend = gameObject.GetComponent<Renderer> ();
rend.material.color = red;
}
void OnMouseDown () {
Application.LoadLevel ("Scene 01");
}
@StarManta I’m getting a CS0029 error code. There are two different scripts that need to be on the block. The original “blockScript” and then one needs to have “redBlock” script added to it. would tags be better for me for this reason? I think it’s tryng to replace blockScript with redBlock and that’s not what I want as that would break my game.
Cannot implicitly convert type redBlock' to blockScript’
public Color red = Color.red;
public Renderer rend;
blockScript [] allBlocks = FindObjectsOfType<blockScript> ();
void Start ()
{
rend = gameObject.GetComponent<Renderer> ();
rend.material.color = red;
blockScript selectedBlock = allBlocks[Random.Range(0, allBlocks.Length)];
selectedBlock = gameObject.AddComponent<redBlock> ();
}
void OnMouseDown () {
Application.LoadLevel ("Scene 01");
}
You have a selectedBlock variable, which is a type of blockScript, and then you are trying to assing it to a gameObject variable which has redBlock script on it.
This will add redBlock script to that selectedBlock which has blockScript on it, also as I understand you may want to remove blockScript from the randomly selected red block candidate. So you should do this:
First of all, where should I put my script for the start of the game?
I added those two lines of code and now it just take over every single block on the screen and turns it into red. I only want 1 block for this level, and adding more blocks in later levels.
Seems like your codes are a little bit in mess. Let me clarify this for you,
You will have 3 scripts, I am naming them myself just to be an example, BlockScript.cs, RedBlockScript.cs and FinderScript.cs .
Lets be organized, now create an empty gameobject on your scene, name it “Finder” and attach FinderScript on it.
Lets clarify, when we start the game, we have for example 20 blocks on the scene, all of them has BlockScript on it, but you want one randomly selected of them to have RedBlockScript on it, and the rest 19 will still have BlockScript on them, right?
When you click the red block, it’ll perform the actions.
If these are the case, let’s continue :
Since we are not talking about BlockScript, I am skipping the contents of it, it’s up to you it seems. Now, this should be your RedBlockScript :
public Color red = Color.red;
public Renderer rend;
void Start ()
{
rend = gameObject.GetComponent<Renderer> ();
rend.material.color = red;
}
void OnMouseDown () {
Application.LoadLevel ("Scene 01");
}
Now, open up your FinderScript.cs, and write these lines into it :
using UnityEngine;
using System.Collections;
public class FinderScript : MonoBehaviour {
private BlockScript[] allBlocks = FindObjectsOfType<BlockScript>();
void Start()
{
BlockScript selectedBlock = allBlocks[Random.Range(0, allBlocks.Length)];
GameObject selectedGO = selectedBlock.gameObject;
selectedBlock.enabled = false;
selectedGO.AddComponent<RedBlockScript>();
}
}
This Finder script will look for all the BlockScript attached gameobjects, randomly select one, remove the BlockScript component on it, and then Add RedBlockScript component to it.
Following your scripts and instructions exactly I get this error code
"
UnityException: You are not allowed to call this function when declaring a variable.
Move it to the line after without a variable declaration.
If you are using C# don’t use this function in the constructor or field initializers, Instead move initialization to the Awake or Start function.
UnityEngine.Object.FindObjectsOfType[blockScript] () (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:108)
Finder…ctor ()"
public class blockScript : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void OnMouseDown () {
gameObject.SetActive (false);
}
}
public class redBlock : MonoBehaviour {
public Color red = Color.red;
public Renderer rend;
void start () {
rend = gameObject.GetComponent<Renderer> ();
rend.material.color = red;
}
void OnMouseDown () {
Application.LoadLevel (Application.loadedLevel);
}
}
We were trying to call a function on the variable which was just declared, which Unity doesn’t accept. So we will call the FindObjectsOfType function on the start to fill up the array.
Since the component is added after the game has started, it wouldn’t run the Start function which changes the color. To solve it, we added a public function and called it after the component has added.
it works! I understand why its not a problem too, we set redBlock as block and then made block = selectedGo which avoids the numbers problem. thanks! now how would I make it so that in later levels there are 2 maybe 3 red blocks?
Use the same logic, you can edit your Finder script according to the level that you are currently in, or you can write seperate Finder scripts for seperate levels. Design is up to you, but the main thing is the same, you will search for the block scripts, select one randomly, add redBlock to it, disable it’s blockScript. And then, you will search for the block scripts again( because we dont want to find the same block ) , select one randomly etc. So like:
thanks for all the help @lineupthesky now ive been playing around with the code a little trying to make it so itll select all of te objects with that script and not just one (for instance, I want every other block that isn’t red or green to be changed to a random color… I think I have my code right, but I cant get it to initiate the ChangeColor function…
public Color green = Color.green;
public Color blue = Color.blue;
public Color magenta = Color.magenta;
public Color white = Color.white;
public Color yellow = Color.yellow;
public Renderer rend;
public int color;
void Start () {
color = Random.Range (0, 4);
Debug.Log ("it's running");
if (color >= 0) {
rend.material.color = green;
}
else
if (color >= 1) {
rend.material.color = blue;
}else
if (color >= 2) {
rend.material.color = magenta;
}
else
if (color >= 3) {
rend.material.color = white;
}
else
if (color >= 4) {
rend.material.color = yellow;
}
}
you cant set one object of blockScript to an array. If you want to select all the blockScripts, you need to start a Coroutine and use for loop for that. Also, there is no ChangeColor function in your changeColor script. You need to write a public void for that and put the things inside the Start into that function.
I removed the ColorChanger function and moved it into the start function just trying to get it to work in general. no results. whenever I set the function and call it in the finder script, it says there is no definition for it. I don’t recall having to declare it in the last one though
Also, my level is just a bunch of boxes creating a bigger box. All of the cubes are under a parent empty object for organizational purposes. I tried attatching my rotator script and instead of it rotating around the axis like it does on a single cube, it rotates more like a planet does around the solar system. I assume its because of the parent object, and I use one for organization as theres a lot of cubes…