Skip to content

[UUM-131032] Coreclr - fast enter playmode#666

Open
lopezt-unity wants to merge 13 commits intomasterfrom
coreclr/uum-131032-fast-enter-playmode
Open

[UUM-131032] Coreclr - fast enter playmode#666
lopezt-unity wants to merge 13 commits intomasterfrom
coreclr/uum-131032-fast-enter-playmode

Conversation

@lopezt-unity
Copy link
Copy Markdown
Collaborator

Purpose of this PR

Resetting static states on enter playmode :
Using [InitializeOnEnterPlayMode] attribute for editor only scripts and [RuntimeInitializeOnLoadMethod] for runtime ones.
Also fixing the state of tools when entering / exiting playmode as there were desync when in used while entering playmode.

Links

Jira: https://jira.unity3d.com/browse/UUM-131032

Comments to Reviewers

[List known issues, planned work, provide any extra context for your code.]

Copy link
Copy Markdown

@u-pr u-pr Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May require changes

This review identifies several issues related to static state management and potential memory leaks. Key concerns include a race condition in ActionSettings, incorrect initialization timing in ShowHoveredInfo, and potential material leaks. Several minor optimizations and consistency improvements are also recommended.

🤖 Helpful? 👍/👎

bool m_IsHovering;

#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high
The default load type for RuntimeInitializeOnLoadMethod is AfterSceneLoad, which executes after the scene has loaded and Awake has been called. If an instance of ShowHoveredInfo exists in the scene, its Start method may run before this reset, causing it to initialize m_Material only for it to be immediately nulled here. This can lead to NullReferenceExceptions if the material is used later and also results in a resource leak.

Using BeforeSceneLoad ensures the static reference is cleared before any instance logic runs.

Suggested change
[RuntimeInitializeOnLoadMethod]
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]

🤖 Helpful? 👍/👎

