Hi there! So I’m trying to do something I feel is pretty simple, and my current code is working, but I’m mostly just curious if there is a cleaner way of writing the same logic.
Here’s the situation:
I have a class that uses raycast to interact with objects. When a game object is hit, I want to check if that game object or its child has a particular component (SomeComponent).
Then I want to access a method in that component.
So here is my code:
SomeComponent component = null;
if (raycastSystem.CurrentHitObject.GetComponent<SomeComponent >())
{
component = raycastSystem.CurrentHitObject.GetComponent<SomeComponent >();
}
else if (raycastSystem.CurrentHitObject.GetComponentInChildren<SomeComponent >())
{
component = raycastSystem.CurrentHitObject.GetComponentInChildren<SomeComponent >();
}
if (component != null)
{
component.DoStuff();
}
Like I said, this works, but I wonder if it could be cleaner. Thanks in advance!
Very close, but also remember DRY and SPOT… you have duplicate code all over the place there. Instead, try this:
var target = raycastSystem.CurrentHitObject;
// try find it on us
SomeComponent component =
target.GetComponent<SomeComponent >();
// if not, look in our children
if (!component)
{
component = target.GetComponentInChildren<SomeComponent >();
}
if (component)
{
component.DoStuff();
}
Correct, but if you actually CARED to find the one ON you first, you’d need OP’s two-stage flow.
Specifically in the case you mentioned, GetComponentInChildren would search the parent object first, as the documentation mentions it uses depth-first-search. That would only be necessary if you wanted different behavior if it was on one of the children or the parent.
I also wanted to include TryGetComponent in my original post, but did not because there was no TryGetComponentInChildren unfortunately.
Back to original post:
Something Kurt put in his post but didn’t really go over is that you can just set the value to what GetComponent or GetComponentInChildren returns instead of checking if it returns something before setting the value to it. I may be wrong, but the way you wrote the original code made it seem like you thought it wouldn’t work.
// fine to set component to this value, but the value might be null. Still need to do null check before DoStuff
SomeComponent component = target.GetComponent<SomeComponent >();