12
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Unity】レイヤーを実質無限に使えるようにするライブラリの紹介【Layer2】

Last updated at Posted at 2022-12-15

はじめに

この記事は Unity Advent Calendar 2022 (その1) 16日目の記事になります。

前日の記事は @anidomanta さんの 「Tilemapを使ってキャラクターを歩かせたりジャンプさせたりする」 でした。

本稿では自分が個人で開発している「Unityのレイヤーを実質無限に使えるようにする」ライブラリを紹介します。

まだ開発途中の v0.1.0 で今後破壊的な変更あり&実践未投入なので、不具合など見つけたらTwitter(@su10_dev)かGitHubリポジトリのIssueまでお願いします🙏

モチベーション

Unityにはレイヤーの機能があり、レイヤーを使用することで以下のようなことができます。

  • 当たり判定の設定・管理
  • オブジェクトを描画する/しないの切り替え( Camera の設定)およびグループ化
  • ポストプロセシングを適用するオブジェクトの切り替えおよびグループ化

少なくともUnity2021.3で利用可能なレイヤーは最大32個で、そのうち5個( Default , TransparentFX , Ignore Raycast , Water , UI )がUnityによって予約・使用されています。

スクリーンショット_2022_12_15_20_20.png スクリーンショット_2022_12_15_20_25.png

Unityのレイヤー名設定画面とPhysicsのコリジョン設定

 
この制限は小規模な開発であれば問題ありませんが、中規模以上の開発やミニゲーム集のようなゲームでレイヤーを使おうとしたときに大きな障害となります。

例えば「6~20は演出(デザイナー)、21〜30は当たり判定(エンジニア)で使用する」みたいなルールで辛い経験をした結果、「今後はレイヤーを使用しない」という判断をするのも割とよくあることだと思います。

また、なるべくレイヤーを使わないために使えるAPIとして Physics.IgnoreCollision() というものもありますが、いちいちすべてのコリジョンに対して呼び出すのは現実的ではありません(参考:レイヤーを使わずに衝突判定をなくす方法)。

 
Layer2は

  • 個別のアセットとしてレイヤー設定(レイヤー名・コリジョンマトリクス)をまとめる
  • コンテキストに応じて複数のレイヤー設定を切り替える

ことで32個の上限を取り払い、レイヤーを実質無限に使えるようにします。

スクリーンショット 2022-12-15 20.30.24.png

Layer2のレイヤー設定アセット

 
イメージとしてはUnityのレイヤー設定の上に一つ間接化のレイヤーを敷く感じです。

レイヤー設定を間接化することは単にレイヤー数の制限を取り払うだけでなく、設定への依存をコンテキスト内に局所化することでレイヤーの負債化・硬直化を緩和する効果があります。

簡単な実装解説

コリジョンマトリクスの設定切り替えは通常のUnityのAPI呼び出しになっていて、

しているだけです。

レイヤー名は動的に変更するAPIが提供されていないので、レイヤー名を参照したい場合は LayerMask の代わりに Layer2Mask を使用する必要があります。

インストール

  • 対応バージョン:Unity2021.3以降
  1. Package Managerを開く
  2. [+▼] ボタンを押して Add package from git URL... を選択
  3. 以下を入力してEnter

使い方

設定ファイルを作成する

デフォルトの状態だと設定ファイルを作成できないので、必要に応じて SamplesCreate Asset Menu をインポートします。

スクリーンショット_2022_12_15_21_15.png

インポートが完了したら、

 AssetsCreateLayer2Layer Settings

で設定ファイルが生成されます。

スクリーンショット 2022-12-15 20.30.24.png

Layer2のレイヤー設定アセット

ちなみに

Create Asset Menu でインポートされるものは以下の小さなスクリプト一つです。

LayerSettingAsset.cs
using UnityEngine;

namespace Jagapippi.Layer2
{
    [CreateAssetMenu(menuName = "Layer2/Layer Setting")]
    public partial class LayerSettingAsset
    {
    }
}

設定アセットを作成するメニューのパスを変更したい場合は "Layer2/Layer Setting" のところを適宜変更してください。


