テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】2019.2で追加されたTryGetComponentについて

f:id:tsubaki_t1:20190716231235j:plain

Unity 2019.2から、TryGetComponentというAPIが追加されました。何時も通りGetComponentで取得する際、なんか見覚えがないAPIがあってビビったのはここだけの話。

TryGetComponent

今まで「コンポーネントが割り当てられていない状態」を取得する場合、とりあえず GetComponent で取得して中身がNullかどうかを確認するというのが常套手段でした。

            var component = array[i].GetComponent<SampleComponent>();
            if (component != null)
                component.Value++;

TryGetComponentは、戻り値にコンポーネントを取得できたかを確認してくれます。例えば上と同じ動作は、下のように記述出来ます。

            if( TryGetComponent(out SampleComponent comp))
                comp.Value++;

パフォーマンスは?

パフォーマンスですが、GetComponentで取得後にNullチェックするのと大して変わりません。これは「ビルド前後」「取得するコンポーネントの有無」に関わらずです。

試しに下のようなコードで毎フレーム1000個ほどGameObjectを複製してGetComponentした所、こんな結果になりました。エディターでTryGetComponent時に妙に遅いのを除けば、大体想定した感じの動きです。

        SampleComponent comp;

        Profiler.BeginSample("test_TryGetComponent");

        for (int i = 0; i < data.capacity; i++)
        {
            if( TryGetComponent(out  comp))
                comp.Value++;
        }

        Profiler.EndSample();
        Profiler.BeginSample("test_GetComponent");

        for(int i=0; i<data.capacity; i++)
        {
            var component = array[i].GetComponent<SampleComponent>();
            if (component != null)
                component.Value++;
        }

        Profiler.EndSample();

f:id:tsubaki_t1:20190716232530j:plain
コンポーネント有りエディター

f:id:tsubaki_t1:20190716232613j:plain
コンポーネント有りビルド後

f:id:tsubaki_t1:20190716232402j:plain
コンポーネント無しエディター

f:id:tsubaki_t1:20190716232300j:plain
コンポーネント無しビルド後

というか、コンポーネントが存在する対象に対するGetComponentが妙に早い気がします。あれ?こんな速度だっけ?

【Unity】LWRPの2Dパイプラインで、ShaderGraphを使ってみる

f:id:tsubaki_t1:20190710212151g:plain

今回はLWRPの2DRendererでShaderGraphを使用してみます。

2Dパイプライン

コチラを参照

tsubakit1.hateblo.jp

Shader Graph

この2Dパイプラインでは、単純なLit/Unlitのシェーダーだけでなく2D用のマスターノードが用意されています。コレを使用すると、スプライトレンダラー向けの表示にもShaderGraphを使用したシェーダー構築が可能になります。

それ以前にもUnlitのシェーダーを使用すれば簡単な表現はできたんですが、Spite Mask等にちゃんと対応したマスターノードが提供されたという感じです。マスターノード、もうちょっと簡単に構築出来れば良いんですが…

f:id:tsubaki_t1:20190710212013j:plain

使ってみる

Shaderを用意する際には、Create > シェーダー > 2D Renderer から作りたいシェーダーを選択します。Litが光源処理に対応したシェーダー、Unlitが対応していないシェーダーです。

あとは作成したシェーダーをダブルクリックでShader Graphを起動、編集していきます。

f:id:tsubaki_t1:20190710212452j:plain

Shader Graphでスプライトを使用する場合、必ず _MainTexのTexture2Dを要求しますので、コレを追加します。下のシェーダーは今までのシェーダーと同じような動きをするシェーダーの例です。

MainTexが無い場合、「Material does not have a MainTex property. it is required for sprite renderer」と表示されます。

f:id:tsubaki_t1:20190710212846j:plain

他のテクスチャ設定ですが、Secondary Textureで設定したテクスチャの名称と一致します。例えばNormalMapのテクスチャを設定した場合、ShaderGraph側でもNormalMapと設定すれば、シェーダー側で使用できるようになります。

なおノーマルマップは普通にSamplerTexture2Dでとってくれば良いです。

f:id:tsubaki_t1:20190710213235j:plain

f:id:tsubaki_t1:20190710213605j:plain

後は色々と頑張って作れば、簡単なエフェクト程度なら割とサクっと作れます。下は試しに作ったスプライトをチェック柄に消す奴(トップ絵の)

f:id:tsubaki_t1:20190710213753j:plain

注意事項

  • Emissiveが効きません。
  • SpriteAtlasを使用すると絵が破綻します
  • 別に2D用ノード必要なくね?…それな

【Unity】LWRPのライトで †暗黒の光† をしたかった

f:id:tsubaki_t1:20190709193621j:plain

今回は昨日チラっと書いた、暗闇をライトで表現するアプローチについてです。

意図的に暗い空間を作る

ステージを作るとき、 重要である事を示すために明るくする 事はよくやりますが、メリハリを付けるためにどうでも良い空間は暗くしたいといった事がよくあります。また同様に、隠すといった目的で特定の範囲を暗くしたいといった場合もあります。ゾンビは暗がりから出るものです。

今回は光の減算で、暗がりを意図的に作ってみます。

