Planned breaking changes in Unity 6.5 [updated 2026-03-27]

Hi everyone,

As we did with Unity 6.4, here is some early notice about upcoming breaking changes we plan to make in Unity 6.5.

While our goal is for every release in the 6.x series to be a completely seamless upgrade experience, we also need to balance that goal against the need to evolve the product, both in response to external changes in our platforms and ecosystem, and as part of our long-term product roadmap. So, we’re making a few changes that may require a little bit of upgrade work on your part.

We’re sharing this now so that you can plan any needed work, and to give you the opportunity to let us know if there is some aspect of the change we haven’t considered. We don’t guarantee that every intentional breaking change is captured here, but we’ll cover as much as we can.

You may want to ‘Watch’ this thread, so that you can be notified when updates are posted.


Minimum supported Android API raised to Android 26 (8.0)

In Unity 6.5 we will update the minimum supported API required for running the Android Player to 26 (Android 8.0).

We are making this adjustment to be able to better support newer versions of Android. Android 7.1 has stopped receiving security updates since 2019. We expect this change to impact a very small number of devices and customers that are unable to upgrade to Android 8 or higher; the number of devices impacted is projected to drop even lower over 2026-2027.

Unity 6.0 LTS, 6.3 LTS, and Unity 2022 LTS will continue to support your projects at their existing minimum API requirements.

Updating Gradle and Android Gradle Plugin versions

We are updating Android’s internal build system to use Gradle 9.1.0 (updated from 8.11) and Android Gradle Plugin (AGP) 9.0.0 (updated from 8.7.2). This update is essential because Android mandates a new API level every year for publishing on the Play Store, and we need to update our tooling to support these new APIs. Leaving the tooling un-updated has been shown to increase risk for users in the long term, since then we need to stack up multiple Android tools updates at once.

Impact and Guidance if you are using custom Gradle plugins

While we will provide upgrade paths for the majority of potential user issues, the high configurability of the Android platform and the ability for users to add or create custom .gradle plugins means there may be cases where existing project-level Gradle code is incompatible with the new update. The breakage will likely manifest as build errors, specifically for projects with custom Gradle logic or older, incompatible third-party libraries.

To navigate this change when you upgrade, you should:

  • Review Migration Guides: If you are using custom gradle templates, check the official Gradle and Android Gradle Plugin migration guides to update any custom build logic and resolve common deprecation warnings.
  • Test Thoroughly: Prioritize testing any custom Gradle logic, as well as popular libraries (such as Firebase and Ads), after the upgrade to ensure full compatibility.
  • As previously mentioned, upgrading the majority of projects will happen seamlessly.

Removal of legacy Render Graph compiler

The Render Graph feature in the Scriptable Render Pipelines Core package historically had two graph compiler interfaces - a ‘legacy’ one, used by HDRP, and a newer one, used by URP. In Unity 6.3, we migrated HDRP to also use the newer interface, and marked the legacy one as obsolete with warnings.

In Unity 6.5, we will fully remove the legacy compiler interface. If you have a custom Scriptable Render Pipeline using legacy Render Graph, this may be a breaking change for you; you will need to use the new Render Graph interface instead, documented in the manual.

If you have a custom Scriptable Render Pipeline which is based on pre-Unity-6.3 HDRP, you may find it helpful to review the way we ported HDRP itself to use the new interface.

This change does not affect you if you are using the standard URP or HDRP pipelines, as we have already upgraded those pipelines to use the newer interfaces.

Decoupling Android Navigation Bar from fullscreen state

In current versions of Unity on Android, the Navigation Bar is hidden when the app is running in fullscreen mode, and shown when it is not running in fullscreen mode. This is controlled by your Player Settings (the setting is called “Hide Navigation Bar”, but actually governs whether the app runs in full screen), as well as by the runtime API Screen.fullscreen.

In Unity 6.5, we are introducing new controls and APIs to explicitly manage the visibility of inlays such as the Navigation Bar and Status Bar. As a part of this change, we are decoupling the visibility of the Navigation Bar from the fullscreen state.

The configuration in your PlayerSettings will carry over to the new system, but if you are using the Screen.fullscreen API at runtime to switch the Navigation Bar on/off, this will no longer affect the Navigation Bar visibility. You will need to migrate to our new runtime API, UnityEngine.Android.AndroidApplication.currentWindowInsets, to control Navigation Bar visibility at runtime.

Rendering Debugger transition to UITK

We’re planning to migrate the Rendering Debugger from being powered by uGUI and IMGUI, to being powered by UI Toolkit.

