うどんてっくメモ

技術的なメモをまったりと

【Unity】TextMeshProのアウトラインを理解する

はじめに

本記事で紹介および検証を行なっているツール、ライブラリのバージョンは次の通りです。

  • Unity 2021.3.1f1
  • com.unity.textmeshpro@3.0.6

バージョンによっては挙動に差異がある場合もありますので、ご了承ください。

TextMeshProのアウトライン

UIを作っていく上で必要になりがちなアウトライン表現ですが、TextMeshProでやる場合にはMaterialのパラメータで実現できます。

Thicknessの値を大きくすれば、アウトラインを太くすることが可能です。

適当にアウトラインをつけたいだけならこれでいいのですが、たとえば5pxのアウトラインをつけたい!ということをする際、パラメータをどう設定すればいいかいまいち掴めませんでした。 そこで、Forumを漁ってみると公式の説明が投稿されていました。

forum.unity.com

この説明をもとに、アウトラインの大きさや見え方の仕組みについて紹介します。

アウトラインの大きさ

まず最終的なアウトラインの大きさの式から示します。

アウトラインのサイズ(大体) = FontSize * Padding / Sampling Point Size * Thickness * 2

たとえばテキストのFontSizeが50px、参照するFontAssetのSampling Point Sizeが100px、Paddingが9px、そしてMaterialのThicknessが0.5であれば、アウトライン幅は50 * 0.09 * 0.5 * 2 = 4.5pxになります。ここで大体という注釈をつけているのは、内部計算で端数の切り捨てや補完の計算が働くケースもあるためです。詳細は本記事では省略するため、実際のシェーダーの中身を参照してもらうといいかと思います。

FontSize

そのままで、TextMeshProによるGUIコンポーネントに設定されたFont Sizeです。

Padding / Sampling Point Size

わかりにくいですが、FontAssetのGeneration SettingsにあるSampling Point SizeをPaddingで割ったものになります。 Sampling Point Sizeが100でPaddingが9であれば「サンプリングされている文字のサイズに対するパディングの割合値」は0.09といった形です。

Sampling Point SizeとPaddingはTextMeshProにおけるSDF Textureでの文字ひとつひとつのサイズと間隔を表します。Atlas Population Modeについて、動的にサンプリングするDynamicであればこの画像にもあるGeneration Settingsの値を変更して調整しますが、事前にサンプリングしておくStaticであればFont Asset Creatorによる生成時にバインドされます。

この生成時にも、SP/PD Ratioという値で出力されてたりします。

Thickness

冒頭でも説明した、MaterialのOutlineにあるパラメータです。

内側と外側のアウトライン

注意しなければならないのが、このアウトラインは文字の輪郭を中心軸に外側と内側に描画されることです。 なので、大きさを求める計算式では最後に2を掛けています。 また、アウトラインの見せ方にも注意が必要です。たとえば外側にアウトラインをつけたいだけだと、内側に描画されてしまう分文字部分が潰れてしまいます。 対応するにはMaterialのFaceにあるDilateというパラメータを調整します。Dilateは文字の太さの拡縮の役割があります。

以上のように、アウトラインの大きさや見え方を調整するにはさまざまなパラメータを考慮する必要があります。

まとめ

これまで雰囲気でTextMeshProのアウトラインをつけていましたが、TextMeshProのパラメータを理解するいい機会になりました。 文中でも言及しましたが、詳細なロジックは実際のTextMeshProのシェーダーで確認できます。興味のある方はぜひのぞいてみるのがおすすめです。 また、本記事に誤りがある場合には筆者までコメントなどで指摘いただけますと幸いです。

【Unity】TextMeshProのバージョンを更新してRectMask2Dのsoftnessを反映させる

本記事で紹介および検証を行なっているツールのバージョンは次の通りです。

  • Unity 2021.2.0f1
  • com.unity.textmeshpro@3.2.0-pre.2

バージョンによっては挙動に差異がある場合もありますので、ご了承ください。


RectMask2Dのsoftnessを使ってソフトマスクをかけていたところ、効果がTextMeshProに反映されていないことに気づきました。

f:id:myudon:20220313010801g:plain

issueを調べてみると、どうやらTextMeshPro3.2.0-pre.2以降で対応されているそうです。

