Compare commits

..

18 Commits

Author SHA1 Message Date
max
ebee93d107 Update ScenePartitionSO.cs 2023-07-30 01:47:12 +02:00
max
83776072c9 SceneObjectNames & ObjectInfo
- Try to get the scene object names
- Try to get the object type
- Try to get create object info
2023-07-30 01:36:26 +02:00
max
40c49b076e Update EditorGUIUtils.cs 2023-07-30 00:22:39 +02:00
max
fbd5a342fb Update ProfilerUtility.cs 2023-07-29 17:38:55 +02:00
max
8d567c8cda Update ProfilerUtility.cs 2023-07-29 16:08:47 +02:00
max
73ac3485aa Load additive
closes #9
2023-07-29 16:06:03 +02:00
max
12fd64f015 Update README.md 2023-07-29 02:38:35 +02:00
max
6fc95943fb Update ScenePartitionSOEditor.cs 2023-07-29 01:51:21 +02:00
max
df82f44c4a Toolbar reload and unload buttons 2023-07-28 18:07:39 +02:00
max
52b9a60918 Start working on Toolbar 2023-07-27 23:52:53 +02:00
max
ebb8ba559e MenuItems for GameObjects
- CopyObjectId
- AddToAlwaysLoad
- RemoveFromAlwaysLoad
- Added utility to get the TargetObjectId

closes #10
2023-07-27 18:23:03 +02:00
max
6edb307e9c Update ScenePartitionEditorWindow.cs
- Draw scene partition in scene partition editor window
2023-07-26 23:52:13 +02:00
max
236c7377c7 Update license 2023-07-26 22:14:55 +02:00
max
daf622f327 Update ScenePartitionSOEditor.cs 2023-07-16 20:27:39 +02:00
max
6667f013bf Profiling scopes
- Added profiling scope utility
- Added profiling scopes around some functions
- Testing StreamWriter and FileStream
2023-07-16 19:58:37 +02:00
max
d859ad1af5 Update ScenePartitionSOEditor.cs 2023-07-09 23:08:55 +02:00
max
8b44c33813 Editor layout
- Cleanup the editors a bit
- Editor foldout scope
- Cell size to editor (this is user preference data, could be put in EditorPrefs later)
2023-07-09 23:01:48 +02:00
max
ddf71ef7d7 GameObject menu copy file Id
- GameObject menu copy file id
2023-07-09 23:00:23 +02:00
26 changed files with 1538 additions and 260 deletions

View File

@ -16,5 +16,18 @@ namespace VertexColor.ScenePartition.Editor
}
public static void HorizontalLine() => HorizontalLine(horizontalLineColor);
public struct FoldoutHeaderScope : System.IDisposable
{
public FoldoutHeaderScope(string label, ref bool foldout)
{
foldout = EditorGUILayout.BeginFoldoutHeaderGroup(foldout, label);
}
public readonly void Dispose()
{
EditorGUILayout.EndFoldoutHeaderGroup();
}
}
}
}

8
Editor/Icons.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 60276e4d3d7c1074a8718c58a545fe31
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
Editor/Icons/GenerateGrid.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,123 @@
fileFormatVersion: 2
guid: 62eb74ebb0f60354abe70675fd2beedb
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Editor/Icons/Load.png (Stored with Git LFS) Normal file

Binary file not shown.

123
Editor/Icons/Load.png.meta Normal file
View File

@ -0,0 +1,123 @@
fileFormatVersion: 2
guid: 1364209397e55e04ea9c1aca613fb86a
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Editor/Icons/Reload.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,123 @@
fileFormatVersion: 2
guid: ab6018b4eb072fa4b8db2154f19559c1
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Editor/Icons/Save.png (Stored with Git LFS) Normal file

Binary file not shown.

123
Editor/Icons/Save.png.meta Normal file
View File

