広告
広告

Unity の Transform の読み書きは遅い

カテゴリ:unity

Unity のバージョン 2017.2 で再計測したらパフォーマンスの改善が入っていた. バージョン 5.4 で約 14ms かかっていた 10,000 個のオブジェクトの position の更新処理は 2017.2 では約 3.5 ms になっている. これは約 4 倍のパフォーマンスの改善だ.

position V.S. localPosition

position ではなく localPosition を使えば早いのでは?という指摘があったのでテストしてみたが変わらなかった. 子オブジェクトを持たないオブジェクトの更新速度は position でも localPosition でも変わらない.

pos vs localPos
10,000 個のオブジェクトの更新処理

ベンチスクリプト

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Profiling;

public class NewBehaviourScript : MonoBehaviour {
    int n = 10000;
    List<GameObject> objects = new List<GameObject>();
    List<Transform> transforms = new List<Transform>();
    void Awake () {
        for(int i = 0; i < n; ++i) {
            var o = GameObject.CreatePrimitive(PrimitiveType.Cube);
            objects.Add(o);
            transforms.Add(o.transform);
        }
    }
	
    void Update () {
        var newPos = new Vector3();

        Profiler.BeginSample("position");
        for(int i = 0; i < n; ++i) {
            objects[i].transform.position = newPos;
        }
        Profiler.EndSample();

        Profiler.BeginSample("localposition");
        for(int i = 0; i < n; ++i) {
            objects[i].transform.localPosition = newPos;
        }
        Profiler.EndSample();
        
        Profiler.BeginSample("transform cache");
        for(int i = 0; i < n; ++i) {
            transforms[i].position = newPos;
        }
        Profiler.EndSample();
    }
}

古い記事

以下のベンチの結果は古いので参考にする必要はないが,対処法自体は今でも有効だ.

Unity のバージョンは 5.4.

Pentium G3220 のマシンで 10,000 個のオブジェクトの transform.position を更新するだけの処理(transform.position = newPos の実行)に約 14 ms かかっている. 60fps の上限が 16ms なので,Unity で 10,000 個の動くオブジェクトを出すのはほぼ不可能だ.

stats
1フレームの更新にかかった時間の統計

続きを読む

実行時の Awake の実行順の問題

カテゴリ:unity

最初からアクティブなオブジェクトは以下の順で初期化メソッドが実行される. これは子オブジェクトがあっても同じで,すべてのオブジェクトの Awake が実行されてから OnEnable が実行される.

  1. Awake
  2. OnEnable
  3. Start

しかし非アクティブ状態でスタートした親オブジェクトを実行時にアクティブにすると問題が起こる.

続きを読む

Live2D の Cubism Parameters Inspector をスクリプトから操作する

カテゴリ:unity

Cubism SDK のバージョンは 3.0.

// Live2D プレハブのインスタンス化
var p = Resources.Load<GameObject>(/*プレハブ名*/);
var l2d = GameObject.Instantiate(p);

// パラメータリストの取得
var params = l2d.transform.Find("Parameters");

// 個々のパラメータの取得
var paramObj = params.transform.Find(/*パラメータ名*/);

// パラメータスクリプトの取得
var param = paramObj.GetComponent<Live2D.Cubism.Core.CubismParameter>();

// 値の設定
param.Value = 30f;

// アップデート
var model = l2d.GetComponent<Live2D.Cubism.Core.CubismModel>();
model.ForceUpdateNow();

Linux Mint 18.1(MATE)で GPU 負荷を調べる

カテゴリ:linux

Intel

Intel の内臓 GPU の負荷は intel_gpu_time または intel_gpu_top で調べられる.

Debian の場合デフォルトでインストールされていないこともある.その場合は以下のコマンドでインストールできる.

$ sudo apt-get update

$ sudo apt-get install install intel-gpu-tools

GPU 使用率を調べる

一般的な状況では intel_gpu_top が便利だ.以下のコマンドで実行できる.

$ sudo intel_gpu_top

result
intel_gpu_top の実行例

特定アプリの GPU 使用率を調べる

intel_gpu_time は特定プログラムの GPU 負荷を調べられる. 例えば chrome の GPU 負荷を調べたければ以下のコマンドを入力する.

$ sudo intel_gpu_time chrome

継続して GPU 使用率をチェックしたければ,su で root になってから以下のスクリプトを実行する. 終了は CTRL + C で.

$ while true; do intel_gpu_time アプリ名; sleep 1s; done

nVidia

続きを読む

Unity の uGUI でルビを表示する

カテゴリ:unity

この記事で実現する方法は,ルビが必要な場所に uGUI のテキストを配置する方法だ. テキストがレンダリングされる位置は TextGenerator.GetCharactersArray() で取得できる.

ルビの必要な部分が途中で改行されると正しい位置が計算できないので, その場合はルビの必要な部分の直前に改行を入れる必要がある. 改行については Unity の uGUI Text の改行位置を調べる を参照.

実行結果
実行結果

続きを読む


広告
広告