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.
Анализатор обнаружил разыменование потенциально уничтоженного или имеющего значение 'null' объекта. Это может стать причиной выбрасывания исключения.
Рассмотрим простой пример:
GameObject _obj;
bool _objDestructionCondition;
public void Foo()
{
if (_objDestructionCondition)
{
Destroy(_obj);
}
....
var position = _obj.transform.position;
....
}
Здесь '_obj' уничтожается, если '_objDestructionCondition' равно 'true'. В этом случае последующий вызов свойства '_obj.transform.position' приведёт к выбрасыванию исключения.
Избежать этой проблемы можно, добавив оператор 'return' в конце блока условного выражения:
if (_objDestructionCondition)
{
Destroy(_obj);
return;
}
Другим вариантом исправления является добавление проверки '_obj != null' перед использованием объекта:
if (_obj != null)
{
var position = _obj.transform.position;
}
Рассмотрим ещё один пример:
Projectile _projectile;
....
public void UpdateAction()
{
if (HasActionExecutionTimeEnded())
{
....
UnityEngine.Object.Destroy(_projectile);
}
....
UpdateProjectileState(_projectile); // <=
}
public void UpdateProjectileState(Projectile projectile)
{
....
projectile.transform.position = ....; // <=
}
Если проверка 'HasActionExecutionTimeEnded()' возвращает 'true', объект '_projectile' уничтожается с помощью метода 'UnityEngine.Object.Destroy'. В этом случае последующее использование '_projectile' внутри метода 'UpdateProjectileState' может привести к исключению.
Как и в предыдущем примере, решить проблему здесь можно двумя способами.
1. Добавление оператора 'return' после 'UnityEngine.Object.Destroy':
if (HasActionExecutionTimeEnded())
{
UnityEngine.Object.Destroy(_projectile);
return;
}
2. Реализация проверки '_projectile != null':
if (_projectile != null)
{
UpdateProjectileState(_projectile)
}