Using two versions (or more) of Unity on your computer
By default, when you install a
new version of Unity, it replaces the current one. But it is actually possible
to keep more than one version on your computer, which is useful if you're
working on a project and don't want to upgrade immediately, while still being
able to try and test the latest features. For example, when I was finishing to
port Flower Garden to Android, and getting ready to publish it, I kept using
4.1.2 since it was stable and the next versions introduced some bugs I could
not work around; but at the same time I was also getting those versions, to
check if there were some improvements the game could benefit from in the future,
and verify what the status was on those aforementioned bugs.
Keeping several versions is not
difficult: before installing a new one, you just have to rename the folder
containing the current one, et voila. For example, on Windows 7, I have the
older version in c:\Program Files (x86)\Unity4.1.2, and the newer one in
c:\Program Files (x86)\Unity. To run the current version, I use the usual Unity
icon; to launch the old one, I suppose I could create another icon, but I got
into the habit of opening a command window, navigating to the desired folder,
and launching Editor\Unity.exe.
By default, Unity reloads the
last project you worked on; but if that was a 4.1.2 project, and you're
launching 4.3, you don't want this behavior since your project would be
converted to 4.3 and you may not be able to load it in 4.1.2 anymore.
Fortunately, Unity warns you about it. One solution is to specify what project
you want to open, like this:
Editor\Unity.exe -projectPath
myProject
Or, you can also use a project
name that does not exist, and Unity will bring up the Project Wizard dialog.
However, the easiest way to solve the issue is to go to
Edit\Preferences\General in Unity's menu, and check Always Show Project Wizard
once and for all.
When you go back and forth
between versions of Unity and projects like this, it is possible that after
loading your scene looks empty and your hierarchy tab only contains the Main
Camera; do not panic, somehow the scene selection got lost, and you just have
to find and double click your scene in the Project tab to bring everything back
to normal.
Version control
As soon as you start working on a
project, you should put it under version control, so that you can go back in
time and check the changes you made even weeks ago if something goes wrong, or
merge with other people's changes if you're part of a team. In its initial
configuration, Unity is very unfriendly with external version control systems (by
"external" I mean: anything other than the Unity
Asset Server, which is a separate paid product): it creates lots of binary
files in the Library folder, mostly under Library\metadata, and there is no way
to know which ones need to be checked in. Even if there was, that wouldn't be
very useful, since binary files cannot be merged, and looking at differences
tells you nothing.
Fortunately, some version of
Unity introduced a
setting that will make your life easier: go to Edit\Project
Settings\Editor, and in the inspector, under Version Control, select the
Visible Meta Files mode. Ideally you should do that before you create anything
in your project, otherwise you probably want to quit Unity so that the magic
happens. Basically, once you're in this mode, every file under the Assets
folder will generate a new file of the same name with an additional
".meta" extension, that contains some information about the
corresponding asset. For example, the values of the parameters you can edit in
the inspector for one of your textures. These meta files are text files,
therefore it becomes possible to diff and merge them.
This is great for most assets,
but it's not a silver bullet: scenes and prefabs are still stored in binary
files, and cannot be merged if two people modify them around the same time. For
more information, see the following links:
Scripting and rendering
If you load resources with Resources.Load, you need to know it doesn't like backslashes in its file path,
only forward slashes should be used. This is especially annoying on Windows,
where backslash is the character used by Path.Combine to concatenate strings.
Therefore, don't forget to do something like: string filename = Path.Combine(ContentRoot,
name).Replace("\\", "/");
Since the geometry in Flower
Garden is procedurally generated, and although it could still have been stored
in game objects, I didn't feel the need to use mesh renderers and mesh filters:
instead, I call the lower level Graphics.DrawMeshNow function, that takes a
mesh and a matrix. Since I was taking that path, I thought I could do all the
processing and rendering of a single frame from the Update function of my main
script, pretty much the same way it works in the iOS version. That's not the
case though: rendering doesn't work in
Update, because the camera hasn't been set up yet and the frame buffer
cleared, etc. OnRenderObject was the right place for me, OnRenderImage and
OnPostRender are also worth checking out if you're thinking of doing some
"manual rendering".
At some point, I wanted to apply a
specific change to all the textures in my project, and I thought: Unity sure
knows who they are, and has all the code needed to load them, so why not write
a C# script, attach it to the main camera, and launch the game in the editor
once to run the code I'll put in the Start function? That sounded clever, until
I realized most of my textures were compressed and read only (most of yours
probably are too), and I needed them uncompressed and writeable in order to
process them. No problem, a quick search in the forums told me how to retrieve
the corresponding texture importers, and
change their properties before loading the textures the way I wanted them.
Problem is: when you do that, you don't work on copies of the importers, you
really modify "the real thing", and after happily running the game,
you soon notice you lost all your texture compression settings. So: be careful,
and use version control so that you can revert those unwanted changes.
Shaders in Unity are a strange beast, at least at first. I've
written simple shaders before, in assembly and HLSL, but when I started looking
for examples to do it in Unity, it seemed like there were 3 different ways to
do it, which I found confusing. My understanding is: you can use commands to
rely on color combiners and the fixed function pipeline, or write Cg code, or
use some kind of meta programming that will allow your shader to work correctly
with Unity's lights in both rendering modes (forward and deferred). Anyway, the
thing I want to point out is a bunch of rendering states (for example: writing
to the z-buffer or not, changing its test mode, setting the blending mode,
back-face culling, etc) are hard coded in the shader, and I did not find a way
to turn them into parameters I could set from script. I can see why it was done
like this, but it means each time I want to reuse a shader with one or more
rendering states having a different value than before, I need to duplicate the
shader. Not a huge deal in my case, but that's how Flower Garden ends up having
23 shaders (which I'm sure you would not guess by looking at it).
When assigning data to a Mesh, it seemed using null was not a good idea
(I haven't verified it recently, this may have changed). For example, if your
data doesn't contain texture coordinates, don't do mesh.uv = null; (that would
trigger an error), just leave that array alone. Same thing for normals, etc. I
can only assume mesh.uv (in my example) references a zero-sized array by
default, and replacing it with null prevents the engine from getting its
length, or something like that.
Making builds
Creating builds may fail on some platforms if some of your files are read only (for example, if you're using
Perforce for version control, and haven't checked those files out). The one I
know of from the top of my head is AndroidManifest.xml, that gets copied to
Temp\StagingArea during the build and needs to be writable to get modified.
Code stripping is not as smart as you may think. This Pro-only feature,
found in the Player Settings under Optimization | Stripping Level (for some platforms only), is meant to
reduce the size of your executable (and therefore the size of the file people
will download to play your game) by removing some libraries your script code is
not using. Ideally, this would mean that after the compiler has done its job,
the build process would figure out what classes or dll's are required, and get
rid of the rest (which is pretty much was this page says:
http://docs.unity3d.com/Documentation/Manual/iphone-playerSizeOptimization.html).
In reality, at least on Android, this is not what happens: it looks like a predefined list of classes, that are supposed to not be used very often by most developers, is simply excluded from the build, without any further test. I believe encryption classes are part of this list, and HttpWebRequest most definitely is: when I tried to enable code stripping in Flower Garden, the game would crash as soon as a script tried to use this class, that could not be found anymore (and no, I am not accessing it through reflection). One problem is: I don't use that class a lot, therefore I did not notice the crashes immediately, and when I got one it took me a while to realize code stripping was the culprit. No compiler error, no error when building, it's nasty. When I finally understood the issue, I had 2 options: disable code stripping, or rewrite the scripts that used the missing class in a different way; since I was getting close to publishing the game, and had 100 other little things left to do, you can guess which solution won.
http://docs.unity3d.com/Documentation/Manual/iphone-playerSizeOptimization.html).
In reality, at least on Android, this is not what happens: it looks like a predefined list of classes, that are supposed to not be used very often by most developers, is simply excluded from the build, without any further test. I believe encryption classes are part of this list, and HttpWebRequest most definitely is: when I tried to enable code stripping in Flower Garden, the game would crash as soon as a script tried to use this class, that could not be found anymore (and no, I am not accessing it through reflection). One problem is: I don't use that class a lot, therefore I did not notice the crashes immediately, and when I got one it took me a while to realize code stripping was the culprit. No compiler error, no error when building, it's nasty. When I finally understood the issue, I had 2 options: disable code stripping, or rewrite the scripts that used the missing class in a different way; since I was getting close to publishing the game, and had 100 other little things left to do, you can guess which solution won.
Since then, I learned there is a
third option: you can create a link.xml file under the Assets folder, and
specify in it some namespaces that should be included in (or: not excluded
from) the build. I haven't tried it yet, which is why I'm borrowing the
encryption example I found (warning: use at your own risk), instead of
following up with HttpWebRequest. It's good to have this workaround, but it still
looks to me like I'm doing the job of the computer, that should be able to
figure these things out much better than me.
<linker>
<assembly
fullname="mscorlib">
<namespace
fullname="System.Security.Cryptography" preserve="all"/>
<namespace fullname="System.Security.Cryptography.X509Certificates"
preserve="all"/>
</assembly>
</linker>
To Be Continued...
Nice tips! Couple clarifications:
ReplyDeleteOn version control. By default files like prefabs & materials are binary, but there's a setting to make them be text format right there in editor settings ("Asset Serialization").
Shaders and controlling states like blend mode etc. from variables: that was implemented in Unity 4.3. You can do "Cull [MyCullModeVariable]" for example and do material.SetInt ("MyCullModeVariable", x) from a script.
Thanks, that's great information!
Delete