As a consequence of this, the Rendering Debugger package will no longer have a dependency on uGUI. If your project is using uGUI and the Rendering Debugger but you never explicitly declared a dependency on uGUI, it’s possible you’ll be broken by this change; to fix it, just declare the dependency in your project’s manifest.json explicitly.

We’re also removing the classes that support uGUI-based custom controls for the debugger. While they were technically public API, we don’t think it was actually possible for anyone to make them work without forking the package.

If you are using the DebugUI API to add custom controls to the Rendering Debugger, this change should be completely transparent to you. However, if your custom control needs to store state across domain reloads, we recommend updating your code to use the new ISerializedDebugDisplaySettings-based API, which we’re adding as part of this release. In a future release of Unity, we intend to make use of ISerializedDebugDisplaySettings mandatory for storing DebugUI state.

VR Module removal

The built-in “VR Module” in the Engine was marked as obsolete in Unity 6.3, and will be fully removed in Unity 6.5. This module supported some early Unity integrations with VR platforms.

All Unity XR packages have already been migrated to using the built-in “XR Module” as of Unity 2019 LTS, so no changes are required if you’re already on the latest XR packages.

If you have built a dependency on the VR module, please upgrade your projects to the latest XR packages, and modify any custom code using the VR Module to use the XR Module instead.

Removal of Entities ForEach and Aspects

Following our deprecation of ForEach and Aspects in Entities 1.4, we will fully remove these features from Entities in the upcoming release.

Projects using Entities.ForEach should migrate to using either IJobEntity or SystemAPI.Query, and projects using Aspects must instead make queries for the explicit components of interest. Detailed information about this is available in the Entities documentation.

ModelImporter API removal

Some obsolete ModelImporter APIs will now cause compilation errors if used. These APIs have been obsolete with warnings for some time now, and replacement APIs exist in all cases. Where possible your code will be automatically upgraded, but in some cases manual action will be needed. Follow the instructions provided in the error messages in order to resolve the issues.

This affects the following ModelImporter APIs:

  • isFileScaleUsed
  • normalImportMode
  • optimizeMesh
  • resampleRotations
  • splitTangentsAcrossSeams
  • tangentImportMode

Removal of ReplayKit support

We are removing the ReplayKit API, which was marked as obsolete in February 2024. ReplayKit allowed recording gameplay video and audio, including user commentary, via the device microphone and camera. It was implemented only for iOS.

If your project needs to use ReplayKit, you will have to interact with it directly through a native plugin. There are third party plugins available in the Unity ecosystem that may meet your needs.

Changing default log file path

Today, by default, the Editor log file is stored at the same location for all projects opened by a user:

  • Windows: %LOCALAPPDATA%\Unity\Editor\Editor.log
  • MacOS: /Library/Logs/Unity/Editor.log
  • Linux: /.config/unity3d/Editor.log

This is different from OS to OS, and also means that opening multiple projects can cause logs to be lost.

We will change this default location to be relative to the project by default, to Logs/Editor.log, making it consistent on all platforms and removing the possibility that Editor sessions will overwrite each other.

You may have scripts or automation that need updating to account for this change (for example, harvesting the log file as a CI/CD artifact). For scripts within Unity, use Application.consoleLogPath to retrieve the log file path instead of hard-coding it. For scripts outside of Unity, you can control where the log file is created by passing the -logFile parameter to the Editor when launching it.

Removal of temporary InstanceID type

As part of our ECS For All efforts, we are replacing the ‘instance ID’ concept used by all Unity objects with a new ‘entity ID’ which can be shared between both GameObjects and Entities. Part of this work included updating all Unity APIs that currently take an ‘instance ID’ to use the explicit EntityId type for the identifier, rather than simply an int value.

In Unity 6.2 we introduced both EntityId and also a temporary InstanceId type to help some (mostly internal-to-Unity) teams transition. The InstanceID type was marked as obsolete from its introduction, and in Unity 6.5 we are now making the use of it a compile error, meaning that only EntityId should be used going forward.

For more information, see ECS Development Status - December 2025.

Removal of Android x86_64 support

Following our deprecation of Android x86_64 support in Unity 6.3, Unity no longer supports the x86_64 Android architecture from Unity 6.5 and beyond.

As a result:

  • From Unity 6.5 you will no longer be able to select or build for the x86_64 Android architecture in Unity.
  • From Unity 6.5 Unity will no longer ship with the x86_64 Android runtime.