issuetracker.unity3d.com

当然preview版のパッケージなので不具合が発生する可能性もあるのですが、更新することでsoftnessの問題は解決しそうです。(ちなみにこの記事を検証しているUnity2021.2.0f1のTextMesh Proのバージョンは3.0.6となります。) その場合、Package ManagerからTextMeshProのバージョンを上げる必要があります。 preview版なので、Add by package name...から直接入力します。

f:id:myudon:20220227213926p:plain:w500

f:id:myudon:20220227214242p:plain:w500

TextMesh Proのバージョンを上げたらEssential Resourcesも同時に更新する必要があります。 Window -> TextMesh Pro -> Import Essential Resourcesから更新してください。

f:id:myudon:20220313004743p:plain:w500

f:id:myudon:20220313005220p:plain:w500

以上の工程で正常にバージョンを上げると、softnessが反映されることが確認できます。

f:id:myudon:20220313010830g:plain

バージョン差分は公式のよりChangeLogより参照できるので、気になる方は確認してください。

docs.unity3d.com

【Rider】Code Cleanup Profileを使ってカスタムしたコード整形を行う

RiderにはCode Cleanupというコードの整形機能があり、いい感じにコードを整えてくれます。

pleiades.io

便利ではあるものの、デフォルトのまま使うといささかプロジェクトのコード規約にそぐわなかったり、意図しない不要な差分を生み出てしまうこともあります。 プロジェクトに適切な整形処理だけ走らせたい、そんな時にはカスタマイズした設定、Code Cleanup Profileを作成することで実現することができます。

Code Cleanup Profileの設定

まずはCode CleanUpを行う画面をCode -> Reformat and Cleanup Codeから開きます。

f:id:myudon:20220206214705p:plain

左下に表示されるのが設定となるCode Cleanup Profileです。デフォルトではFull Cleanup、Reformat & Apply Syntax Style、Reformat Codeの3つが用意されており、特に指定がなければFull Cleanupが指定され実行します。 右には実際にそのProfileに設定されている処理の項目が表示されます。

f:id:myudon:20220206215002p:plain

新しくProfileを作るには左上のEditボタンを押します。

f:id:myudon:20220206215714p:plain

Profileの設定画面が開くので、左上のプラスボタンから新規Profileを名前をつけて作成します。

f:id:myudon:20220206215907p:plain

後は使いたい処理を右から選択して適用します。選択後は右下のSaveを必ず押してください。 筆者はUnityでのC#コーディングに活用しているため、C#周りの設定をよしなに採用して使っています。

f:id:myudon:20220206220309p:plain

そしてCleanupを行う際に、作成したProfileを選択して実行すれば完了です。

f:id:myudon:20220206220634p:plain

Reformat and Cleanup on Saveでの活用

Rider2021.3以降には、保存時にReformatおよびCode Cleanupを呼び出す新機能が備わっています。

www.jetbrains.com

この機能においてもCode CleanUp Profileの適応が可能です。 Tools -> Actions on SaveからReformat and Cleanup on Saveを設定する画面を開き、Profileと指定されている部分を設定します。 デフォルトだとビルトインのFull Cleanupが指定されています。

f:id:myudon:20220206211639p:plain

設定したら、実際に保存してみて処理が走るか確認してください。

おわりに

RiderのCode Cleanupは適切に使いこなすことで、効率的にコーディングを進められます。 プロジェクトに則したProfileをもとに、Code Cleanupの導入を検討してみてはいかがでしょうか。

Unity2022でさらに進化したSearch Windowが便利だった

はじめに

2022年も始まりということで、Unity2021から導入され、さらにUnity2022で進化を遂げているSearch Windowの使い方について紹介します。 Search WindowについてはUnity2021以降で使用できる機能になりますので、ご留意ください。

本記事で紹介および検証を行なっているツールのバージョンは次の通りです。

  • Unity 2022.1.0b1

バージョンによっては挙動に差異がある場合もありますので、ご了承ください。

Search Window

Search Windowはプロジェクト内のアセットの参照およびさまざまな操作について、名前や特定の条件で絞り込んで検索する機能です。

f:id:myudon:20220102213051p:plain

