Version: 2022.1
Legacy Upgrade Guides
Upgrading to Unity 2017.3

Upgrading to Unity 2018 LTS

Note: Follow the advice in this section in release order. For example, if you need to upgrade your project from 2018 to 2020, read the 2019 upgrade guides to see if there are any changes that you need to make before you read the 2020 upgrade guides.

This page lists changes in Unity 2018 LTS which might affect existing projects when you upgrade from a Unity 2017 version.

Note that 2018 LTS is also known as 2018.4.

Page outline


Improved Prefabs

  • PrefabsAn asset type that allows you to store a GameObject complete with components and properties. The prefab acts as a template from which you can create new object instances in the scene. More info
    See in Glossary
    automatically upgrade to the new Prefabs system.
  • To support prefab nesting, the prefab workflow has changed. To edit Prefabs, you now need to open them in Prefab Mode. You can no longer edit Prefabs in the Project Browser.
  • You also make structural changes in Prefab Mode, such as deleting GameObjectsThe fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject’s functionality is defined by the Components attached to it. More info
    See in Glossary
    , reparenting GameObjects, or replacing a Transform with a RectTransform. Alternatively, you can unpack a Prefab instance if you want to entirely remove its link to its Prefab Asset and thus be able to restructure the resulting plain GameObjects as necessary. You can no longer disconnect a Prefab instance.
  • The Editor tooling that creates GameObjects should use ObjectFactory.CreateGameObject to make sure that the GameObject ends up in the Prefab SceneA Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More info
    See in Glossary
    if a Prefab Asset is currently being edited in Prefab Mode.
  • As a safety precaution, scriptsA piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
    See in Glossary
    with the [ExecuteInEditMode] attribute cause the Editor to exit Prefab Mode when going into Play Mode, if any script on the open Prefab has that attribute. For details on how to make such scripts compatible with Prefab Mode, see the Scripting Reference pages for ExecuteInEditMode and the new ExecuteAlways attribute.
  • It’s no longer possible to make arbitrary modifications to Prefab Assets from scripts because Prefabs are now imported assets. Instead you need to use PrefabUtility.LoadPrefabContents, PrefabUtility.SaveAsPrefabAsset and PrefabUtility.UnloadPrefabContents.
  • If you use AssetDatabase.AddObjectToAsset to add additional assets to Prefabs, you must now call PrefabUtility.SavePrefabAsset after adding the requisite objects.

Back to top

USS flex shorthand expansion now follows CSS standard

  • The USS flex directive now accepts up to three parameters representing flex-grow, flex-shrink and flex-basis. The flex-shrink and flex-basis parameters are optional. If omitted, flex-basis defaults to 0 and flex-shrink defaults to 1.
  • Before 2018.3, flex: N was equivalent to flex N 0 auto. This now follows the CSS standard by making it equivalent to flex: N 1 0. To preserve the old semantic, you should replace all flex: N directives with flex: N 0 auto in your USS files.

Back to top

Support for logging unhandled exceptions in managed user threads

  • Before 2018.3, the Unity Editor did not log unhandled exceptions thrown in managed user threads. From 2018.3 onwards, unhandled exceptions thrown in managed user threads are logged on the Unity Editor console.
  • Because logging now includes all managed user threads, you may see exceptions that have always been thrown in your Projects, but were never emitted to the console until now.

Back to top

The VFACE shader variable is now inverted in DirectX (11 & 12)

  • The VFACE shaderA program that runs on the GPU. More info
    See in Glossary
    variable was not coherent between DirectX and other graphics APIs when rendering to a cubemapA collection of six square textures that can represent the reflections in an environment or the skybox drawn behind your geometry. The six squares form the faces of an imaginary cube that surrounds an object; each face represents the view along the directions of the world axes (up, down, left, right, forward and back). More info
    See in Glossary
    . Now it has the same behavior.
  • If you are using a VFACE bool shader variable in a DirectX shader to render a cubemap, then you have to flip the logic in your code.
  • See Issue ID 1027670.

Back to top

Upgraded PhysX from 3.3.1 to 3.4.2