@ -0,0 +1,123 @@
fileFormatVersion: 2
guid: f8afdb607709a2d4ba6f59767274ef6b
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 32
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Editor/Icons/Unload.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,123 @@
fileFormatVersion: 2
guid: 08a68b1330e59aa409bd68cd3e541161
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 12
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMasterTextureLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -9,8 +9,12 @@ namespace VertexColor.ScenePartition.Editor
private const int cellSize = 10;
private Vector2 scrollPos = Vector2.zero;
private bool foldoutGroupEnabled = false;
[MenuItem("Max/ScenePartitionWindow")]
private ulong id = 0;
private int gridId = 0;
[MenuItem("Window/ScenePartition")]
public static void ShowExample()
{
ScenePartitionEditorWindow window = GetWindow<ScenePartitionEditorWindow>();
@ -18,6 +22,99 @@ namespace VertexColor.ScenePartition.Editor
}
private void OnGUI()
{
using (new EditorGUILayout.VerticalScope())
{
DrawScenePartition();
GUILayout.FlexibleSpace();
DrawSceneDataCache();
}
}
private void DrawScenePartition()
{
if (!ScenePartitionUtils.TryGetScenePartitionSOForActiveScene(out var scenePartitionSO)) return;
EditorGUILayout.LabelField($"ScenePartition | {scenePartitionSO.SceneName}", EditorStyles.boldLabel);
if (scenePartitionSO.SceneAsset == null)
{
if (GUILayout.Button("Create Scene"))
{
scenePartitionSO.CreateScene();
}
}
else
{
if (GUILayout.Button("Load All"))
{
scenePartitionSO.LoadAll();
}
using (new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Button(new GUIContent("Unload", "Empty the scene and save it (so it has no changes in source control)."), EditorStyles.miniButtonLeft))
{
scenePartitionSO.Unload();
}
if (GUILayout.Button(new GUIContent("Reload", "Discard changes and reload loaded partitions."), EditorStyles.miniButtonRight))
{
scenePartitionSO.Reload();
}
}
if (GUILayout.Button("Save"))
{
scenePartitionSO.Save();
}
EditorGUIUtils.HorizontalLine();
using (new EditorGUILayout.HorizontalScope())
{
id = (ulong)EditorGUILayout.LongField("id", (long)id);
if (GUILayout.Button("Load Id"))
{
scenePartitionSO.LoadPartitions(new ulong[1] { id });
}
}
EditorGUIUtils.HorizontalLine();
ScenePartitionSceneViewEditor.cellSize = EditorGUILayout.IntSlider("cellSize", ScenePartitionSceneViewEditor.cellSize, 10, 1000);
if (GUILayout.Button("GenerateSceneGrid"))
{
scenePartitionSO.GenerateSceneGridData();
}
if (scenePartitionSO.Data.SceneGrid != null)
{
using (new EditorGUILayout.HorizontalScope())
{
gridId = EditorGUILayout.IntField("gridId", gridId);
if (GUILayout.Button("LoadSceneGrid"))
{
scenePartitionSO.LoadCell(gridId);
}
}
}
EditorGUIUtils.HorizontalLine();
if (GUILayout.Button("Open Scene Data Folder"))
{
EditorUtility.RevealInFinder(ScenePartitionUtils.GetDataPath(scenePartitionSO));
}
}
}
private void DrawSceneDataCache()
{
EditorGUILayout.LabelField("Cache", EditorStyles.boldLabel);
@ -36,11 +133,10 @@ namespace VertexColor.ScenePartition.Editor
EditorGUIUtils.HorizontalLine();
DrawSceneDataCache();
}
private void DrawSceneDataCache()
using (EditorGUIUtils.FoldoutHeaderScope foldoutGroup = new EditorGUIUtils.FoldoutHeaderScope("SceneDataCache", ref foldoutGroupEnabled))
{
if (!foldoutGroupEnabled) return;
using (EditorGUILayout.ScrollViewScope scope = new EditorGUILayout.ScrollViewScope(scrollPos))
{
scrollPos = scope.scrollPosition;
@ -101,3 +197,4 @@ namespace VertexColor.ScenePartition.Editor
}
}
}
}

View File

