Most recently, I realized that with the growing number of finished projects, more and more time has to be devoted to building builds. It cannot be said that the unit somehow complicates this process, but it certainly does not simplify it. Especially when each project is built for several platforms and even in different configurations. In principle, the problem is not new and has many different solutions. But for several reasons, I stopped writing my own plugin.
It looks like this:
And why, why, where to get and how to use, I will tell below.
The first discomfort is usually felt when more than one platform is being prepared for release. It turns out that in the unit some project settings are common for all platforms, and some are not. And it must always be remembered and taken into account. But in general, you can live.
Then it turns out that there is no possibility to save different settings within the same platform. A simple example: build one, and there are many sites on which it will be distributed. And for each you need something different. Partially this problem is solved by removing the settings in the runtime configuration in StreamingAssets. But only partially, because only what is happening inside the game can be configured this way. The icon in this way can not be replaced. Icon each time you need to change yourself. Whether by code, by hand, but by hand. And at some point, the responsible manager, whom you trained for a month to work with StreamingAssets, goes on vacation, but builds are needed yesterday.
Later you will learn that a separate Korean version is planned, everything should be different there and without #ifdef.
And then you are told that the game needs to be launched on mobile platforms, playstation, nintendo and washing machines.
As a result, the preparation of each new build over time becomes similar to this:
Check the instrument readings, turn on the toggle switch on the left, turn the lever on the right, turn the red valve on. Do not confuse and do not forget.
At first, it can still and nothing, but quickly tires. And remember all the manipulations in a month or two.
Internets and folk wisdom offer us the following:
Solved. We write our plugin with UI and fairies.
First you need to decide what we actually want to get and why.
The main part of our plugin is working with project settings, as well as storing and processing individual options settings. Therefore, we focus on this.
All unit settings are stored in the ProjectSettings directory in the project root. First of all, during initialization, we will save these settings in the plug-in directory (by the way, this is BuildVariants at the root of the project). This will be required so that we can track all subsequent changes. Next we need to somehow store them. The simplest thing would be to simply copy ProjectSettings to a separate place for each option. And at the time of its activation just replace them entirely. The idea is quite working and at first I looked at it. But this completely prevents us from inheriting options. And if we are already writing a plugin, we will immediately make it beautiful. So we need to learn how to read and write the contents of ProjectSettings.
For this you need to understand what is stored there. And the most ordinary assets are stored there, which are serialized and deserialized in a regular way. This means that we can read them through AssetsDatabase and get a SerializedObject. This is already something. Because we can go through all the SerializedProperty, track their differences with the original "snapshot" and save them in the version. Then, when assembling or activating a variant, we collect changes along the entire inheritance chain, apply them to the "snapshot" and drop them in ProjectSettings. Voila
But SerializedProperty has some unpleasant features: the way of storing values (all these intValue, floatValue, isArray), the absence of a normal mechanism for comparing them (there are two related objects, how do we understand all of them have the same values) and paradoxical (or no) the absence of the Serializable attribute (which means we will need some kind of wrapper to save). I can not say that these are some fatal flaws, All this was done more than once in numerous editor scripts. But I still want something more simple, understandable and universal.
Or maybe we will slightly limit the use of our plugin? Let it work only on projects with textual serialization of assets (and someone else uses binary?). Then all ProjectSettings will be stored as yaml documents. You can take the YamlDotNet library and use it to parse and save the settings. At the same time and keep your configs in yaml. So even clearer. It is only necessary to add a few extensions for diffs yaml documents and their combination.
A little mess with the editor window (I don’t even want to describe it, I hope that with UIElements it will be easier and more fun to live), collecting everything in a heap and ready.
It's time to show what I did . You have already familiarized with the main mechanisms of the plug-in operation, so further on some features:
$unity_path -batchmode -projectPath $project_path -quit -logfile -executeMethod BuildVariants.Controller.BuildController.BuildCollection -collection standalone
Of course, I want to feed the plugin with features to infinity, but it's time to return to real projects, and at the same time test the existing functionality. A little later, I want to apply UIElements for fresh versions of the unit, I hope this will make everything more beautiful and comfortable. I would also like to tie in versioning and some semblance of environment variables. Maybe the public will tell you something else in terms of functionality or usability.
Therefore, I will be glad to any wishes, comments, questions and bug reports. Easy builds to you!
Source: https://habr.com/ru/post/433460/
All Articles