Physics behaviour has changed and some Projects may behave differently with the new version. In particular:

  • The contact patches now contain up to 6 contacts in the Persistent Contact Manifold mode. This is an increase from 5 contacts per patch in previous versions. There is new code that merges patches in the manifold, and new code that selects contacts. CollisionsA collision occurs when the physics engine detects that the colliders of two GameObjects make contact or overlap, when at least one has a Rigidbody component and is in motion. More info
    See in Glossary
    appear to be a lot more accurate than before. You may need to work on Projects that rely on a particular arrangement of contacts to make them compatible with the new code. You are most likely to notice this when convex bodies collide with meshes and primitives.
  • A new algorithm is now used to compute contacts with terrains. It used to be special-cased, but now it’s the same mesh-primitive code that is used with MeshColliders. It’s robust, more accurate and performs well. However, it doesn’t support TerrainData.thickness, which means the tunneling effect with terrains is now possible. To avoid this, you need to enable continuous collision detectionAn automatic process performed by Unity which determines whether a moving GameObject with a Rigidbody and collider component has come into contact with any other colliders. More info
    See in Glossary
    on the fast moving objects. Before that, if a body was discovered to be no deeper than TerrainData.thickness under the terrainThe landscape in your scene. A Terrain GameObject adds a large flat plane to your scene and you can use the Terrain’s Inspector window to create a detailed landscape. More info
    See in Glossary
    , it was popped up automatically, but the normals were never correct. To get the old behaviour, uncheck the Enable Unified Heightmaps option in the Physics settings.
  • Negative meshThe main graphics primitive of Unity. Meshes make up a large part of your 3D worlds. Unity supports triangulated or Quadrangulated polygon meshes. Nurbs, Nurms, Subdiv surfaces must be converted to polygons. More info
    See in Glossary
    scaling
    no longer leads directly to mesh baking in all the cases. Concave meshes are not baked any more. However, Convex meshes still need to have scaling to be baked. With this change, negative scaling inverts the mesh normals when scale.x * scale.y * scale.z < 0. Additionally, non-trivial scaling like skew and shear still have to be baked, as before.
  • Convex mesh inflation is deprecated because it doesn’t seem to be needed with the new convex hull computation algorithm (Quickhull) that is more tolerant towards all sorts of imperfections in the input mesh.

Back to top

The AssetBundle.mainAsset property has been marked Obsolete

  • In Unity versions prior to 5.0, users had to build asset bundles using the AssetBundleBuildAssetBundle API which required providing an Object that would be returned when loaded using the AssetBundle’s mainAsset property.
  • The AssetBundle.BuildAssetBundle API was marked obsolete in Unity 5.0 and was replaced by AssetBundle.BuildAssetBundles, which changed how you get Assets from an AssetBundle.
  • You now need to get the Asset’s name, or path with the AssetBundle.LoadAsset API to get content from the AssetBundle. See documentation on Building AssetBundles, Using AssetBundles Natively, and the AssetBundle Scripting API.

Back to top

Upgrading Projects that use NavMesh components

  • If you are moving a Project from 2018.2 or earlier to 2018.3b and it uses NavMeshA mesh that Unity generates to approximate the walkable areas and obstacles in your environment for path finding and AI-controlled navigation. More info
    See in Glossary
    components obtained from Unity’s GitHub repository, you now need to use this branch.

Back to top

Particle System bug fixes

Unity 2018.3 includes some particle bugs fixes and this can affect your projects that were created in a previous version.

  • When using non-uniform Transform scale on billboardA textured 2D object that rotates so that it always faces the Camera. More info
    See in Glossary
    particles, the Y and Z axes were inverted. This has now been fixed.
  • When using non-uniform Transform scale on mesh particles, rotation was applied after scaling. This was a regression in 2017.x. It behaved correctly in 5.6 and earlier, but was broken in the 2017 cycle. Fixing this bug corrects content created in 5.6 and earlier, but changes content created in 2017.x.
  • Spherical wind zones had the opposite effect on particles compared to trees. This has been corrected so the spherical wind zones now repel particles instead of attracting them. You can restore the previous behavior by negating the External Forces Multiplier, or the Wind ZoneA GameObject that adds the effect of wind to your terrain. For instance, Trees within a wind zone will bend in a realistic animated fashion and the wind itself will move in pulses to create natural patterns of movement among the tree. More info
    See in Glossary
    strength. Unity can’t change this automatically as Scenes with trees or directional wind zones could be incorrectly affected.

Back to top

C# compiler upgrade to Roslyn