WindowsであればCtrl + KMacであればCmd + Kのショートカットキーで開きます。 また、Projectビューの検索欄の右にあるボタンでも表示されます。一番検索欄に近い矢印が入ってるボタンです。

f:id:myudon:20220102215304p:plain

アセットについてパス、種類、名前などを指定して一覧として確認することが可能です。 次の画像は入れているPackage含めて全ての場所にあるTextureアセットを確認しているところです。

f:id:myudon:20220103011028p:plain

タイプと名前と言ったように、複合した条件も指定できます。

f:id:myudon:20220103011632p:plain

また、各種メニュー行える操作、および各種設定のウィンドウについてもSearch Windowからショートカットすることができます。

f:id:myudon:20220103011751p:plain

f:id:myudon:20220102220607p:plain

筆者はよく「あの画面ってどうやって出すんだっけ...」みたいになっておもむろにググるみたいなことがちょこちょこあったのですが、これを活用すれば名前さえ把握していればささっと出すことが可能です。

また、現在開いているシーンのヒエラルキー状のオブジェクトの検索も可能です。 ヒエラルキーにある検索機能でも同等のことはできるので、条件を色々と変えてヒエラルキーの内容を色々と確認したい時には有用です(ちょっとした検索をその場でしたいだけであれば、ヒエラルキーの検索機能でやってしまった方が早いです)。

f:id:myudon:20220103013424p:plain

2022で進化した絞り込み機能 Query Builder Mode

Unity2022からSearch Windowの絞り込み機能が視覚的に進化しました。 そもそもUnity2021では絞り込みを行う際に直に条件を打ち込む必要がありました。 タブキーでサジェストしてくれるものの、一定記述する必要はあったので、やや直感的ではありませんでした。

f:id:myudon:20220103001044p:plain

Unity2022ではこれがGUIによって設定できるQuery Builder Modeというのが追加されました。 これによって絞り込みたい要素をかなり視覚的に設定できます。

f:id:myudon:20220103001231p:plain

使う時には左上のボタンで切り替えます。

f:id:myudon:20220103010901p:plain

Query Builder Modeでは検索条件を追加する時は検索欄にあるプラスボタンを押して、フィルタ条件を指定します。

f:id:myudon:20220103012106p:plain

f:id:myudon:20220103012048p:plain

フィルタはアセットの種類やアタッチされているComponentなど、色々な条件がメニューに用意されています。 追加したフィルタは右クリックで後からアクティブの切り替えや中身の差し替えが可能です。

f:id:myudon:20220103020646p:plain

物によっては対象となるパラメータを元に条件を指定することも可能です。 たとえばアセットのIDやファイルサイズだったり、Prefabの種類だったり、特定のコンポーネントについてインスペクターから指定できる設定値だったり、様々なフィルタが用意されています。

f:id:myudon:20220103020502p:plain

f:id:myudon:20220103021234p:plain

f:id:myudon:20220103021255p:plain

パラメータ系のフィルタについては値やその条件となる等号などを調整可能です。

f:id:myudon:20220103021315p:plain

もちろんこれらの情報はQuery Builder Modeじゃなくとも記述すれば適応できるのですが、直感的に指定できるので便利です。

f:id:myudon:20220103014928p:plain

f:id:myudon:20220103015511p:plain

以上がQuery Builder Modeの紹介になります。

おわりに

本記事では紹介していない細かい機能もあるのですが、こちらは公式ドキュメントを参考にしてください。

docs.unity3d.com

何かしらアセットを探したり、メニューの操作や設定の調整で時間を消耗している人は活用してみてはいかがでしょうか。

2021年の振り返りと2022年の抱負

2021年にやったことを振り返りつつ、2022年頑張ることを書いていきます。

2021年やったこと

個人ブログ投稿 12本

昨年この技術ブログである「うどんてっくメモ」を再開し、今年は12個の記事を投稿しました。 単純に割ると月1つ出るかな、ぐらいのペースでした。

myudon.hatenablog.com

特にUnityが多くを占めていましたが、個人的に勉強を始めたRustに関してもちょろっと記事を出せたのは良かったなと思います。 閲覧数についても日々じわじわと上がっていっており、少し達成感を感じています。 今後も定期的に知識をアウトプットする場として活動していきたいです。

