generated from max/template-unity-project
Compare commits
16 Commits
8b44c33813
...
ReadableFi
Author | SHA1 | Date | |
---|---|---|---|
ebee93d107 | |||
83776072c9 | |||
40c49b076e | |||
fbd5a342fb | |||
8d567c8cda | |||
73ac3485aa | |||
12fd64f015 | |||
6fc95943fb | |||
df82f44c4a | |||
52b9a60918 | |||
ebb8ba559e | |||
6edb307e9c | |||
236c7377c7 | |||
daf622f327 | |||
6667f013bf | |||
d859ad1af5 |
@ -17,14 +17,14 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
|
|
||||||
public static void HorizontalLine() => HorizontalLine(horizontalLineColor);
|
public static void HorizontalLine() => HorizontalLine(horizontalLineColor);
|
||||||
|
|
||||||
public class FoldoutHeaderScope : System.IDisposable
|
public struct FoldoutHeaderScope : System.IDisposable
|
||||||
{
|
{
|
||||||
public FoldoutHeaderScope(string label, ref bool foldout)
|
public FoldoutHeaderScope(string label, ref bool foldout)
|
||||||
{
|
{
|
||||||
foldout = EditorGUILayout.BeginFoldoutHeaderGroup(foldout, label);
|
foldout = EditorGUILayout.BeginFoldoutHeaderGroup(foldout, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public readonly void Dispose()
|
||||||
{
|
{
|
||||||
EditorGUILayout.EndFoldoutHeaderGroup();
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
||||||
}
|
}
|
||||||
|
8
Editor/Icons.meta
Normal file
8
Editor/Icons.meta
Normal 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
BIN
Editor/Icons/GenerateGrid.png
(Stored with Git LFS)
Normal file
Binary file not shown.
123
Editor/Icons/GenerateGrid.png.meta
Normal file
123
Editor/Icons/GenerateGrid.png.meta
Normal 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
BIN
Editor/Icons/Load.png
(Stored with Git LFS)
Normal file
Binary file not shown.
123
Editor/Icons/Load.png.meta
Normal file
123
Editor/Icons/Load.png.meta
Normal 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
BIN
Editor/Icons/Reload.png
(Stored with Git LFS)
Normal file
Binary file not shown.
123
Editor/Icons/Reload.png.meta
Normal file
123
Editor/Icons/Reload.png.meta
Normal 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
BIN
Editor/Icons/Save.png
(Stored with Git LFS)
Normal file
Binary file not shown.
123
Editor/Icons/Save.png.meta
Normal file
123
Editor/Icons/Save.png.meta
Normal 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
BIN
Editor/Icons/Unload.png
(Stored with Git LFS)
Normal file
Binary file not shown.
123
Editor/Icons/Unload.png.meta
Normal file
123
Editor/Icons/Unload.png.meta
Normal 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:
|
@ -11,6 +11,9 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
private Vector2 scrollPos = Vector2.zero;
|
private Vector2 scrollPos = Vector2.zero;
|
||||||
private bool foldoutGroupEnabled = false;
|
private bool foldoutGroupEnabled = false;
|
||||||
|
|
||||||
|
private ulong id = 0;
|
||||||
|
private int gridId = 0;
|
||||||
|
|
||||||
[MenuItem("Window/ScenePartition")]
|
[MenuItem("Window/ScenePartition")]
|
||||||
public static void ShowExample()
|
public static void ShowExample()
|
||||||
{
|
{
|
||||||
@ -19,6 +22,99 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void OnGUI()
|
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);
|
EditorGUILayout.LabelField("Cache", EditorStyles.boldLabel);
|
||||||
|
|
||||||
@ -37,11 +133,6 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
|
|
||||||
EditorGUIUtils.HorizontalLine();
|
EditorGUIUtils.HorizontalLine();
|
||||||
|
|
||||||
DrawSceneDataCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawSceneDataCache()
|
|
||||||
{
|
|
||||||
using (EditorGUIUtils.FoldoutHeaderScope foldoutGroup = new EditorGUIUtils.FoldoutHeaderScope("SceneDataCache", ref foldoutGroupEnabled))
|
using (EditorGUIUtils.FoldoutHeaderScope foldoutGroup = new EditorGUIUtils.FoldoutHeaderScope("SceneDataCache", ref foldoutGroupEnabled))
|
||||||
{
|
{
|
||||||
if (!foldoutGroupEnabled) return;
|
if (!foldoutGroupEnabled) return;
|
||||||
|
@ -5,25 +5,50 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
{
|
{
|
||||||
public static class ScenePartitionMenuEditor
|
public static class ScenePartitionMenuEditor
|
||||||
{
|
{
|
||||||
[MenuItem("GameObject/CopyFileId", false, 10000)]
|
[MenuItem("GameObject/ScenePartition/CopyObjectId", false, 10000)]
|
||||||
public static void CreateTextArea5()
|
public static void CopyObjectId(MenuCommand menuCommand)
|
||||||
{
|
{
|
||||||
GameObject go = Selection.activeGameObject;
|
// 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 == null) return;
|
||||||
|
if (go.scene == null) return;
|
||||||
|
|
||||||
GlobalObjectId id = GlobalObjectId.GetGlobalObjectIdSlow(go);
|
ulong id = ScenePartitionUtils.GetTargetObjectId(go);
|
||||||
|
|
||||||
if (id.targetPrefabId == 0) // 0 = no prefab.
|
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)
|
||||||
{
|
{
|
||||||
EditorGUIUtility.systemCopyBuffer = id.targetObjectId.ToString();
|
// Get context from menu command instead of selection because the menu command is executed for each selected object when executed from the hierarchy.
|
||||||
Debug.Log($"object id: {id.targetObjectId}");
|
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})");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
[MenuItem("GameObject/ScenePartition/RemoveFromAlwaysLoad", false, 10000)]
|
||||||
|
public static void RemoveFromAlwaysLoad(MenuCommand menuCommand)
|
||||||
{
|
{
|
||||||
EditorGUIUtility.systemCopyBuffer = id.targetPrefabId.ToString();
|
// Get context from menu command instead of selection because the menu command is executed for each selected object when executed from the hierarchy.
|
||||||
Debug.Log($"object id: {id.targetPrefabId}");
|
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})");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -81,13 +81,13 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void LoadScenePartitions(SortedSet<ulong> partitionIds)
|
private void LoadScenePartitions(SortedSet<ulong> partitionIds)
|
||||||
|
{
|
||||||
|
using (new ProfilerUtility.ProfilerScope($"{nameof(LoadScenePartitions)}"))
|
||||||
{
|
{
|
||||||
if (!Data.HasCreatedPartitions) return;
|
if (!Data.HasCreatedPartitions) return;
|
||||||
|
|
||||||
string scenePath = ScenePartitionUtils.GetScenePath(this);
|
string scenePath = ScenePartitionUtils.GetScenePath(this);
|
||||||
|
|
||||||
List<string> sceneData = new List<string>();
|
|
||||||
|
|
||||||
Data.LoadedScenePartitions.Clear();
|
Data.LoadedScenePartitions.Clear();
|
||||||
|
|
||||||
// Add always load ids.
|
// Add always load ids.
|
||||||
@ -97,49 +97,77 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
partitionIds.Add(id);
|
partitionIds.Add(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear file.
|
||||||
|
File.WriteAllText(scenePath, string.Empty);
|
||||||
|
|
||||||
// Create scene data.
|
// Create scene data.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (FileStream outputStream = new FileStream(scenePath, FileMode.Append, FileAccess.Write))
|
||||||
|
{
|
||||||
foreach (ulong id in partitionIds)
|
foreach (ulong id in partitionIds)
|
||||||
{
|
{
|
||||||
ScenePartition p = Data.ScenePartitions[id];
|
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.
|
Data.LoadedScenePartitions.Add(p.id, p);
|
||||||
File.WriteAllLines(scenePath, sceneData);
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
Debug.LogException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
AssetDatabase.Refresh();
|
AssetDatabase.Refresh();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convert scene to partitions and save them to disk.
|
/// Convert scene to partitions and save them to disk.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Save()
|
public void Save()
|
||||||
|
{
|
||||||
|
using (new ProfilerUtility.ProfilerScope($"{nameof(Save)}"))
|
||||||
{
|
{
|
||||||
DeleteLoadedPartitions(); // Delete the loaded partitions from disk so we can write the new ones.
|
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 dataPath = ScenePartitionUtils.GetDataPath(this);
|
||||||
string scenePath = ScenePartitionUtils.GetScenePath(this);
|
string scenePath = ScenePartitionUtils.GetScenePath(this);
|
||||||
|
|
||||||
// Read the data from the scene file.
|
// Read the data from the scene file.
|
||||||
string[] sceneData = File.ReadAllLines(scenePath);
|
string[] sceneData = File.ReadAllLines(scenePath);
|
||||||
|
|
||||||
|
Dictionary<ulong, string> sceneObjectNameById = GetSceneObjectNames(in sceneData);
|
||||||
|
|
||||||
// Split it into blocks.
|
// Split it into blocks.
|
||||||
int lastIndex = sceneData.Length;
|
int lastIndex = sceneData.Length;
|
||||||
for (int i = sceneData.Length - 1; i >= 0; i--)
|
for (int i = sceneData.Length - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (sceneData[i].StartsWith("---")) // --- is the start of a new yaml document.
|
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)
|
if (match.Success)
|
||||||
{
|
{
|
||||||
// Extract the file number
|
// Extract the file number
|
||||||
string id = match.Groups[1].Value;
|
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.
|
// 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;
|
lastIndex = i;
|
||||||
@ -149,11 +177,14 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
// Write header to disk.
|
// Write header to disk.
|
||||||
File.WriteAllLines($"{dataPath}/{SceneName}.yaml", sceneData[0..lastIndex]);
|
File.WriteAllLines($"{dataPath}/{SceneName}.yaml", sceneData[0..lastIndex]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Empty the scene and save it (so it has no changes in source control).
|
/// Empty the scene and save it (so it has no changes in source control).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Unload()
|
public void Unload()
|
||||||
|
{
|
||||||
|
using (new ProfilerUtility.ProfilerScope($"{nameof(Unload)}"))
|
||||||
{
|
{
|
||||||
string dataPath = ScenePartitionUtils.GetDataPath(this);
|
string dataPath = ScenePartitionUtils.GetDataPath(this);
|
||||||
string scenePath = ScenePartitionUtils.GetScenePath(this);
|
string scenePath = ScenePartitionUtils.GetScenePath(this);
|
||||||
@ -173,8 +204,11 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
|
|
||||||
AssetDatabase.Refresh();
|
AssetDatabase.Refresh();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void DeleteLoadedPartitions()
|
private void DeleteLoadedPartitions()
|
||||||
|
{
|
||||||
|
using (new ProfilerUtility.ProfilerScope($"{nameof(DeleteLoadedPartitions)}"))
|
||||||
{
|
{
|
||||||
if (!Data.HasLoadedPartitions) return;
|
if (!Data.HasLoadedPartitions) return;
|
||||||
|
|
||||||
@ -185,8 +219,11 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
File.Delete(scenePartition.Value.filePath);
|
File.Delete(scenePartition.Value.filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void LoadPartitions(ulong[] ids)
|
public void LoadPartitions(ulong[] ids)
|
||||||
|
{
|
||||||
|
using (new ProfilerUtility.ProfilerScope($"{nameof(LoadPartitions)}"))
|
||||||
{
|
{
|
||||||
SortedSet<ulong> partitionIds = new SortedSet<ulong>();
|
SortedSet<ulong> partitionIds = new SortedSet<ulong>();
|
||||||
|
|
||||||
@ -201,6 +238,36 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
|
|
||||||
LoadScenePartitions(partitionIds);
|
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()
|
private SortedSet<ulong> GetAlwaysLoadIds()
|
||||||
{
|
{
|
||||||
@ -219,6 +286,8 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void GenerateSceneGridData()
|
public void GenerateSceneGridData()
|
||||||
|
{
|
||||||
|
using (new ProfilerUtility.ProfilerScope($"{nameof(GenerateSceneGridData)}"))
|
||||||
{
|
{
|
||||||
LoadAll();
|
LoadAll();
|
||||||
|
|
||||||
@ -277,7 +346,7 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
|
|
||||||
for (int i = 0; i < ids.Length; i++)
|
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.
|
if (ids[i].targetPrefabId == 0) // 0 = no prefab.
|
||||||
{
|
{
|
||||||
@ -291,6 +360,7 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
|
|
||||||
Unload();
|
Unload();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void LoadCell(int gridId)
|
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()
|
public void ClearCache()
|
||||||
{
|
{
|
||||||
data = null;
|
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}";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,3 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@ -9,7 +8,6 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
{
|
{
|
||||||
private ulong id = 0;
|
private ulong id = 0;
|
||||||
private int gridId = 0;
|
private int gridId = 0;
|
||||||
private bool foldoutGroupEnabled = false;
|
|
||||||
|
|
||||||
public override void OnInspectorGUI()
|
public override void OnInspectorGUI()
|
||||||
{
|
{
|
||||||
@ -39,32 +37,29 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
|
|
||||||
EditorGUIUtils.HorizontalLine();
|
EditorGUIUtils.HorizontalLine();
|
||||||
|
|
||||||
using (new EditorGUILayout.HorizontalScope())
|
if (GUILayout.Button("Load All"))
|
||||||
{
|
|
||||||
if (GUILayout.Button("Load All", EditorStyles.miniButtonLeft))
|
|
||||||
{
|
{
|
||||||
scenePartitionSO.LoadAll();
|
scenePartitionSO.LoadAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GUILayout.Button("Unload", EditorStyles.miniButtonRight))
|
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();
|
scenePartitionSO.Unload();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
using (new EditorGUILayout.HorizontalScope())
|
if (GUILayout.Button(new GUIContent("Reload", "Discard changes and reload loaded partitions."), EditorStyles.miniButtonRight))
|
||||||
{
|
|
||||||
if (GUILayout.Button("Save", EditorStyles.miniButtonLeft))
|
|
||||||
{
|
|
||||||
scenePartitionSO.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GUILayout.Button(new GUIContent("Reload", "Discard changes and reload"), EditorStyles.miniButtonRight))
|
|
||||||
{
|
{
|
||||||
scenePartitionSO.Reload();
|
scenePartitionSO.Reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("Save"))
|
||||||
|
{
|
||||||
|
scenePartitionSO.Save();
|
||||||
|
}
|
||||||
|
|
||||||
EditorGUIUtils.HorizontalLine();
|
EditorGUIUtils.HorizontalLine();
|
||||||
|
|
||||||
using (new EditorGUILayout.HorizontalScope())
|
using (new EditorGUILayout.HorizontalScope())
|
||||||
@ -87,6 +82,8 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (scenePartitionSO.Data.SceneGrid != null)
|
if (scenePartitionSO.Data.SceneGrid != null)
|
||||||
|
{
|
||||||
|
using (new EditorGUILayout.HorizontalScope())
|
||||||
{
|
{
|
||||||
gridId = EditorGUILayout.IntField("gridId", gridId);
|
gridId = EditorGUILayout.IntField("gridId", gridId);
|
||||||
|
|
||||||
@ -94,26 +91,6 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
{
|
{
|
||||||
scenePartitionSO.LoadCell(gridId);
|
scenePartitionSO.LoadCell(gridId);
|
||||||
}
|
}
|
||||||
|
|
||||||
using (EditorGUIUtils.FoldoutHeaderScope foldoutGroup = new EditorGUIUtils.FoldoutHeaderScope("gridData", ref foldoutGroupEnabled))
|
|
||||||
{
|
|
||||||
if (!foldoutGroupEnabled) return;
|
|
||||||
|
|
||||||
EditorGUILayout.LabelField($"generatedSceneGrid");
|
|
||||||
|
|
||||||
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--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,7 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
GenericMenu menu = new GenericMenu();
|
GenericMenu menu = new GenericMenu();
|
||||||
|
|
||||||
menu.AddItem(new GUIContent($"Load {gridId}"), false, Load, gridId);
|
menu.AddItem(new GUIContent($"Load {gridId}"), false, Load, gridId);
|
||||||
|
menu.AddItem(new GUIContent($"LoadAdditive {gridId}"), false, LoadAdditive, gridId);
|
||||||
menu.ShowAsContext();
|
menu.ShowAsContext();
|
||||||
|
|
||||||
Event.current.Use();
|
Event.current.Use();
|
||||||
@ -95,5 +96,14 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
|
|
||||||
scenePartitionSO.LoadCell(cellId);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
130
Editor/ScenePartitionToolbar.cs
Normal file
130
Editor/ScenePartitionToolbar.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Editor/ScenePartitionToolbar.cs.meta
Normal file
11
Editor/ScenePartitionToolbar.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fb370b37d068c4244acc38008f1960f1
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -32,11 +32,14 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static SortedSet<ulong> FindDeeplyLinkedObjects(SortedList<ulong, ScenePartition> scenePartitions, ulong partitionId)
|
public static SortedSet<ulong> FindDeeplyLinkedObjects(SortedList<ulong, ScenePartition> scenePartitions, ulong partitionId)
|
||||||
|
{
|
||||||
|
using (new ProfilerUtility.ProfilerScope($"{nameof(FindDeeplyLinkedObjects)}"))
|
||||||
{
|
{
|
||||||
SortedSet<ulong> linkedObjects = new SortedSet<ulong>();
|
SortedSet<ulong> linkedObjects = new SortedSet<ulong>();
|
||||||
FindDeeplyLinkedObjectsRecursive(scenePartitions, partitionId, linkedObjects);
|
FindDeeplyLinkedObjectsRecursive(scenePartitions, partitionId, linkedObjects);
|
||||||
return linkedObjects;
|
return linkedObjects;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void FindDeeplyLinkedObjectsRecursive(SortedList<ulong, ScenePartition> scenePartitions, ulong partitionId, SortedSet<ulong> 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)
|
public static bool TryGetScenePartitionSOForActiveScene(out ScenePartitionSO scenePartitionSO)
|
||||||
|
{
|
||||||
|
using (new ProfilerUtility.ProfilerScope($"{nameof(TryGetScenePartitionSOForActiveScene)}"))
|
||||||
{
|
{
|
||||||
scenePartitionSO = null;
|
scenePartitionSO = null;
|
||||||
|
|
||||||
@ -88,4 +93,19 @@ namespace VertexColor.ScenePartition.Editor
|
|||||||
return false;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
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:
|
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:
|
||||||
|
|
||||||
|
@ -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`.
|
||||||
|
26
Runtime/ProfilerUtility.cs
Normal file
26
Runtime/ProfilerUtility.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Runtime/ProfilerUtility.cs.meta
Normal file
11
Runtime/ProfilerUtility.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7338cbb3bcd0a224fbfca184c7efcd7e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Reference in New Issue
Block a user