Before 2018.3, the Unity Editor used the mono C# compiler (mcs) when compiling C# files in a project. From 2018.3 onwards, the Roslyn C# compiler (csc) is used for projects targeting the new scripting runtime (.NET 4.x Equivalent). Different behavior may be noticed from the switch to Roslyn:

  • C# 7.3 is the supported
  • Additional warnings may be reported
  • Response files for the Roslyn compiler should be named csc.rsp. See PlatformDependentCompilation.

Back to top

The UnityScript and Boo scripts compiler has been removed

UnityScript (.js) and Boo (.boo) script files can no longer be compiled in the Editor.

For more information see this blog post from August 2017 and you can use the unityscript2csharp tool to convert UnityScript to C#.

Back to top

Animator Root Motion playback has changed

Animator Root MotionMotion of character’s root node, whether it’s controlled by the animation itself or externally. More info
See in Glossary
playback has changed slighly to correct some inconsistencies when authoring Root Motion Animations in the Animation Window.

  • Root Motion curves do not need to be generated for AnimationClips anymore. The application of Root Motion now depends solely on the Animator.applyRootMotion.

2018.2 to 2018.4 equivalencies

Case Generated Root Motion Animator.applyRootMotion 2018.2 2018.3 & 2018.4 (LTS)
A yes yes Apply Root Motion cumulatively on Root TransformThe Transform at the top of a hierarchy of Transforms. In a Prefab, the Root Transform is the topmost Transform in the Prefab. In an animated humanoid character, the Root Transform is a projection on the Y plane of the Body Transform and is computed at run time. At every frame, a change in the Root Transform is computed, and then this is applied to the GameObject to make it move. More info
See in Glossary
.
Same as 2018.2
B no no Apply Position, Rotation and Scale curves as authored in the AnimationClip. Same as 2018.2
C* yes no No root transform movement Apply Position, Rotation and Scale as authored in the AnimationClip.
D* no yes No root transform movement Apply Root Motion cumulatively on Root.

For cases C and D, to achieve the same result in 2018.3, you need to implement OnAnimatorMove, then discard Animator.deltaPosition and Animator.deltaRotation in cases where you don’t want to apply Root Motion.

If your Project uses applyRootMotion to “mute” Position, Rotation and Scale Animation on your Root Transform, then you need to override the Root Transform properties manually.

Back to top

UIElements.ContextualMenu changes

The UIElements.ContextualMenu menu action callbacks now takes a ContextualMenu.MenuAction parameter instead of an EventBase parameter.

ContextualMenu.InsertSeparator takes an additional string parameter.

Back to top

Multiplayer: The deprecated legacy networking APIs have been removed (RakNet based)

This feature was deprecated in Unity 5.1 and has now been removed. You can no longer use it in your projects in Unity 2018.2.

See the Multiplayer and Networking section for more information on networkingThe Unity system that enables multiplayer gaming across a computer network. More info
See in Glossary
in Unity.

Back to top

Photoshop Data file (PSD) import using transparency

When having actual transparency, Photoshop will tweak pixelThe smallest unit in a computer image. Pixel size depends on your screen resolution. Pixel lighting is calculated at every screen pixel. More info
See in Glossary
colors to blend them with matte (background) color. The process of preparing alpha channels properly is described in our how to prepare alpha channels documentation.

You can ignore dilation in this document, the important part is the note that states that you want to have an “opaque” image with a separate alpha channel/mask (instead of having transparency). Unity tweaked colors to “remove” matte, but this has ceased as of 2018.2. If you had PSD with transparency you might start seeing white color on the edges. To fix this, consult the manual link above and make an actual alpha channel (instead of transparency).

Back to top

Coroutines returned from a MonoBehaviour while its GameObject is being disabled or destroyed are no longer started.

Historically, when a GameObject is disabled or destroyed, it stops all running coroutines on its children MonoBehaviours. In certain cases, however, coroutines started from methods called during these times (for example, OnBecameInvisible()) were previously allowed to start. This led to component order-specific behavior and, in some cases, crashes.

In Unity 2018.1, coroutines returned during GameObject disable or destroy are no longer started.

Back to top

BuildPipeline APIs now return a BuildReport object instead of a string

