com.artromskiy.deltaecs.unity 0.0.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/Editor/BoundEntityRootEditor.cs +288 -0
  3. package/Editor/BoundEntityRootEditor.cs.meta +2 -0
  4. package/Editor/ComponentDropdown.cs +73 -0
  5. package/Editor/ComponentDropdown.cs.meta +2 -0
  6. package/Editor/ComponentListController.cs +26 -0
  7. package/Editor/ComponentListController.cs.meta +2 -0
  8. package/Editor/DeltaECS.Unity.Editor.asmdef +18 -0
  9. package/Editor/DeltaECS.Unity.Editor.asmdef.meta +7 -0
  10. package/Editor/EditorLifecycle.cs +143 -0
  11. package/Editor/EditorLifecycle.cs.meta +2 -0
  12. package/Editor/EntityInspectorTarget.cs +26 -0
  13. package/Editor/EntityInspectorTarget.cs.meta +3 -0
  14. package/Editor/HierarchyMenu.cs +85 -0
  15. package/Editor/HierarchyMenu.cs.meta +2 -0
  16. package/Editor/HierarchyNodeHandler.cs +950 -0
  17. package/Editor/HierarchyNodeHandler.cs.meta +2 -0
  18. package/Editor/HierarchySelection.cs +171 -0
  19. package/Editor/HierarchySelection.cs.meta +3 -0
  20. package/Editor/InspectorState.cs +220 -0
  21. package/Editor/InspectorState.cs.meta +2 -0
  22. package/Editor/Resources/Inspector/BoundEntityRootEditor.uss +28 -0
  23. package/Editor/Resources/Inspector/BoundEntityRootEditor.uss.meta +2 -0
  24. package/Editor/Resources/Inspector/SceneAuthoringEditor.uss +282 -0
  25. package/Editor/Resources/Inspector/SceneAuthoringEditor.uss.meta +12 -0
  26. package/Editor/Resources/Inspector/SceneAuthoringEditor.uxml +8 -0
  27. package/Editor/Resources/Inspector/SceneAuthoringEditor.uxml.meta +10 -0
  28. package/Editor/Resources/Inspector.meta +8 -0
  29. package/Editor/Resources.meta +8 -0
  30. package/Editor/SceneEntityInspectorView.cs +1103 -0
  31. package/Editor/SceneEntityInspectorView.cs.meta +2 -0
  32. package/Editor/SelectionProxy.cs +19 -0
  33. package/Editor/SelectionProxy.cs.meta +2 -0
  34. package/Editor/SelectionProxyBridge.cs +64 -0
  35. package/Editor/SelectionProxyBridge.cs.meta +2 -0
  36. package/Editor/SelectionProxyEditor.cs +33 -0
  37. package/Editor/SelectionProxyEditor.cs.meta +2 -0
  38. package/LICENSE.md +21 -0
  39. package/LICENSE.md.meta +7 -0
  40. package/README.md +66 -0
  41. package/README.md.meta +2 -0
  42. package/Runtime/AssemblyInfo.cs +3 -0
  43. package/Runtime/AssemblyInfo.cs.meta +2 -0
  44. package/Runtime/ComponentData.cs +120 -0
  45. package/Runtime/ComponentData.cs.meta +2 -0
  46. package/Runtime/DeltaECS.Unity.asmdef +14 -0
  47. package/Runtime/DeltaECS.Unity.asmdef.meta +7 -0
  48. package/Runtime/Editor.meta +8 -0
  49. package/Runtime/EntityAuthoring.cs +47 -0
  50. package/Runtime/EntityAuthoring.cs.meta +2 -0
  51. package/Runtime/EntityReference.cs +21 -0
  52. package/Runtime/EntityReference.cs.meta +2 -0
  53. package/Runtime/SceneAuthoring.cs +202 -0
  54. package/Runtime/SceneAuthoring.cs.meta +2 -0
  55. package/Runtime/SceneData.cs +120 -0
  56. package/Runtime/SceneData.cs.meta +2 -0
  57. package/Runtime/SceneWorld.cs +618 -0
  58. package/Runtime/SceneWorld.cs.meta +2 -0
  59. package/Runtime/ThrowHelpers.cs +44 -0
  60. package/Runtime/ThrowHelpers.cs.meta +2 -0
  61. package/package.json +31 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+
