Search Unity

Unity 2019.3 で再生モードへの素早い切り替えが可能に

, 11月 5, 2019

再生モードは、Unity での作業を快適なものにするための基本的な要素です。しかし、プロジェクトが複雑になってくると、再生モードの起動に時間がかかることがあります。再生モードの開始・終了の切り替えが素早くなればなるほど、修正作業やそのテストのスピードもアップします。このため、Unity 2019.3 ベータ版で、Configurable Enter Play Mode を実験版機能として公開します。

現段階では、エディターで再生モードに入ると Unity は 2 つの事を実行します ― スクリプトの状態のリセット(Domain Reload)と、シーンの再ロード(Scene Reload)です。これには時間がかかり、プロジェクトが複雑になればなるほど、新しく加えた変更を再生モードでテストする際の待機時間が長くなります。しかし Unity 2019.3 ベータ版からは、この「Domain Reload」と「Scene Reload」の 2 つのアクションのどちらかまたは両方を無効にすることが可能になります。

社内テストの結果、これにより待機時間が(プロジェクトによって)最大で 50% ~ 90% 短縮されることが分かっています。

某 AA 作品、Unity の『FPS Sample』、『Megacity』、そして空のプロジェクトを使って、Configurable Enter Play Mode のテストを行いました。上のグラフは、エディターが再生モードを起動するのに掛かった秒数を表しています。数字が小さいほど好ましい結果となります。

Edit > Project Settings > Editor から「Enter Play Mode Options」をオンにすると、 「Reload Domain」と「Reload Scene」のオプションが利用可能になります。詳細は Unity ドキュメンテーションの、再生モードの設定方法に関するセクションをご参照ください。

このオプションを使用すると、コードに変更が加えられていない場合に Enter Play Mode の処理から「スクリプトの状態のリセット(Domain Reload)」と「シーンの再ロード(Scene Reload)」の片方あるいは両方を省くことができます。また、再生モードを開始する前にゲームの状態をリセットしたい場合は、API とコールバックによって本機能にアクセスすることも可能です。

下の図は「Reload Domain」と「Reload Scene」をオフにしていない場合(Before)とオフにした場合(After)それぞれの、Enter Play Mode の処理を示すものです。

Unity が再生モードに入る時に実行する処理に関する詳細はドキュメンテーションでご確認いただけます。

本機能は現段階では試験的なものであり、全ての Unity パッケージが Domain Reload と Scene Reload の無効化に対応済み(検証済み)なわけではありません。何か問題を発見された場合は、フォーラムからご報告くださいますようお願いいたします。

Domain Reload をオフにした場合にスクリプトを正しく修正する方法

上述の通り、Domain Reload の回避は非常に簡単に行えますが、これには代償が伴います。再生モードの開始時にスクリプトの状態が正常にリセットされるようにするために、スクリプト内で static フィールドと static イベントハンドラーを調整することが必要になります。

以下のサンプルコードには、プレイヤーがジャンプボタンを押した時に上昇するカウンターが含まれています。「Reload Domain」がオンになっている場合、再生モードの開始時にカウンターが自動的にゼロにリセットされます。「Reload Domain」をオフにすると、カウンターがリセットされずに、再生モードの開始時・終了時に値が保持されるようになります。つまり、エディターでプロジェクトを実行した時に、(前回の実行時に値が変更されていれば)カウンターがゼロではなくなっている可能性が出てくるということです。

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] 属性を使用して、Domain Reload をオフにした場合にカウンターが正常にリセットされるように値を明示的にリセットしてください。以下に一例を示します。

Domain Reload をオフにすると、再生モードの終了時に、メソッドが静的なイベントハンドラーから登録解除されなくなります。静的なイベントハンドラーでメソッドを登録するコードがある場合は、これにより問題が発生する可能性があります。例えば、エディターでプロジェクトを初めて再生するとメソッドが通常通り登録されます。しかしこれを再び再生した時に、これらのメソッドは(1 回目の時に加えて)もう 1 回登録されることになり、したがってイベントの発生時に重複して呼び出されることになります。

