- Home /
Double TryGetComponent gives an intellisense error
Using this code with Visual Studio 2019 gives an error
// rib gives the error
if (go.TryGetComponent(out Collider col) || go.TryGetComponent(out Rigidbody rib))
{
if (col != null)
{
co = col;
}
if (rib != null)
{
rb = rib;
}
}
// But if you try this "col" gives the error
if (go.TryGetComponent(out Rigidbody rib) || go.TryGetComponent(out Collider col))
{
if (col != null)
{
co = col;
}
if (rib != null)
{
rb = rib;
}
}
Is this correct as you can't use double TryGetComponent
within the same If statement, or is this a bug?
Answer by Bunny83 · Sep 20, 2021 at 08:17 AM
While you can do what Captain Pinapple suggested, Why do you actually check both TryGetComponent in a single if statement with an "or", just to test the result of both individually again? This is completely redundant. Just do
if (go.TryGetComponent(out Collider col))
co = col;
if(go.TryGetComponent(out Rigidbody rb))
{
// do whatever you want with rb
}
Note: You have marked your Collider variable "co" with SerializeField, so this value is serialized and can be assigned in the inspector. However using TryGetComponent will always override what may have been serialized in that variable if the gameobject "go" has a Collider. So this whole bit of code looks confusing. If you want to set the collider through code, why serialize the field? If you want to implement some sort of fallback and only use TryGetComponent when you did not assign a collider in the inspector, you should do something like
if (co != null || go.TryGetComponent(out co))
{
// do something with the collider co.
}
This first checks if the collider was assigned in the inspector and only if it was not assigned, it tries to get the collider from the gameobject "go". If that fails as well, the code in the if body will not execute since we don't have a Collider.
ps: Another way to use the original code would be to use the arithmetic / bitwise "or" and not the logic "or". So yo ucan do
if (go.TryGetComponent(out Collider col) | go.TryGetComponent(out Rigidbody rb))
{
// [ ... ]
However this would be horrible code ^^. The bitwise "or" always evaluates both operand and then simply combines both values with the operation "or". So both TryGetComponent will be always executed.
The original code uses the logic "or" ||
. It will shortcut when the logical outcome is already deter$$anonymous$$ed. In your case when the first TryGetComponent returns true, the compiler would simply stop evaluating the rest of your condition, because the first operand is already true so the outcome of the second operand is irrelevant for the outcome of the condition. Of course you are interested in the side-effects of the second TryGetComponent which of course won't take place when the first condition is already true.
So I highly recommend to rethink about what you actually want to do and if you need both, the rigidbody and the collider or really just one of them. Though as I said in the answer, if you need just one of them you should seperate the code.
As always nicely done.. I guess i sometimes should spend more time on thinking about the "why" before offering a workaround ;)
@Bunny83 Thank you for the informative reply! I was really just seeing if you could use two TryGetComponent in the same IF statement for a simple script that can be run on different GameObjects, but only if they have one of two certain component types.
Answer by Captain_Pineapple · Sep 20, 2021 at 07:58 AM
This is not a bug.
The error tells you everything in the shortest way possible what is going on: You try to use a variable which is not assigned.
Change this to
Rigidbody rb = null;
if( ..... || go.TryGetComponent(out rb))
and it will work. You might have to do the same for col
as well.