Unityでは動作していたのに実機で動作しなくなった場合に、確認すべき箇所
unityで問題なく動作していたゲームをビルドし、実機でテストを行なった場合に動作しなくなることがありました。
その際の原因となった箇所、対処法をメモ。
原因は、foreachで回す値にnullが含まれていることでした。
例えば、以下のようにnullを含む配列をforeachで回すような状況です。
public string[] items = {"item1", null , "item3"};
foreach (var item in items)
{
Debug.Log(item);
}
解決方法1
対処法は、以下のような形です。
public string[] items = {"item1", null , "item3"};
foreach (var item in items ?? Enumerable.Empty<T>())
{
Debug.Log(item);
}
??演算子は、null合体演算子とも呼び、null値である場合には、右側の値(Enumerable.Empty<T>())を返すようです。
??演算子参考:https://docs.microsoft.com/ja-jp/previous-versions/ms173224(v=vs.120)
また、この状態だと利用しづらいため、以下のように拡張メソッドを作成することが推奨されています。
public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> collection)
{
return collection ?? Enumerable.Empty<T>();
}
利用方法としては、以下のような形です。
public string[] items = {"item1", null , "item3"};
foreach (var item in items.OrEmptyIfNull())
{
Debug.Log(item);
}
もし、以下のようなエラーが出る場合には、using宣言が必要です。
The name 'Enumerable' does not exist in the current context [Assembly-CSharp]csharp(CS0103)
using System.Linq;
解決法2
上記のような方法(解決法1)では、null値が入った場合に、その型のemptyを返すという処理でした。
しかし、nullを除去した配列を再生成する場合には、以下の方法が良さそうです。
public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T> source)
where T : class
{
if (source == null)
{
return Enumerable.Empty<T>();
}
return source.Where(x => x != null);
}
参考:https://qiita.com/shima_/items/060fd3f35ea59ecd576a
私の場合は、配列数からアニメーションを生成していたため、nullを除去する必要があり、こちらの方法をとりました。
もし、null判定が正しく行えない場合には、以下の記事が参考になると思います。