V3188. Unity Engine. The value of an expression is a potentially destroyed Unity object or null. Member invocation on this value may lead to an exception.
The analyzer detected dereference of a potentially destroyed or 'null' object. This may cause an exception to be thrown.
Look at the following example:
GameObject _obj;
bool _objDestructionCondition;
public void Foo()
{
if (_objDestructionCondition)
{
Destroy(_obj);
}
....
var position = _obj.transform.position;
....
}
Here, '_obj' is destroyed if '_objDestructionCondition' is 'true'. In this case, the subsequent '_obj.transform.position' property call will cause an exception to be thrown.
You can avoid this error by adding the 'return' operator at the end of the conditional expression block:
if (_objDestructionCondition)
{
Destroy(_obj);
return;
}
Another option is to add the '_obj != null' check before using the object:
if (_obj != null)
{
var position = _obj.transform.position;
}
Look at another example:
Projectile _projectile;
....
public void UpdateAction()
{
if (HasActionExecutionTimeEnded())
{
....
UnityEngine.Object.Destroy(_projectile);
}
....
UpdateProjectileState(_projectile); // <=
}
public void UpdateProjectileState(Projectile projectile)
{
....
projectile.transform.position = ....; // <=
}
If the 'HasActionExecutionTimeEnded()' returns 'true', the '_projectile' object is destroyed via the 'UnityEngine.Object.Destroy' method. In this case, the subsequent use of '_projectile' within the 'UpdateProjectileState' method may lead to an exception.
As in the previous example, you can fix this issue in 2 ways.
1. Add the 'return' operator after 'UnityEngine.Object.Destroy':
if (HasActionExecutionTimeEnded())
{
UnityEngine.Object.Destroy(_projectile);
return;
}
2. Implement the '_projectile != null' check:
if (_projectile != null)
{
UpdateProjectileState(_projectile)
}