Version: 2021.1
Other Upgrade Notes for Unity 5.0
Обновление до Unity 3.5

Руководство по обновлению до Unity 4.0

Активное состояние игрового объекта

Unity 4.0 меняет способ управления активным состоянием Игровых Объектов. Теперь активное состояние Игровых Объектов наследуется дочерними Игровыми Объектами, так что при отключении любого Игрового Объекта, будут отключены и все его дочерние объекты. Мы верим что новое поведение гораздо правильнее старого, и всегда должно быть таким. Более того, грядущая новая система GUI сильно зависит от нового поведения 4.0 и была бы невозможна без него. К сожалению могут потребоваться усилия, чтобы исправить существующие проекты для работы с новым поведением Unity 4.0, и вот изменения:

Старое поведение:

  • Активен ли игровой объект или нет, определялось его свойством .active.
  • Это можно было проверить и определить обратившись к свойству .active.
  • Активное состояние Игровых объектов не влияело на активное состояние дочерних Игровых Объектов. Если вы хотели включить или отключить Игровой Объект и все его дочерние объекты, было необходимо вызвать GameObject.SetActiveRecursively.
  • При использовании SetActiveRecursively на игровом объекте, предыдущее активное состояние всех дочерних игровых объектов терялось. Когда вы деактивировали и затем активировали игровой объект и все его дочерние объекты используя SetActiveRecursively, любые дочерние объекты, которые были неактивны перед вызовом SetActiveRecursively, становились активными, и вам было необходимо вручную отслеживать активное состояние дочерних игровых объектов, если вы хотели восстановить его в прежнее состояние.
  • Префабы не хранили информацию об активном состоянии и были активны по умолчанию при создании экземпляра.

Новое поведение:

  • Активен ли игровой объект или нет определяется его собственным свойством .activeSelf, а так же этим свойством всех его родительских объектов. Игровой объект активен, если его свойство .activeSelf и это же свойство всех его родительских объектов равно - true. Если у любого из них это свойство равно - false, игровой объект будет неактивен.
  • This can be queried using the .activeInHierarchy property.
  • The .activeSelf state of a GameObject can be changed by calling GameObject.SetActive. When calling SetActive (false) on a previously active GameObject, this will deactivate the GameObject and all its children. When calling SetActive (true) on a previously inactive GameObject, this will activate the GameObject, if all its parents are active. Children will be activated when all their parents are active (i.e., when all their parents have .activeSelf set to true).
  • This means that SetActiveRecursively is no longer needed, as active state is inherited from the parents. It also means that, when deactivating and activating part of a hierarchy by calling SetActive, the previous active state of any child GameObject will be preserved.
  • Prefabs can contain active state, which is preserved on prefab instantiation.

Пример:

You have three GameObjects, A, B and C, so that B and C are children of A.

  • Деактивация C вызовом функции C.SetActive(false).
  • Теперь, A.activeInHierarchy == true, B.activeInHierarchy == true и C.activeInHierarchy == false.
  • Также, A.activeSelf == true, B.activeSelf == true и C.activeSelf == false.
  • Теперь деактивируем родительский объект A вызовом функции A.SetActive(false).
  • Теперь, A.activeInHierarchy == false, B.activeInHierarchy == false и C.activeInHierarchy == false.
  • Также, A.activeSelf == false, B.activeSelf == true и C.activeSelf == false.
  • Теперь мы активируем родитель A опять вызвав функцию A.SetActive(true).
  • Теперь мы возвращаемся к A.activeInHierarchy == true, B.activeInHierarchy == true и C.activeInHierarchy == false.
  • Также, A.activeSelf == true, B.activeSelf == true и C.activeSelf == false.

Новое активное состояние в редакторе

Для визуализации этих изменений, в редакторе Unity 4.0, любой неактивный Игровой Объект (любой если его свойство .activeSelf, либо у одного из его родителей, выставлено на false), будет серым в иерархии, и будет иметь серую иконку в инспекторе. Собственное свойство .activeSelf Игрового Объекта отображается его активным флажком, который может быть переключен независимо от состояния родителя (но активирует Игровой Объект, только если активны все его родители).