Zenn投稿 1本

基本的にアウトプットをブログに移行したのでQiita投稿はなかったのですが、Zennは一度投稿してみたくてRustの記事を書きました。

zenn.dev

結果的に想定していたよりも多くの方に見ていただけたようで、個人的には嬉しい記事になりました。 今後もちょっとしたTips系統はZennとかQiitaとかにあげれたらいいかもなと思っています。

技術書典の出典 会社と個人

技術書典で「UniTips」というUnityの技術書を定期的に会社で出しているのですが、2021年も執筆に参加しました。

creator.game.cyberagent.co.jp

第1回から携わってきていて、もう7冊目になるらしいです。時の流れを感じます。 技術書典12も既に予定されていますが、そこにも執筆予定です。 そして、個人執筆としてついに本を出すことができました。2021年の目標として掲げていた大きな点ですが、無事達成できました。

執筆自体は2月ぐらいからまずAmethystでサンプルゲームを作ったものをざっくり文章化し、それに伴って実装も調整したりし、なんやかんや半年ぐらいはかかった気がします。 隙間時間でちょこちょこと書いていたというのが大きな要因ではあるのですが、半年かかってようやく形になって本をビルドした時は感慨深いものがありました。 Twitter上でも多くの方に拡散していただけまして、結果としては想定を遥かに上回る数を手に取っていただけました。 今後も個人での本の執筆は挑戦していきたいですね。

商業誌執筆2冊

商業誌については業務でのお話と、技術書典で出した本の商業化のお話をいただきまして、執筆する運びとなりました。

creator.game.cyberagent.co.jp

nextpublishing.jp

商業誌を書く機会がまさか2回もあると思っていなかったので、今思うと貴重な体験をさせてもらえたなと思っています。 特に店頭に自分が書いた本が並んだり、Amazonでも自分の書いた本がヒットするというのはなかなかに嬉しかったです。 今後もお話をいただける機会があったり、チャンスがあったりすれば積極的に取り組んでみたいですね。

CA.unityの開催

どちらかというと業務に寄った話なのでアレですが、CA.unityというUnityのLTイベントを企画し、開催し始めました。 これは今年やったことの中でも大きな挑戦でした。

meetup.unity3d.jp

特に第1回は763人もの参加登録があり、運営としても驚愕のスケールとなりました。参加してくださったみなさま、本当にありがとうございました。 アーカイブに関しては全てUnityLearningMaterialsに掲載されてますので、ぜひチェックしてみて下さい。

learning.unity3d.jp

Gotanda.unity 登壇

Gotanda.unityというUnityのLTイベントについて、初登壇しました。 外部LTイベントについて、聞き手側としてはちらほら参加させてもらっているものの、登壇したことないなということで思い切って参加登録をポチりました。

learning.unity3d.jp

LT自体は社内ではちょこちょことやっていたので、ある程度は喋れるだろうと思っていたのですが、いざ本番になったらとても緊張したのを覚えています。 今振り返るともっと綺麗に話せたなとか、もっとスライド構成よくできたなとか、外部資料として残るならここの情報は可視化した方が良かったなとか、反省点が多いです。いい経験になりました。 今後も外部登壇にはチャレンジしていく予定です。

Qiitaアドベントカレンダー 2つ参加

毎年恒例アドベントカレンダー、2021年は会社のものとUnityのものに参加させていただきました。

myudon.hatenablog.com

myudon.hatenablog.com

会社のものについては去年同様に自分が運営を務めているのですが、今年も多くの方にご協力いただき、中身の大変濃いカレンダーが完成しました。 Unity、Golang、課金基盤、技術施策、新卒体験記などなど...さまざまな知見が詰まっていますので、よければ覗いてみて下さい。

qiita.com

2022年の抱負

アウトプットの戦略を立てる

2021年はブログ投稿、本の執筆、外部LT登壇、CA.unity、SNS宣伝などなど多角的にアウトプットに挑戦した一年でした。 結果的にこれまでの年で一番多くの人に知見を届けられたかなと思っています。多角的にやることで、アウトプットの手段についてのノウハウやそれぞれのメリデメを体感することができました。 これらの経験を活かし、自分にとっても業界にとってもより良いアウトプットに繋げられるように戦略をしっかり立てていきたいです。

  • アウトプットする内容の中でどこを簡潔に、どこを詳細に言語化するのか
  • どういったアウトプットの手法、規模感が好ましいか
  • 自分の知見でどの部分がアウトプットとして切り出せるか、どの部分がターゲットに有意義な知見になっているか
  • どういった広報で多くの人に届けることができるか

