Extra steps when addressing components

I am at the halfway point of the Realm Rush chapter of the 3D course and have a few questions about correctly adressing components and their properties.

Let me start with an example from Realm Rush

[SerializeField] ParticleSystem projectiles;

void Attack(bool isActive)
    {
        var shooting = projectiles.emission;
        shooting.enabled = isActive;
        
    }

Why do we have to take the extra step of introducing the variable “shooting”?
Why does “projectiles.emission.enabled = isActive” not work in the Attack Method?

I assume the reason behind this is the same but I have another example.
When building a tower in Realm rush, I would like the material of the floor tile to change, so I came up with this Method for the Tower script:

Transform parent;
Renderer ground;
[SerializeField] Material towerMaterial;

void ChangeGroundColor()
    {
        ground = parent.Find("Tile").GetComponent<Renderer>();
        ground.material = towerMaterial;
    }

This does work, but why can’t I just address the material directly with the following?

Transform parent;
Renderer ground;
[SerializeField] Material towerMaterial;
Material groundMaterial;

void ChangeGroundColor()
    {
        groundMaterial = parent.Find("Tile").GetComponent<Renderer>().material;
        groundMaterial = towerMaterial;
    }

Thank you in advance

1 Like

Hi Thilol,

Did you test that? If so, what was the result?

I’m asking because in many cases, there are multiple ways to make something work in Unity. Just because Ben or Rick show only one solution, that does not mean that theirs is the only valid one.

I’ll focus on the second case first.

Both solutions are good solutions and you can even make that solution shorter, something like this:

parent.Find("Tile").GetComponent<Renderer>().material = towerMaterial;

So, Which one to pick? Well, it all comes down to two things: code readability, and efficiency.

The third example, where you create a variable outside the method is not worth unless you are going to use that particular variable in other methods, if that’s not the case, then just put in inside the methods, no need for an instance variable.

Now, you end up with 2 other solutions; the one I gave you and the second you showed, yours is actually better because is far more readable than mine, is all about that at the end but don’t worry too much about that, with practice this type of things will become second nature.

Why does “projectiles.emission.enabled = isActive” not work in the Attack Method?

Some components in Unity require you to create an instance, modify the instance and then apply the modifications, one example of this is the transform component, try modifying the scale’s X value only of any transform in code, it won’t work, Unity does not allow that, Why? To be truly honest I’m not sure, that’s just how certain parts of certain components work.

Thank you for your answers so far.

Yes I tried the both options for the particle effects.
“projectiles.emission.enabled = isActive” leads to the following error message
Cannot modify the return value of 'ParticleSystem.emission' because it is not a variable

And about the ground materials:

That was a carried over from my code because I want to reverse the color change when I remove the tower.
The actual question for that snippet of code was “Why does the color of the ground tile not change?”
but I think I found the answer myself:

Material groundMaterial = parent.Find("Tile").GetComponent<Renderer>().material;

stores just the type of material and not which component that particular instance of material is attached to.
Did I understand that correctly?

1 Like

Exactly, you are just storing the material, to change the material you would need to store a reference to the Renderer component.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms