├── Documents
├── imgs
│ ├── img_sample_save_play_mode_changes.png
│ └── img_sample_save_play_mode_changes.png.meta
└── imgs.meta
├── LICENSE.meta
├── README.md.meta
├── README_CN.md.meta
├── package.json.meta
├── Documents.meta
├── Editor.meta
├── Editor
├── Scripts.meta
├── Scripts
│ ├── Inspector.meta
│ └── Inspector
│ │ ├── SavePlayModeChangesInspector.cs.meta
│ │ └── SavePlayModeChangesInspector.cs
├── GBG.SavePlayModeChanges.Editor.asmdef.meta
└── GBG.SavePlayModeChanges.Editor.asmdef
├── EditorRuntime.meta
├── EditorRuntime
├── Scripts.meta
├── GBG.SavePlayModeChanges.EditorRuntime.asmdef.meta
├── Scripts
│ ├── SavePlayModeChanges.cs.meta
│ ├── SavePlayModeChangesTool.cs.meta
│ ├── SavePlayModeChanges.cs
│ └── SavePlayModeChangesTool.cs
└── GBG.SavePlayModeChanges.EditorRuntime.asmdef
├── README_CN.md
├── package.json
├── README.md
├── LICENSE
└── .gitignore
/Documents/imgs/img_sample_save_play_mode_changes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SolarianZ/UnitySavePlayModeChangesTool/HEAD/Documents/imgs/img_sample_save_play_mode_changes.png
--------------------------------------------------------------------------------
/LICENSE.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: de6edca8158e59a409ca3b190dd6ad6d
3 | DefaultImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/README.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 40bebb54d7898b64dab8d0a46da1fb4c
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/README_CN.md.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3be2e73a293280547bf412e9823f863d
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/package.json.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 726bdf36d20100744ba139283f976228
3 | PackageManifestImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Documents.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c2dd409603afa0540ad0b0582d7563a8
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2a44cbfed737a3e4daeee2a138c41928
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Documents/imgs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b152a64f7ab3dac4983fec665ab723e0
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Editor/Scripts.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d1ce08b5bc880654c9ee69f0b791349b
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/EditorRuntime.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 99d4de116f07ff94c88e70e5c59951a8
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Editor/Scripts/Inspector.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 0895ce4f6b0bf914495d7a8663ea4dbd
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/EditorRuntime/Scripts.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: dede3711c9270dc4488c2d5b8fc611f2
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Editor/GBG.SavePlayModeChanges.Editor.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 18d6fd1a284348649a729d586d9db99c
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/EditorRuntime/GBG.SavePlayModeChanges.EditorRuntime.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a2396422bacf79348bde7adf290b3c03
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/EditorRuntime/Scripts/SavePlayModeChanges.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 20a0b2c151d007f4da7a1d7e04cf8bb8
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/EditorRuntime/Scripts/SavePlayModeChangesTool.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f76fdde73110e9c499212811febc00b1
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Editor/Scripts/Inspector/SavePlayModeChangesInspector.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ed476579707c05b4e804c5e05ad3cbca
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/EditorRuntime/GBG.SavePlayModeChanges.EditorRuntime.asmdef:
--------------------------------------------------------------------------------
1 | {
2 | "name": "GBG.SavePlayModeChanges.EditorRuntime",
3 | "rootNamespace": "GBG.SavePlayModeChanges",
4 | "references": [],
5 | "includePlatforms": [],
6 | "excludePlatforms": [],
7 | "allowUnsafeCode": false,
8 | "overrideReferences": false,
9 | "precompiledReferences": [],
10 | "autoReferenced": true,
11 | "defineConstraints": [],
12 | "versionDefines": [],
13 | "noEngineReferences": false
14 | }
--------------------------------------------------------------------------------
/README_CN.md:
--------------------------------------------------------------------------------
1 | # Unity Play Mode 修改保存工具
2 |
3 | 
4 |
5 | [English](./README.md)
6 |
7 | ## 支持的Unity版本
8 |
9 | Unity 2019.4 或更新版本。
10 |
11 | ## 如何使用
12 |
13 | 将 `SavePlayModeChanges` 组件添加到Scene中的任意GameObject上,然后将要保存PlayMode修改的其他组件拖放到 `SavePlayModeChanges` 组件的 `ComponentsToSave` 列表属性中。
14 |
15 | 进入PlayMode并修改要保存的组建的属性,然后退出PlayMode,对**受支持的**属性的修改将会被保留。
16 |
17 | ## 使用限制
18 |
19 | 仅能在Editor中使用。
20 |
21 | 仅支持 **可序列化 托管** 属性。
22 |
--------------------------------------------------------------------------------
/Editor/GBG.SavePlayModeChanges.Editor.asmdef:
--------------------------------------------------------------------------------
1 | {
2 | "name": "GBG.SavePlayModeChanges.Editor",
3 | "rootNamespace": "GBG.SavePlayModeChanges.Editor",
4 | "references": [
5 | "GUID:a2396422bacf79348bde7adf290b3c03"
6 | ],
7 | "includePlatforms": [
8 | "Editor"
9 | ],
10 | "excludePlatforms": [],
11 | "allowUnsafeCode": false,
12 | "overrideReferences": false,
13 | "precompiledReferences": [],
14 | "autoReferenced": true,
15 | "defineConstraints": [],
16 | "versionDefines": [],
17 | "noEngineReferences": false
18 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "com.greenbamboogames.saveplaymodechanges",
3 | "version": "1.0.1",
4 | "displayName": "SavePlayModeChanges!",
5 | "description": "Save play mode changes.",
6 | "unity": "2019.4",
7 | "documentationUrl": "https://github.com/SolarianZ/UnitySavePlayModeChangesTool",
8 | "changelogUrl": "",
9 | "licensesUrl": "https://github.com/SolarianZ/UnitySavePlayModeChangesTool/blob/main/LICENSE",
10 | "keywords": [],
11 | "author": {
12 | "name": "GBG",
13 | "email": "vdergow@hotmail.com",
14 | "url": ""
15 | },
16 | "type": "tool",
17 | "hideInEditor": false
18 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Unity Save Play Mode Changes Tool.
2 |
3 | 
4 |
5 | [中文](./README_CN.md)
6 |
7 | ## Supported Unity Version
8 |
9 | Unity 2019.4 and later.
10 |
11 | ## How to use
12 |
13 | Add `SavePlayModeChanges` component to any game object in scene, then drag the component you want to save to `SavePlayModeChanges.ComponentsToSave` list.
14 |
15 | Enter play mode and modify any properties on the component you want to save, then exit play mode, all changes of **supported** properties will be saved.
16 |
17 | ## Limitations
18 |
19 | Editor use only.
20 |
21 | Only support **serialized managed** properties.
22 |
--------------------------------------------------------------------------------
/Editor/Scripts/Inspector/SavePlayModeChangesInspector.cs:
--------------------------------------------------------------------------------
1 | using UnityEditor;
2 | using UnityEngine;
3 |
4 | namespace GBG.SavePlayModeChanges.Editor
5 | {
6 | ///
7 | /// Custom inspector of .
8 | ///
9 | [CustomEditor(typeof(SavePlayModeChanges))]
10 | internal class SavePlayModeChangesInspector : UnityEditor.Editor
11 | {
12 | public override void OnInspectorGUI()
13 | {
14 | EditorGUILayout.HelpBox(SavePlayModeChanges.Tips, MessageType.Info);
15 |
16 | EditorGUI.BeginDisabledGroup(Application.isPlaying);
17 | base.OnInspectorGUI();
18 | EditorGUI.EndDisabledGroup();
19 |
20 | if (SavePlayModeChanges.CanCollectComponents())
21 | {
22 | EditorGUILayout.Space();
23 |
24 | if (GUILayout.Button("Collect All Components"))
25 | {
26 | ((SavePlayModeChanges)target).EditorOnlyCollectAllComponents();
27 | }
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Qiuyu ZHANG
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # This .gitignore file should be placed at the root of your Unity project directory
2 | #
3 | # Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore
4 | #
5 | /[Ll]ibrary/
6 | /[Tt]emp/
7 | /[Oo]bj/
8 | /[Bb]uild/
9 | /[Bb]uilds/
10 | /[Ll]ogs/
11 | /[Mm]emoryCaptures/
12 |
13 | # Asset meta data should only be ignored when the corresponding asset is also ignored
14 | !/[Aa]ssets/**/*.meta
15 |
16 | # Uncomment this line if you wish to ignore the asset store tools plugin
17 | # /[Aa]ssets/AssetStoreTools*
18 |
19 | # Autogenerated Jetbrains Rider plugin
20 | [Aa]ssets/Plugins/Editor/JetBrains*
21 |
22 | # Visual Studio cache directory
23 | .vs/
24 |
25 | # Gradle cache directory
26 | .gradle/
27 |
28 | # Autogenerated VS/MD/Consulo solution and project files
29 | ExportedObj/
30 | .consulo/
31 | *.csproj
32 | *.unityproj
33 | *.sln
34 | *.suo
35 | *.tmp
36 | *.user
37 | *.userprefs
38 | *.pidb
39 | *.booproj
40 | *.svd
41 | *.pdb
42 | *.mdb
43 | *.opendb
44 | *.VC.db
45 |
46 | # Unity3D generated meta files
47 | *.pidb.meta
48 | *.pdb.meta
49 | *.mdb.meta
50 |
51 | # Unity3D generated file on crash reports
52 | sysinfo.txt
53 |
54 | # Builds
55 | *.apk
56 | *.unitypackage
57 |
58 | # Crashlytics generated file
59 | crashlytics-build.properties
60 |
61 |
--------------------------------------------------------------------------------
/EditorRuntime/Scripts/SavePlayModeChanges.cs:
--------------------------------------------------------------------------------
1 | #if UNITY_EDITOR
2 | using System.Runtime.CompilerServices;
3 | using UnityEditor;
4 | using UnityEngine;
5 | using UnityEngine.Assertions;
6 |
7 | [assembly: InternalsVisibleTo("GBG.SavePlayModeChanges.Editor")]
8 |
9 | namespace GBG.SavePlayModeChanges
10 | {
11 | ///
12 | /// Save changes made to the components during play mode.
13 | ///
14 | [DisallowMultipleComponent]
15 | internal class SavePlayModeChanges : MonoBehaviour
16 | {
17 | public const string Tips = "Only support serialized fields and limited range of properties." +
18 | "\nProperty limitations:" +
19 | "\n SetMethod.MethodImplementationFlags should be contains InternalCall(declare with 'extern').";
20 |
21 | [Tooltip(Tips)]
22 | [SerializeField]
23 | private Behaviour[] _componentsToSave;
24 |
25 |
26 | private void Start()
27 | {
28 | if (_componentsToSave == null)
29 | {
30 | return;
31 | }
32 |
33 | foreach (var component in _componentsToSave)
34 | {
35 | if (component)
36 | {
37 | SavePlayModeChangesTool.RegisterComponent(component);
38 | }
39 | }
40 | }
41 |
42 |
43 | public static bool CanCollectComponents()
44 | {
45 | return Application.isPlaying == false;
46 | }
47 |
48 | public void EditorOnlyCollectAllComponents()
49 | {
50 | Assert.IsTrue(CanCollectComponents());
51 |
52 | var components = GetComponents();
53 | var validComponentCount = 0;
54 | foreach (var component in components)
55 | {
56 | if (component == this)
57 | {
58 | continue;
59 | }
60 |
61 | ++validComponentCount;
62 | }
63 |
64 | Undo.RecordObject(this, "Collect All Components");
65 | _componentsToSave = new Behaviour[validComponentCount];
66 | var componentIndex = 0;
67 | foreach (var component in components)
68 | {
69 | if (component == this)
70 | {
71 | continue;
72 | }
73 |
74 | _componentsToSave[componentIndex] = component;
75 | ++componentIndex;
76 | }
77 | }
78 | }
79 | }
80 | #endif
81 |
--------------------------------------------------------------------------------
/Documents/imgs/img_sample_save_play_mode_changes.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6ca35052c1a654e4ca8411e1eb337fb6
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 1
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | vTOnly: 0
27 | ignoreMasterTextureLimit: 0
28 | grayScaleToAlpha: 0
29 | generateCubemap: 6
30 | cubemapConvolution: 0
31 | seamlessCubemap: 0
32 | textureFormat: 1
33 | maxTextureSize: 2048
34 | textureSettings:
35 | serializedVersion: 2
36 | filterMode: 1
37 | aniso: 1
38 | mipBias: 0
39 | wrapU: 0
40 | wrapV: 0
41 | wrapW: 0
42 | nPOTScale: 1
43 | lightmap: 0
44 | compressionQuality: 50
45 | spriteMode: 0
46 | spriteExtrude: 1
47 | spriteMeshType: 1
48 | alignment: 0
49 | spritePivot: {x: 0.5, y: 0.5}
50 | spritePixelsToUnits: 100
51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
52 | spriteGenerateFallbackPhysicsShape: 1
53 | alphaUsage: 1
54 | alphaIsTransparency: 0
55 | spriteTessellationDetail: -1
56 | textureType: 0
57 | textureShape: 1
58 | singleChannelComponent: 0
59 | flipbookRows: 1
60 | flipbookColumns: 1
61 | maxTextureSizeSet: 0
62 | compressionQualitySet: 0
63 | textureFormatSet: 0
64 | ignorePngGamma: 0
65 | applyGammaDecoding: 0
66 | platformSettings:
67 | - serializedVersion: 3
68 | buildTarget: DefaultTexturePlatform
69 | maxTextureSize: 2048
70 | resizeAlgorithm: 0
71 | textureFormat: -1
72 | textureCompression: 1
73 | compressionQuality: 50
74 | crunchedCompression: 0
75 | allowsAlphaSplitting: 0
76 | overridden: 0
77 | androidETC2FallbackOverride: 0
78 | forceMaximumCompressionQuality_BC6H_BC7: 0
79 | spriteSheet:
80 | serializedVersion: 2
81 | sprites: []
82 | outline: []
83 | physicsShape: []
84 | bones: []
85 | spriteID:
86 | internalID: 0
87 | vertices: []
88 | indices:
89 | edges: []
90 | weights: []
91 | secondaryTextures: []
92 | nameFileIdTable: {}
93 | spritePackingTag:
94 | pSDRemoveMatte: 0
95 | pSDShowRemoveMatteOption: 0
96 | userData:
97 | assetBundleName:
98 | assetBundleVariant:
99 |
--------------------------------------------------------------------------------
/EditorRuntime/Scripts/SavePlayModeChangesTool.cs:
--------------------------------------------------------------------------------
1 | #if UNITY_EDITOR
2 | using System.Collections.Generic;
3 | using UnityEditor;
4 | using UnityEngine;
5 | using UDebug = UnityEngine.Debug;
6 |
7 | namespace GBG.SavePlayModeChanges
8 | {
9 | ///
10 | /// A tool used for save changes made to the components during play mode.
11 | ///
12 | internal static class SavePlayModeChangesTool
13 | {
14 | private static bool _isInitialized;
15 |
16 | private static readonly string _logPrefix = $"[Editor][{nameof(SavePlayModeChangesTool)}]";
17 |
18 | private static readonly HashSet _componentRegistry = new HashSet();
19 |
20 |
21 | ///
22 | /// Register a component so that to save the changes to it.
23 | ///
24 | ///
25 | public static void RegisterComponent(Behaviour component)
26 | {
27 | if (!Application.isPlaying)
28 | {
29 | UDebug.LogError($"{_logPrefix} Can't register component during edit mode.", component);
30 | return;
31 | }
32 |
33 | if (!component)
34 | {
35 | UDebug.LogError($"{_logPrefix} Register component failed: component is null.");
36 | return;
37 | }
38 |
39 | Initialize();
40 |
41 | _componentRegistry.Add(component);
42 |
43 | UDebug.Log($"{_logPrefix} Register component: {component}.", component);
44 | }
45 |
46 |
47 | private static void Initialize()
48 | {
49 | if (_isInitialized)
50 | {
51 | return;
52 | }
53 |
54 | UDebug.Log($"{_logPrefix} Initialize {nameof(SavePlayModeChangesTool)}.");
55 |
56 | EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
57 | EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
58 |
59 | _componentRegistry.Clear();
60 |
61 | _isInitialized = true;
62 | }
63 |
64 | private static void OnPlayModeStateChanged(PlayModeStateChange state)
65 | {
66 | if (state != PlayModeStateChange.EnteredEditMode)
67 | {
68 | return;
69 | }
70 |
71 | EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
72 | _isInitialized = false;
73 |
74 | ApplyChanges();
75 | }
76 |
77 | private static void ApplyChanges()
78 | {
79 | UDebug.Log($"{_logPrefix} Apply play mode changes...");
80 |
81 | foreach (var playModeComponent in _componentRegistry)
82 | {
83 | // playModeComponent==null is always true, but you can use ?. operator
84 | var componentId = playModeComponent?.GetInstanceID();
85 | if (componentId == null)
86 | {
87 | UDebug.LogError($"{_logPrefix} Skip destroyed play mode component.");
88 | continue;
89 | }
90 |
91 | var editModeComponent = EditorUtility.InstanceIDToObject(playModeComponent.GetInstanceID()) as Behaviour;
92 | if (!editModeComponent)
93 | {
94 | UDebug.LogError($"{_logPrefix} Skip nonexistent edit mode component: {playModeComponent}.");
95 | continue;
96 | }
97 |
98 | Undo.RecordObject(editModeComponent, "Apply Play Mode Changes");
99 | EditorUtility.CopySerializedManagedFieldsOnly(playModeComponent, editModeComponent);
100 |
101 | UDebug.Log($"{_logPrefix} Apply play mode changes to {editModeComponent}.", editModeComponent);
102 | }
103 |
104 | _componentRegistry.Clear();
105 |
106 | UDebug.Log($"{_logPrefix} Apply play mode changes done.");
107 | }
108 | }
109 | }
110 | #endif
111 |
--------------------------------------------------------------------------------