ZenjectEditorWindowの紹介
導入
こんにちは!クライアントエンジニアのNatsukiです。
みなさん、Unityの開発でZenject(Extenject含む)は使ってますか?
本日はZenjectEditorWindowをご紹介します。
対象読者はZenject初級者~中級者あたりを想定しています。
Zenject自体の説明はしませんのでご了承ください。
紹介
さて突然ですが、ZenjectにはContextという概念があります。
Zenjectでは、Contextに属するContainerを使って依存関係を解決します。
Contextには種類があり、それぞれ何らかの寿命に紐づいています。
Contextの種類をざっと挙げると、ProjectContext, SceneContext, GameObjectContextがあります。
ProjectContextはアプリの寿命(起動/終了)に紐づくContext、
SceneContextはシーンの寿命(Load/Unload)に紐づくContext、
GameObjectContextはGameObjectの寿命(Instantiate/Destroy)に紐づくContextです。
RuntimeやPlayモードでは上記のContextで問題なさそうですね。
ところで、「Editor上でZenjectが使いたい」という場合はどうするのでしょうか?
Contextを紐づけるための、何らか寿命があるオブジェクトは存在するのでしょうか?
もちろん、寿命があるオブジェクトは存在します。
それはウィンドウです!(ブログのタイトルでネタバレしてますが)
確かに、ウィンドウは開いた瞬間に生成されますし、閉じたら破棄されますもんね。
それをそのままContextにしてしまおう、というのがZenjectEditorWindowです。
(初めてZenjectEditorWindowを知ったとき、面白いアイデアだな~よく思いついたな~と思いました(小並感))
さて、紹介するだけなのもアレなので、実際のコードを交えて説明していきます。
ただ、ミニマムな状態で説明したいので、コードでやっていること自体に特に意味はありません。ご了承ください。
実践
ZenjectをImportした状態で、以下の3つのファイルを用意します。
- FilePathProvider: 書き込むファイルの場所を提供するクラス
- TheEditorWindowInstaller: ZenjectEditorWindowを継承したクラス
- TheEditorWindowCore: ウィンドウの実行部分
1 2 3 4 5 6 7 |
namespace Scripts { public class FilePathProvider { public readonly string TestText = "test.txt"; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
using UnityEditor; using UnityEngine; using Zenject; namespace Scripts.Editor { public class TheEditorWindowInstaller : ZenjectEditorWindow { [MenuItem("Window/TheEditorWindow")] public static TheEditorWindowInstaller GetOrCreateWindow() { var window = GetWindow<TheEditorWindowInstaller>(); window.titleContent = new GUIContent("TheEditorWindow"); return window; } public override void InstallBindings() { // IGuiRenderableやIDisposableを実装しているクラスに対してBindInterfacesAndSelfToすると // ZenjectがGuiRender()やDispose()を実行してくれる Container.BindInterfacesAndSelfTo<TheEditorWindowCore>().AsSingle(); Container.Bind<FilePathProvider>().AsSingle(); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
using System; using System.IO; using UnityEngine; using Zenject; namespace Scripts.Editor { public class TheEditorWindowCore : IGuiRenderable, IDisposable { private readonly StreamWriter _streamWriter; public TheEditorWindowCore(FilePathProvider filePathProvider) { _streamWriter = new StreamWriter(filePathProvider.TestText); Debug.Log("生成!"); } public void GuiRender() { if (GUILayout.Button("Hello World!")) { _streamWriter.WriteLine("Hello World!"); Debug.Log("書いた!"); } } public void Dispose() { _streamWriter.Dispose(); Debug.Log("破棄!"); } } } |
この状態でUnityを起動すると、WindowメニューにTheEditorWindowメニューが追加されているはずです。
TheEditorWindowを開くと「生成!」、ボタンを押すと「書いた!」、閉じると「破棄!」と表示されます。
また、プロジェクトフォルダを見ると「Hello World!」という中身でtest.txtが作られているはずです。
以上から分かる通り、ウィンドウをContextとして扱い、Editor上でZenjectを使うことができます。
サンプルコードでは特にメリットが感じられなかったかもしれませんが、Editor上でZenjectが使えるのは非常に強力です。
先ほどの例のように、Contextがウィンドウに紐づくので、
- ウィンドウでのみ使うリソースの注入/解放等をZenjectに任せること
ができます。更には
- 普段Zenjectで管理しているオブジェクトやキャラクターをシーンに出す
等も可能になります(!)。
以上、ZenjectEditorWindowの紹介でした。
日本語ではあまり取り上げられてないかなと思って取り上げてみました☆
- Tag
- Unity