レイヤーは設定アセット一つにつき32個まで定義できます。

デフォルトの状態だと自身で名前を決められるのは6~31までの25個までですが、編集不可になっている Builtin Layer はInspectorをDebugモードにすると強制的に変更できます(使用は自己責任で)。

Collision Matrixの設定は3D/2D両方対応していますが、UnityのAPIとの兼ね合いで一つの設定に3Dと2Dの設定がどちらも含まれる形になっています。

シーンやミニゲーム毎といった適当なコンテキストにつき一つの設定を作って使うイメージです。

レイヤーは並び替え可能ですが、並び替えてもシーンやプレハブにシリアライズされているレイヤーの値は変更されないので、すでに使用されているレイヤーの並び順を変更するともろもろ壊れてしまうことに注意してください。

レイヤー設定を切り替える

作成したレイヤー設定は LayerSettingSelection クラスから適用できます。

現状 LayerSettingSelection クラスは internal なので、Samplesの LayerManager プレハブを使用することを強くおすすめします。

また、Unityエディタ上では設定ファイルを選択したときのInspectorのヘッダーから以下の操作が行えます。

  • 現在適用されているレイヤー設定の確認
  • 設定を選択(エディタ用,非再生時のみ)
  • 設定を適用
  • 設定をコピー/ペースト
  • 設定をProject Settingsからロード

スクリーンショット_2022_12_15_21_47.png

ボタンのツールチップにも説明が表示されますが、非再生時にレイヤー設定を適用( Apply ボタン)すると以下のファイルに変更が走ります。

  • DynamicsManager.asset
  • Physics2DSettings.asset
  • TagManager.asset

レイヤー設定を切り替えるたびにファイルが変更されてほしくない場合は選択( Select ボタン)を使用してください。

選択/適用されているレイヤー設定は GameObject を選択したときのInspectorのヘッダーのレイヤー表示に反映されます(Layer2のドロップダウンが追加される)。

スクリーンショット_2022_12_15_21_50.png

その他の機能

デフォルトのGUIシステムをUI Toolkitに変更

2022以前のUnityエディタにLayer2を導入すると、Inspectorの表示に使われるデフォルトのGUIシステムがIMGUIからUI Toolkitに切り替わります。

これによって既存のカスタムエディタに問題が起きた場合、Scripting Define Symbolsに LAYER2_DISABLE_DEFAULT_CUSTOM_EDITOR を追加することでデフォルトのGUIシステムをIMGUIに戻すことができます。

その場合はLayer2のクラス・コンポーネントが正しく表示されなくなるので、自分でGUIの描画処理を書く必要があります。

Unity2022からはそもそもデフォルトでUI Toolkitが使用されるので、Unity2022を使用していれば問題は起きないはずです。

LayerMask から Layer2Mask への移行

Layer2を導入した場合、 LayerMask は使わずに Layer2Mask を使う必要があります。

プロジェクトの途中でLayer2を導入した場合は LayerMask 記述部分を機械的に Layer2Mask で置き換えればOKです。

Camera のInspector表示の拡張

Camera コンポーネントの最上部にLayer2用のレイヤー選択ドロップボックスが追加されます。

スクリーンショット_2022_12_15_22_36.png

既存のカスタムエディタとコンフリクトする場合、Scripting Define Symbolsに LAYER2_DISABLE_CAMERA_EDITOR_OVERRIDE を追加することで処理を無効化できます。

TODO

  • サンプルを充実させる
  • Harmonyを導入してUIをUnityエディタと統合する
    • GameObject 選択時のヘッダーを簡素化
    • Camera のレイヤー表示を簡素化
    • Layer2Maskstatic
  • 配布形態の追加
    • OpenUPM対応
    • unitypackage生成&リリースページ作成
  • GitHub Actionsでリリースの自動化

さいごに

私事で恐縮ですが、最近父親になりました。

育児って難しいですね。エンジニア的にいろいろ自動化・楽していきたいです。

 
◆ ◆ ◆

 
明日の Unity Advent Calendar 2022@yahagi_day さんの 「UnityをGithubActionsでビルドする」 です。

12
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?