f:id:tsubaki_t1:20190709194039j:plain

前提条件として、前回の作業は完了しているものとします。また作業環境も同じです。

tsubakit1.hateblo.jp

ライトの減算設定を登録

2D Renderer Data(カスタムパイプラインに登録しているアセット)の設定に少し手を加えます。

  • Blend Style 2 にチェックを入れる
  • 名前を Dark に設定 *1
  • Blend Modeを 減法 に設定

f:id:tsubaki_t1:20190709194324j:plain

実際に暗黒の光を発する発光体を配置する

実際にライトを配置してみます。

  1. 2Dライトを配置(種類は問わない)
  2. Blend StyleをDarkに設定

f:id:tsubaki_t1:20190709194706j:plain

通常のライトを配置した場合と比較すると、こんな感じになります。ダークパワーが溜まって云々

f:id:tsubaki_t1:20190709194948j:plain

f:id:tsubaki_t1:20190709194958j:plain

注意点

  • 色は「現状の光 - 白(1,1,1)」なので、色を黒くするとダークパワーが低下します。
  • Sorting Layer関係なく全てのスプライトに影響します(やり方はあるかもしれませんが)

*1:喧嘩チームDRAKではない

【Unity】LWRPの2D向けライト機能を試してみる

f:id:tsubaki_t1:20190708212813g:plain

今回はLWRPに追加された2Dライトを試してみます。

2Dにライト

最近の海外で2Dなゲームでは、2Dでもライティング…正しくは法線効果で光源の位置を示しているゲームをよく見ます。

そのやり方については下の記事で紹介していましたが、LWRPに標準機能として2Dライティングの機能が追加されました。

tsubakit1.hateblo.jp

大雑把に言えば、以下の機能が追加されています。

  • スプライトにノーマル等の補助用テクスチャ追加
  • 2DスプライトShaderがノーマル計算用に参照するライト

実際に使ってみます

導入手順

まず Unity 2019.2Light Weight 6.7.1 をインポートします。 インポートは何時も通り Package Managerで。

f:id:tsubaki_t1:20190708213553j:plain

導入後にレンダリングパイプラインをLWRPに変更し、2D用カスタムパイプラインを導入します。

  1. Assets>Createのメニューから、Pipeline Assets2D Renderer を作成
  2. Pipeline Assetsの Renderer Typeカスタム に変更して、2D Renderer を登録
  3. プロジェクト設定グラフィックススクリプタブルレンダーパイプライン設定 を、先程作成したパイプラインに設定

f:id:tsubaki_t1:20190708213801j:plain

f:id:tsubaki_t1:20190708214135j:plain

f:id:tsubaki_t1:20190708214143j:plain

これで準備完了です。

とりあえずライトを試す

とりあえず2Dライトを試してみます。

LWRPの2Dを導入すると、ライトに 2D の項目が追加されます。このライト設定はスプライトにも影響します。

光の見え方は Inner RadiusOuter Radius 、それと Fall off Intensity で大体決まります。

f:id:tsubaki_t1:20190708214725j:plain

f:id:tsubaki_t1:20190708214839j:plain

f:id:tsubaki_t1:20190708215231g:plain

ライトの形状は、円形だけでなくポリゴンの形状や、スプライトの切り抜き等が可能みたいです。例えば 「出口を光らせる」のような演出をしたい場合や、ユニークな発光現象を表現したい場合でも使えます。

f:id:tsubaki_t1:20190708220202j:plain
Freedom Lightで矩形の光源(右下の緑)

f:id:tsubaki_t1:20190708220232j:plain
Sprite Lightでスプライトの形状にくり抜く

ちなみにライトは加算だけでなく減算や他のブレンドも可能みたいです。ダークライト…普通に3Dでも欲しい*1

f:id:tsubaki_t1:20190708222326j:plain

陰影表現の追加

光源の向きを示すため、ノーマルマップを使用して陰影表現してみます。

f:id:tsubaki_t1:20190708221513j:plain

やることは単純で、スプライトにノーマル等のテクスチャを追加します。

  1. Sprite Editor を開く
  2. Secondary Texture を選択
  3. + ボタンで要素を増やして、名称を _NormalMap に設定
  4. _NormalMapにノーマルマップを追加

あとはライトで Use Normal Mapにチェックを入れます。

f:id:tsubaki_t1:20190708220805j:plain

f:id:tsubaki_t1:20190708221025j:plain

この手順はTilemapに使用する場合でも有効です。

f:id:tsubaki_t1:20190708222032j:plain

注意事項

  • 現状SpriteAtlasには対応していません。SpriteAtlasでパッキングすることでUVが変化してしまうので。
  • 対応しているのは「陰影」で、影には対応していません。
  • ライトのZの位置も影響します。Zが大きく外れていると、GameViewに反映しない事があります。
  • 最初に表示される最新のLWRPバージョンが6.7.1より下の場合、一覧表示すれば選択出来るようになります。
  • このバージョンのLWRPには、Pixel perfect Cameraが含まれます

f:id:tsubaki_t1:20190708222717j:plain

*1:暗黒の光とか言ってはいけない。いいね?