ユニティでデッドサイクルとカード死をどうやって検出しますか?


携帯電話/シミュレータでゲームが死んだらログ出力もなく、スタック情報もないし、バグもないので、イライラしますか?この記事では、私たちのプロジェクトでユニティカードの死を検出する方法を紹介します。おそらくあなたに似合うと思います。
原理を実現する
ほとんどの場合、ユニティはシングルスレッドと考えられます。これに基づいてユニティのシステム関数FixedUpdateでゲームの実行期間の総フレーム数を統計します。ユニティがカード死していないなら、Total Frameはずっと累積しています。もしある時間内にTotal Frameは変化しないなら、ユニティはもうカードが死んだと考えられます。
Unityのメインスレッドがすでにカードが死んでいる以上、もう一つのスレッドを使ってタイミングを合わせてunityのメインスレッドのTotalFrameが変化しないかどうかを確認する必要があります。
サンプルコード

using System;
using System.Threading;
using UnityEngine;

namespace KEngine
{
 /// <summary>
 ///          unity     
 /// </summary>
 public static class UnityThreadDetect
 {
  public static Thread _MainThread = System.Threading.Thread.CurrentThread;//  unity  
  private static int check_interval = 3000;//    

  public static void Start()
  {
   new Thread(CheckMainThread).Start();
  }
  
  static void CheckMainThread()
  {
   long frame = 0;
   while(!AppEngine.IsApplicationQuit)
   {
    frame = AppEngine.TotalFrame;
    Thread.Sleep(check_interval);
    if (frame == AppEngine.TotalFrame)
    {
     Log.LogToFile("unity thread dead,ThreadState:{0}",_MainThread.ThreadState);
     if (AppEngine.IsApplicationFocus)
     {
      //todo report error
     }
    }
   }
  }
 }
}
カードを捕獲して死ぬ方法名
私たちのゲームでは一般的にカードが死ぬ場合はタイマーの中にあります。私たちのタイマーはユニティのUpdateでタイマーのリストを駆動することによって、カードが死ぬと他のスレッドにタイマーで実行中の関数をプリントアウトして、カードの死の関数を特定できます。タイマーは、ユニティTimerのTimer.csを参照することができる。
同時にUnityのUpdateで複数のイベントを配布します。例えば、PreUpdate、Updateは問題が発生して、カードがそこに位置しやすくなります。
問題を例をあげて説明する
次に私たちが出会ったカード死の問題を例に挙げます。
死の循環
次のこの死はユニティではカードが死ぬが、NETではできない。NETではiがbyteの最大値255を超えるとiは0から始まる。

public static void TesBadCode()
{
	byte i = 0; 
	while (true)
	{
		i++;
	}
}
現在私達が遭遇したほとんどの状況は論理コードにwhere(true) do xxx と書かれています。その後、中にはbreakがありません。循環が永遠に下がらないことになります。
イベントシステムをブロックしました。
いくつかのシステムでUGUIのイベントシステムをブロックし、ユーザーの入力を受け入れることができなくなりました。この問題はユニティカードの死に分類されるべきではありません。
タイマーの追加を繰り返す
その理由は、下の階に同名のタイマーが制限されていないため、いくつかのロジックで誤って使用され、毎秒1つのタイマーが追加されています。タイマーの中のロジックが大きく、長い間終了しない場合、繰り返しタイマーを追加すると、ゲームの運行が遅くなります。
重複登録イベント
いくつかのインターフェースのリフレッシュ関数とコントローラ関数では、頻繁にイベントを繰り返し登録し、イベントを投げ出す際に同じ関数がN回呼び出されます。この問題はUnityのProfilerで関数の呼び出し回数がはっきりと見えます。
拡張
再帰的呼び出し
再帰的に呼び出し、Stck overflowに報告します。unityカードを死なせません。
なぜ無限再帰的に呼び出されたのですか?
これは、各方法の は限られています。超えたら、Stocoverflowに報告して、アプリケーションカードを死なせないからです。

public static void TesBadCode()
{
	while (true)
	{
		TesBadCode();
	}
}
締め括りをつける
この記事ではユニティで死のサイクルとカードの死を検出する記事について紹介していますが、ユニティの死のサイクルやカードの死の内容については以前の記事を検索したり、次の関連記事を見たりしてください。これからもよろしくお願いします。