0
\$\begingroup\$

I found some code I needed online, but I want to understand how it works.

Renderer c = (Renderer)b; What is this (Renderer)b action called so I can Google about it?

It looks like it's trying to get a Renderer instance from b, but isn't b a Component of type Renderer already? Or is this because Renderer is a subclass of Component?

void SetTargetInvisible(GameObject Target)
{
    Component[] a = Target.GetComponentsInChildren(typeof(Renderer));
    foreach (Component b in a)
    {
        Renderer c = (Renderer)b;
        c.enabled = false;
    }
}

Code is from https://forum.unity.com/threads/how-to-make-all-children-invisible.27259/

Thanks for taking the time!

\$\endgroup\$
4
\$\begingroup\$

This is a feature of the C# programming language called an explicit cast.

When you have a reference of a type of a base class or interface, but you are sure that the object it points to is of a certain more specific sub-class, then you can use it to convert that reference to a reference of the more specific class.

In this particular example, a Renderer is a sub-class of Component. Every Renderer is a Component but not every Component is a Renderer. So when you have a reference of type Component, then you can only use those methods and properties which all components have in common. The component might actually be a renderer, but the C# compiler can't be 100% sure about that just from this sourcecode. So it won't let you use any methods or properties of that object which are part of the Renderer class.

However, in this particular case you as the programmer can be pretty sure that this Component b is not any component but a Renderer. After all, you acquired it through the method GetComponentsInChildren(typeof(Renderer)). So you can actually "promote" that reference from Component to Renderer by writing (Renderer)b. But should you be wrong about that and due to some bug in your code b is actually a different component, then this operation will throw an InvalidCastException at runtime.


But, as Nikaas pointed out, this code example is very outdated. It's from over 10 years ago. In more modern versions of Unity you would use GetComponentsInChildren<Renderer>() instead, because that way you get the result set already cast into Renderers and not as Components.

Unity changed a lot in the past couple years. But unfortunately, information from the early years is still abundant around the Internet. So when you want to learn Unity you are well-advised to look at the publication dates of what you are reading/viewing/hearing and take any advise older than a couple years with a grain of salt.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You explained type cast very well, really appreciate your help! I read the doc too and I understand what's happening in the code now. I just wasn't sure how google search that part of the code. I will pay attention to the publication dates from now on :) \$\endgroup\$ – rickyc Sep 3 at 18:07
3
\$\begingroup\$

Renderer is a subclass of Component. So (Renderer)b casts current Component to Renderer.

GetComponentsInChildren(Type type) (that returns Component[]) was used before its generic counterpart GetComponentsInChildren<T>() (that returns T[]) was added to Unity.

In today's Unity this code can be simplified to:

void SetTargetInvisible(GameObject Target)
{
    Renderer[] renderers = Target.GetComponentsInChildren<Renderer>();
    foreach (Renderer aRenderer in renderers)
    {
        aRenderer.enabled = false;
    }
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks so much Nikaas, for your explanation and your simplifying of the code! \$\endgroup\$ – rickyc Sep 3 at 17:57

Not the answer you're looking for? Browse other questions tagged or ask your own question.