All officially supported Unity Android platforms (including phones, tablets, and XR devices) run on ARM; the only exceptions to this have been ChromeOS, which we stopped supporting after 2022 LTS, and Magic Leap, which we have announced will no longer be supported as of Unity 6.5. We are aware that some people may have used the Android x86_64 support to target unsupported emulated platforms such as Google Games for PC, but… well, they’re unsupported. If you still need to target Android x86_64, you should remain on Unity 6.3 or earlier.

If your project was exclusively targeting Android x86_64 and you upgrade it to 6.5, your project will no longer specify any target architectures.To ensure your project continues to build successfully, you must ensure you are targeting at least one supported Android architecture. This can be done in Player Settings.

GameObject.active and GameObject.SetActiveRecursively() formally obsoleted

GameObject.active and GameObject.SetActiveRecursively() have been marked as obsolete (with a warning) for a long time. We are cleaning up the public APIs for GameObjects and are now marking these two APIs as obsolete; attempting to use them in your code will produce a compile error. In a future version of Unity, these two APIs will be removed, to make the GameObject API easier and cleaner to work with.

If you are making use of GameObject.active, you should switch over to GameObject.SetActive(), GameObject.activeSelf or GameObject.activeInHierarchy depending on your use case.

If you are making use of GameObject.SetActiveRecursively(), Unity will automatically update the method to GameObject.SetActive().

EntityID (tentatively) changed to 8 bytes

We have replaced usages of the InstanceID int type with an opaque EntityId type to help lay the ground for ECS for All. This type should be treated as fully opaque and should not be treated as a fixed size or as containing a single int value. Starting with Unity 6.5, EntityId values will be represented by 8 bytes to support Entity index and versioning.

The move from InstanceID, which was 4 bytes, to an 8 byte EntityId, may result in extra memory being used per object; an increase of 4 bytes is small, but may add up across many objects. However, we are also working on some optimizations in the same area that may reduce memory consumption, so there is no guarantee that this change will result in an increase in memory overall - it may even be that with our optimizations, memory consumption goes down.

We are still in the process of measuring the impact of this change on real games through our Production Verification programme, but in the meantime, we plan to land this change into the 6.5 alpha releases. If we discover, either through Production Verification or through your reports to us, that the impact is to increase memory consumption by an unreasonable amount, then we will revert the change. We encourage you to try your projects on the 6.5 releases and review how your memory usage changes.

This change will also break any situations where you are packing an EntityId value into a 4-byte storage slot (e.g. when using a struct with explicit layout). You will need to review and adjust any of these places in your code.

HierarchyView and HierarchyWindow Event Signatures Updated

All public events on HierarchyView and HierarchyWindow now pass the sender instance as the first parameter, making it easier to identify which view or window fired the event when multiple Hierarchy windows are open. All multi-parameter events also use named delegate types instead of Action<...> for consistency and discoverability.

If your project subscribes to any of these events, you will receive compile errors. Update your handler signatures to include the new leading parameters. If you don’t need the sender, you can discard it with _.

Affected APIs:

HierarchyView events:

  • SourceHierarchyChangingEventHandler(Hierarchy, Hierarchy, HierarchyNodeFlags)SourceHierarchyChangingEventHandler(HierarchyView, Hierarchy, Hierarchy, HierarchyNodeFlags)
  • SourceHierarchyChangedEventHandler(Hierarchy, HierarchyNodeFlags)SourceHierarchyChangedEventHandler(HierarchyView, Hierarchy, HierarchyNodeFlags)
  • BindViewItem event type: ActionBindViewItemEventHandler(HierarchyView, HierarchyViewItem)
  • UnbindViewItem event type: ActionUnbindViewItemEventHandler(HierarchyView, HierarchyViewItem)
  • FlagsChanged event type: HierarchyViewModel.FlagsChangedEventHandler(HierarchyNodeFlags)HierarchyView.FlagsChangedEventHandler(HierarchyView, HierarchyNodeFlags)
  • PopulateContextMenuEventHandler(HierarchyViewItem, DropdownMenu)PopulateContextMenuEventHandler(HierarchyView, HierarchyViewItem, DropdownMenu)
  • GetTooltipEventHandler(HierarchyViewItem, bool, StringBuilder)GetTooltipEventHandler(HierarchyView, HierarchyViewItem, StringBuilder, bool) (note: tooltip and filtering parameters are also swapped)