これらを考えつつ、良質なアウトプットを積極的にしていきたいなと思います。

インプットを大きめの年に

2021年は多角的にアウトプットを行った結果少しインプットは自分の満足いくものにはなりませんでした。 隙間時間に本を読んだり、記事を読んだり、というインプットは継続的にしているものの、ガッツリとインプットに時間を割いて知識を積む時間を作るというのは少し余裕がなかった一年でした。 今年はアウトプットを計画的にする中で効率化し、その時間をインプットに割いてより技術力を高める年にしていきたいです。 特に個人的にはRustに興味が強く、まだまだ勉強したいものも多いので、重視して計画していきます。

最後に

ここまでポエムを読んでいただきありがとうございました。 2021年はアウトプットについて大きな挑戦をしつつ、積極的に活動の幅を広げてみた一年でした。 2022年は2021年で培った土台をもとに、より多くのアクションを計画しながら知識を研鑽していければと思います。 2022年もよろしくお願いいたします。

【Unity】Unity2021.2で正式リリースされた2D Lightの紹介

この記事はUnity Advent Calender 2021 16日目の記事です。
15日目は @monry さんの「Unity Addressables Tips 〜2021年に於けるアップデート情報を添えて〜」でした。

先日Unity2021.2がリリースされ、さまざまな機能の改修が公式で紹介されていました。 その一つが「2D Light」の正式リリースです。

f:id:myudon:20211107200347g:plain

2D Lightはその名の通り2Dの描画物に対してライティングを行うもので、より高度な2D演出を可能にしてくれます。 初めての登場としてはUnity2019あたりで、Experimentalな機能としてここまで提供されていました。そんな正式リリースした2D Lightについて、その基礎的な機能や使い方について紹介します。 本記事で紹介および検証を行なっているツールのバージョンは次の通りです。

  • Unity 2021.2.0f1
  • Universal Render Pipeline 12.0.0

バージョンによっては挙動に差異がある場合もありますので、ご了承ください。

使い方

2D Renderer(SRP Asset)のとMaterialの設定

まず2D Lightを使うには、SRPの2D Rendererの設定を行う必要があります。 必要なのは2D Rendererのアセットです。メニューから2D Renderer付きのURP Assetを作成します。

f:id:myudon:20211105000856p:plain

作成するとRendererとPipelineのアセットが生成され、Pipelineには自動的にRendererがアタッチされた状態となります。 Edit -> Project SettingsからGraphicsの項目を開き、この生成したアセットを設定します。

f:id:myudon:20211105193736p:plain

Qualityごとの設定についても、必要に応じてアタッチしてください。

f:id:myudon:20211105194155p:plain

以上でRendererの設定は完了です。
Lightの影響を受けるスプライトについては専用のLitシェーダーが設定されていることを確認してください。

f:id:myudon:20211107185334p:plain

以上でスプライトが2D Lightの影響を受けるまでの前準備が完了です。

基本的なLightの作成と設定

2D Lightには次の4つの種類が存在します。

  • Global
  • Freeform
  • Sprite
  • Spot

それぞれのライトはヒエラルキー上の右クリックのメニューから作成できます。 作成されるもの自体は2D LightのコンポーネントがアタッチされたGame Objectで、その設定が違うだけです。

f:id:myudon:20211106103851p:plain

パラメータの設定はインスペクター上で設定可能です。 ColorとIntensity、そしてTarget Sorting Layerの項目があり、ライトの色と光の強さ、および対象のSorting Layerを調整できます。

f:id:myudon:20211106183050p:plain

ライトの種類ごとの挙動や設定についても説明します。

Global Light

Global Lightは全体を照らすライトです。設定した値が全体のライティングに反映されます。

f:id:myudon:20211107175031g:plain

全体的な2Dのベースのライティングの調整に活用するライトです。

Freeform Light

Freeform Lightはその名の通り自由変形してライティングする領域を矩形で指定できるライトです。

f:id:myudon:20211107175105g:plain

2Dの描画物に対してとりあえず任意の部分を明るくしたいといったケースでは非常にお手軽に反映させることができます。

Spot Light

Spot Lightは特定の位置に照明を当てたような円形のライティング効果を与えるライトです。 半径や円形に広がるライティング効果の減衰などを調整し、照らし方の調整ができます。

f:id:myudon:20211107175223g:plain

一点から照らすような効果を与えたい時にはSpot Lightを調整するといいでしょう。

Sprite Light

Sprite Lightはライティング効果を特定のスプライトの形状及び値を元に行います。

f:id:myudon:20211107175551g:plain

特定のシルエットによってライティング効果を出したい時には活用できます。

以上が2D Lightを使う上で基本となるライトの種類と設定になります。

Blending

2D Lightではそのライティング効果について、インスペクターからブレンドする計算を乗算にするか加算にするかを選択することができます。

f:id:myudon:20211107200834p:plain

画像にあるようにインスペクタからライトのブレンドを示すBlend Type、反映順序を示すLight Order、そして重なった際のライトの値の処理の種類となるOverlap Operationを設定できます。 Overlap Operationについては純粋な加算となるAdditiveとアルファ値の合成となるAlpha Blendが存在しており、単純にLightを合成する場合には前者を、Light Orderに沿って反映される効果を上書きしたい場合には後者を選択します。

Shadow Caster

2D Lightではライティングだけでなく、影を落とすこともできます。

f:id:myudon:20211113200446p:plain

影を落とすには2D Lightの設定と、スプライト側のコンポーネントのアタッチが必要になります。 まず2D Light側です。インスペクタのShadowsからStrengthを与えるとそれに伴った影が落ちるようになります。

f:id:myudon:20211107201618p:plain

そしてスプライト側ですが、これにはShadow Caster 2Dというコンポーネントをアタッチします。

f:id:myudon:20211107201731p:plain

落とす影の設定として、Use Renderer SilhouetteとCasts ShadowsとSelf Shadowsの三つの項目があります。 Casts Shadowsはそのまま影を落とすかどうかの設定となり、Use Renderer SilhouetteとSelf Shadowsは影の形状を調整する設定になります。Use Renderer Silhouetteでは影について描画されるスプライトの形状を加味するかどうか、Self Shadowsは自身に影を落とすかどうかの設定です。 こちらは公式ドキュメントの説明画像がわかりやすいです。引用した画像を次に示します。

f:id:myudon:20211109222017p:plain

また、複数のShadow Caster 2Dを利用する際には、Composite Shadow Caster 2Dというコンポーネントを利用します。 複数のそれらのオブジェクトの親にComposite Shadow Caster 2Dをアタッチすることで、それぞれをマージした一つの影として効果をシーン上に落とすことが可能です。

f:id:myudon:20211113195046p:plain

こちらについても公式ドキュメントの説明画像がわかりやすいです。 引用した画像を次に示します。 f:id:myudon:20211109223134p:plain

複数の影を干渉させるような表現を行う際には活用すべきコンポーネントとなります。

Normal Map

スプライトについて、ノーマルマップを用意したものについてはLight 2Dの効果にも反映されます。 例としてレンガのパターンで紹介します。これは反映せずにSpot Lightを当てた画像です。

f:id:myudon:20211106194404p:plain

これに適当に作ったNormal Mapを設定し、ライトの設定も調整すると次のようにライティング効果が変わります。

f:id:myudon:20211106194804p:plain

陰影が反映されて立体感が演出されているのがわかるかと思います。この手順についてみていきます。
まずはスプライト側です。これは難しいことはなく、該当するスプライトのSprite EditorからSecondery Textureとしてノーマルマップを指定するだけです。 スプライトのインスペクタからSprite Editorを選択し、左上のメニューからSecondary Textureの指定を行います。

f:id:myudon:20211107161718p:plain

_NormalMapと名前をつけ、設定するテクスチャをアタッチします。設定したSecondary Textureは選択して確認可能です。

f:id:myudon:20211107161613p:plain

以上でスプライト側の設定は完了です。次に2D Light側の設定を行います。 インスペクタの下の方にメニューがあるのでそこを調整します。