The BuildPipeline APIs, such as BuildPipeline.BuildPlayer, and BuildPipeline.BuildAssetBundles, previously returned a string. This was empty if the build succeeded and contained an error message if the build failed.

In 2018.1, this has been replaced with the new BuildReport object, which contains much richer information about the build process.

To check whether the build succeeded, retrieve the summary property of the report object, and check its result property - it will be BuildResult.Succeeded for a successful build. For example:

var report = BuildPipeline.BuildPlayer(...);

if (report.summary.result != BuildResult.Succeeded)
{
    throw new Exception("Build failed");
}

Back to top

Player Quit notifications have changed from messages to Events

Previously, to be notified when the Unity standalone player was quitting, you would implement the OnApplicationQuit method on a MonoBehaviour and to abort the player from quitting you would call Application.CancelQuit.

Two new events have been introduced. These are Application.wantsToQuit and Application.quitting. You can listen to these events to get notified when the Unity standalone player is quitting. Application.wantsToQuit is called when the player is intending to quit, the listener for wantsToQuit must return true or false. Return true if you want the player to continue quitting or false to abort the quit. The Application.quitting event is called when the player is guaranteed to quit and cannot be aborted.

Application.CancelQuit has been deprecated, please use the Application.wantsToQuit instead.

using UnityEngine;

public class PlayerQuitExample

{

    static bool WantsToQuit()

    {

        // Do you want the editor to quit?

        return true;

    }

    static void Quit()

    {

        Debug.Log("Quitting the Player");

    }

    [RuntimeInitializeOnLoadMethod]

    static void RunOnStart()

    {

        Application.wantsToQuit += WantsToQuit;

        Application.quit += Quit;

    }

}

Back to top

Deprecating AvatarBuilder.BuildHumanAvatar on .NET platform

This change affect the following runtime platform: WSAPlayerX86, WSAPlayerX64, and WSAPlayerARM.

There is no replacement for now.

Back to top

TouchScreenKeyboard.wasCanceled and TouchScreenKeyboard.done have been made obsolete

There is a new TouchScreenKeyboard.status that can be queried to cover the deprecated states and more states.

Back to top

MonoDevelop 5.9.6 removed from Unity Installers and support for it has been deprecated in Unity.

MonoDevelop 5.9.6 has been replaced by Visual Studio for Mac on macOS as the bundle C# script editor in the macOS installer. Visual Studio 2017 Community is now the only C# script editor installed with Unity on Windows.

When it is installed in the default location next to the Unity executable, Unity no longer recognises MonoDevelopAn integrated development environment (IDE) supplied with Unity 2017.3 and previous versions. From Unity 2018.1 onwards, MonoDevelop is replaced by Visual Studio. More info
See in Glossary
as the “MonoDevelop (built-in)” external script editor in preferences. When no C# code editor is installed and selected in preferences, Unity uses the system default application for opening C# (.cs) scripts.

Back to top

BuildPipeline callback interfaces now take a BuildReport object

The BuildPipeline callback interfaces: IPreprocessBuild, IPostprocessBuild and IProcessScene have been changed so that they now require you to pass in a BuildReport object. This replaces the previous parameters for build path / target platform; you will need to change your code if you are implementing these interfaces.

Both the build path and the target platform can be accessed via the BuildReport object. The build path is now report.summary.outputPath and the target platform is report.summary.platform.

Back to top

Assets located in plugin folders will no longer be imported via specialized importers

Previously, assets located in plugin folders (for example, in directories with the extension .bundle, .plugin, or .folder) were imported using specialized importers. Textures were imported via texture importers, AudioClips via the audio importer, etc. Now all those assets will be imported using default importer, that means you won’t be able to reference those assets like you did before, because they no longer have a specialized type (Texture, AudioClip, etc). Plugin folders are contained packages, thus assets inside shouldn’t be accessible externally, except through plugin accessing techniques.

To continue using those assets, you’ll need to move them outside of your plugin folders.

Back to top

Particle System Mesh particles applied the Pivot Offset value incorrectly

The mathematical formula used for applying pivot offsets to Meshes was incorrect, and was inconsistent with how it worked for Billboard particles. To achieve the correct scale, the Pivot Offset should be multiplied by the size of the particle, so a Pivot Offset of 1 is equal to one full width of the particle.

For Meshes, the size was being multiplied twice, meaning the pivot amount was based on the squared particle size. This made it impossible to get consistent results in systems containing varying sized particles.

