About 'Count Breakable Blocks'!

Got it!

2 Likes

Hi there Rick,

Thank you for this course. It’s awesome!
I just have a question. Why did we use “FindObjectOfType” instead of just linking the Level and Block prefab objects (like we have been doing it from the beginning) in the unity interface and then applying the change so that it will be applied to all blocks? When do we do one or the other? Or does this simply depend on the preference of the developer?

Hi Steven,

If this is the bit of code I suspect it is, e.g. the code that gets all the GameObjects of type Block, it’s because you use this for the count of the blocks in the scene. If you did this the other way, you would need to drag all of those blocks in to the Inspector. Admittedly, you could create an array and then drag/drop the lot in, but the FindObjectOfType method takes the sting out of that a bit.

Be aware though, any of the Find methods do have a cost, so you want to use these as infrequently as possible from a performance perspective, the same is true of GetComponent, but less so, as you are only iterating over the one GameObject, where-as Find iterates over every GameObject in the scene.

On the off chance I am wrong about the specific case I think you are referring to, you can always copy/paste your script in and I will be happy to take a look.


See also;

1 Like

Got it. Thank you very much for the explanation Rob. Have a great day!

1 Like

Hi Steven,

You’re more than welcome :slight_smile:

8 posts were split to a new topic: What exactly is the type of an object?

When I tried the challenge before watching the full video, I found the Awake() method. Reading it, it sounds like Awake would be a better method to instantiate finding the object, before finding the blocks. so in my Block.cs I did this:


    // Cached reference
    Level level;

    private void Awake()
    {
        level = FindObjectOfType<Level>();
    }

    public void Start()
    {
        level.CountBreakableBlocks();
    }

Here are the reference URLs:
https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html

https://docs.unity3d.com/ScriptReference/MonoBehaviour.Start.html

I found the concept very confusing at first until I read the Q&A. Couldn’t understand how the code we entered referenced the blocks and ended with an accurate count. The explanation in Q&A pointed out the counting function call in Start() in the Blocks.cs script, which runs once for each block. Rick may have explained this and I just missed it.

Here is my working code attempt at the challenge to find the total number of blocks…

private GameObject blocksParent;

public void CountBlocks()
{
    blocksParent = GameObject.Find("Blocks");
    remainingBlocks = blocksParent.transform.childCount;
    Debug.Log(remainingBlocks);
}

Could have serialized the “Blocks” string, which is the empty object we made to parent all our blocks. Only found what I needed to write that thanks to a little practice looking up code as Rick has been teaching us. Loving the videos so far!

EDIT: Rick clarified the issue in the next video. At least I wasn’t the only one baffled!

6 posts were split to a new topic: Why aren’t my blocks being counted in the Level game object?

Hi Rick, this course is awesome and I can tell I’ve already learned a lot!

I decided to take on the “mega challenge” before watching the rest of this lesson, and I came up with this, and it works. Then I watched your lesson and, of course, it’s way different than what I came up with. Is this a typical case of “many roads leading to the same place”, or is this way I came up with an illusory solution (maybe you could tell me why not use what I came up with)?

thanks!

Here it is:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Level : MonoBehaviour {

// Use this for initialization
void Start () {
    GameObject go = GameObject.Find("Blocks");
    //Debug.Log(go.name + " has " + go.transform.childCount + " children");
}

// Update is called once per frame
void Update () {
    GameObject go = GameObject.Find("Blocks");
   // Debug.Log(go.name + " has " + go.transform.childCount + " children");

    if (go.transform.childCount == 0) {

       // Debug.Log("You won!");
        SceneManager.LoadScene("Start Menu", LoadSceneMode.Single);

   }
}

}

I’m a big believer in “if it works, and its easy to understand, then run with it and refactor it later if necessary”.

2 Likes

Thanks!

I’m getting a weird “zombie block” in my count. My count is always 1 higher than the number of blocks in my scene… I’ve countered it by running “breakableBlocks–” in Start() of the Level script, but that’s kind of a hacky approach. I’m going to keep punching at it myself, but if anyone else encountered this and figured it out please let me know!

1 Like

Hi @mpbMKE,

That sounds really strange. What is the initial value of your breakableBlocks variable? 0? If so, add a Debug.Log to the Start method of your Block script. For example:

Debug.Log("Block script attached to: " + gameObject.name + " " + GetInstanceID(), gameObject);

If the returned names do not help, check if there appears the same instance id twice. If it does, click on the message once. The concerning game object should get highlighted in your Console.

2 Likes

Bingo! I must have mistakenly attached it to my GameCanvas prefab like a dope. :joy:

Thanks!

So I did what was shown initially and put CountBreakableBlocks in the level manager script, now though I decided to put in the Block script itself because I figured Things that do with the Block should stay in the Block script. However after doing that my CountBreakableBlocks only runs once why is that? I thought each Block gameobject has its own script and they all run separately at the same time.

With that in mind shouldn’t I be getting the same count as i did when it was in the level manager script.

EDIT: I’m trying to limit how much I use find object of type, because it seems like every script I have is referencing eachother.

1 Like

bump, still curious as to why putting count breakable blocks in the block script itself doesnt work.

If you declared a blockCount variable in the Block class, the variable belongs to the instance. If you have 20 Block instances, you also have 20 different blockCount variables. This is the only explanation that comes to my mind without knowing anything about your project.

Ok that makes sense, so rather then having one variable that = 20 when we have it in the level manage script I get 20 variables that = 1.

1 Like

Exactly. :slight_smile:

Privacy & Terms