[RuntimeInitializeOnLoadMethod]
static void ResetStaticsOnLoad()
{
m_Material = null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium
When 'Enter Play Mode' is used with Domain Reload disabled, static material instances created via new Material() will leak if the reference is nulled without the material being destroyed. It is recommended to explicitly destroy the material before clearing the reference to prevent memory accumulation in the Editor.

Suggested change
m_Material = null;
if (m_Material != null) UnityEngine.Object.DestroyImmediate(m_Material);
m_Material = null;

🤖 Helpful? 👍/👎

[InitializeOnEnterPlayMode]
internal static void ResetPreviewActionManagerStatics()
{
Cancel();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high
There is a race condition here because the execution order of [InitializeOnEnterPlayMode] methods is undefined across different classes. If UndoUtility.ResetStaticsOnLoad (in UndoUtility.cs) executes before this method, the preview group index will be reset to -1 before Cancel() is called. This prevents UndoUtility.CancelPreview() from reverting the preview geometry, potentially leaving 'ghost' objects in the scene when Play Mode starts.

Consider using EditorApplication.playModeStateChanged with PlayModeStateChange.ExitingEditMode to ensure the cancellation happens before any static states are reset.

🤖 Helpful? 👍/👎

{
// Window may be destroyed when entering Play Mode without domain reload.
try { s_NotificationWindow.RemoveNotification(); }
catch {}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low
Empty catch blocks can swallow unexpected exceptions and make troubleshooting difficult. If the exception is expected because the window might be destroyed, consider checking for null first or catching a specific exception type (e.g., MissingReferenceException).

🤖 Helpful? 👍/👎

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void ResetStaticsOnLoad()
{
PI_2 = 2.0 * Math.PI;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low
This reset appears to be redundant because PI_2 is a private static variable assigned a constant value and does not seem to be modified anywhere else in the class.

🤖 Helpful? 👍/👎

// Reset the static variables to their initial values, these 3 static variables will be re-initialized when accessed
s_DefaultMaterial = null;
s_UnityDefaultDiffuse = null;
s_ShapePreviewMaterial = null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium
If these materials were instantiated using new Material() (which can occur in Init() if the resource load fails), they will leak in memory when the reference is nulled across Play Mode sessions. It is safer to check for null and call DestroyImmediate before resetting the reference.

🤖 Helpful? 👍/👎

Comment thread Runtime/Core/Normals.cs
Comment on lines +27 to +29
s_SmoothAvg = new Vector3[Smoothing.smoothRangeMax];
s_SmoothAvgCount = new float[Smoothing.smoothRangeMax];
s_CachedIntArray = new int[ushort.MaxValue];
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium
Re-allocating these large arrays every time Play Mode is entered increases GC pressure. Since these are static caches, consider using Array.Clear to reuse the existing arrays if they are already allocated.

🤖 Helpful? 👍/👎


#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void ResetStaticsOnLoad_UvAutoManualConversion()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low
The method name ResetStaticsOnLoad_UvAutoManualConversion is inconsistent with the ResetStaticsOnLoad naming pattern used throughout this PR.

🤖 Helpful? 👍/👎

@codecov-github-com
Copy link
Copy Markdown

codecov-github-com Bot commented Apr 23, 2026

Codecov Report

Attention: Patch coverage is 27.56098% with 297 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
Editor/EditorCore/PolyShapeTool.cs 0.00% 18 Missing ⚠️
Editor/EditorCore/SmoothGroupEditor.cs 0.00% 18 Missing ⚠️
Editor/EditorCore/Lightmapping.cs 0.00% 17 Missing ⚠️
Editor/EditorCore/MeshSelection.cs 26.08% 17 Missing ⚠️
Editor/EditorCore/EditorGUIUtility.cs 5.88% 16 Missing ⚠️
Editor/EditorCore/DrawShapeTool.cs 0.00% 14 Missing ⚠️
Editor/EditorCore/SceneDragAndDropListener.cs 6.66% 14 Missing ⚠️
Editor/EditorCore/EditShapeTool.cs 40.90% 13 Missing ⚠️
Editor/EditorCore/EditorUtility.cs 0.00% 13 Missing ⚠️
Editor/Overlays/ActionSettings.cs 0.00% 13 Missing ⚠️
... and 31 more
@@            Coverage Diff             @@
##           master     #666      +/-   ##
==========================================
+ Coverage   36.05%   37.79%   +1.73%     
==========================================
  Files         277      277              
  Lines       34909    38874    +3965     
==========================================
+ Hits        12588    14691    +2103     
- Misses      22321    24183    +1862     
Flag Coverage Δ
probuilder_MacOS_6000.0 35.25% <5.24%> (+0.67%) ⬆️
probuilder_MacOS_6000.3 35.25% <5.24%> (+0.67%) ⬆️
probuilder_MacOS_6000.4 35.24% <5.24%> (+0.67%) ⬆️
probuilder_MacOS_6000.5 35.25% <5.24%> (+0.67%) ⬆️
probuilder_MacOS_6000.6 35.25% <5.24%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
Editor/EditorCore/UVEditor.cs 39.11% <100.00%> (-0.67%) ⬇️
Runtime/Core/MaterialUtility.cs 50.00% <100.00%> (+7.14%) ⬆️
Editor/EditorCore/EditorHandleDrawing.cs 69.06% <96.00%> (+4.97%) ⬆️
Runtime/Core/Log.cs 7.87% <66.66%> (+1.27%) ⬆️
Runtime/Core/TransformUtility.cs 86.13% <50.00%> (-0.31%) ⬇️
Runtime/Core/UvUnwrapping.cs 96.55% <66.66%> (+1.16%) ⬆️
Editor/EditorCore/CutTool.cs 64.54% <72.72%> (+2.69%) ⬆️
Editor/EditorCore/EditorGUILayout.cs 15.21% <57.14%> (-1.26%) ⬇️
Editor/EditorCore/IconUtility.cs 84.84% <0.00%> (+0.23%) ⬆️
Editor/EditorCore/ProBuilderShapeEditor.cs 5.03% <40.00%> (+0.15%) ⬆️
... and 33 more

... and 40 files with indirect coverage changes

ℹ️ Need help interpreting these results?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant