(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

既に無効になっているGameObjectに、SetActive(false)を実行した時の負荷【Unity】【最適化】


このエントリーをはてなブックマークに追加

この記事でのバージョン
Unity 2017.2.0f3


はじめに

GameObjectの有効無効を切り替える時にはSetActiveを使いますが、


f:id:kan_kikuchi:20171216165524j:plain


既に無効になっているGameObjectに対して、SetActive(false)を実行した場合に

どの程度の負荷が発生するのかって気になりませんか?

なんか気になってしまったので、調べて見ました!


ちょっと言ってる事が分かりにくいかもしれないので補足すると、以下のように

GameObjectを無効にする際に、有効の時だけ無効にした方が軽くなるのかどうかと言った感じです。

//有効の時だけ無効にする
if(gameObject.activeSelf){
  gameObject.SetActive(false);
}


なお、記事内の処理時間は以下のProcessTimerを使って測っています。





比較

では早速、比較を行っていきましょう。比較対象は3つ。

  1. 単純にSetActive(false)を実行
  2. activeSelfを確認して、trueのときだけSetActive(false)を実行
  3. 有効かどうかの変数(_isActive)を使って、trueのときだけSetActive(false)を実行


コードで表すと以下のような感じ。

//単純にSetActive(false)を実行
_gameObject.SetActive(false);
//activeSelfを確認して、trueのときだけSetActive(false)を実行
if(_gameObject.activeSelf){
  _gameObject.SetActive(false);
}
//有効かどうかの変数(_isActive)を使って、trueのときだけSetActive(false)を実行
if(_isActive){
  _gameObject.SetActive(false);
  _isActive = _gameObject.activeSelf;
}


なお、GameObjectはStartでキャッシュしており、初期状態では有効になっています。

private GameObject _gameObject = null;
private bool _isActive = false;

private void Start () {
  _gameObject = gameObject;
  _gameObject.SetActive(true);
  _isActive = _gameObject.activeSelf;

  /*それぞれの処理(時間計測箇所)*/
}


実際の結果は以下の通りです。(処理回数はそれぞれ100万回)

処理内容 処理時間[秒]
1.単純にSetActive 0.0278
2.activeSelfを使う 0.0199
3._isActiveを使う 0.0053


今回のケースだとactiveSelfを使うことで約28%の高速化、

_isActiveを使うことで約81%の高速化が出来る事が分かりました……!


activeSelfを使う事で無駄なSetActiveをしなければ早くなりそうだなとは思っていましたが、

キャッシュしていたとしてもGameObjectにアクセスしない方が早くなるのはちょっと意外でした。


なお、%で言うと結構な最適化のような感じはしますが、

そもそもが大した負荷ではないので基本的に気にする必要はないと思います。