Как это влияет на существующие проекты:

  • To make you aware of places in your code where this might affect you, the GameObject.active property and the GameObject.SetActiveRecursively() function have been deprecated.
  • They are, however still functional. Reading the value of GameObject.active is equivalent to reading GameObject.activeInHierarchy, and setting GameObject.active is equivalent to calling GameObject.SetActive(). Calling GameObject.SetActiveRecursively() is equivalent to calling GameObject.SetActive() on the GameObject and all of it’s children.
  • Exiting scenes from 3.5 are imported by setting the selfActive property of any GameObject in the scene to it’s previous active property.
  • As a result, any project imported from previous versions of Unity should still work as expected (with compiler warnings, though), as long as it does not rely on having active children of inactive GameObjects (which is no longer possible in Unity 4.0).
  • If your project relies on having active children of inactive GameObjects, you need to change your logic to a model which works in Unity 4.0.

Changes to the asset processing pipeline

During the development of 4.0 our asset import pipeline has changed in some significant ways internal in order to improve performance, memory usage and determinism. For the most part these changes does not have an impact on the user with one exception: Objects in assets are not made persistent until the very end of the import pipeline and any previously imported version of an assets will be completely replaced.

The first part means that during post processing you cannot get the correct references to objects in the asset and the second part means that if you use the references to a previously imported version of the asset during post processing do store modification those modifications will be lost.

Example of references being lost because they are not persistent yet

Рассмотрим небольшой пример:

public class ModelPostprocessor : AssetPostprocessor
{
    public void OnPostprocessModel(GameObject go)
    {
        PrefabUtility.CreatePrefab("Prefabs/" + go.name, go);
    }
}


In Unity 3.5 this would create a prefab with all the correct references to the meshes and so on because all the meshes would already have been made persistent, but since this is not the case in Unity 4.0 the same post processor will create a prefab where all the references to the meshes are gone, simply because Unity 4.0 does not yet know how to resolve the references to objects in the original model prefab. To correctly copy a modelprefab in to prefab you should use OnPostProcessAllAssets to go through all imported assets, find the modelprefab and create new prefabs as above.

Example of references to previously imported assets being discarded

The second example is a little more complex but is actually a use case we have seen in 3.5 that broke in 4.0. Here is a simple ScriptableObject with a references to a mesh.

public class Referencer : ScriptableObject
{
    public Mesh myMesh; 
}


We use this ScriptableObject to create an asset with references to a mesh inside a model, then in our post processor we take that reference and give it a different name, the end result being that when we have reimported the model the name of the mesh will be what the post processor determines.

public class Postprocess : AssetPostprocessor
{
    public void OnPostprocessModel(GameObject go)
    {
        Referencer myRef = (Referencer)AssetDatabase.LoadAssetAtPath("Assets/MyRef.asset", typeof(Referencer));
        myRef.myMesh.name = "AwesomeMesh";
    }
}


This worked fine in Unity 3.5 but in Unity 4.0 the already imported model will be completely replaced, so changing the name of the mesh from a previous import will have no effect. The Solution here is to find the mesh by some other means and change its name. What is most important to note is that in Unity 4.0 you should ONLY modify the given input to the post processor and not rely on the previously imported version of the same asset.

Опция Чтения/Записи меша

Unity 4.0 adds a “Read/Write Enabled” option in the Model import settings. When this option is turned off, it saves memory since Unity can unload a copy of mesh data in the game.

However, if you are scaling or instantiating meshes at runtime with a non-uniform scale, you may have to enable “Read/Write Enabled” in their import settings. The reason is that non-uniform scaling requires the mesh data to be kept in memory. Normally we detect this at build time, but when meshes are scaled or instantiated at runtime you need to set this manually. Otherwise they might not be rendered in game builds correctly.

Оптимизация меша

The Model Importer in Unity 4.0 has become better at mesh optimization. The “Mesh Optimization” checkbox in the Model Importer in Unity 4.0 is now enabled by default, and will reorder the vertices in your Mesh for optimal performance. You may have some post-processing code or effects in your project which depend on the vertex order of your meshes, and these might be broken by this change. In that case, turn off “Mesh Optimization” in the Mesh importer. Especially, if you are using the SkinnedCloth component, mesh optimization will cause your vertex weight mapping to change. So if you are using SkinnedCloth in a project imported from 3.5, you need to turn off “Mesh Optimization” for the affected meshes, or reconfigure your vertex weights to match the new vertex order.

Мобильный ввод

With Unity 4.0 mobile sensor input got better alignment between platforms, which means you can write less code when handling typical input on mobile platforms. Now acceleration and gyro input will follow screen orientation in the same way both on iOS and Android platforms. To take advantage of this change you should refactor your input code and remove platform and screen orientation specific code when handling acceleration and gyro input. You still can get old behavior on iOS by setting Input.compensateSensors to false.

Other Upgrade Notes for Unity 5.0
Обновление до Unity 3.5