3
+ ## 0.0.37
4
+
5
+ - Initial UPM package for the DeltaECS Unity scene authoring and editor integration.
6
+ - Requires Unity 6.7 (`6000.7`) or newer.
@@ -0,0 +1,288 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using Delta.ECS;
4
+ using UnityEditor;
5
+ using UnityEditor.UIElements;
6
+ using UnityEngine;
7
+ using UnityEngine.UIElements;
8
+
9
+ namespace Delta.ECS.Unity.Editor
10
+ {
11
+ internal static class BoundEntityRootEditorSelector
12
+ {
13
+ private static bool _creatingDefaultGameObjectEditor;
14
+
15
+ [RootEditor(supportsAddComponent: true)]
16
+ private static Type SelectRootEditor(UnityEngine.Object[] objects)
17
+ {
18
+ if (_creatingDefaultGameObjectEditor)
19
+ {
20
+ return null;
21
+ }
22
+
23
+ if (objects == null || objects.Length != 1 || objects[0] is not GameObject gameObject)
24
+ {
25
+ return null;
26
+ }
27
+
28
+ if (SceneWorld.TryFindLiveWorld(gameObject, out _, out _))
29
+ {
30
+ return typeof(BoundEntityRootEditor);
31
+ }
32
+
33
+ if (EditorApplication.isPlayingOrWillChangePlaymode)
34
+ {
35
+ return null;
36
+ }
37
+
38
+ SceneAuthoring authoring = SceneAuthoring.FindForScene(gameObject.scene);
39
+ return authoring != null && authoring.TryGetStableId(gameObject, out _)
40
+ ? typeof(BoundEntityRootEditor)
41
+ : null;
42
+ }
43
+
44
+ internal static UnityEditor.Editor CreateDefaultGameObjectEditor(GameObject gameObject)
45
+ {
46
+ _creatingDefaultGameObjectEditor = true;
47
+ try
48
+ {
49
+ return UnityEditor.Editor.CreateEditor(gameObject);
50
+ }
51
+ finally
52
+ {
53
+ _creatingDefaultGameObjectEditor = false;
54
+ }
55
+ }
56
+ }
57
+
58
+ internal sealed class BoundEntityRootEditor : UnityEditor.Editor
59
+ {
60
+ private const string ComponentHeadersStyleResourcePath =
61
+ "Inspector/BoundEntityRootEditor";
62
+
63
+ private readonly List<UnityEditor.Editor> _componentEditors = new();
64
+ private readonly List<Component> _componentTargets = new();
65
+ private UnityEditor.Editor _gameObjectEditor;
66
+ private SceneEntityInspectorView _view;
67
+ private VisualElement _componentInspectorRoot;
68
+
69
+ private void OnEnable()
70
+ {
71
+ if (target is GameObject gameObject)
72
+ {
73
+ _gameObjectEditor = BoundEntityRootEditorSelector.CreateDefaultGameObjectEditor(gameObject);
74
+ }
75
+
76
+ _view = new SceneEntityInspectorView(ResolveTarget, embedded: true);
77
+ EditorApplication.hierarchyChanged += RefreshComponentInspectors;
78
+ Undo.undoRedoPerformed += RefreshComponentInspectors;
79
+ }
80
+
81
+ private void OnDisable()
82
+ {
83
+ _view?.Dispose();
84
+ _view = null;
85
+ if (_gameObjectEditor != null)
86
+ {
87
+ DestroyImmediate(_gameObjectEditor);
88
+ _gameObjectEditor = null;
89
+ }
90
+
91
+ EditorApplication.hierarchyChanged -= RefreshComponentInspectors;
92
+ Undo.undoRedoPerformed -= RefreshComponentInspectors;
93
+ _componentInspectorRoot = null;
94
+ DisposeComponentEditors();
95
+ }
96
+
97
+ protected override void OnHeaderGUI()
98
+ {
99
+ // The root editor's generic object header is replaced by the native
100
+ // GameObjectInspector header embedded at the top of CreateInspectorGUI.
101
+ }
102
+
103
+ private void DisposeComponentEditors()
104
+ {
105
+ foreach (UnityEditor.Editor componentEditor in _componentEditors)
106
+ {
107
+ if (componentEditor != null)
108
+ {
109
+ DestroyImmediate(componentEditor);
110
+ }
111
+ }
112
+
113
+ _componentEditors.Clear();
114
+ _componentTargets.Clear();
115
+ }
116
+
117
+ public override bool UseDefaultMargins() => false;
118
+
119
+ public override bool RequiresConstantRepaint()
120
+ {
121
+ if (EditorApplication.isPlaying)
122
+ return true;
123
+
124
+ foreach (UnityEditor.Editor componentEditor in _componentEditors)
125
+ {
126
+ if (componentEditor != null && componentEditor.RequiresConstantRepaint())
127
+ return true;
128
+ }
129
+
130
+ return false;
131
+ }
132
+
133
+ public override VisualElement CreateInspectorGUI()
134
+ {
135
+ var root = new VisualElement();
136
+ StyleSheet componentStyles = Resources.Load<StyleSheet>(ComponentHeadersStyleResourcePath);
137
+ if (componentStyles != null)
138
+ {
139
+ root.styleSheets.Add(componentStyles);
140
+ }
141
+
142
+ if (_gameObjectEditor != null)
143
+ {
144
+ root.Add(new IMGUIContainer(() =>
145
+ {
146
+ if (_gameObjectEditor != null)
147
+ {
148
+ _gameObjectEditor.DrawHeader();
149
+ }
150
+ }));
151
+ }
152
+
153
+ VisualElement ecsContent = _view.CreateGUI();
154
+ bool ecsExpanded = SessionState.GetBool("DeltaECS.EntityInspector.Expanded", true);
155
+ ecsContent.style.display = ecsExpanded ? DisplayStyle.Flex : DisplayStyle.None;
156
+ root.Add(new IMGUIContainer(() =>
157
+ {
158
+ GUIStyle titlebar = GUI.skin.GetStyle("IN Title");
159
+ GUIStyle foldoutStyle = GUI.skin.GetStyle("Titlebar Foldout");
160
+ Rect headerRect = GUILayoutUtility.GetRect(GUIContent.none, titlebar,
161
+ GUILayout.ExpandWidth(true));
162
+ bool expanded = GUI.Toggle(headerRect, ecsExpanded, GUIContent.none, GUIStyle.none);
163
+ if (Event.current.type == EventType.Repaint)
164
+ {
165
+ titlebar.Draw(headerRect, GUIContent.none, false, false, false, false);
166
+ Rect arrowRect = new Rect(headerRect.x + foldoutStyle.margin.left + 1f,
167
+ headerRect.y + (headerRect.height - 13) / 2 + titlebar.padding.top, 13, 13);
168
+ foldoutStyle.Draw(arrowRect, false, false, expanded, false);
169
+ }
170
+ Rect textRect = new Rect(headerRect.x + 28, headerRect.y,
171
+ headerRect.width - 28, headerRect.height);
172
+ GUI.Label(textRect, "Delta ECS Entity", GUI.skin.GetStyle("IN TitleText"));
173
+ if (expanded == ecsExpanded) return;
174
+ ecsExpanded = expanded;
175
+ SessionState.SetBool("DeltaECS.EntityInspector.Expanded", expanded);
176
+ ecsContent.style.display = expanded ? DisplayStyle.Flex : DisplayStyle.None;
177
+ }));
178
+ root.Add(ecsContent);
179
+ _componentInspectorRoot = new VisualElement();
180
+ root.Add(_componentInspectorRoot);
181
+ RebuildComponentInspectors();
182
+ return root;
183
+ }
184
+
185
+ private void RefreshComponentInspectors()
186
+ {
187
+ if (_componentInspectorRoot != null && !HaveSameComponents())
188
+ {
189
+ RebuildComponentInspectors();
190
+ }
191
+ }
192
+
193
+ private bool HaveSameComponents()
194
+ {
195
+ if (target is not GameObject gameObject || gameObject == null)
196
+ {
197
+ return _componentTargets.Count == 0;
198
+ }
199
+
200
+ int index = 0;
201
+ foreach (Component component in gameObject.GetComponents<Component>())
202
+ {
203
+ if (!ShouldDrawComponent(component))
204
+ {
205
+ continue;
206
+ }
207
+
208
+ if (index >= _componentTargets.Count || _componentTargets[index] != component)
209
+ {
210
+ return false;
211
+ }
212
+
213
+ index++;
214
+ }
215
+
216
+ return index == _componentTargets.Count;
217
+ }
218
+
219
+ private void RebuildComponentInspectors()
220
+ {
221
+ DisposeComponentEditors();
222
+ _componentInspectorRoot.Clear();
223
+ if (target is not GameObject gameObject || gameObject == null)
224
+ {
225
+ return;
226
+ }
227
+
228
+ foreach (Component component in gameObject.GetComponents<Component>())
229
+ {
230
+ if (!ShouldDrawComponent(component))
231
+ {
232
+ continue;
233
+ }
234
+
235
+ UnityEditor.Editor componentEditor = CreateEditor(component);
236
+ if (componentEditor == null)
237
+ {
238
+ continue;
239
+ }
240
+
241
+ _componentEditors.Add(componentEditor);
242
+ _componentTargets.Add(component);
243
+ var inspector = new InspectorElement(componentEditor);
244
+ string expandedKey = $"DeltaECS.ComponentInspector.{component.GetEntityId()}.Expanded";
245
+ bool expanded = SessionState.GetBool(expandedKey, true);
246
+ inspector.style.display = expanded ? DisplayStyle.Flex : DisplayStyle.None;
247
+ _componentInspectorRoot.Add(new IMGUIContainer(() =>
248
+ {
249
+ if (component == null) return;
250
+ bool next = EditorGUILayout.InspectorTitlebar(expanded, component);
251
+ if (next == expanded) return;
252
+ expanded = next;
253
+ SessionState.SetBool(expandedKey, next);
254
+ inspector.style.display = next ? DisplayStyle.Flex : DisplayStyle.None;
255
+ }));
256
+ _componentInspectorRoot.Add(inspector);
257
+ }
258
+ }
259
+
260
+ private static bool ShouldDrawComponent(Component component) => component != null
261
+ && (component.hideFlags & HideFlags.HideInInspector) == 0;
262
+
263
+ private EntityInspectorTarget ResolveTarget()
264
+ {
265
+ if (target is not GameObject gameObject || gameObject == null)
266
+ {
267
+ return default;
268
+ }
269
+
270
+ if (SceneWorld.TryFindLiveWorld(gameObject, out SceneWorld world, out Entity entity))
271
+ {
272
+ SceneAuthoring liveAuthoring = SceneAuthoring.FindForScene(gameObject.scene);
273
+ return new EntityInspectorTarget(liveAuthoring, null, world, entity);
274
+ }
275
+
276
+ if (!EditorApplication.isPlayingOrWillChangePlaymode)
277
+ {
278
+ SceneAuthoring authoring = SceneAuthoring.FindForScene(gameObject.scene);
279
+ if (authoring != null && authoring.TryGetStableId(gameObject, out string stableId))
280
+ {
281
+ return new EntityInspectorTarget(authoring, stableId);
282
+ }
283
+ }
284
+
285
+ return default;
286
+ }
287
+ }
288
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 7378c953e20147a1bb2b3214561054e6
@@ -0,0 +1,73 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using System.Linq;
4
+ using System.Reflection;
5
+ using Delta.ECS.Integration;
6
+ using UnityEditor.IMGUI.Controls;
7
+ using UnityEngine;
8
+
9
+ namespace Delta.ECS.Unity.Editor
10
+ {
11
+ internal sealed class ComponentDropdown : AdvancedDropdown
12
+ {
13
+ private readonly ComponentDescriptor[] _components;
14
+ private readonly Func<ComponentDescriptor, string> _getMenuPath;
15
+ private readonly Action<ComponentDescriptor> _add;
16
+ private readonly Dictionary<int, ComponentDescriptor> _items = new();
17
+
18
+ public ComponentDropdown(ComponentDescriptor[] components,
19
+ Func<ComponentDescriptor, string> getMenuPath, Action<ComponentDescriptor> add)
20
+ : base(new AdvancedDropdownState())
21
+ {
22
+ _components = components;
23
+ _getMenuPath = getMenuPath;
24
+ _add = add;
25
+ minimumSize = new Vector2(230, 320);
26
+ // Unity keeps this bound internal; set it before Show captures the popup bounds.
27
+ typeof(AdvancedDropdown).GetProperty("maximumSize", BindingFlags.Instance | BindingFlags.NonPublic)
28
+ ?.SetValue(this, new Vector2(4000, 400));
29
+ }
30
+
31
+ protected override AdvancedDropdownItem BuildRoot()
32
+ {
33
+ var root = new AdvancedDropdownItem("Component");
34
+ var folders = new Dictionary<string, AdvancedDropdownItem> { [string.Empty] = root };
35
+ int id = 0;
36
+
37
+ foreach (var entry in _components
38
+ .Select(component => (Component: component, Path: _getMenuPath(component)))
39
+ .OrderBy(entry => entry.Path, StringComparer.Ordinal))
40
+ {
41
+ string[] path = entry.Path.Split('/');
42
+ string folderPath = string.Empty;
43
+ AdvancedDropdownItem parent = root;
44
+ foreach (string folder in path.Take(path.Length - 1))
45
+ {
46
+ folderPath += "/" + folder;
47
+ if (!folders.TryGetValue(folderPath, out AdvancedDropdownItem item))
48
+ {
49
+ item = new AdvancedDropdownItem(folder) { id = ++id };
50
+ folders.Add(folderPath, item);
51
+ parent.AddChild(item);
52
+ }
53
+
54
+ parent = item;
55
+ }
56
+
57
+ var componentItem = new AdvancedDropdownItem(path[path.Length - 1]) { id = ++id };
58
+ parent.AddChild(componentItem);
59
+ _items.Add(componentItem.id, entry.Component);
60
+ }
61
+
62
+ return root;
63
+ }
64
+
65
+ protected override void ItemSelected(AdvancedDropdownItem item)
66
+ {
67
+ if (_items.TryGetValue(item.id, out ComponentDescriptor descriptor))
68
+ {
69
+ _add(descriptor);
70
+ }
71
+ }
72
+ }
73
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: cabed0bc7e964c17829f6e89738d3b1b
@@ -0,0 +1,26 @@
1
+ using UnityEditor.UIElements;
2
+ using UnityEditor.IMGUI.Controls;
3
+ using UnityEngine;
4
+ using UnityEngine.UIElements;
5
+
6
+ namespace Delta.ECS.Unity.Editor
7
+ {
8
+ internal sealed class ComponentListController : ListViewController
9
+ {
10
+ private readonly SceneEntityInspectorView _view;
11
+
12
+ public ComponentListController(SceneEntityInspectorView view) => _view = view;
13
+
14
+ public override void Move(int index, int newIndex)
15
+ {
16
+ int componentCount = _view.ComponentCount;
17
+ if (index < 0 || index >= componentCount || componentCount == 0)
18
+ {
19
+ return;
20
+ }
21
+
22
+ base.Move(index, Mathf.Clamp(newIndex, 0, componentCount - 1));
23
+ _view.ScheduleRefreshContent();
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 91147ca0e95244c787a993a847c31c2a
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "DeltaECS.Unity.Editor",
3
+ "rootNamespace": "Delta.ECS.Unity.Editor",
4
+ "references": [
5
+ "DeltaECS.Unity"
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
+ }
@@ -0,0 +1,7 @@
1
+ fileFormatVersion: 2
2
+ guid: c0286b8c5453b9f77454004c35a47bc7
3
+ AssemblyDefinitionImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
@@ -0,0 +1,143 @@
1
+ using UnityEditor;
2
+ using UnityEditor.SceneManagement;
3
+ using UnityEngine;
4
+ using UnityEngine.SceneManagement;
5
+
6
+ namespace Delta.ECS.Unity.Editor
7
+ {
8
+ [InitializeOnLoad]
9
+ internal static class EditorLifecycle
10
+ {
11
+ private static bool _sceneAuthoringSetupScheduled;
12
+
13
+ static EditorLifecycle()
14
+ {
15
+ Undo.undoRedoPerformed += OnUndoRedo;
16
+ EditorSceneManager.sceneOpened += OnSceneOpened;
17
+ EditorSceneManager.sceneClosed += OnSceneClosed;
18
+ EditorSceneManager.newSceneCreated += OnNewSceneCreated;
19
+ ScheduleSceneAuthoringSetup();
20
+ }
21
+
22
+ private static void OnUndoRedo()
23
+ {
24
+ HierarchyNodeHandler.RefreshAll();
25
+ }
26
+
27
+ private static void OnSceneOpened(UnityEngine.SceneManagement.Scene scene, OpenSceneMode mode)
28
+ {
29
+ ScheduleSceneAuthoringSetup();
30
+ }
31
+
32
+ private static void OnSceneClosed(Scene scene)
33
+ {
34
+ HierarchyNodeHandler.RefreshAll();
35
+ }
36
+
37
+ private static void OnNewSceneCreated(Scene scene, NewSceneSetup setup, NewSceneMode mode)
38
+ {
39
+ ScheduleSceneAuthoringSetup();
40
+ }
41
+
42
+ private static void ScheduleSceneAuthoringSetup()
43
+ {
44
+ if (_sceneAuthoringSetupScheduled)
45
+ {
46
+ return;
47
+ }
48
+
49
+ _sceneAuthoringSetupScheduled = true;
50
+ EditorApplication.delayCall += EnsureAuthoringForLoadedScenes;
51
+ }
52
+
53
+ private static void EnsureAuthoringForLoadedScenes()
54
+ {
55
+ _sceneAuthoringSetupScheduled = false;
56
+ if (EditorApplication.isPlayingOrWillChangePlaymode)
57
+ {
58
+ return;
59
+ }
60
+
61
+ for (int i = 0; i < SceneManager.sceneCount; i++)
62
+ {
63
+ EnsureSceneAuthoring(SceneManager.GetSceneAt(i));
64
+ }
65
+
66
+ HierarchyNodeHandler.RefreshAll();
67
+ }
68
+
69
+ private static void EnsureSceneAuthoring(Scene scene)
70
+ {
71
+ if (!scene.IsValid() || !scene.isLoaded || EditorSceneManager.IsPreviewScene(scene))
72
+ {
73
+ return;
74
+ }
75
+
76
+ SceneAuthoring existing = SceneAuthoring.FindForScene(scene);
77
+ if (existing != null && IsDedicatedAuthoringObject(existing.gameObject))
78
+ {
79
+ GameObject existingObject = existing.gameObject;
80
+ bool changed = false;
81
+ if (!string.Equals(existingObject.name, SceneAuthoring.AuthoringObjectName, System.StringComparison.Ordinal))
82
+ {
83
+ existingObject.name = SceneAuthoring.AuthoringObjectName;
84
+ changed = true;
85
+ }
86
+
87
+ if ((existingObject.hideFlags & HideFlags.HideInHierarchy) == 0)
88
+ {
89
+ existingObject.hideFlags |= HideFlags.HideInHierarchy;
90
+ changed = true;
91
+ }
92
+
93
+ if (changed)
94
+ {
95
+ EditorUtility.SetDirty(existingObject);
96
+ EditorSceneManager.MarkSceneDirty(scene);
97
+ }
98
+
99
+ return;
100
+ }
101
+
102
+ var authoringObject = new GameObject(SceneAuthoring.AuthoringObjectName);
103
+ SceneManager.MoveGameObjectToScene(authoringObject, scene);
104
+ SceneAuthoring replacement = authoringObject.AddComponent<SceneAuthoring>();
105
+
106
+ if (existing != null)
107
+ {
108
+ EditorUtility.CopySerialized(existing, replacement);
109
+ replacement.SceneData.EnsureStableIds();
110
+ UnityEngine.Object.DestroyImmediate(existing);
111
+ }
112
+
113
+ authoringObject.hideFlags |= HideFlags.HideInHierarchy;
114
+
115
+ if (existing != null)
116
+ {
117
+ EditorUtility.SetDirty(replacement);
118
+ EditorUtility.SetDirty(authoringObject);
119
+ }
120
+
121
+ EditorSceneManager.MarkSceneDirty(scene);
122
+ }
123
+
124
+ private static bool IsDedicatedAuthoringObject(GameObject gameObject)
125
+ {
126
+ Component[] components = gameObject.GetComponents<Component>();
127
+ if (components.Length != 2)
128
+ {
129
+ return false;
130
+ }
131
+
132
+ bool hasAuthoring = false;
133
+ bool hasTransform = false;
134
+ for (int i = 0; i < components.Length; i++)
135
+ {
136
+ hasAuthoring |= components[i] is SceneAuthoring;
137
+ hasTransform |= components[i] is Transform;
138
+ }
139
+
140
+ return hasAuthoring && hasTransform;
141
+ }
142
+ }
143
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 6b33bd95ec1b4077b588251454b2d5fe
@@ -0,0 +1,26 @@
1
+ using Delta.ECS;
2
+
3
+ namespace Delta.ECS.Unity.Editor
4
+ {
5
+ internal readonly struct EntityInspectorTarget
6
+ {
7
+ internal readonly SceneAuthoring Authoring;
8
+ internal readonly string StableId;
9
+ internal readonly SceneWorld RuntimeWorld;
10
+ internal readonly Entity RuntimeEntity;
11
+
12
+ internal EntityInspectorTarget(
13
+ SceneAuthoring authoring,
14
+ string stableId,
15
+ SceneWorld runtimeWorld = null,
16
+ Entity runtimeEntity = default)
17
+ {
18
+ Authoring = authoring;
19
+ StableId = stableId;
20
+ RuntimeWorld = runtimeWorld;
21
+ RuntimeEntity = runtimeEntity;
22
+ }
23
+
24
+ internal bool IsRuntime => RuntimeWorld != null && RuntimeEntity.IsValid;
25
+ }
26
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 37e1f33b80b347bbb192b6ef0b30de22
3
+ timeCreated: 1790675350