About 'Count Breakable Blocks'!

In this video (objectives)…

  1. Map out our workflow for determining how many blocks are in a scene so that we can know when we reach zero.

  2. Create level GameObject and script.

  3. Increment our number of blocks for each block in our scene.

  4. Introduction to FindObjectOfType.

After watching (learning outcomes)… Tally up the total number of blocks in our scene.

(Unique Video Reference: 21_BR_CUD)

We would love to know…

  • What you found good about this lecture?
  • What we could do better?

Remember that you can reply to this topic, or create a new topic. The easiest way to create a new topic is to follow the link in Resources. That way the topic will…

  • Be in the correct forum (for the course).
  • Be in the right sub-forum (for the section)
  • Have the correct lecture tag.

Enjoy your stay in our thriving community!

Hello Rick,

thank you for the lesson so far, learned alot!

There is one maybe dumb question about this lecture. I get all the findObjectType stuff.
But how does Unity actually know, how many blocks there are? You just create a new level and put in the variable “int breakableBlocks” and suddenly it automaticly stores, how many blocks there are inside the level? Or does it have something to do with the breakableBlocks++?

Would love to become some wiser!

Greetings,

Henry

Hi Henry,

I’m not exactly sure where I explain this in the course, but I realised that your exact question was something I’d be wondering and I think in the very next video, at the start of the video, I explain it.

Here’s a summary:
Each block in our scene has a script on it. Each of those scripts is executed when we start the game. So if you have 20 block, there will be 20 instances of the script that run. Each script says “hey, I’m here, count me!”… so there are 20 things saying “hey count me” and we then have one variable which stores the value each time one of the scripts says to count them.

2 Likes

Thank you! Got it, makes sense. Each time one script finds the Gameobject Level, it is aible to use CountBreakableBlocks(). And with each time it is used, we get ++ to our variable. And because every block has the same Block.cs, we get the number of blocks.

Thank you for explaining, have a nice day!

Henry

2 Likes

Got it!

1 Like

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”.

1 Like

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!

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.

1 Like

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.