@ -0,0 +1,54 @@
using UnityEditor;
using UnityEngine;
namespace VertexColor.ScenePartition.Editor
{
public static class ScenePartitionMenuEditor
{
[MenuItem("GameObject/ScenePartition/CopyObjectId", false, 10000)]
public static void CopyObjectId(MenuCommand menuCommand)
{
// Get context from menu command instead of selection because the menu command is executed for each selected object when executed from the hierarchy.
if (menuCommand.context is not GameObject go) return;
if (go == null) return;
if (go.scene == null) return;
ulong id = ScenePartitionUtils.GetTargetObjectId(go);
EditorGUIUtility.systemCopyBuffer = id.ToString();
Debug.Log($"Copied object id '{id}' from '{go}' to clipboard");
}
[MenuItem("GameObject/ScenePartition/AddToAlwaysLoad", false, 10000)]
public static void AddToAlwaysLoad(MenuCommand menuCommand)
{
// Get context from menu command instead of selection because the menu command is executed for each selected object when executed from the hierarchy.
if (menuCommand.context is not GameObject go) return;
if (go == null) return;
if (go.scene == null) return;
if (!ScenePartitionUtils.TryGetScenePartitionSOForActiveScene(out var scenePartitionSO)) return;
ulong id = ScenePartitionUtils.GetTargetObjectId(go);
if (scenePartitionSO.alwaysLoadIds.Contains(id)) return;
scenePartitionSO.alwaysLoadIds.Add(id);
Debug.Log($"Added '{go}' ({id}) to '{scenePartitionSO.name}' ({scenePartitionSO.SceneName})");
}
[MenuItem("GameObject/ScenePartition/RemoveFromAlwaysLoad", false, 10000)]
public static void RemoveFromAlwaysLoad(MenuCommand menuCommand)
{
// Get context from menu command instead of selection because the menu command is executed for each selected object when executed from the hierarchy.
if (menuCommand.context is not GameObject go) return;
if (go == null) return;
if (go.scene == null) return;
if (!ScenePartitionUtils.TryGetScenePartitionSOForActiveScene(out var scenePartitionSO)) return;
ulong id = ScenePartitionUtils.GetTargetObjectId(go);
scenePartitionSO.alwaysLoadIds.Remove(id);
Debug.Log($"Removed '{go}' ({id}) from '{scenePartitionSO.name}' ({scenePartitionSO.SceneName})");
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ab63a69b46a3ff4438723520d0656c93
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -81,13 +81,13 @@ namespace VertexColor.ScenePartition.Editor
}
private void LoadScenePartitions(SortedSet<ulong> partitionIds)
{
using (new ProfilerUtility.ProfilerScope($"{nameof(LoadScenePartitions)}"))
{
if (!Data.HasCreatedPartitions) return;
string scenePath = ScenePartitionUtils.GetScenePath(this);
List<string> sceneData = new List<string>();
Data.LoadedScenePartitions.Clear();
// Add always load ids.
@ -97,49 +97,77 @@ namespace VertexColor.ScenePartition.Editor
partitionIds.Add(id);
}
// Clear file.
File.WriteAllText(scenePath, string.Empty);
// Create scene data.
try
{
using (FileStream outputStream = new FileStream(scenePath, FileMode.Append, FileAccess.Write))
{
foreach (ulong id in partitionIds)
{
ScenePartition p = Data.ScenePartitions[id];
sceneData.AddRange(File.ReadAllLines(p.filePath));
Data.LoadedScenePartitions.Add(p.id, p);
using (FileStream inputStream = new FileStream(p.filePath, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
outputStream.Write(buffer, 0, bytesRead);
}
}
// Create scene.
File.WriteAllLines(scenePath, sceneData);
Data.LoadedScenePartitions.Add(p.id, p);
}
}
}
catch (System.Exception ex)
{
Debug.LogException(ex);
}
AssetDatabase.Refresh();
}
}
/// <summary>
/// Convert scene to partitions and save them to disk.
/// </summary>
public void Save()
{
using (new ProfilerUtility.ProfilerScope($"{nameof(Save)}"))
{
DeleteLoadedPartitions(); // Delete the loaded partitions from disk so we can write the new ones.
string pattern = @"&(\d+)";
const string objectIdPattern = @"&(\d+)";
string dataPath = ScenePartitionUtils.GetDataPath(this);
string scenePath = ScenePartitionUtils.GetScenePath(this);
// Read the data from the scene file.
string[] sceneData = File.ReadAllLines(scenePath);
Dictionary<ulong, string> sceneObjectNameById = GetSceneObjectNames(in sceneData);
// Split it into blocks.
int lastIndex = sceneData.Length;
for (int i = sceneData.Length - 1; i >= 0; i--)
{
if (sceneData[i].StartsWith("---")) // --- is the start of a new yaml document.
{
Match match = Regex.Match(sceneData[i], pattern);
Match match = Regex.Match(sceneData[i], objectIdPattern);
if (match.Success)
{
// Extract the file number
string id = match.Groups[1].Value;
ulong objectId = ulong.Parse(id);
GetObjectInfo(in sceneData, in sceneObjectNameById, i, lastIndex, objectId, out string objectInfo);
// Write data to disk.
File.WriteAllLines($"{dataPath}/{SceneName}-{id}.yaml", sceneData[i..lastIndex]);
File.WriteAllLines($"{dataPath}/{SceneName}-{id}{objectInfo}.yaml", sceneData[i..lastIndex]);
}
lastIndex = i;
@ -149,11 +177,14 @@ namespace VertexColor.ScenePartition.Editor
// Write header to disk.
File.WriteAllLines($"{dataPath}/{SceneName}.yaml", sceneData[0..lastIndex]);
}
}
/// <summary>
/// Empty the scene and save it (so it has no changes in source control).
/// </summary>
public void Unload()
{
using (new ProfilerUtility.ProfilerScope($"{nameof(Unload)}"))
{
string dataPath = ScenePartitionUtils.GetDataPath(this);
string scenePath = ScenePartitionUtils.GetScenePath(this);
@ -173,8 +204,11 @@ namespace VertexColor.ScenePartition.Editor
AssetDatabase.Refresh();
}
}
private void DeleteLoadedPartitions()
{
using (new ProfilerUtility.ProfilerScope($"{nameof(DeleteLoadedPartitions)}"))
{
if (!Data.HasLoadedPartitions) return;
@ -185,8 +219,11 @@ namespace VertexColor.ScenePartition.Editor
File.Delete(scenePartition.Value.filePath);
}
}
}
public void LoadPartitions(ulong[] ids)
{
using (new ProfilerUtility.ProfilerScope($"{nameof(LoadPartitions)}"))
{
SortedSet<ulong> partitionIds = new SortedSet<ulong>();
@ -201,6 +238,36 @@ namespace VertexColor.ScenePartition.Editor
LoadScenePartitions(partitionIds);
}
}
public void LoadPartitionsAdditive(ulong[] ids)
{
using (new ProfilerUtility.ProfilerScope($"{nameof(LoadPartitions)}"))
{
SortedSet<ulong> partitionIds = new SortedSet<ulong>();
// Additive partitions to load.
for (int i = 0; i < ids.Length; i++)
{
SortedSet<ulong> connections = ScenePartitionUtils.FindDeeplyLinkedObjects(Data.ScenePartitions, ids[i]);
foreach (ulong c in connections)
{
partitionIds.Add(c);
}
}
// Partitions already loaded.
if (Data.HasLoadedPartitions)
{
foreach (KeyValuePair<ulong, ScenePartition> item in Data.LoadedScenePartitions)
{
partitionIds.Add(item.Key);
}
}
LoadScenePartitions(partitionIds);
}
}
private SortedSet<ulong> GetAlwaysLoadIds()
{
@ -219,6 +286,8 @@ namespace VertexColor.ScenePartition.Editor
}
public void GenerateSceneGridData()
{
using (new ProfilerUtility.ProfilerScope($"{nameof(GenerateSceneGridData)}"))
{
LoadAll();
@ -277,20 +346,21 @@ namespace VertexColor.ScenePartition.Editor
for (int i = 0; i < ids.Length; i++)
{
Debug.Log($"{ids[i].assetGUID} | {ids[i].identifierType} | {ids[i].targetObjectId} | {ids[i].targetPrefabId}");
//Debug.Log($"{ids[i].assetGUID} | {ids[i].identifierType} | {ids[i].targetObjectId} | {ids[i].targetPrefabId}");
if (ids[i].targetPrefabId == 0) // 0 = no prefab.
{
Data.SceneGrid.Insert(ids[i].targetObjectId, rootGameObjects[i].transform.position);
Data.SceneGrid.Insert(ids[i].targetObjectId, rootGameObjects[i].transform.position, ScenePartitionSceneViewEditor.cellSize);
}
else
{
Data.SceneGrid.Insert(ids[i].targetPrefabId, rootGameObjects[i].transform.position);
Data.SceneGrid.Insert(ids[i].targetPrefabId, rootGameObjects[i].transform.position, ScenePartitionSceneViewEditor.cellSize);
}
}
Unload();
}
}
public void LoadCell(int gridId)
{
@ -300,9 +370,197 @@ namespace VertexColor.ScenePartition.Editor
}
}
public void LoadCellAdditive(int gridId)
{
if (Data.SceneGrid.Grid.TryGetValue(gridId, out GridList ids))
{
LoadPartitionsAdditive(ids.list.ToArray());
}
}
public void ClearCache()
{
data = null;
}
private Dictionary<ulong, string> GetSceneObjectNames(in string[] sceneData)
{
using ProfilerUtility.ProfilerScope profilerScope = new(nameof(GetSceneObjectNames));
Dictionary<ulong, string> sceneObjectNameById = new Dictionary<ulong, string>();
const string objectIdPattern = @"&(\d+)";
int lastIndex = sceneData.Length;
for (int i = sceneData.Length - 1; i >= 0; i--)
{
bool foundName = false;
{ // GameObjects.
const string gameObjectHeaderPattern = "--- !u!1 &";
if (!foundName && sceneData[i].StartsWith(gameObjectHeaderPattern))
{
Match match = Regex.Match(sceneData[i], objectIdPattern);
if (!match.Success) continue;
if (!ulong.TryParse(match.Groups[1].Value, out ulong id)) continue;
for (int j = i; j < lastIndex; j++)
{
const string namePattern = "m_Name: ";
int nameStartIndex = sceneData[j].LastIndexOf(namePattern);
if (nameStartIndex < 0) continue;
nameStartIndex += namePattern.Length;
string name = sceneData[j][nameStartIndex..];
sceneObjectNameById.Add(id, name);
foundName = true;
break;
}
}
}
{ // Prefabs.
const string prefabHeaderPattern = "--- !u!1001 &";
if (!foundName && sceneData[i].StartsWith(prefabHeaderPattern))
{
Match match = Regex.Match(sceneData[i], objectIdPattern);
if (!match.Success) continue;
if (!ulong.TryParse(match.Groups[1].Value, out ulong id)) continue;
// Get name form property override in Scene.
for (int j = i; j < lastIndex; j++)
{
const string propertyPattern = "propertyPath: m_Name";
int propertyStartIndex = sceneData[j].LastIndexOf(propertyPattern);
if (propertyStartIndex < 0) continue;
const string valuePattern = "value: ";
int valueStartIndex = sceneData[j + 1].LastIndexOf(valuePattern);
if (valueStartIndex < 0) continue;
valueStartIndex += valuePattern.Length;
string name = sceneData[j + 1][valueStartIndex..];
sceneObjectNameById.Add(id, name);
foundName = true;
break;
}
// Get name from prefab in AssetDatabase.
if (!foundName)
{
// Find the match using regex
const string guidPattern = @"guid:\s(\w+)";
Match guidMatch = Regex.Match(sceneData[lastIndex - 1], guidPattern);
if (guidMatch.Success)
{
// Extract the GUID
string guid = guidMatch.Groups[1].Value;
string path = AssetDatabase.GUIDToAssetPath(guid);
string name = Path.GetFileNameWithoutExtension(path);
sceneObjectNameById.Add(id, name);
foundName = true;
}
}
}
}
if (sceneData[i].StartsWith("---"))
{
lastIndex = i;
continue;
}
}
return sceneObjectNameById;
}
private bool TryGetObjectTypeName(string data, out string objectTypeName)
{
objectTypeName = data.Remove(data.Length - 1);
return true;
}
private void GetObjectInfo(in string[] sceneData, in Dictionary<ulong, string> sceneObjectNameById, int index, int lastIndex, ulong objectId, out string objectInfo)
{
using ProfilerUtility.ProfilerScope profilerScope = new(nameof(GetObjectInfo));
objectInfo = "";
// Try get scene object name.
bool foundSceneObjectName = false;
// If it is a gameObject or prefab try to get the name directly.
const string gameObjectHeaderPattern = "--- !u!1 &";
const string prefabHeaderPattern = "--- !u!1001 &";
if (!foundSceneObjectName && sceneData[index].StartsWith(gameObjectHeaderPattern) || sceneData[index].StartsWith(prefabHeaderPattern))
{
if (sceneObjectNameById.TryGetValue(objectId, out string sceneObjectName))
{
objectInfo += $"-{sceneObjectName}";
foundSceneObjectName = true;
}
}
if (!foundSceneObjectName)
{
// Most components have a property that links to the GameObject.
for (int j = index; j < lastIndex; j++)
{
const string gameObjectPattern = @"m_GameObject:\s{fileID:\s(\d+)}";
// Find the match using regex
Match gameObjectMatch = Regex.Match(sceneData[j], gameObjectPattern);
if (!gameObjectMatch.Success) continue;
if (ulong.TryParse(gameObjectMatch.Groups[1].Value, out ulong fileNumber))
{
if (fileNumber == 0) break; // 0 == nothing.
if (!sceneObjectNameById.TryGetValue(fileNumber, out string sceneObjectName)) break;
objectInfo += $"-{sceneObjectName}";
foundSceneObjectName = true;
}
break;
}
}
if (!foundSceneObjectName)
{
// Some have a property that links to the PrefabInstance.
for (int j = index; j < lastIndex; j++)
{
const string prefabInstancePattern = @"m_PrefabInstance:\s{fileID:\s(\d+)}";
// Find the match using regex
Match prefabInstanceMatch = Regex.Match(sceneData[j], prefabInstancePattern);
if (!prefabInstanceMatch.Success) continue;
if (ulong.TryParse(prefabInstanceMatch.Groups[1].Value, out ulong fileNumber))
{
if (fileNumber == 0) break; // 0 == nothing.
if (!sceneObjectNameById.TryGetValue(fileNumber, out string sceneObjectName)) break;
objectInfo += $"-{sceneObjectName}";
foundSceneObjectName = true;
}
break;
}
}
// Try get object type name.
if (TryGetObjectTypeName(sceneData[index + 1], out string objectTypeName))
{
objectInfo += $"-{objectTypeName}";
}
}
}
}

View File

@ -1,4 +1,3 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
@ -20,7 +19,7 @@ namespace VertexColor.ScenePartition.Editor
//EditorGUILayout.PropertyField(sceneAssetProperty);
serializedObject.ApplyModifiedProperties();
EditorGUILayout.Space();
EditorGUIUtils.HorizontalLine();
if (scenePartitionSO.SceneAsset == null)
{
@ -31,72 +30,67 @@ namespace VertexColor.ScenePartition.Editor
}
else
{
if (GUILayout.Button("Open Scene Data Folder"))
{
EditorUtility.RevealInFinder(ScenePartitionUtils.GetDataPath(scenePartitionSO));
}
EditorGUIUtils.HorizontalLine();
if (GUILayout.Button("Load All"))
{
scenePartitionSO.LoadAll();
}
if (GUILayout.Button("Reload"))
using (new EditorGUILayout.HorizontalScope())
{
if (GUILayout.Button(new GUIContent("Unload", "Empty the scene and save it (so it has no changes in source control)."), EditorStyles.miniButtonLeft))
{
scenePartitionSO.Unload();
}
if (GUILayout.Button(new GUIContent("Reload", "Discard changes and reload loaded partitions."), EditorStyles.miniButtonRight))
{
scenePartitionSO.Reload();
}
}
if (GUILayout.Button("Save"))
{
scenePartitionSO.Save();
}
if (GUILayout.Button("Unload"))
EditorGUIUtils.HorizontalLine();
using (new EditorGUILayout.HorizontalScope())
{
scenePartitionSO.Unload();
}
EditorGUILayout.Space();
if (GUILayout.Button("Open Scene Data Folder"))
{
EditorUtility.RevealInFinder(ScenePartitionUtils.GetDataPath(scenePartitionSO));
}
EditorGUILayout.Space();
id = (ulong)EditorGUILayout.LongField("id", (long)id);
if (GUILayout.Button("Load Section"))
if (GUILayout.Button("Load Id"))
{
scenePartitionSO.LoadPartitions(new ulong[1] { id });
}
}
EditorGUIUtils.HorizontalLine();
ScenePartitionSceneViewEditor.cellSize = EditorGUILayout.IntSlider("cellSize", ScenePartitionSceneViewEditor.cellSize, 10, 1000);
if (GUILayout.Button("GenerateSceneGrid"))
{
scenePartitionSO.GenerateSceneGridData();
}
if (scenePartitionSO.Data.SceneGrid != null)
{
using (new EditorGUILayout.HorizontalScope())
{
gridId = EditorGUILayout.IntField("gridId", gridId);
if (GUILayout.Button("LoadSceneGrid"))
{
scenePartitionSO.LoadCell(gridId);
}
if (scenePartitionSO.Data.SceneGrid != null)
{
EditorGUILayout.LabelField($"generatedSceneGrid");
scenePartitionSO.Data.SceneGrid.cellSize = EditorGUILayout.IntSlider("cellSize", scenePartitionSO.Data.SceneGrid.cellSize, 10, 1000);
foreach (KeyValuePair<int, GridList> item in scenePartitionSO.Data.SceneGrid.Grid)
{
EditorGUILayout.LongField("gridId", item.Key);
EditorGUI.indentLevel++;
foreach (ulong id in item.Value.list)
{
EditorGUILayout.LongField((long)id);
}
EditorGUI.indentLevel--;
}
}
}

View File

@ -6,6 +6,8 @@ namespace VertexColor.ScenePartition.Editor
[InitializeOnLoad]
public class ScenePartitionSceneViewEditor : UnityEditor.Editor
{
public static int cellSize = 100;
private static ScenePartitionSO scenePartitionSO = null;
static ScenePartitionSceneViewEditor()
@ -18,7 +20,6 @@ namespace VertexColor.ScenePartition.Editor
if (Event.current.modifiers != EventModifiers.Control) return;
if (!ScenePartitionUtils.TryGetScenePartitionSOForActiveScene(out scenePartitionSO)) return;
int cellSize = scenePartitionSO.Data.SceneGrid.cellSize;
Vector3 gridPosition = CalculateGridPosition(Event.current.mousePosition);
int gridId = SceneGrid.CalculateGridPosition(gridPosition, cellSize);
@ -65,6 +66,7 @@ namespace VertexColor.ScenePartition.Editor
GenericMenu menu = new GenericMenu();
menu.AddItem(new GUIContent($"Load {gridId}"), false, Load, gridId);
menu.AddItem(new GUIContent($"LoadAdditive {gridId}"), false, LoadAdditive, gridId);
menu.ShowAsContext();
Event.current.Use();
@ -94,5 +96,14 @@ namespace VertexColor.ScenePartition.Editor
scenePartitionSO.LoadCell(cellId);
}
private static void LoadAdditive(object gridId)
{
if (scenePartitionSO == null) return;
if (gridId == null) return;
if (gridId is not int cellId) return;
scenePartitionSO.LoadCellAdditive(cellId);
}
}
}

View File

@ -0,0 +1,130 @@
using UnityEditor;
using UnityEditor.Overlays;
using UnityEditor.Toolbars;
using UnityEngine;
namespace VertexColor.ScenePartition.Editor
{
[Overlay(typeof(SceneView), "ScenePartition")]
public class ScenePartitionToolbar : ToolbarOverlay
{
private const string iconPath = "Packages/com.vertexcolor.scenepartition/Editor/Icons";
public ScenePartitionToolbar() : base(Load.Id, Save.Id, Reload.Id, Unload.Id, GenerateGrid.Id) { }
[EditorToolbarElement(Id, typeof(SceneView))]
public class Load : EditorToolbarButton, IAccessContainerWindow
{
public const string Id = "ScenePartition/Load";
public EditorWindow containerWindow { get; set; }
public Load()
{
text = "Load";
icon = AssetDatabase.LoadAssetAtPath<Texture2D>($"{iconPath}/Load.png");
tooltip = "Load the entire scene";
clicked += OnClick;
}
void OnClick()
{
if (!ScenePartitionUtils.TryGetScenePartitionSOForActiveScene(out ScenePartitionSO scenePartitionSO)) return;
scenePartitionSO.LoadAll();
}
}
[EditorToolbarElement(Id, typeof(SceneView))]
public class Save : EditorToolbarButton, IAccessContainerWindow
{
public const string Id = "ScenePartition/Save";
public EditorWindow containerWindow { get; set; }
public Save()
{
text = "Save";
icon = AssetDatabase.LoadAssetAtPath<Texture2D>($"{iconPath}/Save.png");
tooltip = "Save scene";
clicked += OnClick;
}
void OnClick()
{
if (!ScenePartitionUtils.TryGetScenePartitionSOForActiveScene(out ScenePartitionSO scenePartitionSO)) return;
scenePartitionSO.Save();
}
}
[EditorToolbarElement(Id, typeof(SceneView))]
public class Reload : EditorToolbarButton, IAccessContainerWindow
{
public const string Id = "ScenePartition/Reload";
public EditorWindow containerWindow { get; set; }
public Reload()
{
text = "Reload";
icon = AssetDatabase.LoadAssetAtPath<Texture2D>($"{iconPath}/Reload.png");
tooltip = "Discard changes and reload scene";
clicked += OnClick;
}
void OnClick()
{
if (!ScenePartitionUtils.TryGetScenePartitionSOForActiveScene(out ScenePartitionSO scenePartitionSO)) return;
scenePartitionSO.Reload();
}
}
[EditorToolbarElement(Id, typeof(SceneView))]
public class Unload : EditorToolbarButton, IAccessContainerWindow
{
public const string Id = "ScenePartition/Unload";
public EditorWindow containerWindow { get; set; }
public Unload()
{
text = "Unload";
icon = AssetDatabase.LoadAssetAtPath<Texture2D>($"{iconPath}/Unload.png");
tooltip = "Unload the scene";
clicked += OnClick;
}
void OnClick()
{
if (!ScenePartitionUtils.TryGetScenePartitionSOForActiveScene(out ScenePartitionSO scenePartitionSO)) return;
scenePartitionSO.Unload();
}
}
[EditorToolbarElement(Id, typeof(SceneView))]
public class GenerateGrid : EditorToolbarButton, IAccessContainerWindow
{
public const string Id = "ScenePartition/GenerateGrid";
public EditorWindow containerWindow { get; set; }
public GenerateGrid()
{
text = "GenerateGrid";
icon = AssetDatabase.LoadAssetAtPath<Texture2D>($"{iconPath}/GenerateGrid.png");
tooltip = "Generate scene grid";
clicked += OnClick;
}
void OnClick()
{
if (!ScenePartitionUtils.TryGetScenePartitionSOForActiveScene(out ScenePartitionSO scenePartitionSO)) return;
scenePartitionSO.GenerateSceneGridData();
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fb370b37d068c4244acc38008f1960f1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -32,11 +32,14 @@ namespace VertexColor.ScenePartition.Editor
}
public static SortedSet<ulong> FindDeeplyLinkedObjects(SortedList<ulong, ScenePartition> scenePartitions, ulong partitionId)
{
using (new ProfilerUtility.ProfilerScope($"{nameof(FindDeeplyLinkedObjects)}"))
{
SortedSet<ulong> linkedObjects = new SortedSet<ulong>();
FindDeeplyLinkedObjectsRecursive(scenePartitions, partitionId, linkedObjects);
return linkedObjects;
}
}
private static void FindDeeplyLinkedObjectsRecursive(SortedList<ulong, ScenePartition> scenePartitions, ulong partitionId, SortedSet<ulong> linkedObjects)
{
@ -59,6 +62,8 @@ namespace VertexColor.ScenePartition.Editor
}
public static bool TryGetScenePartitionSOForActiveScene(out ScenePartitionSO scenePartitionSO)
{
using (new ProfilerUtility.ProfilerScope($"{nameof(TryGetScenePartitionSOForActiveScene)}"))
{
scenePartitionSO = null;
@ -88,4 +93,19 @@ namespace VertexColor.ScenePartition.Editor
return false;
}
}
public static ulong GetTargetObjectId(Object targetObject)
{
GlobalObjectId globalId = GlobalObjectId.GetGlobalObjectIdSlow(targetObject);
if (globalId.targetPrefabId == 0) // 0 = no prefab.
{
return globalId.targetObjectId;
}
else
{
return globalId.targetPrefabId;
}
}
}
}

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) <year> <copyright holders>
Copyright (c) 2023 Max Kruf
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -1,2 +1,9 @@
# template-unity-project
# Scene Partition
**One file per scene object** (in editor time).
Trying to reduce the overlap between users by splitting the scene data into multiple small files. This removes the need to save the entire scene into one file. Usually when working with multiple people on a level you have to lock the entire scene to prevent having to merge the conflicting changes. This approach tries to avoid that and if you have conflicting changes they are on small readable files which should be easier to merge.
Next to that an other tool is to put the scene objects into a grid to allow for **partial scene loading** (in editor time), this could be helpful when working on large scenes where you only want to test/work on a small portion. Keeping the editor fast and your work focused.
The scene data is stored outside of the asset folder to prevent Unity from importing many small files into the asset database, instead it is saved into a data folder located at `ProjectRoot/Data/ScenePartition`.

View File

@ -0,0 +1,26 @@
using UnityEngine;
using UnityEngine.Profiling;
namespace VertexColor.ScenePartition
{
public static class ProfilerUtility
{
public struct ProfilerScope : System.IDisposable
{
public ProfilerScope(string name)
{
Profiler.BeginSample(name);
}
public ProfilerScope(string name, Object target)
{
Profiler.BeginSample(name, target);
}
public readonly void Dispose()
{
Profiler.EndSample();
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7338cbb3bcd0a224fbfca184c7efcd7e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -5,15 +5,12 @@ namespace VertexColor.ScenePartition
[System.Serializable]
public class SceneGrid
{
[SerializeField]
public int cellSize = 10;
[SerializeField]
private SceneGridDictionary grid = new SceneGridDictionary();
public SceneGridDictionary Grid => grid;
public void Insert(ulong scenePartitionId, Vector3 point)
public void Insert(ulong scenePartitionId, Vector3 point, int cellSize)
{
int gridId = CalculateGridPosition(point, cellSize);
if (grid.TryGetValue(gridId, out GridList ids))