HierarchyWindow events:

  • BindView event type: ActionBindViewEventHandler(HierarchyWindow, HierarchyView)
  • UnbindView event type: ActionUnbindViewEventHandler(HierarchyWindow, HierarchyView)
  • BindViewItem event type: ActionBindViewItemEventHandler(HierarchyWindow, HierarchyView, HierarchyViewItem)
  • UnbindViewItem event type: ActionUnbindViewItemEventHandler(HierarchyWindow, HierarchyView, HierarchyViewItem)
  • PopulateContextMenu event type: HierarchyView.PopulateContextMenuEventHandler(HierarchyViewItem, DropdownMenu)HierarchyWindow.PopulateContextMenuEventHandler(HierarchyWindow, HierarchyView, HierarchyViewItem, DropdownMenu)
  • GetTooltip event type: HierarchyView.GetTooltipEventHandler(HierarchyViewItem, bool, StringBuilder)HierarchyWindow.GetTooltipEventHandler(HierarchyWindow, HierarchyView, HierarchyViewItem, StringBuilder, bool) (note: tooltip and filtering parameters are also swapped)

Raising LevelPlay package version

For customers using Unity LevelPlay, we are raising the minimum supported version of LevelPlay to 9.0.0. If you upgrade a project using an older version of LevelPlay, Unity will automatically change your project to use version 9.0.0 of the LevelPlay package, and you may need to update your own code to work with the newer package. Information about how to do this can be found in the LevelPlay documentation.

Raising ML-Agents package version

We are updating the version of ML-Agents referenced in the Editor Manifest to 4.0. The previously referenced version depended on a very old and unsupported version of the Inference Engine; the newer version references a newer, currently-supported version.

If your project is using a version of ML-Agents which is older than 4.0, it will be automatically updated to 4.0 when opening your project in Unity 6.5.

32 Likes

The fact that we don’t even have beta 6.4 yet, but we already have a list of critical changes in 6.5, I’ll be honest, it shocks me a little. In any case, I am glad that we will find out about this in advance, although some things still remain a surprise - it was strange to learn with the release of Unity 6.3 that the Polybrush package was marked as deprecated, despite the fact that nothing was said about it anywhere.

Regarding the full switch to EntityId instead of InstanceID. It seems that the attribute for the OnOpenAssetAttribute callback was either not translated to EntityId, or it was not reflected in the documentation in any way - the term InstanceID is still used there, there is not a word about EntityId. But, the culbeck mechanism itself is so unfortunate that without documentation, we don’t even have the opportunity to understand which set of arguments is correct for the marked method and which is not.

UPD:
Sorry, my mistake: at the time of writing this post, I did not notice that beta 6.4 has been available for at least a few hours.

Im just building a project in 6.4 beta, its available now

We do: Unity 6.4 Beta is now available

3 Likes

“Removal of Entities ForEach and Aspects”

Does this mean you are actually going to update the DOTS Character Controller? Or will you leave it broken.

1 Like

Will these properties of Component ever be removed? It’s been quite some time since these were marked as deprecated.

[Obsolete("Property rigidbody has been deprecated. Use GetComponent<Rigidbody>() instead. (UnityUpgradable)", true)]
public Component rigidbody

[Obsolete("Property rigidbody2D has been deprecated. Use GetComponent<Rigidbody2D>() instead. (UnityUpgradable)", true)]
public Component rigidbody2D

[Obsolete("Property camera has been deprecated. Use GetComponent<Camera>() instead. (UnityUpgradable)", true)]
public Component camera

[Obsolete("Property light has been deprecated. Use GetComponent<Light>() instead. (UnityUpgradable)", true)]
public Component light

[Obsolete("Property animation has been deprecated. Use GetComponent<Animation>() instead. (UnityUpgradable)", true)]
public Component animation

[Obsolete("Property constantForce has been deprecated. Use GetComponent<ConstantForce>() instead. (UnityUpgradable)", true)]
public Component constantForce

[Obsolete("Property renderer has been deprecated. Use GetComponent<Renderer>() instead. (UnityUpgradable)", true)]
public Component renderer

[Obsolete("Property audio has been deprecated. Use GetComponent<AudioSource>() instead. (UnityUpgradable)", true)]
public Component audio

[Obsolete("Property networkView has been deprecated. Use GetComponent<NetworkView>() instead. (UnityUpgradable)", true)]
public Component networkView

[Obsolete("Property collider has been deprecated. Use GetComponent<Collider>() instead. (UnityUpgradable)", true)]
public Component collider

[Obsolete("Property collider2D has been deprecated. Use GetComponent<Collider2D>() instead. (UnityUpgradable)", true)]
public Component collider2D