For systems using particles of equal size, the formula can be reverse-engineered to decide how much to adjust the pivot offset by, to compensate for this change in behavior:

Old formula: offset = size * size * pivot

New formula: offset = size * pivot

Therefore, if all particles are of equal size:

newOffset = pivot / size

In systems where the size varies between particles, a visual reassessment of the systems in question will be necessary.

Back to top

GPU Instancing supports Global Illumination

From 2018.1, Global IlluminationA group of techniques that model both direct and indirect lighting to provide realistic lighting results.
See in Glossary
(GI) is supported by GPU Instancing rendering in Unity. Each GPU instance can support GI coming from either different Light ProbesLight probes store information about how light passes through space in your scene. A collection of light probes arranged within a given space can improve lighting on moving objects and static LOD scenery within that space. More info
See in Glossary
, one lightmapA pre-rendered texture that contains the effects of light sources on static objects in the scene. Lightmaps are overlaid on top of scene geometry to create the effect of lighting. More info
See in Glossary
(but different region in the atlas), or one Light Probe Proxy VolumeA component that allows you to use more lighting information for large dynamic GameObjects that cannot use baked lightmaps (for example, large Particle Systems or skinned Meshes). More info
See in Glossary
component (baked for the space volume containing all the instances). Standard shaders and surface shadersA streamlined way of writing shaders for the Built-in Render Pipeline. More info
See in Glossary
come with these changes automatically, but you need to update custom shader code to enable these features.

Back to top

Handle Draw and Size Function Defaults

Complex handles in the UnityEditor.IMGUI.Controls namespace, such as BoxBoundsHandle, CapsuleBoundsHandle, SphereBoundsHandle, ArcHandle, and JointAngularLimitHandle have delegates that can be assigned to, in order to alter the appearance of their control points. Previously, assigning a value of null to these delegates would fall back to a default behavior. Assigning a value of null to them now results in no behavior, making it easier to disable particular control handles. Respectively, each class now has public API points for the default methods if you need to reset the control handles to their default behavior.

Back to top

Compiling ‘unsafe’ C# code in the Unity Editor now requires enabling of option.

Compiling ‘unsafe’ C# code now requires the Allow ‘unsafe’ code option to be enabled in the Player SettingsSettings that let you set various player-specific options for the final game built by Unity. More info
See in Glossary
for predefined assemblies (like Assembly-CSharp.dll) and in the inspectorA Unity window that displays information about the currently selected GameObject, asset or project settings, allowing you to inspect and edit the values. More info
See in Glossary
for Assembly Definition Files assemblies. Enabling this option will make Unity pass /unsafe option to the C# compiler when compiling scripts.

Back to top

‘UnityPackageManager’ directory renamed to ‘Packages’

In 2017.2 and 2017.3, the Unity Package Manager introduced the UnityPackageManager directory, which was used to store a file named manifest.json. Package content could be accessed by scripts using virtual relative paths starting with PackagesPackages are collections of assets to be shared and re-used in Unity. The Unity Package Manager (UPM) can display, add, and remove packages from your project. These packages are native to the Unity Package Manager and provide a fundamental method of delivering Unity functionality. However, the Unity Package Manager can also display Asset Store packages that you downloaded from the Asset Store. More info
See in Glossary
.

In 2018.1, the UnityPackageManager directory has been renamed to Packages for consistency with the virtual relative paths of packaged assets. The manifest.json file should automatically be moved to the new directory.

As a result:

  • If your project uses a Version ControlA system for managing file changes. You can use Unity in conjunction with most common version control tools, including Perforce, Git, Mercurial and PlasticSCM. More info
    See in Glossary
    System (VCS) such as PerforceA version control system for file change management. More info
    See in Glossary
    or Git, it may be necessary to update its configuration to track the Packages directory instead of the UnityPackageManager directory.

  • If your project uses Nuget (or any external package manager) in a way that makes it use the Packages directory, its configuration should be changed to use a different directory. This is recommended to eliminate the small chance that a package be picked up by the Unity Package Manager, which could result in hard-to-debug issues like compilation errors or import errors.

  • After migrating to the new directory, the UnityPackageManager directory can safely be deleted.

Legacy Upgrade Guides
Upgrading to Unity 2017.3