以下のコードは静的なイベントハンドラー Application.quitting にメソッドを登録します。

上のサンプルコードは、Domain Reload がオフになっていると、再生モードが開始される度に新しく「Quit」メソッドを追加します。その結果、再生モードが終了される度に「Quitting!」のメッセージの表示が 1 回ずつ増えていくことになります。

[RuntimeInitializeOnLoadMethod] 属性を使用して明示的にメソッドを登録解除し、重複して追加されないようにしてください。

Domain Reload をオフにした場合にスクリプトが正常に実行されるようにするための修正に関する詳細は、ドキュメンテーションをご参照ください。

アセットストア

Unity では、アセットストアで人気のパッケージを確実に Domain Reload・Scene Reload の無効化に対応させたいと考えています。ご自分のプロジェクトで問題が発生したら、該当パッケージのパブリッシャー様にご報告いただくという形でご協力いただければありがたく思います。

Unity 2019.3 ベータプログラムにご参加ください

現在、ご自分のプロジェクトで再生モードの開始に時間がかかる場合は、本機能によって大幅なスピードアップが望めるでしょう。 ぜひ Unity 2019.3 ベータプログラムにご参加の上、本機能をお試しください。皆様のご意見・ご感想をフォーラムでお待ちしております。本機能は現段階では実験版です。皆様のニーズに合った機能の実現に向けて、ぜひご協力ください。特に(あらゆる種類の)問題についてのご報告をお待ちしております。

すでに本機能をお試しになり、コミュニティ全体にとって為になる貴重なご意見をお寄せくださったフォーラムユーザーの @Sini さん、@chrisk さん、@Peter77 さん、@Baste さんに深く感謝申し上げます。ありがとうございました。

26 replies on “Unity 2019.3 で再生モードへの素早い切り替えが可能に”

In my case, this function is wonderful. Thank you very much.
It would be good if you change

Options in File > Project Settings > Editor,

by

Options in Edit > Project Settings > Editor.

Have a nice day.

Why not just having an attribute to add to the fields/properties we want to be reset instead directly?
Like [InitializeOnLoadField]

I’ve tried InitializeOnLoadField approach and found that it introduces more issues than helps the feature.
There are mostly performance reasons:
1) Scanning for all fields of all classes in the domain is expensive – even with mono native api it takes 600ms on empty project (and seconds on big projects)
2) Static fields are initialized as a part of static class constructor. Simple 0 init case is trivial, but if there is anything else you basically have to split static constructor into 2 methods during compilation which involves a lot of changes in Mono, increases compile/jit times and is very risky.
TBH perhaps I exaggerated the issue with statics reset – in reality more likely you have a few singletons which might make sense to reset. If you don’t do any reset – the worst you can get is that you e.g. get asserts if you have any checks for singletons must be null, start playing from the same position you were last PlayMode cycle, etc. Which might be enough not not use the feature for existing projects. But if in the new project you rely on Awake/OnEnable for initialization (singletons, statics), then you will not have any issues.

Wow!
I just turned that on and playback is now instant!
Great for physics tuning, setting up a scene, doing some lighting and testing it in playback.
The extra [init stuff] is verbose, make it more HumanReadable

Saving a few seconds of your time to enter play mode doesn’t make much sense if you have to first spend a few hours (or days, for large projects) to fix all your code and make it compatible. And even after all the code is adjusted, you’ll always have to keep writing additional lines of code in the future as your project grows + spend more of your time hunting for obscure bugs happening because you forgot to reset correctly some variables. Won’t all of that essentially eliminate any time and productivity advantage gained through faster entering of play mode? Maybe a feature like that would make more sense if it came with an editor extension script (or something like that) automatically resetting all static variables and stuff.

We have it on our roadmap for the future to be able to customize the toolbar UI and use that to hook up this feature to toolbar buttons.

It is not that much of the code you have to change and maintain (can’t say for all projects, but for ones I saw). Some projects have very real 10-20 seconds wait time when entering Play Mode. You can taken that down to 1-2 seconds with this feature and then have happy artists on the team. Yes, when coding you have to keep 1-2 extra things in mind, but it is a low cost in most cases.
If you don’t have any issues with existing workflow – you can keep it as is. But if you have and want to iterate faster on your game we are opening new possibilities and working on a better tooling to highlight performance issues. The goal is that you enjoy you time in Unity Editor

How about quick access drodown in Play window for these Domain/Scene reload options?. this seems like the kind of thing which need to frequently accessed when going through rapid scrip iteration cycles. Sometimes i would want to enter as fast as possible if all i have changed is inspector values etc. but if i am doing significant code changes , i might seek domain reload to be able to validate the edits properly. This is far more relevant for someone like me , whoa is the sole designer/programmer in a very small team.

Totally agree, Have it as a separate play button with a rebuild script will be nice, sometines you want a quick play to balance the game and sometimes you want your code to be rebuild. Anyway, this is a great feature!

Yes, I agree. Wouldn’t it be easier to add another button to the main UI in the editor?
Instead of hiding it away in the settings menu? Maybe Refresh / Play / Pause / Step ?

well those workarounds to reset the statics and other stuff looks really dodgy.. I’m sure there is a way to have this performance boost and yet hide all that manual resetting of variables away from devs.. it sounds like another potential source of bugs and funky behaviors (even though only in editor)

Add the drop down UI near to enter play mode triangle. In order to faster switching between play modes and not go into settins each time.

Seems like holding a modifier key (or two) or providing a dropdown (or right-click popup) beside the play button to fast-select the mode you want to be in would be much more useful than digging into project configuration options, since sometimes I just want to nuke it all to debug something by performing a full domain reload, but this wouldn’t be often.
It would be LOADS better for FLOW to give users a fast way to access these options only a moment before pressing play…. A menu is not the right way forward for this — even temporarily.

I think what TextusGames meant was that sometimes you would want to change it to domain reload, scene reload, both, or none.
Basically sometimes we may not always want the same setting.

The decision, whether or not to adjust your script lifecycle to this needs to be done globally for your team. All coders need to keep this in mind while writing code. It’s then either turned on, giving you the benefit, or turned off, not introducing odd bugs. Leaving it up to individual team members to use it ad-hoc would be doing them a disfavor. This is not a “just hot patch my quick code/scene change in” toggle after all.

Would there be any way for the Editor to run some diagnostics automatically for us and find all these things that will break with the domain/scene reload disabled? The feature itself sounds incredibly cool, but could also cause a mountain of both initial and ongoing work to make sure that something insidious isn’t breaking the game because somebody forgot to reset a static.

Not in the 2019.3 release. In the short term the goal is to collect the feedback and get better understanding of what are the pain points with the experimental workflow.
I’ve highlighted the potential issue that had been already found in the forum post. Once we have a better coverage and a confidence that this mode is beneficial, we can design the tooling (e.g. static analysis) which can help with making sure project is not broken after code modifications.
And then move the feature out of the “experimental”. Please let us know what works and especially what not :)

AA production? Surely you mean AAA? AA is not an industry accepted term as far as I can see and google seems to agree.

AA games refer to games that do not reach the same scope as AAA games. It’s pretty common to see it pop up in dev circles in discussions about game budget and scope.

AA is pretty commonly referred to as higher-end indie games that have a larger budget and scope than most indie games, but is still a much smaller team/budget than a AAA production.

Yeah I have also known that as triple I, I am wondering whether that is just a UK thing?

Can also go the other direction: smaller scale non-indie contract work for a publisher with a budget higher than your regular indie but not reaching the hundreds of millions of AAA projects.

Comments are closed.