[Obsolete("Property hingeJoint has been deprecated. Use GetComponent<HingeJoint>() instead. (UnityUpgradable)", true)]
public Component hingeJoint

[Obsolete("Property particleSystem has been deprecated. Use GetComponent<ParticleSystem>() instead. (UnityUpgradable)", true)]
public Component particleSystem
18 Likes

FWIW, we don’t consider marking something deprecated to be a breaking change (as it doesn’t actively stop it working, so it shouldn’t block you from upgrading to the new release), which is why there was nothing about it in the breaking changes thread. You’re right that there should still have been some communication about it somewhere else, though. We are investigating what happened there and I think someone will be coming through with a statement about it in the near future.

Thanks! It looks like the attribute was indeed updated in 6.3 to support EntityId alongside int, but the documentation was missed. I’ve submitted a ticket for the Docs team to update the page.

4 Likes

Hi @RichardFine,

I really like the transparency you provide well in advance about this breaking changes.

Two and a half years ago, I reported IN-46716: Unity Issue Tracker - Pose variable format doesn’t change when changing its format
Issue is that Pose.ToString("f6") works great but the string interpolation $"{pose:f6}" don’t: it only output 2 decimals for the position and 5 for the rotation.

The bug has been closed as “won’t fix”:

After evaluating the impact, workaround and risk associated with fixing this issue, in addition to the current team’s bandwidth and priorities, we have concluded that this issue will not be addressed in the foreseeable future.

I don’t even understand how it was considered as a risky change: if someone is using “:f6” in string interpolation, it’s already broken for him.

Is it a bug Unity can now consider to fix in a new 6.x version, along those breaking changes? How to get it re-evaluated?

The character controller was updated to remove aspects two months ago, right? Honestly, I found aspects and EntityForeach quite convenient, but I think they removed them because they didn’t have enough manpower to maintain them.

The latest update of the character package (1.4.1) made Aspects optional

So, users can now use the package without any reliance on Aspects, but their old characters that were relying on the Aspect will still work until Aspects are truly gone from the engine. This gives users a time window in which they can convert their characters to aspect-less.

Here’s the post on the topic, with instructions for converting to aspects-less:
https://discussions.unity.com/t/new-aspects-less-structure-in-com-unity-charactercontroller-1-4-1/1693777

Hi. I think the docs could have more info with respect to these changes. Most of these APIs for EntityId exist since 6.3, but EntityId doesn’t even appear in the reference. Object.GetEntityId is also missing from the reference. Are there any plans to add this kind of missing APIs to the docs?

IMO, it’d be nice if there was a page in the manual about using EntityId with UnityEngine.Object, and the affected APIs. It could help a lot with migration. From what I’m seeing, I could do most of the changes in my code from Unity 6.3, which is nice because it’s LTS, and be prepared for the future.

The only thing I see missing in Unity 6.3 to do all the required changes is SerializedProperty.objectReferenceEntityIdValue, which is needed in custom editors to detect when an Object reference is missing. It’d be nice if that property could be added to 6.3, though I imagine it might be against the usual policy.

1 Like

If I’m getting this right, Object.GetInstanceID is getting deprecated or it will change to return an EntityID instead of int?

It was deprecated in 6.4. There’s a new method GetEntityId, introduced in 6.3, but it’s not in the docs.

That’s a pretty huge change… since the return type is not int anymore I guess that opening a 6.3 project with 6.4 won’t auto-update the code, right?

I guess so too, I haven’t tried. EntityId is currently castable to an int, but it seems it will not be castable in 6.5, because the data inside EntityId will need 64 bits.

Yeah, looking at EntityID it seems that internally is an int m_data.

But if it stops being an int is a pity, because it was a great way to have a fast index for dicitonaries, for example.

1 Like

From the post about ECS status:

The ECS Entity type consists of 2 components: an index and a version. It also implements IEquatable and has a proper GetHashCode. So you can still use EntityId as the key of a dictionary.

Note that the version signifies how many times the index has been reused. So the sole index is not enough to guarrantee the uniqueness of EntityId.

3 Likes

Yeah, performance-wise it’s slower having a struct as key “in theory”, but should be negible in real world.

And as you mention we can’t rely just in the index, the whole struct is the unique identifier.

2 Likes

Yeah, but it may not be as fast. One can also use Objects themselves as keys, but int tends to be more performant.

One could keep their own int ids easily, though. It just needs a static field to keep the last id assigned to an Object, and every new id is just the last id incremented by one.