f:id:myudon:20211107162032p:plain

Qualityではその精度を設定できます。デフォルトではDisable、つまりは無効になっており、簡易的な計算によるFastとより正確な計算によるAccurateを選択します。 Distanceはライトとスプライトの距離を示しています。

Light Explorer

2D Lightも通常のLight同様にLight Explorerで設定の調整ができます。Light Explorerについて知りたい方は公式ドキュメントを参考にしてください。

f:id:myudon:20211107200730p:plain

一括でシーン中の光源の管理をしたいときにおすすめな機能です。

おわりに

Unity2021.2でようやく正式版になった2D Lightですが、さまざまな機能が用意されています。 単純に2Dの世界を明るくするだけではなく、よりリッチな表現をする上では非常に便利な機能となっているので、2Dの演出を考えている人はぜひ試してみてください。

さて、明日の Unity Advent Calendar 2021 は @Takaaki Ichijo さんの「ゲームのアドベンチャーパート(キャラクター掛け合い)の時系列演出をつくる」です。
お楽しみに〜!

参考文献

本記事の検証をするにあたって以下のサイトの素材を使用させていただきました。

かわいいフリー素材集 いらすとや

岩の無料イラスト | フリーイラスト素材集 ジャパクリップ

また、機能については公式ドキュメントを参考にさせていただきました。詳細な仕様を知りたい方はこちらを参照してください。

2D Graphics Features | Universal RP | 13.0.0

Riderで開発するなら知っておきたい2つのデバッグ機能

はじめに

本記事はQualiArts Advent Calender 1日目の記事となります。 今年もUnity、Golang、会社施策などQualiArtsで使われている様々な技術、取り組みについて紹介しますので、ぜひぜひチェックしてみてください。

qiita.com

自分からはUnityで開発する上で重宝するJetBrains製IDE、Riderに備わっているデバッグ実行時に使える便利な機能を2つ紹介します。 本記事で検証しているツールのバージョンは以下の通りです。

  • Rider 2021.2

バージョンによっては挙動に差異がある場合がありますのでご注意ください。

Riderのデバッグ機能

開発において必要不可欠と言えるのがデバッグ実行によるプログラムの検証です。 バグを調べるのに怪しい部分にブレークポイントを貼って、挙動を検証して、というのは誰しもやる開発手順だと思います。 Riderではステップごとに値を出力してくれるおかげで、とりあえずブレークポイントを貼って実行してみるだけでも多くの情報を得ることができます。

f:id:myudon:20211119195537p:plain

これだけでもありがたいのですが、Riderにはデバッグ実行をさらに効率化する2つの大きな機能が存在します。

Evaluate expressions

プログラムの実行中に「このタイミングで任意のパラメータの確認や評価をしたい...」ということは多々あるのではないでしょうか。そんな時に便利なのがこのEvaluate expressionsです。 Evaluate expressionsはブレークポイントで停止した地点で任意の式を評価し、その結果をいい感じに出力してくれる機能です。 使うには、ブレークポイントのステップ停止の時に画像にある電卓マークのボタンを押します。

f:id:myudon:20211119195710p:plain

押すとEvaluate expressionsのウィンドウが開きます。ここに任意の式を入力します。

f:id:myudon:20211119195824p:plain

gameObject.nameの中身が表示されているのがわかると思います。より機能を説明するために、次のUnityのプログラムとブレークポイントで動かしてみます。

public class test : MonoBehaviour
{
    void Start()
    {
        var hoge = new Hoge();
        var fuga = new Fuga();
        
        Debug.Log(hoge.value);
    }
}

public class Hoge
{
    public int value = 1;

    public void Test()
    {
        value *= 100;
    }
}

public class Fuga
{
    public List<int> list = new List<int>(){ 0, 1, 2 };

    public override string ToString()
    {
        return "FugaToString";
    }
}

f:id:myudon:20211119210716p:plain

プログラムを動かし、ブレークポイントの地点まで進んだところで、Evaluate expressionsを使用し、hogeの中身を確認します。

f:id:myudon:20211119211304p:plain

画像にあるように、Evaluate expressionsではそのステップでの入力補完をサジェストしてくれるので便利です。ローカル変数などもしっかりサジェストされます。 実行するとhogeの中身が確認できます。

