【Unity】ShaderファイルがVisual Studioに追加されないときに確認すべきこと

Unityが生成するVisual Studioのプロジェクトファイルには、シェーダーファイルも含まれます。
これにより、拡張子がshader、cginc、hlslのファイルを、Visual Studioの検索ウィンドウから全文検索することができます。
シェーダーにはIntelliSenseは有効ではないので、ファイル間の参照を確認するにはこの検索機能が必須です。

しかし、ある条件下では、含まれてくれません!

.shaderファイルがVisual Studioプロジェクトに追加されないのは、例えばUnityプロジェクトが以下のような構成のときです。
f:id:kraihd:20200404183324p:plain

  • Assets/Scripts/NewAssembly.asmdef
  • Assets/Scripts/NewBehaviourScript.cs
  • Assets/Shaders/NewUnlitShader.shader

この状態で生成されるプロジェクトは以下のようになってしまいます。 f:id:kraihd:20200404183342p:plain

NewUnlitShader.shader が追加されていませんね。

この現象にはAssembly Definition File (上記でいうNewAssembly.asmdef)が関係しています。
……しかし、なぜC#アセンブリの構成が、C#が全く関係ないはずのシェーダーに影響するのでしょうか。
ここではかなりややこしいことが起こっています。

Unityは基本的に、csファイルを「Assembly-CSharp」というアセンブリコンパイルします。
EditorやPluginsなど特殊な役割のフォルダを除いて、Assets以下全てのcsファイルがコンパイル範囲となります。
Unityプロジェクト内にcsファイルが1つでもあれば――つまり普通は――Assembly-CSharpは生成されます。

ただし、Assembly Definition File を使う場合はその限りではありません。
Assembly Definition Fileとは、置かれたフォルダ以下をコンパイル範囲とし、独自のアセンブリへと区切る機能です。
この機能は便利なため、Assembly-CSharpは生成されるのが普通とは限らなくなりました。

ところで、Unityは、1つのアセンブリコンパイル範囲から、1つのVSプロジェクトを生成します。
そして、アセンブリコンパイル対象となるフォルダの中に、シェーダーファイルがあれば、csだけでなくそれも含めてくれるのです。例えば、アセンブリがAssembly-CSharpただ1つであれば、全てのシェーダーファイルがAssembly-CSharpプロジェクトに含まれます。

何が起こっているか察してきましたね?

全てのcsファイルが、いずれかのAssembly Definitionに属しており、Assembly-CSharpという「Assets以下全てのcsファイル」を担当するアセンブリが生成されない場合。
すなわち、全てのアセンブリが何か特定のフォルダ以下をコンパイル範囲としている場合。
そのうちのどのフォルダにも含まれない所にあるshaderファイルは、どのVSプロジェクトにも含まれないのです!

上記の例でいうと、ShadersフォルダにAssembly Definiton Fileを配置すれば解決できないのでしょうか? ……できないどころか警告すら出ます。csファイルが1つ以上ないとアセンブリは生成されないのです。

バグ報告を行ったところ、これらの挙動は仕様との回答をいただきました。
解決するには、上記のようなフォルダ構成をやめ、csとshaderファイルを近いフォルダに混在させる以外に方法はありません。

【Unity】BGMの途中からループは、できる! もっと簡単に!

貴方は、「UnityではBGMの途中からループができない」と思っている、または思っていませんでしたか? そして、そのためだけに、貴方はADX2とかの導入を検討しませんでしたか?
私はしました。

私はその後一度、「BGMデータを2ループ分作り、timeSamplesを巻き戻す」という方法があることに気づきました。他にも、世の中にはAudioSource.PlayScheduledを次々に実行するという実装をした方もいらっしゃるようです。

ですが、今なら言えます。
そんなことをする意味は、最初から無かったのです!

BGMをちゃんと途中からループさせたい。それだけであれば、ミドルウェアはもちろんのこと、コードの1行すら書く必要がありません。

(追記:ただしWebGLを除きます)

続きを読む

【東方鬼形獣予想】閻魔様、また長野県出身キャラ説

3面ボスの久侘歌ちゃんが、閻魔様という上司がいることを仄めかしていますね。(あ、万一まだ鬼形獣体験版をプレイしていなければ次の文に目を移す前に今すぐページを閉じるんだ!)

神なんだから上司なんていなくても信仰を動機に仕事してもいいはずなのに、そこをあえて、しかも3面道中の進行をぶったぎってまで言及される存在です。鬼形獣の物語に登場しないということはまずないでしょう。
みんなが言及してるうえにみんなの動機になってるのにキャラは出てこない嫦娥という例があるけどな!

また、前回の記事では、動物霊の性格は罪に対応しているのではないかと考察しました。
もしそうなら、閻魔の持つ浄頗梨の鏡は、自機装備に応じて違う弾幕を繰り出すためのいいギミックになるでしょう。

閻魔が出るとして、それは一体どんな閻魔なんでしょうか?

続きを読む

【Unity】コンポーネントの初期化にAwakeを使うか自作メソッドを使うかで例外発生時の止まり方が違う

(※この記事は先月投稿したQiita記事のミラーです)

Instantiateなどで生成したコンポーネントを、その場ですぐに初期化する場合、大きく分けて2つの方法があると思います。

  1. Awake() のように、Unityのメッセージで初期化する
  2. Init() のように、メソッドを呼んで初期化する

どちらにもそれぞれのメリットがあります。
例えばAwakeはいつ呼ばれるのか単純明快ですし、生成側とコンポーネントが依存しない造りにできます。
一方メソッドを作るのなら引数を自由に変えられますし、Unity独特の仕様に依存しない造りにできます。
パフォーマンスも、InstantiateやAddComponentそれそのものに比べたら差はないも同然です。

というわけで、引数もなくて同じ所で呼ぶなら、様式以外は大差ない――

――と思っていました。

続きを読む

【東方鬼形獣予想】動物霊は何者なのか?

この先の文章には、東方鬼形獣体験版をプレイしての感想が含まれています。
一応、まだ博麗幻想書譜しか読んでいない人がこれを読んでも、作品の楽しみを損なわないよう、具体的な話は一切していません。
それでも、厳密にネタバレを回避したい方はご注意ください。

続きを読む