まとめて2017年分

続きを読む…

広告
投稿者 tel | 2018年10月7日

C#での文字列と数字の連結

C#で文字列と数値を連結するときに数値をToStringしなくても連結できる。

string a = "a" + 1.ToString();
Console.WriteLine(a);    // a1
string a = "a" + 1;
Console.WriteLine(a);    // a1

文字列同士の連結は string.Concat(string, string) が呼び出されるが、文字列と数値を連結するときは string.Concat(object, object) が呼び出されている。

もちろん string.Concat(object, object) を呼び出した場合、boxingがされるので文字列同士の連結をしたほうがいい。普通は文字列に数値を連結する場合に直接連結することはないのでいいのだけど、以下のコードのようにパースしたあとに加算しようと思ってたのに先に加算したことで文字列連結になってしまってバグるということがあった。

string a = "10";
int b = int.Parse(a + 1);

ほんとは以下のように書きたかった。

string a = "10";
int b = int.Parse(a) + 1;

文字列同士の加算じゃない場合は、コンパイラエラーになってくれるといいのに。

投稿者 tel | 2018年9月30日

TGS2018

Tokyo Game Show 2018に行ってきた。9月21日のビジネスデイ。

毎年、いちおう行ってはいるんだけど並ぶのが嫌なのであんまりプレイしないで見て回っているだけになっている。
最近はメーカーのゲームを見るよりもインディーブースや専門学校のブースのゲームを見るのが面白くなってきた。並ばずに遊べるということもあるけど、1箇所にいろんなゲームがまとまっているのが遊びやすい。あとコンシューマでもスマートフォンゲームでもがっつりと作られたものは面白くなるまでにある程度プレイしないといけないので試遊だけだとなかなか面白さが伝わらない。

特に印象に残ったのが、ゲーム大賞のアマチュア部門の応募作品の「PROJECTION RMAINS」。
http://awards.cesa.or.jp/prize/amateur/05.html

ゲームの内容はステージクリア型のパズルゲームでキャラクターを操作して扉までたどり着けばクリアとなる。特徴的なシステムとしてスクリーンを表示するエリアが存在し、スクリーンに別のエリアを写して足場などにできる。

他にもグラフィックスのクオリティが高い作品もあったが、ドット絵がすきなのもあるけど全体的な統一感があるアートがよくできている。
レベルデザインもよくできていて、できる操作やギミックなどがそれほど多くないのに、こんな解法もあったのかと思わせる作りになっている。
全体的な完成度が高くて、また遊んでみたくなる作品だった。

投稿者 tel | 2018年8月31日

CEDEC2018

例年通りCEDECに行ってきた。忙しくないのに忙しい人がいるので8/22の1日だけ。

見たセッション

  • 明快で軽快なUI 『Nintendo Switch 本体機能』の制作事例
  • シェーダの工夫で超えられる表現の壁がある! -ゲームエフェクトにおけるトリッキーなシェーダ講座-
  • シミュレーションベース炎エフェクトの作り方
  • ゼノブレイド2のレイマーチングを使った雲表現
  • 一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術

任天堂の「明快で軽快なUI 『Nintendo Switch 本体機能』の制作事例」はとてもよかった。UIデザイナーだけでなくプログラマーやプランナーがみても得るものが多いともう。例のごとくSNS禁止なので当たり障りのないことを書いておくと、

  • UIデザイナーにとっては当たり前なのかもしれないけど、UIを作る組み立て方が順序立てて説明されている
  • 分かりづらい仕様を放置しないで突き詰めている
  • コンセプトに対して要素を分解して様々な方向からアプローチする仕事の進め方
  • チーム全員で成果物をさわる日を作る

こういったことは本体機能の制作だけに限らず、ゲーム開発でも意識してできるといいゲームが作れるんだろうと思う。

今年はちゃんとUnityのTシャツをもらえた。プラチナスポンサーになっているだけあっていい生地。

Unity完全に理解したTシャツがオライリーブースにあった。

タイムシフトがあるので1日だけしかいけなくてもあとで見れるのはいいけど、もう少し公開期限を延ばしてほしい。

 

投稿者 tel | 2018年7月31日

法線やUVを確認するシェーダ

Unityでメッシュの法線とかUVとか頂点カラーを確認するためのシェーダを書いた。頂点カラー使ってないのにメッシュに含まれてる場合に確認するために使う。

別々のシェーダをいちいちつけ直すのが面倒なのでマテリアルのプロパティから変更する。

法線表示

UV表示

投稿者 tel | 2018年6月28日

UnityのTRANSFORM_TEXマクロ

シェーダでタイリングなどを計算するためのマクロとしてTRANSFORM_TEXをつかう。
以下のようにUVスクロールするためにUVを計算してからTRANSFORM_TEXをつかったところタイリングが効かなくなった。

o.texcoord = TRANSFORM_TEX(v.texcoord + _Time.yy, _MainTex);


TRANSFORM_TEXはUnity.cgincに定義されている。

// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)

これをそのまま適用するとGLSLでは以下のように展開される。
先に_Time.yyと_MainTex_ST.xyが乗算されてしまっている。

xlv_TEXCOORD0 = ((_glesMultiTexCoord0.xy + (_Time.yy * _MainTex_ST.xy)) + _MainTex_ST.zw);

ようするにちゃんと括弧を付けてあげないといけない。

o.texcoord = TRANSFORM_TEX((v.texcoord + _Time.yy), _MainTex);


GLSLに展開されるとちゃんと加算が先にされている。

xlv_TEXCOORD0 = (((_glesMultiTexCoord0.xy + _Time.yy) * _MainTex_ST.xy) + _MainTex_ST.zw);
投稿者 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円。

続きを読む…

Older Posts »

カテゴリー