f:id:myudon:20211119211417p:plain

fugaについても同様に見てみます。

f:id:myudon:20211119213019p:plain

fugaについてはObject.ToStringが実装されているため、その文字列が出力されています。デバッグ時に見やすくなるよう実装してあると捗ります。 また、fugaのメンバにはListがありますが、その中身についても確認できることがわかるかと思います。
今度は値の変更を行ってみます。hoge.valueについて別の値にしてみます。 右クリックして「Set Value」を選択すると値の変更ができます。

f:id:myudon:20211119213842p:plain

f:id:myudon:20211119213818p:plain

画像のように値の変更も可能です。この後にプログラムの実行を再開するとDebug.Logの結果として変更した値が出力されるのを確認できるかと思います。 このように、よしなに情報を確認したり変更したりするとても便利な機能がEvaluate expressionsとなります。 ちなみに筆者は業務でこのEvaluate expressionsは愛用しています。

Immediate window

Riderのデバッグ実行に付随する機能の中でも最も強力かなと思うのが、このImmediate windowです。 Immediate windowはいわゆる対話式でデバッグ操作を直感的に要求できる機能です。デバッグ実行した際にImmediate Windowは常時起動しています。 次の画像はデフォルトのレイアウトですが、値の表示の下に表示されています。

f:id:myudon:20211119215057p:plain

ここに任意の処理を対話式で入力すると、対応の出力を行なったり、処理を行なってくれます。 使い方について、Evaluate Expressionsと同様のプログラムとブレークポイントで試してみます。

public class test : MonoBehaviour
{
    void Start()
    {
        var hoge = new Hoge();
        var fuga = new Fuga();
        
        Debug.Log(hoge.value);
    }
}

public class Hoge
{
    public int value = 1;

    public void Test()
    {
        value *= 100;
    }
}

public class Fuga
{
    public List<int> list = new List<int>(){ 0, 1, 2 };

    public override string ToString()
    {
        return "FugaToString";
    }
}

f:id:myudon:20211119210716p:plain

まずは適当なパラメータについて確認してみます。出力したい変数の名前を入力するだけです。 ちなみにここでもサジェストはしてくれます。hogeを試しに出力します。

f:id:myudon:20211119215241p:plain

hogeの中身が出力されました。 また、fugaについても見てみます。

f:id:myudon:20211119215401p:plain

fugaのメンバの簡略的な情報が出力されました。また、Evaluate expressions同様にObject.ToStringで実装した文字列が出力されています。 Evaluate Expressionsのようにclassの要素全ては出力してくれませんが、一定の中身は確認することができます。
次はEvaluate Expression同様に値の変更をやってみます。Immediate Windowでは代入処理を書き込むだけで実現可能です。

f:id:myudon:20211120000113p:plain

hogeインスタンスの値を書き換えていることがわかるかと思います。 値の変更については先ほどのEvaluate Expressionsなど他の手順でも可能ですが、このImmediate Windowを介したやり方が一番手軽です。 また、便利なのが任意の関数呼び出しも行えるところです。例としてfugaのlistを操作してみます。

f:id:myudon:20211120000352p:plain

ListのAddを呼び出し、要素を更新しているのがわかるかと思います。ステップでの各値の状態を制御できるのはもちろん、任意の処理について特定のタイミングで正常な挙動をしているかの検証にも活用できます。 そしてさらにすごいのが、一時変数の定義までできてしまうことです。試しに別のListを定義してみます。

f:id:myudon:20211120002603p:plain

適当な一時変数のListを作り、その要素をfuga.listに追加しています。 このように、一時変数を置いて何かしらのパラメータを格納したり、それを元に処理を行うといったことも可能です。 ここまで説明したように、Immediate Windowはお手軽ながらも多くの便利なデバッグ機能が詰まっている素晴らしい機能です。ぜひとも触ってみてください。

おわりに

RiderはJetBrains謹製の強力なIDEであり、本当に多くの機能が存在します。 デバッグのための機能だけでも様々なものがあり、本記事では紹介しきれなかったものもいくつか存在します。 他の機能についても知りたい方は公式のドキュメントを参考にしてみてください。

www.jetbrains.com