投稿者 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;
    }
}
投稿者 tel | 2017年9月10日

CEDEC2017

今年もCEDECに行ってきた。仕事の関係で8/31と9/1の後半2日間。

今回は初めて任天堂がゲームのセッションをもつというのでゼルダの伝説ブレスオブザ・ワイルドのを8つ全部みてきた。(今までもWiiUとかのプラットフォームに関する講演はあった)

すでにいろいろ記事が上がっているけどどれもとても興味深い講演だった。SNS禁止で内容は詳しく書けないので当たり障りのない感想を残しておく。

  • ツール類の充実がすごい
    以前、何かの講演でゲームエンジンでフィールド中に付箋を残せるとよさそう、みたいな話をきいたが実際にタスク管理まで統合して運用しているのはさすがだった。
  • すべてのセッションでスライドの完成度がすごい
    おそらく相当推敲して作られていると思うし、発表も聞きやすかった。
  • ロジカルな思考がすごい
    センスで作られているのではなく理詰めでレベルデザインもサウンドもエフェクトも作っているというすごさ。
    QAですらゲームが面白くなるためにどうしていくかを考えぬいている。

あと1日目に行けなかったのでUnityチョットデキルTシャツがもらえなかったのが心残り。

話題になってた流動床インターフェース。砂がほんとに流体みたいなっていてずっと遊んでられる。

今年から講演のタイムシフト配信があったので見られなかった気になる講演が後から見ることができて非常にありがたかった。ただ、期間が2週間ないくらいで見てられる時間がとれないのでもっと伸ばしてほしかったのと、カメラの前を横切る人が多いので撮影環境をもうちょっとよくしてほしかった。

 

投稿者 tel | 2017年8月31日

C#のConditional属性

C#のConditional属性についてのメモ。
https://msdn.microsoft.com/ja-jp/library/aa664622(v=vs.71).aspx

Unityでデバッグ処理を#ifでくくる代わりにConditional属性を関数に付けておくと、リリース時にデバッグ用のシンボルを消すことで処理が呼び出されなくなる。

  • 呼び出し自体がなくなるので引数も評価もされない
  • 関数自体は残る

下の方の挙動がやっかいでデバッグ処理を完全に消そうとして以下のようなコードを書くとコンパイルエラーになる。

public class ConditionalTest : MonoBehaviour
{
    #if DEBUG_LOG
    string debugText = "debug text";
    #endif

    [System.Diagnostics.Conditional("DEBUG_LOG")]
    void Log()
    {
        Debug.Log(debugText);
    }

    void Start()
    {
        Log();
    }
}

関数の中身も#ifでくくっておけばコンパイルが通るが、関数自体が残ってしまうのでアプリサイズとかメモリが無駄になる。

以下のように書けば完全にデバッグ処理が消せるがコードが読みやすくない。

public class ConditionalTest : MonoBehaviour
{
    #if DEBUG_LOG
    string debugText = "debug text";
    #endif

    #if DEBUG_LOG
    void Log()
    {
        Debug.Log(debugText);
    }
    #endif

    void Start()
    {
        #if DEBUG_LOG
        Log();
        #endif
    }
}

パーティクルにディゾルブのシェーダを使ったら結構いい感じになったのでメモ。

こんな感じ。

続きを読む…

モデルやテクスチャのインポート時に設定をするのはAssetPostprocessorを使う。
https://docs.unity3d.com/jp/540/ScriptReference/AssetPostprocessor.html

たとえばテクスチャのミップマップの設定を無効にしたい場合は以下のようにする。

public class CustomTextureImporter : AssetPostprocessor
{
    void OnPreprocessTexture()
    {
        var importer = assetImporter as TextureImporter;
        importer.mipmapEnabled = false;
    }
}

ただしこの場合、一部のテクスチャだけミップマップを有効にしたくなってチェックを入れてApplyしてもチェックが外れた状態に戻ってしまう。

Applyすると

解決方法

メタファイルがすでに存在していたらOnPreprocessTextureの処理をしないようにする。こうすることで最初にインポートしたときにだけデフォルトの設定をスクリプトからすることができる。

投稿者 tel | 2017年5月30日

ParticleSystemのメッシュが残る

以下のようなエフェクトを作ってアセットバンドルにする。

ビルドログ

Bundle Name: effect
Compressed Size:204.0 kb
Uncompressed usage by category:
Textures 0.0 kb 0.0% 
Meshes 2.8 kb 0.8% 
Animations 0.0 kb 0.0% 
Sounds 0.0 kb 0.0% 
Shaders 267.7 kb 72.0% 
Other Assets 8.2 kb 2.2% 
Levels 0.0 kb 0.0% 
Scripts 0.0 kb 0.0% 
Included DLLs 0.0 kb 0.0% 
File headers 93.3 kb 25.1% 
Complete size 372.1 kb 100.0%

Used Assets and files from the Resources folder, sorted by uncompressed size:
 267.7 kb 72.0% Resources/unity_builtin_extra
 7.1 kb 1.9% Assets/Particle System.prefab
 2.8 kb 0.8% Assets/ico.fbx
 0.9 kb 0.2% Assets/Materials/unnamed.mat
 0.2 kb 0.1% AssetBundle Object

ビルボードなのにメッシュが含まれている。これはParticleSystemのRendererでメッシュを設定した後にビルボードにしたときにメッシュが残ったままになっているため。試しにRender ModeをMeshにしてみると

メッシュがついてる。メッシュをNoneにビルボードに戻せばアセットバンドルに含まれなくなる。

普通はメッシュにしてからビルボードにするとかしないと思うけど、もしメッシュが残っているとファイルサイズやメモリを無駄に使ってしまうので注意。

Older Posts »

カテゴリー