投稿者 tel | 2018年5月6日

C#のオーバーロード

C#とC++でオーバーロードされた関数の呼び出し解決が異なっていたのでメモ。

C#だと以下のコードのコンパイルが通る。引数がないほうが呼び出される。

class Program
{
    static void Test()
    {
    }

    static void Test(int a = 1)
    {
    }
 
    static void Main(string[] args)
    {
        Test();
    }
}

C++だと関数呼び出しが曖昧なのでコンパイルエラーになる。

void Test()
{
}

void Test(int a = 1)
{
}

int main()
{
    Test();
}
広告

Unityでシェーダ名を取得するとUnlit/Textureのようにシェーダファイルに書かれた名前が返ってくる。

ただ以下の場合ではシェーダ名が返ってこない。

  • 初回起動時などLibraryディレクトリが作成されていない
  • プロジェクトに含まれているカスタムシェーダを使用している
  • マテリアルが生成された状態のモデルがプロジェクトに追加されている
  • OnPostprocessModelでモデルのマテリアルからシェーダを参照する

この状態でマテリアルについているシェーダのShader.nameをOnPostprocessModelで取得するとファイル名になる。

void OnPostprocessModel(GameObject g)
{
    foreach (var r in g.GetComponentsInChildren<Renderer>())
    {
        foreach (var m in r.sharedMaterials)
        {
            Debug.Log(m.shader.name);
        }
    }
}

Reimportしたときはシェーダ名が取れる。

この挙動で困るのはfbxのインポート時にシェーダの張替えやマテリアルのプロパティの設定を自動化する場合、シェーダが張り替えられているかどうかを判定するのにShader.nameを参照している意図しない動作をしてしまう。

挙動が確認できるプロジェクト
https://github.com/sapphire-al2o3/FirstImportTest/

 

投稿者 tel | 2018年4月3日

Unity最適化メモ

Object.nameにアクセスするとGC Allocが発生する(Unity 5.6.5p1)

プロファイラで確認すると400KB程度のGC Allocが発生している。

Deep ProfileでみるとObject.get_nameでGC Allocが発生していることがわかる。

一時変数に入れて比較すれば1回分のメモリ確保で済む。

string objectName = this.name;
for (int i = 0; i < 10000; i++)
{
    if (objectName == "")
    {
    }
}

投稿者 tel | 2018年3月31日

サンシャイン水族館

サンシャイン水族館に行ってきた。入場料2200円。

続きを読む…

UnityのParticleSystemでAuto Random Seedのチェックを外してRandom Seedに適当な値をいれて再生するとパーティクルの見た目を再生するごとに同じにできる。

Unity5.4とUnity5.5以上ではParticleSystemのRandom Seedに同じ値を入れても再生されるパーティクルの見た目が変わっている。

1を入れて再生したときの見た目が各バージョンによって以下のようになる。

Unity5.5と5.6ではまったく同じ見た目になっているので5.5でおそらくなんらかの変更が入っている。Unity5.4のプロジェクトをバージョンアップしたときに変換してくれないようなので困った。

投稿者 tel | 2018年1月7日

2018年

あけましておめでとうございます。

幸せになりたいです。

投稿者 tel | 2017年12月31日

PVRTC圧縮テクスチャの端がにじむ

iOS用にテクスチャをPVRTC圧縮すると端がにじむ場合がある。これはPVRTCが4×4ブロックの上下左右を補間しているのが原因らしい。例えば一番左上のブロックは右と下のブロックに加えて反対側の左下と右上のブロックを参照している(みたい)。
ETCだと各ブロックの補間がないためこのようなことは起こらない。

上の図はUnity上で16×16のサイズで各圧縮をしたテクスチャを表示してみた結果。PVRTCは一番下の白のラインが赤くにじんでいる。

対処方法

  • RGBA16にする。
    ファイルサイズが大きくなるがしょうがない。
  • テクスチャの端を使わないようにする。
    マテリアルのオフセットやモデルのUVを調整して画像の端が入らないようにする。
  • iPhone5以前を切り捨てる。
    ETC2を使おう。

特にいい方法はない。

投稿者 tel | 2017年11月29日

C#でintをEnumにキャストする

C#で整数値を列挙体にキャストする。

int n = 0;
EnumTest enumTest = (EnumTest)Enum.ToObject(typeof(EnumTest), n);

上記だとボックス化が解除されてメモリアロケートが発生するので以下のように普通にキャストする。

int n = 0;
EnumTest enumTest = (EnumTest)n;

型があらかじめ分かっているならたぶんEnum.ToObject使う必要がない。

投稿者 tel | 2017年10月31日

Unityで乱数の状態を保存する

UnityでRandomの状態を保存する方法について考えてみた。

目的

ゲーム中に適当なタイミングでアプリを落としても、再度起動したときに続きからできるようにしたい場合、ゲーム中で使っている乱数の状態を保存しておく必要がある。

自前で乱数生成器を用意しているならそのインスタンスのメンバーを保存しておけばいいが、Unity標準のRandomだと状態を表すメンバー(Random.state)をどうにかして保存する必要がある。

https://docs.unity3d.com/ScriptReference/Random.html

続きを読む…

UnityでProfiler.BeginSampleとProfiler.EndSampleで関数をプロファイリングをするときにreturnがたくさんある場合、EndSampleを各returnの前に書かないといけなくてめんどくさい。

float Test(int condition)
{
    Profiler.BeginSample("test");

    if (condition == 1)
    {
        float a = 0.0f;
        for (int i = 0; i < 100000; i++)
        {
            a += Mathf.Cos(i);
        }
        Profiler.EndSample();
        return a;
    }
    else if (condition == 2)
    {
        float b = 0.0f;
        for (int i = 0; i < 100000; i++)
        {
            b += Mathf.Sin(i);
        }
        Profiler.EndSample();
        return b;
    }
    return 0.0f;

    Profiler.EndSample();
}

なのでusingスコープでプロファイリングできるようにするためにIDisposableを継承した構造体を作る。

関数の中でusingのスコープを作って中に計測したいコードを書く。これならどのタイミングでreturnされても計測できる。

float Test2(int condition)
{
    using (var scope = new ProfilerScope("test2"))
    {
        if (condition == 1)
        {
            float a = 0.0f;
            for (int i = 0; i < 100000; i++)
            {
                a += Mathf.Cos(i);
            }
            return a;
        }
        else if (condition == 2)
        {
            float b = 0.0f;
            for (int i = 0; i < 100000; i++)
            {
                b += Mathf.Sin(i);
            }
            return b;
        }
        return 0.0f;
    }
}

Older Posts »

カテゴリー