Initialer Upload neues Unity-Projekt
This commit is contained in:
8
Assets/Oculus/VR/Editor/OVRProjectSetup/Icons.meta
Normal file
8
Assets/Oculus/VR/Editor/OVRProjectSetup/Icons.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10ca0391ac84e854eb1b65f8c7f162bc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Oculus/VR/Editor/OVRProjectSetup/Icons/ovr_icon_category_error.png
(Stored with Git LFS)
Normal file
BIN
Assets/Oculus/VR/Editor/OVRProjectSetup/Icons/ovr_icon_category_error.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,132 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23ed0d2bfc90b1d4f97cf416f2cd23a8
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
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
|
||||
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: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Windows Store Apps
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
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: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Oculus/VR/Editor/OVRProjectSetup/Icons/ovr_icon_category_neutral.png
(Stored with Git LFS)
Normal file
BIN
Assets/Oculus/VR/Editor/OVRProjectSetup/Icons/ovr_icon_category_neutral.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,132 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5c6b8a6ed5d33749ac1f5783e1675f2
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
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
|
||||
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: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Windows Store Apps
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
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: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Oculus/VR/Editor/OVRProjectSetup/Icons/ovr_icon_category_success.png
(Stored with Git LFS)
Normal file
BIN
Assets/Oculus/VR/Editor/OVRProjectSetup/Icons/ovr_icon_category_success.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,132 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0be6bd91c3ed459429f7e023ab85d7ee
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
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
|
||||
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: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Windows Store Apps
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
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: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Oculus/VR/Editor/OVRProjectSetup/Icons/ovr_icon_category_warning.png
(Stored with Git LFS)
Normal file
BIN
Assets/Oculus/VR/Editor/OVRProjectSetup/Icons/ovr_icon_category_warning.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,132 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f02eeecc6e9c02943ba538343bbe1a5b
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
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
|
||||
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: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Windows Store Apps
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
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: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Oculus/VR/Editor/OVRProjectSetup/Icons/ovr_icon_upst.png
(Stored with Git LFS)
Normal file
BIN
Assets/Oculus/VR/Editor/OVRProjectSetup/Icons/ovr_icon_upst.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,135 @@
|
||||
fileFormatVersion: 2
|
||||
guid: daccb634c40170b40a52151fdcb6ea99
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
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: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
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
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
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:
|
||||
276
Assets/Oculus/VR/Editor/OVRProjectSetup/OVRProjectSetup.cs
Normal file
276
Assets/Oculus/VR/Editor/OVRProjectSetup/OVRProjectSetup.cs
Normal file
@ -0,0 +1,276 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Core System for the OVRProjectSetup Tool
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This static class manages <see cref="OVRConfigurationTask"/> that can be added at any point.
|
||||
/// Use the AddTask method to add and register <see cref="OVRConfigurationTask"/>.
|
||||
/// </remarks>
|
||||
public static class OVRProjectSetup
|
||||
{
|
||||
public enum TaskLevel
|
||||
{
|
||||
Optional = 0,
|
||||
Recommended = 1,
|
||||
Required = 2
|
||||
}
|
||||
|
||||
public enum TaskGroup
|
||||
{
|
||||
All = 0,
|
||||
Compatibility = 1,
|
||||
Rendering = 2,
|
||||
Quality = 3,
|
||||
Physics = 4,
|
||||
Packages = 5,
|
||||
Features = 6,
|
||||
Miscellaneous = 7
|
||||
}
|
||||
|
||||
private static readonly OVRConfigurationTaskRegistry _principalRegistry;
|
||||
|
||||
internal static OVRConfigurationTaskRegistry Registry { get; private set; }
|
||||
internal static OVRConfigurationTaskProcessorQueue ProcessorQueue { get; }
|
||||
|
||||
internal const string KeyPrefix = "OVRProjectSetup";
|
||||
internal static OVRProjectSetupSettingBool Enabled;
|
||||
internal static OVRProjectSetupSettingBool RequiredThrowErrors;
|
||||
|
||||
internal static readonly OVRProjectSetupSettingBool AllowLogs =
|
||||
new OVRProjectSetupProjectSettingBool("AllowLogs", false, "Log outstanding issues");
|
||||
|
||||
internal static readonly OVRProjectSetupSettingBool ShowStatusIcon =
|
||||
new OVRProjectSetupProjectSettingBool("ShowStatusIcon", true, "Show Status Icon");
|
||||
|
||||
internal static readonly OVRProjectSetupSettingBool ProduceReportOnBuild =
|
||||
new OVRProjectSetupProjectSettingBool("ProduceReportOnBuild", false, "Produce Report on Build");
|
||||
|
||||
private static readonly HashSet<BuildTargetGroup> SupportedPlatforms = new HashSet<BuildTargetGroup>
|
||||
{ BuildTargetGroup.Android, BuildTargetGroup.Standalone };
|
||||
|
||||
|
||||
static OVRProjectSetup()
|
||||
{
|
||||
_principalRegistry = new OVRConfigurationTaskRegistry();
|
||||
ProcessorQueue = new OVRConfigurationTaskProcessorQueue();
|
||||
ConsoleLinkEventHandler.OnConsoleLink += OnConsoleLink;
|
||||
RestoreRegistry();
|
||||
|
||||
ProcessorQueue.OnProcessorCompleted += RefreshBuildStatusMenuSubText;
|
||||
var statusItem = new OVRStatusMenu.Item()
|
||||
{
|
||||
Name = "Project Setup Tool",
|
||||
Color = OVREditorUtils.HexToColor("#4e4e4e"),
|
||||
Icon = OVREditorUtils.CreateContent("ovr_icon_upst.png", OVRGUIContent.Source.ProjectSetupToolIcons),
|
||||
InfoTextDelegate = GetMenuSubText,
|
||||
OnClickDelegate = OnStatusMenuClick,
|
||||
Order = 0
|
||||
};
|
||||
OVRStatusMenu.RegisterItem(statusItem);
|
||||
}
|
||||
|
||||
private static string _statusMenuSubText;
|
||||
|
||||
private static void RefreshBuildStatusMenuSubText(OVRConfigurationTaskProcessor processor)
|
||||
{
|
||||
var updater = processor as OVRConfigurationTaskUpdater;
|
||||
var summary = updater?.Summary;
|
||||
_statusMenuSubText = summary?.ComputeNoticeMessage();
|
||||
}
|
||||
|
||||
public static string GetMenuSubText() => _statusMenuSubText;
|
||||
|
||||
private static void OnStatusMenuClick()
|
||||
{
|
||||
OVRProjectSetupSettingsProvider.OpenSettingsWindow(OVRProjectSetupSettingsProvider.Origins.Icon);
|
||||
}
|
||||
|
||||
internal static void SetupTemporaryRegistry()
|
||||
{
|
||||
Registry = new OVRConfigurationTaskRegistry();
|
||||
Enabled = new OVRProjectSetupConstSettingBool("Enabled", true, "Enabled");
|
||||
RequiredThrowErrors =
|
||||
new OVRProjectSetupConstSettingBool("RequiredThrowErrors", false, "Required throw errors");
|
||||
OVRProjectSetupUpdater.SetupTemporaryRegistry();
|
||||
}
|
||||
|
||||
internal static void RestoreRegistry()
|
||||
{
|
||||
Registry = _principalRegistry;
|
||||
Enabled =
|
||||
new OVRProjectSetupConstSettingBool("Enabled", true, "Enabled");
|
||||
RequiredThrowErrors =
|
||||
new OVRProjectSetupProjectSettingBool("RequiredThrowErrors", false, "Required throw errors");
|
||||
OVRProjectSetupUpdater.RestoreRegistry();
|
||||
}
|
||||
|
||||
private static void OnConsoleLink(Dictionary<string, string> infos)
|
||||
{
|
||||
if (infos.TryGetValue("href", out var href))
|
||||
{
|
||||
if (href == OVRConfigurationTask.ConsoleLinkHref)
|
||||
{
|
||||
OVRProjectSetupSettingsProvider.OpenSettingsWindow(OVRProjectSetupSettingsProvider.Origins.Console);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static IEnumerable<OVRConfigurationTask> GetTasks(BuildTargetGroup buildTargetGroup, bool refresh)
|
||||
{
|
||||
return Registry.GetTasks(buildTargetGroup, refresh);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an <see cref="OVRConfigurationTask"/> to the Setup Tool.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This methods adds and registers an already created <see cref="OVRConfigurationTask"/> to the SetupTool.
|
||||
/// We recommend the use of the other AddTask method with all the required parameters to create the task.
|
||||
/// </remarks>
|
||||
/// <param name="task">The task that will get registered to the Setup Tool.</param>
|
||||
/// <exception cref="ArgumentException">Possible causes :
|
||||
/// - a task with the same unique ID already has been registered (conflict in hash generated from description message).</exception>
|
||||
internal static void AddTask(OVRConfigurationTask task)
|
||||
{
|
||||
Registry.AddTask(task);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an <see cref="OVRConfigurationTask"/> to the Setup Tool.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This methods creates, adds and registers an <see cref="OVRConfigurationTask"/> to the SetupTool.
|
||||
/// Please note that the Message or ConditionalMessage parameters have to be unique since they are being hashed to generate a Unique ID for the task.
|
||||
/// Those tasks, once added, are not meant to be removed from the Setup Tool, and will get checked at some key points.
|
||||
/// This method is the one entry point for developers to add their own sanity checks, technical requirements or other recommendations.
|
||||
/// You can use the conditional parameters that accepts lambdas or delegates for more complex behaviours if needed.
|
||||
/// </remarks>
|
||||
/// <param name="group">Category that fits the task. Feel free to add more to the enum if relevant. Do not use "All".</param>
|
||||
/// <param name="isDone">Delegate that checks if the Configuration Task is validated or not.</param>
|
||||
/// <param name="platform">Platform for which this Configuration Task applies. Use "Unknown" for any.</param>
|
||||
/// <param name="fix">Delegate that validates the Configuration Task.</param>
|
||||
/// <param name="level">Severity (or behaviour) of the Configuration Task.</param>
|
||||
/// <param name="conditionalLevel">Use this delegate for more control or complex behaviours over the level parameter.</param>
|
||||
/// <param name="message">Description of the Configuration Task.</param>
|
||||
/// <param name="conditionalMessage">Use this delegate for more control or complex behaviours over the message parameter.</param>
|
||||
/// <param name="fixMessage">Description of the actual fix for the Task.</param>
|
||||
/// <param name="conditionalFixMessage">Use this delegate for more control or complex behaviours over the fixMessage parameter.</param>
|
||||
/// <param name="url">Url to more information about the Configuration Task.</param>
|
||||
/// <param name="conditionalUrl">Use this delegate for more control or complex behaviours over the url parameter.</param>
|
||||
/// <param name="validity">Checks if the task is valid. If not, it will be ignored by the Setup Tool.</param>
|
||||
/// <param name="conditionalValidity">Use this delegate for more control or complex behaviours over the validity parameter.</param>
|
||||
/// <exception cref="ArgumentNullException">Possible causes :
|
||||
/// - If either message or conditionalMessage do not provide a valid non null string
|
||||
/// - isDone is null
|
||||
/// - fix is null</exception>
|
||||
/// <exception cref="ArgumentException">Possible causes :
|
||||
/// - group is set to "All". This category is not meant to be used to describe a task.
|
||||
/// - a task with the same unique ID already has been registered (conflict in hash generated from description message).</exception>
|
||||
public static void AddTask(
|
||||
OVRProjectSetup.TaskGroup group,
|
||||
Func<BuildTargetGroup, bool> isDone,
|
||||
BuildTargetGroup platform = BuildTargetGroup.Unknown,
|
||||
Action<BuildTargetGroup> fix = null,
|
||||
OVRProjectSetup.TaskLevel level = OVRProjectSetup.TaskLevel.Recommended,
|
||||
Func<BuildTargetGroup, OVRProjectSetup.TaskLevel> conditionalLevel = null,
|
||||
string message = null,
|
||||
Func<BuildTargetGroup, string> conditionalMessage = null,
|
||||
string fixMessage = null,
|
||||
Func<BuildTargetGroup, string> conditionalFixMessage = null,
|
||||
string url = null,
|
||||
Func<BuildTargetGroup, string> conditionalUrl = null,
|
||||
bool validity = true,
|
||||
Func<BuildTargetGroup, bool> conditionalValidity = null
|
||||
)
|
||||
{
|
||||
var optionalLevel =
|
||||
OptionalLambdaType<BuildTargetGroup, OVRProjectSetup.TaskLevel>.Create(level, conditionalLevel, true);
|
||||
var optionalMessage = OptionalLambdaType<BuildTargetGroup, string>.Create(message, conditionalMessage, true);
|
||||
var optionalFixMessage =
|
||||
OptionalLambdaType<BuildTargetGroup, string>.Create(fixMessage, conditionalFixMessage, true);
|
||||
var optionalUrl = OptionalLambdaType<BuildTargetGroup, string>.Create(url, conditionalUrl, true);
|
||||
var optionalValidity = OptionalLambdaType<BuildTargetGroup, bool>.Create(validity, conditionalValidity, true);
|
||||
AddTask(new OVRConfigurationTask(group, platform, isDone, fix, optionalLevel, optionalMessage,
|
||||
optionalFixMessage, optionalUrl, optionalValidity));
|
||||
}
|
||||
|
||||
internal static bool IsPlatformSupported(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
return SupportedPlatforms.Contains(buildTargetGroup);
|
||||
}
|
||||
|
||||
internal enum LogMessages
|
||||
{
|
||||
Disabled = 0,
|
||||
Summary = 1,
|
||||
Changed = 2,
|
||||
All = 3,
|
||||
}
|
||||
|
||||
private const int LoopExitCount = 4;
|
||||
|
||||
internal static void FixTasks(
|
||||
BuildTargetGroup buildTargetGroup,
|
||||
Func<IEnumerable<OVRConfigurationTask>, List<OVRConfigurationTask>> filter = null,
|
||||
LogMessages logMessages = LogMessages.Disabled,
|
||||
bool blocking = true,
|
||||
Action<OVRConfigurationTaskProcessor> onCompleted = null)
|
||||
{
|
||||
var fixer = new OVRConfigurationTaskFixer(Registry, buildTargetGroup, filter, logMessages, blocking,
|
||||
onCompleted);
|
||||
ProcessorQueue.Request(fixer);
|
||||
}
|
||||
|
||||
internal static void FixTask(
|
||||
BuildTargetGroup buildTargetGroup,
|
||||
OVRConfigurationTask task,
|
||||
LogMessages logMessages = LogMessages.Disabled,
|
||||
bool blocking = true,
|
||||
Action<OVRConfigurationTaskProcessor> onCompleted = null
|
||||
)
|
||||
{
|
||||
// TODO : A bit overkill for just one task
|
||||
var filter = (Func<IEnumerable<OVRConfigurationTask>, List<OVRConfigurationTask>>)(tasks =>
|
||||
tasks.Where(otherTask => otherTask == task).ToList());
|
||||
var fixer = new OVRConfigurationTaskFixer(Registry, buildTargetGroup, filter, logMessages, blocking,
|
||||
onCompleted);
|
||||
ProcessorQueue.Request(fixer);
|
||||
}
|
||||
|
||||
internal static void UpdateTasks(
|
||||
BuildTargetGroup buildTargetGroup,
|
||||
Func<IEnumerable<OVRConfigurationTask>, List<OVRConfigurationTask>> filter = null,
|
||||
LogMessages logMessages = LogMessages.Disabled,
|
||||
bool blocking = true,
|
||||
Action<OVRConfigurationTaskProcessor> onCompleted = null)
|
||||
{
|
||||
var updater =
|
||||
new OVRConfigurationTaskUpdater(Registry, buildTargetGroup, filter, logMessages, blocking, onCompleted);
|
||||
ProcessorQueue.Request(updater);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65fb7bdd13ad2744ebc0000885584ce6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using UnityEngine;
|
||||
|
||||
internal class OVRProjectSetupBuildValidator : IPreprocessBuildWithReport
|
||||
{
|
||||
public int callbackOrder => 0;
|
||||
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
var outputDirectory = Path.GetDirectoryName(report.summary.outputPath);
|
||||
PreprocessBuild(report.summary.platformGroup, outputDirectory);
|
||||
}
|
||||
|
||||
public static void PreprocessBuild(BuildTargetGroup buildTargetGroup, string reportOutputPath = null)
|
||||
{
|
||||
if (!OVRProjectSetup.IsPlatformSupported(buildTargetGroup))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OVRProjectSetup.UpdateTasks(buildTargetGroup, onCompleted: OnUpdated(reportOutputPath));
|
||||
|
||||
foreach (var task in OVRProjectSetup.GetTasks(buildTargetGroup, false))
|
||||
{
|
||||
ValidateTask(task, buildTargetGroup);
|
||||
}
|
||||
}
|
||||
|
||||
private static Action<OVRConfigurationTaskProcessor> OnUpdated(string outputPath)
|
||||
{
|
||||
return (processor) =>
|
||||
{
|
||||
if (!OVRProjectSetup.ProduceReportOnBuild.Value) return;
|
||||
|
||||
var updater = processor as OVRConfigurationTaskUpdater;
|
||||
try
|
||||
{
|
||||
updater?.Summary?.GenerateReport(outputPath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning(e.Message);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static void ValidateTask(OVRConfigurationTask task, BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
if (task.IsIgnored(buildTargetGroup)
|
||||
|| task.Level.GetValue(buildTargetGroup) != OVRProjectSetup.TaskLevel.Required
|
||||
|| task.IsDone(buildTargetGroup))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (OVRProjectSetup.RequiredThrowErrors.Value)
|
||||
{
|
||||
throw new BuildFailedException(task.GetFullLogMessage(buildTargetGroup));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning(task.GetFullLogMessage(buildTargetGroup));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef3b0673029bea046ba4346b5fbbe59e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
|
||||
/// <summary>
|
||||
/// Static class for the OVRProjectSetup Tool that contains methods intended to be called from the CLI
|
||||
/// </summary>
|
||||
public class OVRProjectSetupCLI
|
||||
{
|
||||
/// <summary>
|
||||
/// Generate a project setup report and write it to a file.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This generates a project setup report for the active platform build target and write it to a file.
|
||||
/// The active platform build target may be specified using the "-buildTarget" CLI argument.
|
||||
/// The output file can be specified using the "-reportFile" CLI argument. If not specified, a
|
||||
/// file with a generated name will be created in the current folder.
|
||||
/// </remarks>
|
||||
public static void GenerateProjectSetupReport()
|
||||
{
|
||||
var buildTarget = EditorUserBuildSettings.activeBuildTarget;
|
||||
var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(buildTarget);
|
||||
|
||||
var reportFile = GetArgValue("-reportFile");
|
||||
var outputFolder = reportFile != null ? Path.GetDirectoryName(reportFile) : "./";
|
||||
var outputFile = Path.GetFileName(reportFile);
|
||||
|
||||
OVRProjectSetup.UpdateTasks(buildTargetGroup, logMessages: OVRProjectSetup.LogMessages.Disabled, blocking: true,
|
||||
onCompleted: processor =>
|
||||
{
|
||||
var updater = processor as OVRConfigurationTaskUpdater;
|
||||
updater?.Summary.GenerateReport(outputFolder, outputFile);
|
||||
});
|
||||
}
|
||||
|
||||
private static string GetArgValue(string argName)
|
||||
{
|
||||
var args = System.Environment.GetCommandLineArgs();
|
||||
for (var i = 0; i < args.Length; i++)
|
||||
{
|
||||
if (args[i] == argName)
|
||||
{
|
||||
return args[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de9f8b9e7f4f94a7ebb0b090513870ae
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
728
Assets/Oculus/VR/Editor/OVRProjectSetup/OVRProjectSetupDrawer.cs
Normal file
728
Assets/Oculus/VR/Editor/OVRProjectSetup/OVRProjectSetupDrawer.cs
Normal file
@ -0,0 +1,728 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
internal class OVRProjectSetupDrawer
|
||||
{
|
||||
private class Styles
|
||||
{
|
||||
private const float SmallIconSize = 16.0f;
|
||||
private const float FixButtonWidth = 64.0f;
|
||||
private const float FixAllButtonWidth = 80.0f;
|
||||
internal const float GroupSelectionWidth = 244.0f;
|
||||
internal const float LabelWidth = 96f;
|
||||
internal const float TitleLabelWidth = 196f;
|
||||
|
||||
internal readonly GUIStyle Wrap = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
wordWrap = true,
|
||||
alignment = TextAnchor.MiddleLeft,
|
||||
padding = new RectOffset(0, 5, 1, 1)
|
||||
};
|
||||
|
||||
internal readonly GUIStyle IssuesBackground = new GUIStyle("ScrollViewAlt")
|
||||
{
|
||||
};
|
||||
|
||||
internal readonly GUIStyle ListLabel = new GUIStyle("TV Selection")
|
||||
{
|
||||
border = new RectOffset(0, 0, 0, 0),
|
||||
padding = new RectOffset(5, 5, 5, 3),
|
||||
margin = new RectOffset(4, 4, 4, 5)
|
||||
};
|
||||
|
||||
internal readonly GUIStyle IssuesTitleLabel = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
fontSize = 14,
|
||||
wordWrap = false,
|
||||
stretchWidth = false,
|
||||
fontStyle = FontStyle.Bold,
|
||||
padding = new RectOffset(10, 10, 0, 0)
|
||||
};
|
||||
|
||||
internal readonly GUIStyle GenerateReportButton = new GUIStyle(EditorStyles.miniButton)
|
||||
{
|
||||
margin = new RectOffset(0, 10, 2, 2),
|
||||
stretchWidth = false,
|
||||
};
|
||||
|
||||
internal readonly GUIStyle FixButton = new GUIStyle(EditorStyles.miniButton)
|
||||
{
|
||||
margin = new RectOffset(0, 10, 2, 2),
|
||||
stretchWidth = false,
|
||||
fixedWidth = FixButtonWidth,
|
||||
};
|
||||
|
||||
internal readonly GUIStyle FixAllButton = new GUIStyle(EditorStyles.miniButton)
|
||||
{
|
||||
margin = new RectOffset(0, 10, 2, 2),
|
||||
stretchWidth = false,
|
||||
fixedWidth = FixAllButtonWidth,
|
||||
};
|
||||
|
||||
internal readonly GUIStyle InlinedIconStyle = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
margin = new RectOffset(0, 0, 0, 0),
|
||||
padding = new RectOffset(0, 0, 0, 0),
|
||||
fixedWidth = SmallIconSize,
|
||||
fixedHeight = SmallIconSize
|
||||
};
|
||||
|
||||
internal readonly GUIStyle IconStyle = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
margin = new RectOffset(5, 5, 4, 5),
|
||||
padding = new RectOffset(0, 0, 0, 0),
|
||||
fixedWidth = SmallIconSize,
|
||||
fixedHeight = SmallIconSize
|
||||
};
|
||||
|
||||
internal readonly GUIStyle SubtitleHelpText = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
margin = new RectOffset(10, 0, 0, 0),
|
||||
wordWrap = true
|
||||
};
|
||||
|
||||
internal readonly GUIStyle InternalHelpBox = new GUIStyle(EditorStyles.helpBox)
|
||||
{
|
||||
margin = new RectOffset(5, 5, 5, 5)
|
||||
};
|
||||
|
||||
internal readonly GUIStyle InternalHelpText = new GUIStyle(EditorStyles.miniLabel)
|
||||
{
|
||||
margin = new RectOffset(10, 0, 0, 0),
|
||||
wordWrap = true,
|
||||
fontStyle = FontStyle.Italic,
|
||||
normal =
|
||||
{
|
||||
textColor = new Color(0.58f, 0.72f, 0.95f)
|
||||
}
|
||||
};
|
||||
|
||||
internal readonly GUIStyle NormalStyle = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
margin = new RectOffset(10, 0, 0, 0),
|
||||
wordWrap = true,
|
||||
stretchWidth = false
|
||||
};
|
||||
|
||||
internal readonly GUIStyle BoldStyle = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
margin = new RectOffset(10, 0, 0, 0),
|
||||
stretchWidth = false,
|
||||
wordWrap = true,
|
||||
fontStyle = FontStyle.Bold
|
||||
};
|
||||
|
||||
internal readonly GUIStyle MiniButton = new GUIStyle(EditorStyles.miniButton)
|
||||
{
|
||||
clipping = TextClipping.Overflow,
|
||||
fixedHeight = 18.0f,
|
||||
fixedWidth = 18.0f,
|
||||
margin = new RectOffset(2, 2, 2, 2),
|
||||
padding = new RectOffset(1, 1, 1, 1)
|
||||
};
|
||||
|
||||
internal readonly GUIStyle Foldout = new GUIStyle(EditorStyles.foldoutHeader)
|
||||
{
|
||||
margin = new RectOffset(0, 0, 0, 0),
|
||||
padding = new RectOffset(16, 5, 5, 5),
|
||||
fixedHeight = 26.0f
|
||||
};
|
||||
|
||||
internal readonly GUIStyle FoldoutHorizontal = new GUIStyle(EditorStyles.label)
|
||||
{
|
||||
fixedHeight = 26.0f
|
||||
};
|
||||
|
||||
internal readonly GUIStyle List = new GUIStyle(EditorStyles.helpBox)
|
||||
{
|
||||
margin = new RectOffset(3, 3, 3, 3),
|
||||
padding = new RectOffset(3, 3, 3, 3)
|
||||
};
|
||||
}
|
||||
|
||||
private static Styles _styles;
|
||||
private static Styles styles => _styles ??= new Styles();
|
||||
|
||||
private readonly OVRProjectSetupSettingBool _showOutstandingItems =
|
||||
new OVRProjectSetupUserSettingBool("ShowOutstandingItems", true);
|
||||
|
||||
private readonly OVRProjectSetupSettingBool _showRecommendedItems =
|
||||
new OVRProjectSetupUserSettingBool("ShowRecommendedItems", true);
|
||||
|
||||
private readonly OVRProjectSetupSettingBool _showVerifiedItems =
|
||||
new OVRProjectSetupUserSettingBool("ShowVerifiedItems", false);
|
||||
|
||||
private readonly OVRProjectSetupSettingBool _showIgnoredItems =
|
||||
new OVRProjectSetupUserSettingBool("ShowIgnoredItems", false);
|
||||
|
||||
private static readonly GUIContent Title = new GUIContent("Project Setup Tool");
|
||||
|
||||
private static readonly GUIContent Description =
|
||||
new GUIContent("This tool maintains a checklist of required setup tasks as well as best practices to " +
|
||||
"ensure your project is ready to go. Follow our suggestions and fixes to quickly setup your project.");
|
||||
|
||||
private static readonly GUIContent SummaryLabel = new GUIContent("Current project status: ");
|
||||
private static readonly GUIContent ListTitle = new GUIContent("Checklist");
|
||||
private static readonly GUIContent UnsupportedTitle = new GUIContent("Unsupported Platform");
|
||||
|
||||
private static readonly GUIContent Filter =
|
||||
new GUIContent("Filter by Group :", "Filters the task to the selected group.");
|
||||
|
||||
private static readonly GUIContent FixButtonContent = new GUIContent("Fix", "Fix with recommended settings");
|
||||
|
||||
private static readonly GUIContent FixAllButtonContent =
|
||||
new GUIContent("Fix All", "Fix all the issues from this category");
|
||||
|
||||
private static readonly GUIContent ApplyButtonContent = new GUIContent("Apply", "Apply the recommended settings");
|
||||
|
||||
private static readonly GUIContent ApplyAllButtonContent =
|
||||
new GUIContent("Apply All", "Apply the recommended settings for all the items in this category");
|
||||
|
||||
private static readonly GUIContent RefreshTasksButtonContent =
|
||||
new GUIContent("Refresh", "Refresh the items in the list");
|
||||
|
||||
private static readonly GUIContent GenerateReportButtonContent =
|
||||
new GUIContent("Generate report", "Generate a report of all the issues");
|
||||
|
||||
private static readonly OVRGUIContent WarningIcon = OVREditorUtils.CreateContent("ovr_icon_category_warning.png", OVRGUIContent.Source.ProjectSetupToolIcons);
|
||||
private static readonly OVRGUIContent ErrorIcon = OVREditorUtils.CreateContent("ovr_icon_category_error.png", OVRGUIContent.Source.ProjectSetupToolIcons);
|
||||
|
||||
private static readonly OVRGUIContent InfoIcon = OVREditorUtils.CreateContent("ovr_icon_category_neutral.png", OVRGUIContent.Source.ProjectSetupToolIcons);
|
||||
private static readonly OVRGUIContent TestPassedIcon =
|
||||
OVREditorUtils.CreateContent("ovr_icon_category_success.png", OVRGUIContent.Source.ProjectSetupToolIcons);
|
||||
|
||||
private static readonly OVRGUIContent ConfigIcon =
|
||||
OVREditorUtils.CreateContent("_Popup", OVRGUIContent.Source.BuiltIn, "Additional options");
|
||||
|
||||
|
||||
private static readonly OVRGUIContent DocumentationIcon =
|
||||
OVREditorUtils.CreateContent("ovr_icon_documentation.png", OVRGUIContent.Source.GenericIcons, "Go to Documentation");
|
||||
|
||||
private const string OutstandingItems = "Outstanding Issues";
|
||||
private const string RecommendedItems = "Recommended Items";
|
||||
private const string VerifiedItems = "Verified Items";
|
||||
private const string IgnoredItems = "Ignored Items";
|
||||
private const string OutFolderTitle = "Select output folder";
|
||||
private const string ErrorTitle = "Error";
|
||||
private const string SuccessTitle = "Success";
|
||||
private const string ReportGenerationErrorMessage = "Could not generate the project setup report.";
|
||||
private const string ReportGenerationSuccessMessage = "Project setup report generated successfully at:";
|
||||
private const string TasksRefreshErrorMessage = "Could not refresh the checklist.";
|
||||
private const string TasksRefreshSuccessMessage = "Tasks refreshed successfully.";
|
||||
private const string OkButton = "ok";
|
||||
private const string DocumentationUrl =
|
||||
"https://developer.oculus.com/documentation/unity/unity-upst-overview";
|
||||
|
||||
|
||||
// Internals
|
||||
private OVRProjectSetup.TaskGroup _selectedTaskGroup;
|
||||
private BuildTargetGroup _selectedBuildTargetGroup = BuildTargetGroup.Unknown;
|
||||
private Vector2 _scrollViewPos = Vector2.zero;
|
||||
private OVRConfigurationTaskUpdaterSummary _lastSummary;
|
||||
|
||||
internal OVRProjectSetupDrawer()
|
||||
{
|
||||
_selectedTaskGroup = OVRProjectSetup.TaskGroup.All;
|
||||
}
|
||||
|
||||
private class BuildTargetSelectionScope : GUI.Scope
|
||||
{
|
||||
public BuildTargetGroup BuildTargetGroup { get; protected set; }
|
||||
|
||||
public BuildTargetSelectionScope()
|
||||
{
|
||||
BuildTargetGroup = EditorGUILayout.BeginBuildTargetSelectionGrouping();
|
||||
if (BuildTargetGroup == BuildTargetGroup.Unknown)
|
||||
{
|
||||
BuildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CloseScope() => EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private TEnumType EnumPopup<TEnumType>(GUIContent content, TEnumType currentValue, Action<TEnumType> onChanged)
|
||||
where TEnumType : Enum, IComparable
|
||||
{
|
||||
var previousLabelWidth = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = Styles.LabelWidth;
|
||||
TEnumType newValue =
|
||||
(TEnumType)EditorGUILayout.EnumPopup(content, currentValue, GUILayout.Width(Styles.GroupSelectionWidth));
|
||||
EditorGUIUtility.labelWidth = previousLabelWidth;
|
||||
|
||||
if (!newValue.Equals(currentValue))
|
||||
{
|
||||
onChanged(newValue);
|
||||
}
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
private bool FoldoutWithAdditionalAction(OVRProjectSetupSettingBool key, string label, Rect rect,
|
||||
Action inlineAdditionalAction)
|
||||
{
|
||||
var previousLabelWidth = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = rect.width - 8;
|
||||
|
||||
bool foldout;
|
||||
using (new EditorGUILayout.HorizontalScope(styles.FoldoutHorizontal))
|
||||
{
|
||||
foldout = Foldout(key, label);
|
||||
inlineAdditionalAction?.Invoke();
|
||||
}
|
||||
|
||||
EditorGUIUtility.labelWidth = previousLabelWidth;
|
||||
return foldout;
|
||||
}
|
||||
|
||||
private bool Foldout(OVRProjectSetupSettingBool key, string label)
|
||||
{
|
||||
var currentValue = key.Value;
|
||||
var newValue = EditorGUILayout.Foldout(currentValue, label, true, styles.Foldout);
|
||||
if (newValue != currentValue)
|
||||
{
|
||||
key.Value = newValue;
|
||||
}
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
private OVRGUIContent GetTaskIcon(OVRConfigurationTask task, BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
if (task.IsDone(buildTargetGroup))
|
||||
{
|
||||
return TestPassedIcon;
|
||||
}
|
||||
|
||||
return task.Level.GetValue(buildTargetGroup) switch
|
||||
{
|
||||
OVRProjectSetup.TaskLevel.Required => ErrorIcon,
|
||||
OVRProjectSetup.TaskLevel.Recommended => WarningIcon,
|
||||
OVRProjectSetup.TaskLevel.Optional => InfoIcon,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
}
|
||||
|
||||
private string GenerateReport(BuildTargetGroup buildTargetGroup, string outputPath)
|
||||
{
|
||||
if (_lastSummary == null)
|
||||
{
|
||||
OVRProjectSetup.UpdateTasks(buildTargetGroup, logMessages: OVRProjectSetup.LogMessages.Disabled,
|
||||
blocking: true, onCompleted: processor =>
|
||||
{
|
||||
var updater = processor as OVRConfigurationTaskUpdater;
|
||||
_lastSummary = updater?.Summary;
|
||||
});
|
||||
return _lastSummary?.GenerateReport(outputPath);
|
||||
}
|
||||
|
||||
return _lastSummary.GenerateReport(outputPath);
|
||||
}
|
||||
|
||||
private void UpdateTasks(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
OVRProjectSetup.UpdateTasks(buildTargetGroup, logMessages: OVRProjectSetup.LogMessages.Disabled,
|
||||
blocking: false, onCompleted: OnUpdated);
|
||||
}
|
||||
|
||||
private void OnUpdated(OVRConfigurationTaskProcessor processor)
|
||||
{
|
||||
var updater = processor as OVRConfigurationTaskUpdater;
|
||||
_lastSummary = updater?.Summary;
|
||||
}
|
||||
|
||||
private void ShowSettingsMenu()
|
||||
{
|
||||
var menu = new GenericMenu();
|
||||
OVRProjectSetup.Enabled.AppendToMenu(menu);
|
||||
OVRProjectSetupUpdater.Enabled.AppendToMenu(menu);
|
||||
OVRProjectSetup.RequiredThrowErrors.AppendToMenu(menu);
|
||||
OVRProjectSetup.AllowLogs.AppendToMenu(menu);
|
||||
OVRProjectSetup.ShowStatusIcon.AppendToMenu(menu);
|
||||
OVRProjectSetup.ProduceReportOnBuild.AppendToMenu(menu);
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
|
||||
private void ShowItemMenu(BuildTargetGroup buildTargetGroup, OVRConfigurationTask task)
|
||||
{
|
||||
var menu = new GenericMenu();
|
||||
var hasDocumentation = !string.IsNullOrEmpty(task.URL.GetValue(buildTargetGroup));
|
||||
if (hasDocumentation)
|
||||
{
|
||||
menu.AddItem(new GUIContent("Documentation"), false, OnDocumentation,
|
||||
new object[] { buildTargetGroup, task });
|
||||
}
|
||||
|
||||
var hasSourceCode = task.SourceCode.Valid;
|
||||
if (hasSourceCode)
|
||||
{
|
||||
menu.AddItem(new GUIContent("Go to Source Code"), false, OnGoToSourceCode,
|
||||
new object[] { buildTargetGroup, task });
|
||||
}
|
||||
|
||||
menu.AddItem(new GUIContent("Ignore"), task.IsIgnored(buildTargetGroup), OnIgnore,
|
||||
new object[] { buildTargetGroup, task });
|
||||
menu.ShowAsContext();
|
||||
}
|
||||
|
||||
internal void OnTitleBarGUI()
|
||||
{
|
||||
if (GUILayout.Button(ConfigIcon, styles.MiniButton))
|
||||
{
|
||||
ShowSettingsMenu();
|
||||
}
|
||||
|
||||
if (GUILayout.Button(DocumentationIcon, styles.MiniButton))
|
||||
{
|
||||
Application.OpenURL(DocumentationUrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal void OnGUI()
|
||||
{
|
||||
// Title
|
||||
GUILayout.Label(Title, styles.IssuesTitleLabel);
|
||||
|
||||
// Short Description
|
||||
GUILayout.Label(Description, styles.SubtitleHelpText);
|
||||
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
var enabled = OVRProjectSetup.Enabled.Value;
|
||||
using (new EditorGUI.DisabledScope(!enabled))
|
||||
{
|
||||
// Summary
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
GUILayout.Label(SummaryLabel, styles.NormalStyle);
|
||||
if (enabled)
|
||||
{
|
||||
GUILayout.Label(OVRProjectSetupStatusIcon.ComputeIcon(_lastSummary), styles.InlinedIconStyle);
|
||||
GUILayout.Label(_lastSummary?.ComputeNoticeMessage() ?? "", styles.BoldStyle);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label("Setup Tool is disabled", styles.BoldStyle);
|
||||
}
|
||||
}
|
||||
|
||||
// Checklist
|
||||
using (var buildTargetSelection = new BuildTargetSelectionScope())
|
||||
{
|
||||
var buildTargetGroup = buildTargetSelection.BuildTargetGroup;
|
||||
if (_selectedBuildTargetGroup != buildTargetGroup)
|
||||
{
|
||||
_selectedBuildTargetGroup = buildTargetGroup;
|
||||
UpdateTasks(buildTargetGroup);
|
||||
}
|
||||
|
||||
using (new EditorGUILayout.VerticalScope())
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
DrawTasksList(_selectedBuildTargetGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawTasksList(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
var disableTasksList = EditorApplication.isPlaying;
|
||||
|
||||
using (new EditorGUI.DisabledGroupScope(disableTasksList))
|
||||
{
|
||||
// Header
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
// Title
|
||||
GUILayout.Label(ListTitle,
|
||||
styles.IssuesTitleLabel, GUILayout.Width(Styles.TitleLabelWidth));
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
// Filter
|
||||
EnumPopup<OVRProjectSetup.TaskGroup>(Filter, _selectedTaskGroup,
|
||||
group => _selectedTaskGroup = group);
|
||||
|
||||
// More Actions Menu Button
|
||||
DrawMoreActionsMenuList(buildTargetGroup);
|
||||
}
|
||||
|
||||
// Scroll View
|
||||
_scrollViewPos = EditorGUILayout.BeginScrollView(_scrollViewPos, styles.IssuesBackground,
|
||||
GUILayout.ExpandHeight(true));
|
||||
|
||||
DrawCategory(_showOutstandingItems, tasks => tasks
|
||||
.Where(task =>
|
||||
(_selectedTaskGroup == OVRProjectSetup.TaskGroup.All || task.Group == _selectedTaskGroup)
|
||||
&& !task.IsDone(buildTargetGroup)
|
||||
&& !task.IsIgnored(buildTargetGroup)
|
||||
&& (task.Level.GetValue(buildTargetGroup) == OVRProjectSetup.TaskLevel.Required))
|
||||
.OrderByDescending(task => task.FixAction == null)
|
||||
.ToList(),
|
||||
buildTargetGroup, OutstandingItems, true);
|
||||
|
||||
DrawCategory(_showRecommendedItems, tasks => tasks
|
||||
.Where(task =>
|
||||
(_selectedTaskGroup == OVRProjectSetup.TaskGroup.All || task.Group == _selectedTaskGroup)
|
||||
&& !task.IsDone(buildTargetGroup)
|
||||
&& !task.IsIgnored(buildTargetGroup)
|
||||
&& (task.Level.GetValue(buildTargetGroup) != OVRProjectSetup.TaskLevel.Required))
|
||||
.OrderByDescending(task => task.Level.GetValue(buildTargetGroup))
|
||||
.ThenBy(task => task.FixAction == null)
|
||||
.ToList(),
|
||||
buildTargetGroup, RecommendedItems, true);
|
||||
|
||||
DrawCategory(_showVerifiedItems, tasks => tasks
|
||||
.Where(task =>
|
||||
(_selectedTaskGroup == OVRProjectSetup.TaskGroup.All || task.Group == _selectedTaskGroup)
|
||||
&& task.IsDone(buildTargetGroup)
|
||||
&& !task.IsIgnored(buildTargetGroup))
|
||||
.OrderByDescending(task => task.FixAction == null)
|
||||
.ThenBy(task => task.Level.GetValue(buildTargetGroup))
|
||||
.ToList(),
|
||||
buildTargetGroup, VerifiedItems, false);
|
||||
|
||||
DrawCategory(_showIgnoredItems, tasks => tasks
|
||||
.Where(task =>
|
||||
(_selectedTaskGroup == OVRProjectSetup.TaskGroup.All || task.Group == _selectedTaskGroup)
|
||||
&& task.IsIgnored(buildTargetGroup))
|
||||
.OrderByDescending(task => task.Level.GetValue(buildTargetGroup))
|
||||
.ThenBy(task => task.FixAction != null)
|
||||
.ToList(),
|
||||
buildTargetGroup, IgnoredItems, false);
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCategory(OVRProjectSetupSettingBool key, Func<IEnumerable<OVRConfigurationTask>,
|
||||
List<OVRConfigurationTask>> filter, BuildTargetGroup buildTargetGroup, string title, bool fixAllButton)
|
||||
{
|
||||
var tasks = filter(OVRProjectSetup.GetTasks(buildTargetGroup, false));
|
||||
|
||||
if (key == null || tasks == null || tasks.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (var scope = new EditorGUILayout.VerticalScope(styles.List))
|
||||
{
|
||||
var rect = scope.rect;
|
||||
|
||||
// Foldout
|
||||
title = $"{title} ({tasks.Count})";
|
||||
|
||||
var foldout = FoldoutWithAdditionalAction(key, title, rect, () =>
|
||||
{
|
||||
if (fixAllButton)
|
||||
{
|
||||
if (tasks.Any(task => task.FixAction != null))
|
||||
{
|
||||
var content = tasks[0].Level.GetValue(buildTargetGroup) == OVRProjectSetup.TaskLevel.Required
|
||||
? FixAllButtonContent
|
||||
: ApplyAllButtonContent;
|
||||
EditorGUI.BeginDisabledGroup(
|
||||
OVRProjectSetup.ProcessorQueue.BusyWith(OVRConfigurationTaskProcessor.ProcessorType.Fixer));
|
||||
if (GUILayout.Button(content, styles.FixAllButton))
|
||||
{
|
||||
OVRProjectSetupSettingsProvider.SetNewInteraction(OVRProjectSetupSettingsProvider
|
||||
.Interaction.Fixed);
|
||||
|
||||
OVRProjectSetup.FixTasks(buildTargetGroup, filter, blocking: false,
|
||||
onCompleted: AfterFixApply);
|
||||
}
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (foldout)
|
||||
{
|
||||
DrawIssues(tasks, buildTargetGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AfterFixApply(OVRConfigurationTaskProcessor processor)
|
||||
{
|
||||
AssetDatabase.SaveAssets();
|
||||
UpdateTasks(processor.BuildTargetGroup);
|
||||
}
|
||||
|
||||
private void DrawIssues(List<OVRConfigurationTask> tasks, BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
foreach (var task in tasks)
|
||||
{
|
||||
DrawIssue(task, buildTargetGroup);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawIssue(OVRConfigurationTask task, BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
var ignored = task.IsIgnored(buildTargetGroup);
|
||||
var cannotBeFixed = task.IsDone(buildTargetGroup) ||
|
||||
OVRProjectSetup.ProcessorQueue.BusyWith(OVRConfigurationTaskProcessor.ProcessorType.Fixer);
|
||||
var disabled = cannotBeFixed || ignored;
|
||||
|
||||
// Note : We're not using scopes, because in this very case, we've got a cross of scopes
|
||||
EditorGUI.BeginDisabledGroup(disabled);
|
||||
var clickArea = EditorGUILayout.BeginHorizontal(styles.ListLabel);
|
||||
|
||||
// Icon
|
||||
GUILayout.Label(GetTaskIcon(task, buildTargetGroup), styles.IconStyle);
|
||||
|
||||
// Message
|
||||
GUILayout.Label(new GUIContent(task.Message.GetValue(buildTargetGroup)), styles.Wrap);
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
if (task.FixAction != null)
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(cannotBeFixed);
|
||||
var content = task.Level.GetValue(buildTargetGroup) == OVRProjectSetup.TaskLevel.Required
|
||||
? FixButtonContent
|
||||
: ApplyButtonContent;
|
||||
|
||||
var fixMessage = task.FixMessage.GetValue(buildTargetGroup);
|
||||
var tooltip = fixMessage != null ? $"{content.tooltip} :\n{fixMessage}" : content.tooltip;
|
||||
content = new GUIContent(content.text, tooltip);
|
||||
if (GUILayout.Button(content, styles.FixButton))
|
||||
{
|
||||
OVRProjectSetupSettingsProvider.SetNewInteraction(OVRProjectSetupSettingsProvider.Interaction.Fixed);
|
||||
|
||||
OVRProjectSetup.FixTask(buildTargetGroup, task, blocking: false, onCompleted: AfterFixApply);
|
||||
}
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
|
||||
var current = Event.current;
|
||||
if (GUILayout.Button("", EditorStyles.foldoutHeaderIcon, GUILayout.Width(16.0f))
|
||||
|| (clickArea.Contains(current.mousePosition) && current.type == EventType.ContextClick))
|
||||
{
|
||||
ShowItemMenu(buildTargetGroup, task);
|
||||
if (current.type == EventType.ContextClick)
|
||||
{
|
||||
current.Use();
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void DrawMoreActionsMenuList(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
var current = Event.current;
|
||||
if (GUILayout.Button("", EditorStyles.foldoutHeaderIcon, GUILayout.Width(16.0f)))
|
||||
{
|
||||
var menu = new GenericMenu();
|
||||
menu.AddItem(RefreshTasksButtonContent, false, OnRefresh, new object[] { buildTargetGroup });
|
||||
menu.AddItem(GenerateReportButtonContent, false, OnGenerateReport, new object[] { buildTargetGroup });
|
||||
menu.ShowAsContext();
|
||||
if (current.type == EventType.ContextClick)
|
||||
{
|
||||
current.Use();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadContextMenuArguments(
|
||||
object arg,
|
||||
out BuildTargetGroup buildTargetGroup,
|
||||
out OVRConfigurationTask task)
|
||||
{
|
||||
var args = arg as object[];
|
||||
buildTargetGroup = args != null ? (BuildTargetGroup)args[0] : BuildTargetGroup.Unknown;
|
||||
task = args?[1] as OVRConfigurationTask;
|
||||
}
|
||||
|
||||
private void OnIgnore(object args)
|
||||
{
|
||||
ReadContextMenuArguments(args, out var buildTargetGroup, out var task);
|
||||
|
||||
var ignore = !task.IsIgnored(buildTargetGroup);
|
||||
if (ignore)
|
||||
{
|
||||
OVRProjectSetupSettingsProvider.SetNewInteraction(OVRProjectSetupSettingsProvider.Interaction.Ignored);
|
||||
}
|
||||
|
||||
task?.SetIgnored(buildTargetGroup, ignore);
|
||||
}
|
||||
|
||||
private void OnDocumentation(object args)
|
||||
{
|
||||
OVRProjectSetupSettingsProvider.SetNewInteraction(OVRProjectSetupSettingsProvider.Interaction
|
||||
.WentToDocumentation);
|
||||
|
||||
ReadContextMenuArguments(args, out var buildTargetGroup, out var task);
|
||||
var url = task?.URL.GetValue(buildTargetGroup);
|
||||
|
||||
Application.OpenURL(url);
|
||||
}
|
||||
|
||||
private void OnGoToSourceCode(object args)
|
||||
{
|
||||
OVRProjectSetupSettingsProvider.SetNewInteraction(OVRProjectSetupSettingsProvider.Interaction.WentToSource);
|
||||
|
||||
ReadContextMenuArguments(args, out var buildTargetGroup, out var task);
|
||||
task?.SourceCode.Open();
|
||||
}
|
||||
|
||||
private void OnGenerateReport(object arg)
|
||||
{
|
||||
var buildTargetGroup = arg is object[] args ? (BuildTargetGroup)args[0] : BuildTargetGroup.Unknown;
|
||||
var path = EditorUtility.OpenFolderPanel(OutFolderTitle, "", "");
|
||||
if (string.IsNullOrEmpty(path)) return;
|
||||
try
|
||||
{
|
||||
var reportFileName = GenerateReport(buildTargetGroup, path);
|
||||
EditorUtility.DisplayDialog(SuccessTitle, $"{ReportGenerationSuccessMessage}\n{reportFileName}", OkButton);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
EditorUtility.DisplayDialog(ErrorTitle, $"{ReportGenerationErrorMessage}\n{e.Message}", OkButton);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRefresh(object arg)
|
||||
{
|
||||
var buildTargetGroup = arg is object[] args ? (BuildTargetGroup)args[0] : BuildTargetGroup.Unknown;
|
||||
try
|
||||
{
|
||||
OVRProjectSetup.UpdateTasks(buildTargetGroup, logMessages: OVRProjectSetup.LogMessages.Disabled,
|
||||
blocking: true);
|
||||
EditorUtility.DisplayDialog(SuccessTitle, TasksRefreshSuccessMessage, OkButton);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
EditorUtility.DisplayDialog(ErrorTitle, $"{TasksRefreshErrorMessage}\n{e.Message}", OkButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16be1d6ef5ab58848a7b44f62ab8d345
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
124
Assets/Oculus/VR/Editor/OVRProjectSetup/OVRProjectSetupReport.cs
Normal file
124
Assets/Oculus/VR/Editor/OVRProjectSetup/OVRProjectSetupReport.cs
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[Serializable]
|
||||
internal class OVRConfigurationTaskJsonReport
|
||||
{
|
||||
public string uid;
|
||||
public string group;
|
||||
public string message;
|
||||
public string level;
|
||||
public bool isDone;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
internal class OVRProjectSetupJsonReport
|
||||
{
|
||||
public string createdAt;
|
||||
public string buildTargetGroup;
|
||||
public string projectName;
|
||||
public string unityVersion;
|
||||
public string projectUrl;
|
||||
public List<OVRConfigurationTaskJsonReport> tasksStatus;
|
||||
}
|
||||
|
||||
internal class OVRProjectSetupReport
|
||||
{
|
||||
public const string ReportDefaultFileNamePrefix = "setuptoolreport";
|
||||
public const string ReportDefaultFileNameDateTimeFormat = "yyyy-dd-MM--HH-mm-ss";
|
||||
public const string ReportDefaultOutputPath = "./";
|
||||
|
||||
/// <summary>
|
||||
/// Generate a JSON report and writes it in a JSON file at the given output path.
|
||||
/// </summary>
|
||||
/// <param name="tasks">The tasks that will be included in the report.</param>
|
||||
/// <param name="buildTargetGroup">Platform for which this report applies.</param>
|
||||
/// <param name="outputPath">The path where the report file will be written. If null, the default output path will be used.</param>
|
||||
/// <param name="fileName">The name of the generated report file. If null, a name will be generated.</param>
|
||||
/// <returns>Returns the full path to the created report file, including the file name.</returns>
|
||||
public static string GenerateJson(
|
||||
IEnumerable<OVRConfigurationTask> tasks,
|
||||
BuildTargetGroup buildTargetGroup,
|
||||
string outputPath = null,
|
||||
string fileName = null
|
||||
)
|
||||
{
|
||||
var report = BuildSerializableReport(tasks, buildTargetGroup);
|
||||
var creationTime = DateTime.Parse(report.createdAt);
|
||||
var outputFilePath =
|
||||
Path.Combine(outputPath ?? ReportDefaultOutputPath, fileName ?? GenerateFileName(creationTime));
|
||||
try
|
||||
{
|
||||
var jsonString = JsonUtility.ToJson(report, prettyPrint: true);
|
||||
File.WriteAllText(outputFilePath, jsonString);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("Could not write project setup report", e);
|
||||
}
|
||||
|
||||
return outputFilePath;
|
||||
}
|
||||
|
||||
private static string GenerateFileName(DateTime creationTime)
|
||||
{
|
||||
return ReportDefaultFileNamePrefix + "_" + creationTime.ToString(ReportDefaultFileNameDateTimeFormat) + ".json";
|
||||
}
|
||||
|
||||
private static OVRProjectSetupJsonReport BuildSerializableReport(
|
||||
IEnumerable<OVRConfigurationTask> tasks,
|
||||
BuildTargetGroup buildTargetGroup
|
||||
)
|
||||
{
|
||||
var tasksReports = tasks.Select(t => new OVRConfigurationTaskJsonReport
|
||||
{
|
||||
uid = t.Uid.ToString(),
|
||||
group = t.Group.ToString(),
|
||||
message = t.Message.GetValue(buildTargetGroup).ToString(),
|
||||
level = t.Level.GetValue(buildTargetGroup).ToString(),
|
||||
isDone = t.IsDone(buildTargetGroup)
|
||||
})
|
||||
.ToList();
|
||||
|
||||
var report = new OVRProjectSetupJsonReport
|
||||
{
|
||||
createdAt = DateTime.Now.ToUniversalTime().ToString(),
|
||||
buildTargetGroup = buildTargetGroup.ToString(),
|
||||
projectName = PlayerSettings.productName,
|
||||
unityVersion = Application.unityVersion,
|
||||
projectUrl = RemoveSuffix(Application.dataPath, "/Assets"),
|
||||
tasksStatus = tasksReports
|
||||
};
|
||||
|
||||
return report;
|
||||
}
|
||||
|
||||
private static string RemoveSuffix(string source, string suffix)
|
||||
{
|
||||
return source.EndsWith(suffix) ? source.Remove(source.LastIndexOf(suffix, StringComparison.Ordinal)) : source;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a220840af68244f0b032b4bd1c7304b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
internal abstract class OVRProjectSetupSettingItem<T>
|
||||
{
|
||||
public T Default { get; }
|
||||
public string Uid { get; }
|
||||
public string Label { get; }
|
||||
public string Key { get; }
|
||||
public abstract T Value { get; set; }
|
||||
|
||||
protected OVRProjectSetupSettingItem(string uid, T defaultValue, string label = null)
|
||||
{
|
||||
Default = defaultValue;
|
||||
Uid = uid;
|
||||
Label = label ?? uid;
|
||||
Key = OVRProjectSetup.KeyPrefix + "." + Uid;
|
||||
}
|
||||
|
||||
public abstract void AppendToMenu(GenericMenu menu);
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Value = Default;
|
||||
}
|
||||
|
||||
public void OnSet()
|
||||
{
|
||||
OVRTelemetry.Start(OVRProjectSetupTelemetryEvent.EventTypes.Option)
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Uid, Uid)
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Value, Value.ToString())
|
||||
.Send();
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class OVRProjectSetupSettingBool : OVRProjectSetupSettingItem<bool>
|
||||
{
|
||||
protected OVRProjectSetupSettingBool(string uid, bool defaultValue, string label = null)
|
||||
: base(uid, defaultValue, label)
|
||||
{
|
||||
}
|
||||
|
||||
public override void AppendToMenu(GenericMenu menu)
|
||||
{
|
||||
menu.AddItem(new GUIContent(Label), Value, () => Value = !Value);
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class OVRProjectSetupSettingFloat : OVRProjectSetupSettingItem<float>
|
||||
{
|
||||
protected OVRProjectSetupSettingFloat(string uid, float defaultValue, string label = null)
|
||||
: base(uid, defaultValue, label)
|
||||
{
|
||||
}
|
||||
|
||||
public override void AppendToMenu(GenericMenu menu)
|
||||
{
|
||||
// Do not Append to a GenericMenu
|
||||
}
|
||||
}
|
||||
|
||||
internal class OVRProjectSetupOnlyOnceSettingBool : OVRProjectSetupSettingBool
|
||||
{
|
||||
private static readonly HashSet<string> OnlyOnceSettings = new HashSet<string>();
|
||||
|
||||
public OVRProjectSetupOnlyOnceSettingBool(string uid) : base(uid, true)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
previousTimestamp = new OVRProjectSetupInternalUserSettingFloat($"{Uid}_timestamp", 0.0f);
|
||||
previousTimeSinceStartup = new OVRProjectSetupInternalUserSettingFloat($"{Uid}_timesincestartup", 0.0f);
|
||||
}
|
||||
|
||||
private OVRProjectSetupSettingFloat previousTimestamp;
|
||||
private OVRProjectSetupSettingFloat previousTimeSinceStartup;
|
||||
|
||||
public override bool Value
|
||||
{
|
||||
get => OnlyOnce();
|
||||
set
|
||||
{
|
||||
if (value == Default)
|
||||
{
|
||||
// If back to Default, we remove it from the dictionary to avoid clutter
|
||||
OnlyOnceSettings.Remove(Uid);
|
||||
previousTimestamp.Reset();
|
||||
previousTimeSinceStartup.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool OnlyOnce()
|
||||
{
|
||||
if (OnlyOnceSettings.Contains(Uid))
|
||||
{
|
||||
// If the tuple was found, this means we already went through this test
|
||||
// So either it was the first time the previous time
|
||||
// or it wasn't the first time...so neither is current time
|
||||
return false;
|
||||
}
|
||||
|
||||
// From now on, we can be sure next time won't be the first
|
||||
// So we add it to the HashSet
|
||||
OnlyOnceSettings.Add(Uid);
|
||||
|
||||
var currentTimestamp = (float)DateTime.UtcNow.TimeOfDay.TotalSeconds;
|
||||
// Better timestamp would be absolute number of seconds
|
||||
// But this is too big to be stored in float or int, and EditorPrefs do not allow double or long.
|
||||
var currentTimeSinceStartup = (float)EditorApplication.timeSinceStartup;
|
||||
|
||||
// The tuple was not found, so this is the first time we're testing it
|
||||
// since last compile
|
||||
// We're getting the previous saved timestamps
|
||||
var timeStampDiff = currentTimestamp - previousTimestamp.Value;
|
||||
var timeSinceStartupDiff = currentTimeSinceStartup - previousTimeSinceStartup.Value;
|
||||
|
||||
// If the difference between timestamps is very close
|
||||
// to the difference between timeSinceStartups
|
||||
// Then we're very probably on the same instance of the Editor
|
||||
const float closeThreshold = 5.0f;
|
||||
if (Mathf.Abs(timeSinceStartupDiff - timeStampDiff) < closeThreshold)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// And we're storing the current timestamp for next time
|
||||
previousTimestamp.Value = currentTimestamp;
|
||||
previousTimeSinceStartup.Value = currentTimeSinceStartup;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal class OVRProjectSetupInternalUserSettingFloat : OVRProjectSetupSettingFloat
|
||||
{
|
||||
public OVRProjectSetupInternalUserSettingFloat(string uid, float defaultValue, string label = null)
|
||||
: base(uid, defaultValue, label)
|
||||
{
|
||||
}
|
||||
|
||||
public override float Value
|
||||
{
|
||||
get => EditorPrefs.GetFloat(Key, Default);
|
||||
set => EditorPrefs.SetFloat(Key, value);
|
||||
}
|
||||
}
|
||||
|
||||
internal class OVRProjectSetupInternalUserSettingBool : OVRProjectSetupSettingBool
|
||||
{
|
||||
public OVRProjectSetupInternalUserSettingBool(string uid, bool defaultValue, string label = null)
|
||||
: base(uid, defaultValue, label)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool Value
|
||||
{
|
||||
get => EditorPrefs.GetBool(Key, Default);
|
||||
set => EditorPrefs.SetBool(Key, value);
|
||||
}
|
||||
}
|
||||
|
||||
internal class OVRProjectSetupUserSettingFloat : OVRProjectSetupInternalUserSettingFloat
|
||||
{
|
||||
public OVRProjectSetupUserSettingFloat(string uid, float defaultValue, string label = null)
|
||||
: base(uid, defaultValue, label)
|
||||
{
|
||||
}
|
||||
|
||||
public override float Value
|
||||
{
|
||||
set
|
||||
{
|
||||
base.Value = value;
|
||||
OnSet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class OVRProjectSetupUserSettingBool : OVRProjectSetupInternalUserSettingBool
|
||||
{
|
||||
public OVRProjectSetupUserSettingBool(string uid, bool defaultValue, string label = null)
|
||||
: base(uid, defaultValue, label)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool Value
|
||||
{
|
||||
set
|
||||
{
|
||||
base.Value = value;
|
||||
OnSet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class OVRProjectSettingBool : OVRProjectSetupSettingBool
|
||||
{
|
||||
public OVRProjectSettingBool(string uid, bool defaultValue, string label = null)
|
||||
: base(uid, defaultValue, label)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool Value
|
||||
{
|
||||
get => OVRProjectSetupSettings.GetProjectConfig(create: false)?.GetProjectSetupBool(Key, Default) ?? Default;
|
||||
set
|
||||
{
|
||||
OVRProjectSetupSettings.GetProjectConfig()?.SetProjectSetupBool(Key, value);
|
||||
OnSet();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasRecordedValue => OVRProjectSetupSettings.GetProjectConfig(create: false)?.HasBool(Key) ?? false;
|
||||
}
|
||||
|
||||
internal class OVRProjectSetupProjectSettingBool : OVRProjectSetupSettingBool
|
||||
{
|
||||
public OVRProjectSetupProjectSettingBool(string uid, bool defaultValue, string label = null)
|
||||
: base(uid, defaultValue, label)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool Value
|
||||
{
|
||||
get => OVRProjectSetupSettings.GetProjectConfig(create: false)?.GetProjectSetupBool(Key, Default) ?? Default;
|
||||
set
|
||||
{
|
||||
if (value == Default)
|
||||
{
|
||||
// If back to Default, we remove it from the dictionary to avoid clutter
|
||||
OVRProjectSetupSettings.GetProjectConfig()?.RemoveProjectSetupBool(Key);
|
||||
}
|
||||
else
|
||||
{
|
||||
OVRProjectSetupSettings.GetProjectConfig()?.SetProjectSetupBool(Key, value);
|
||||
}
|
||||
|
||||
OnSet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class OVRProjectSetupConstSettingBool : OVRProjectSetupSettingBool
|
||||
{
|
||||
public OVRProjectSetupConstSettingBool(string uid, bool defaultValue, string label = null)
|
||||
: base(uid, defaultValue, label)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool Value
|
||||
{
|
||||
get => Default;
|
||||
set { }
|
||||
}
|
||||
|
||||
public override void AppendToMenu(GenericMenu menu)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 63422cd755014f419520a814453c957e
|
||||
timeCreated: 1661871624
|
||||
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
[System.Serializable]
|
||||
public class OVRProjectSetupSettings : ScriptableObject
|
||||
{
|
||||
[Serializable]
|
||||
public class BoolProperties : SerializableDictionary<string, bool>
|
||||
{
|
||||
}
|
||||
|
||||
private const string AssetName = "OculusProjectSetupSettings.asset";
|
||||
|
||||
[SerializeField] private BoolProperties boolProperties = new BoolProperties();
|
||||
|
||||
private static OVRProjectSetupSettings _config = null;
|
||||
private static string _configPath = null;
|
||||
|
||||
public bool HasBool(string key)
|
||||
{
|
||||
return boolProperties.ContainsKey(key);
|
||||
}
|
||||
|
||||
public bool GetProjectSetupBool(string key, bool defaultValue)
|
||||
{
|
||||
if (!boolProperties.TryGetValue(key, out var value))
|
||||
{
|
||||
// To avoid clutter, getter doesn't add to the dictionary
|
||||
value = defaultValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public void SetProjectSetupBool(string key, bool value)
|
||||
{
|
||||
boolProperties[key] = value;
|
||||
EditorUtility.SetDirty(this);
|
||||
}
|
||||
|
||||
public void RemoveProjectSetupBool(string key)
|
||||
{
|
||||
boolProperties.Remove(key);
|
||||
EditorUtility.SetDirty(this);
|
||||
}
|
||||
|
||||
private static string GetOculusProjectConfigAssetPath(bool refresh = false)
|
||||
{
|
||||
if (_configPath != null && !refresh)
|
||||
{
|
||||
return _configPath;
|
||||
}
|
||||
|
||||
// Using the same Path logic as OVRProjectConfig
|
||||
_configPath = OVRProjectConfig.ComputeOculusProjectAssetPath(AssetName);
|
||||
return _configPath;
|
||||
}
|
||||
|
||||
public static OVRProjectSetupSettings GetProjectConfig(bool refresh = false, bool create = true)
|
||||
{
|
||||
if (_config != null && !refresh)
|
||||
{
|
||||
return _config;
|
||||
}
|
||||
|
||||
var oculusProjectConfigAssetPath = GetOculusProjectConfigAssetPath(refresh: false);
|
||||
try
|
||||
{
|
||||
_config = AssetDatabase.LoadAssetAtPath(oculusProjectConfigAssetPath,
|
||||
typeof(OVRProjectSetupSettings)) as OVRProjectSetupSettings;
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogWarningFormat("Unable to load ProjectSetupConfig from {0}, error {1}",
|
||||
oculusProjectConfigAssetPath, e.Message);
|
||||
}
|
||||
|
||||
if (_config == null && create && !BuildPipeline.isBuildingPlayer)
|
||||
{
|
||||
Debug.LogFormat("Creating ProjectSetupConfig at path {0}", oculusProjectConfigAssetPath);
|
||||
_config = ScriptableObject.CreateInstance<OVRProjectSetupSettings>();
|
||||
AssetDatabase.CreateAsset(_config, oculusProjectConfigAssetPath);
|
||||
}
|
||||
|
||||
return _config;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 939e07d58bc74256b6cb58d86fe35a56
|
||||
timeCreated: 1663663006
|
||||
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Globalization;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
internal class OVRProjectSetupSettingsProvider : SettingsProvider
|
||||
{
|
||||
public enum Origins
|
||||
{
|
||||
Settings,
|
||||
Menu,
|
||||
Icon,
|
||||
Console
|
||||
}
|
||||
|
||||
public enum Interaction
|
||||
{
|
||||
None,
|
||||
WentToDocumentation,
|
||||
WentToSource,
|
||||
Fixed,
|
||||
Ignored
|
||||
}
|
||||
|
||||
[MenuItem("Oculus/Tools/Project Setup Tool", false, 1)]
|
||||
static void OpenProjectSetupTool()
|
||||
{
|
||||
OpenSettingsWindow(Origins.Menu);
|
||||
}
|
||||
|
||||
public const string SettingsName = "Oculus";
|
||||
public static readonly string SettingsPath = $"Project/{SettingsName}";
|
||||
|
||||
private OVRProjectSetupDrawer _ovrProjectSetupDrawer;
|
||||
private OVRProjectSetupDrawer OvrProjectSetupDrawer => _ovrProjectSetupDrawer ??= new OVRProjectSetupDrawer();
|
||||
private static Origins? _lastOrigin = null;
|
||||
private static Interaction _lastInteraction = Interaction.None;
|
||||
private static bool _activated = false;
|
||||
|
||||
public static double OpenTimestamp { get; set; }
|
||||
public static double TimeSpent => EditorApplication.timeSinceStartup - OpenTimestamp;
|
||||
public static OVRTelemetryMarker? InteractionFlowEvent { get; set; }
|
||||
|
||||
[SettingsProvider]
|
||||
public static SettingsProvider CreateProjectValidationSettingsProvider()
|
||||
{
|
||||
return new OVRProjectSetupSettingsProvider(SettingsPath, SettingsScope.Project);
|
||||
}
|
||||
|
||||
internal static void SetNewInteraction(Interaction interaction)
|
||||
{
|
||||
if (interaction > _lastInteraction)
|
||||
{
|
||||
InteractionFlowEvent = InteractionFlowEvent?.AddPoint(OVRProjectSetupTelemetryEvent.MarkerPoints.Interact);
|
||||
_lastInteraction = interaction;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ResetInteraction()
|
||||
{
|
||||
InteractionFlowEvent = null;
|
||||
_lastInteraction = Interaction.None;
|
||||
_lastOrigin = null;
|
||||
_activated = false;
|
||||
OpenTimestamp = 0.0;
|
||||
}
|
||||
|
||||
private OVRProjectSetupSettingsProvider(string path,
|
||||
SettingsScope scopes)
|
||||
: base(path, scopes)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnActivate(string searchContext, VisualElement rootElement)
|
||||
{
|
||||
if (!_activated)
|
||||
{
|
||||
OpenTimestamp = EditorApplication.timeSinceStartup;
|
||||
_activated = true;
|
||||
_lastOrigin = _lastOrigin ?? Origins.Settings;
|
||||
|
||||
OVRTelemetry.Start(OVRProjectSetupTelemetryEvent.EventTypes.Open)
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.BuildTargetGroup,
|
||||
EditorUserBuildSettings.selectedBuildTargetGroup.ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Origin, _lastOrigin.ToString())
|
||||
.Send();
|
||||
|
||||
InteractionFlowEvent = InteractionFlowEvent?.AddPoint(OVRProjectSetupTelemetryEvent.MarkerPoints.Open)
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Origin, _lastOrigin.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDeactivate()
|
||||
{
|
||||
if (TimeSpent < 0.1)
|
||||
{
|
||||
// Ignore the entire interaction as it was too short to be meaningful
|
||||
return;
|
||||
}
|
||||
|
||||
if (_activated)
|
||||
{
|
||||
OVRTelemetry.Start(OVRProjectSetupTelemetryEvent.EventTypes.Close)
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.BuildTargetGroup,
|
||||
EditorUserBuildSettings.selectedBuildTargetGroup.ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Origin, _lastOrigin.ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.TimeSpent,
|
||||
TimeSpent.ToString(CultureInfo.InvariantCulture))
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Interaction, _lastInteraction.ToString())
|
||||
.Send();
|
||||
|
||||
InteractionFlowEvent = InteractionFlowEvent?.AddPoint(OVRProjectSetupTelemetryEvent.MarkerPoints.Close)
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Interaction, _lastInteraction.ToString())
|
||||
.Send();
|
||||
|
||||
ResetInteraction();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void OnTitleBarGUI()
|
||||
{
|
||||
base.OnTitleBarGUI();
|
||||
OvrProjectSetupDrawer.OnTitleBarGUI();
|
||||
}
|
||||
|
||||
public override void OnGUI(string searchContext)
|
||||
{
|
||||
base.OnGUI(searchContext);
|
||||
OvrProjectSetupDrawer.OnGUI();
|
||||
}
|
||||
|
||||
public static void OpenSettingsWindow(Origins origin)
|
||||
{
|
||||
_lastOrigin = origin;
|
||||
var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
|
||||
EditorUserBuildSettings.selectedBuildTargetGroup = buildTargetGroup;
|
||||
SettingsService.OpenProjectSettings(SettingsPath);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7cef00c42850e534eb89eba031054a2b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
[InitializeOnLoad]
|
||||
internal static class OVRProjectSetupStatusIcon
|
||||
{
|
||||
private static readonly Type _toolbarType;
|
||||
private static readonly PropertyInfo _guiBackend;
|
||||
private static readonly PropertyInfo _visualTree;
|
||||
private static readonly FieldInfo _onGuiHandler;
|
||||
private static readonly OVRGUIContent _iconSuccess;
|
||||
private static readonly OVRGUIContent _iconNeutral;
|
||||
private static readonly OVRGUIContent _iconWarning;
|
||||
private static readonly OVRGUIContent _iconError;
|
||||
private static readonly string OpenOculusSettings = "Open Oculus Settings";
|
||||
|
||||
private static GUIStyle _iconStyle;
|
||||
private static OVRGUIContent _currentIcon;
|
||||
private static Object _appStatusBar;
|
||||
private static VisualElement _container;
|
||||
|
||||
internal static OVRGUIContent CurrentIcon => _currentIcon;
|
||||
|
||||
|
||||
static OVRProjectSetupStatusIcon()
|
||||
{
|
||||
if (!OVREditorUtils.IsMainEditor()) return;
|
||||
|
||||
var editorAssembly = typeof(UnityEditor.Editor).Assembly;
|
||||
var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
|
||||
|
||||
_toolbarType = editorAssembly.GetType("UnityEditor.AppStatusBar");
|
||||
var guiViewType = editorAssembly.GetType("UnityEditor.GUIView");
|
||||
var backendType = editorAssembly.GetType("UnityEditor.IWindowBackend");
|
||||
var containerType = typeof(IMGUIContainer);
|
||||
|
||||
_guiBackend = guiViewType?.GetProperty("windowBackend", bindingFlags);
|
||||
_visualTree = backendType?.GetProperty("visualTree", bindingFlags);
|
||||
_onGuiHandler = containerType?.GetField("m_OnGUIHandler", bindingFlags);
|
||||
|
||||
_iconSuccess = OVREditorUtils.CreateContent("ovr_icon_success.png", OVRGUIContent.Source.GenericIcons);
|
||||
_iconNeutral = OVREditorUtils.CreateContent("ovr_icon_neutral.png", OVRGUIContent.Source.GenericIcons);
|
||||
_iconWarning = OVREditorUtils.CreateContent("ovr_icon_warning.png", OVRGUIContent.Source.GenericIcons);
|
||||
_iconError = OVREditorUtils.CreateContent("ovr_icon_error.png", OVRGUIContent.Source.GenericIcons);
|
||||
_currentIcon = _iconSuccess;
|
||||
|
||||
OVRProjectSetup.ProcessorQueue.OnProcessorCompleted += RefreshData;
|
||||
EditorApplication.update += Update;
|
||||
}
|
||||
|
||||
private static void Update()
|
||||
{
|
||||
if (_appStatusBar == null)
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
private static void Refresh()
|
||||
{
|
||||
var toolbars = Resources.FindObjectsOfTypeAll(_toolbarType);
|
||||
if (toolbars == null || toolbars.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_appStatusBar = toolbars[0];
|
||||
|
||||
var backend = _guiBackend?.GetValue(_appStatusBar);
|
||||
if (backend == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var elements = _visualTree?.GetValue(backend, null) as VisualElement;
|
||||
_container = elements?[0];
|
||||
if (_container == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var handler = _onGuiHandler?.GetValue(_container) as Action;
|
||||
if (handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
handler -= RefreshGUI;
|
||||
handler += RefreshGUI;
|
||||
_onGuiHandler.SetValue(_container, handler);
|
||||
}
|
||||
|
||||
private static void RefreshStyles()
|
||||
{
|
||||
if (_iconStyle != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_iconStyle = new GUIStyle("StatusBarIcon");
|
||||
}
|
||||
|
||||
public static OVRGUIContent ComputeIcon(OVRConfigurationTaskUpdaterSummary summary)
|
||||
{
|
||||
if (summary == null)
|
||||
{
|
||||
return _iconSuccess;
|
||||
}
|
||||
|
||||
var icon = summary.HighestFixLevel switch
|
||||
{
|
||||
OVRProjectSetup.TaskLevel.Optional => _iconNeutral,
|
||||
OVRProjectSetup.TaskLevel.Recommended => _iconWarning,
|
||||
OVRProjectSetup.TaskLevel.Required => _iconError,
|
||||
_ => _iconSuccess
|
||||
};
|
||||
|
||||
icon.Tooltip = $"{summary.ComputeNoticeMessage()}\n{OpenOculusSettings}";
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
private static void RefreshData(OVRConfigurationTaskProcessor processor)
|
||||
{
|
||||
var activeBuildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
|
||||
if (processor.Type == OVRConfigurationTaskProcessor.ProcessorType.Updater
|
||||
&& processor.BuildTargetGroup == activeBuildTargetGroup)
|
||||
{
|
||||
var updater = processor as OVRConfigurationTaskUpdater;
|
||||
_currentIcon = ComputeIcon(updater?.Summary);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RefreshGUI()
|
||||
{
|
||||
if (!OVRProjectSetup.ShowStatusIcon.Value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshStyles();
|
||||
|
||||
var screenWidth = _container.layout.width;
|
||||
// Hardcoded position
|
||||
// Currently overlaps with progress bar, and works with 2020 status bar icons
|
||||
// TODO: Better hook to dynamically position the button
|
||||
var currentRect = new Rect(screenWidth - 130, 0, 26, 30); // Hardcoded position
|
||||
GUILayout.BeginArea(currentRect);
|
||||
if (GUILayout.Button(_currentIcon, _iconStyle))
|
||||
{
|
||||
OVRStatusMenu.ShowDropdown(GUIUtility.GUIToScreenPoint(Vector2.zero));
|
||||
}
|
||||
|
||||
var buttonRect = GUILayoutUtility.GetLastRect();
|
||||
EditorGUIUtility.AddCursorRect(buttonRect, MouseCursor.Link);
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e429af8ad0c53041b56e07532521492
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
[InitializeOnLoad]
|
||||
internal static class OVRProjectSetupUpdater
|
||||
{
|
||||
private static readonly string EnabledSettingItemName = "BackgroundChecks";
|
||||
private static readonly string EnabledSettingItemLabel = "Background Checks";
|
||||
internal static OVRProjectSetupSettingBool Enabled;
|
||||
|
||||
public static readonly OVRProjectSetupSettingBool ShowLogsOnlyOnce =
|
||||
new OVRProjectSetupOnlyOnceSettingBool("ShowLogsOnlyOnce");
|
||||
|
||||
private static readonly double StatusUpdateWatchdogTimer = 5.0;
|
||||
private static double _lastStatusUpdate;
|
||||
|
||||
internal static void SetupTemporaryRegistry()
|
||||
{
|
||||
Enabled = new OVRProjectSetupConstSettingBool(OVRProjectSetupUpdater.EnabledSettingItemName, false,
|
||||
OVRProjectSetupUpdater.EnabledSettingItemLabel);
|
||||
}
|
||||
|
||||
internal static void RestoreRegistry()
|
||||
{
|
||||
Enabled = new OVRProjectSetupProjectSettingBool(OVRProjectSetupUpdater.EnabledSettingItemName, true,
|
||||
OVRProjectSetupUpdater.EnabledSettingItemLabel);
|
||||
}
|
||||
|
||||
static OVRProjectSetupUpdater()
|
||||
{
|
||||
EditorSceneManager.sceneOpened += OnEditorSceneManagerSceneOpened;
|
||||
EditorApplication.update += WatchdogUpdate;
|
||||
}
|
||||
|
||||
private static void WatchdogUpdate()
|
||||
{
|
||||
var currentTime = EditorApplication.timeSinceStartup;
|
||||
if (currentTime - _lastStatusUpdate > StatusUpdateWatchdogTimer)
|
||||
{
|
||||
Update();
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnEditorSceneManagerSceneOpened(Scene scene, OpenSceneMode mode)
|
||||
{
|
||||
Update();
|
||||
}
|
||||
|
||||
private static void Update()
|
||||
{
|
||||
ResetWatchdog();
|
||||
|
||||
if (!Enabled.Value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (OVRProjectSetup.ProcessorQueue.Busy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget);
|
||||
var logOption = (OVRProjectSetup.AllowLogs.Value || ShowLogsOnlyOnce.Value)
|
||||
? OVRProjectSetup.LogMessages.Summary
|
||||
: OVRProjectSetup.LogMessages.Disabled;
|
||||
OVRProjectSetup.UpdateTasks(buildTargetGroup, logMessages: logOption, blocking: false,
|
||||
onCompleted: OnUpdateCompleted);
|
||||
}
|
||||
|
||||
private static void OnUpdateCompleted(OVRConfigurationTaskProcessor processor)
|
||||
{
|
||||
if (processor.Type == OVRConfigurationTaskProcessor.ProcessorType.Updater)
|
||||
{
|
||||
ResetWatchdog();
|
||||
}
|
||||
}
|
||||
|
||||
private static void ResetWatchdog()
|
||||
{
|
||||
_lastStatusUpdate = EditorApplication.timeSinceStartup;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96cefb92e9ef4844a95e7350ef584e5e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
157
Assets/Oculus/VR/Editor/OVRProjectSetup/OVRProjectSetupUtils.cs
Normal file
157
Assets/Oculus/VR/Editor/OVRProjectSetup/OVRProjectSetupUtils.cs
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using UnityEditor;
|
||||
using UnityEditor.PackageManager;
|
||||
using UnityEditor.PackageManager.Requests;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
internal static class OVRProjectSetupUtils
|
||||
{
|
||||
public static T FindComponentInScene<T>() where T : Component
|
||||
{
|
||||
var scene = SceneManager.GetActiveScene();
|
||||
var rootGameObjects = scene.GetRootGameObjects();
|
||||
return rootGameObjects.FirstOrDefault(go => go.GetComponentInChildren<T>())?.GetComponentInChildren<T>();
|
||||
}
|
||||
|
||||
public static List<T> FindComponentsInScene<T>() where T : Component
|
||||
{
|
||||
var activeScene = SceneManager.GetActiveScene();
|
||||
var foundComponents = new List<T>();
|
||||
|
||||
var rootObjects = activeScene.GetRootGameObjects();
|
||||
foreach (var rootObject in rootObjects)
|
||||
{
|
||||
var components = rootObject.GetComponentsInChildren<T>(true);
|
||||
foundComponents.AddRange(components);
|
||||
}
|
||||
|
||||
return foundComponents;
|
||||
}
|
||||
|
||||
public static bool HasComponentInParents<T>(GameObject obj) where T : Component
|
||||
{
|
||||
var currentTransform = obj.transform;
|
||||
|
||||
while (currentTransform != null)
|
||||
{
|
||||
if (currentTransform.GetComponent<T>() != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
currentTransform = currentTransform.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static T FindScriptableObjectInProject<T>() where T : ScriptableObject
|
||||
{
|
||||
var guids = AssetDatabase.FindAssets("t:" + typeof(T).Name);
|
||||
|
||||
if (guids.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var path = AssetDatabase.GUIDToAssetPath(guids[0]);
|
||||
return AssetDatabase.LoadAssetAtPath<T>(path);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static ListRequest _packageManagerListRequest;
|
||||
|
||||
static OVRProjectSetupUtils()
|
||||
{
|
||||
RefreshPackageList(false);
|
||||
OVRGUIContent.RegisterContentPath(OVRGUIContent.Source.ProjectSetupToolIcons, "OVRProjectSetup/Icons");
|
||||
}
|
||||
|
||||
public static bool PackageManagerListAvailable => _packageManagerListRequest.Status == StatusCode.Success;
|
||||
|
||||
public static bool IsPackageInstalled(string packageName) =>
|
||||
PackageManagerListAvailable &&
|
||||
(_packageManagerListRequest.Result?.Any(package => package.name == packageName) ?? false);
|
||||
|
||||
public static bool RefreshPackageList(bool blocking)
|
||||
{
|
||||
_packageManagerListRequest = Client.List(offlineMode: false, includeIndirectDependencies: true);
|
||||
if (blocking)
|
||||
{
|
||||
while (!PackageManagerListAvailable)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
return PackageManagerListAvailable;
|
||||
}
|
||||
|
||||
public static bool InstallPackage(string packageName)
|
||||
{
|
||||
var request = Client.Add(packageName);
|
||||
|
||||
// TODO: make this async later
|
||||
while (!request.IsCompleted)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
// Refresh the Client list
|
||||
RefreshPackageList(false);
|
||||
|
||||
return request.Status == StatusCode.Success;
|
||||
}
|
||||
|
||||
public static bool UninstallPackage(string packageName)
|
||||
{
|
||||
var request = Client.Remove(packageName);
|
||||
|
||||
// TODO: make this async later
|
||||
while (!request.IsCompleted)
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
|
||||
// Refresh the Client list
|
||||
RefreshPackageList(false);
|
||||
|
||||
return request.Status == StatusCode.Success;
|
||||
}
|
||||
|
||||
public static BuildTarget GetBuildTarget(this BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
// It is a bit tricky to get the build target from the build target group
|
||||
// because of some additional variations on build targets that the build target group doesn't know about
|
||||
// This function aims at offering an approximation of the build target, but it's not guaranteed
|
||||
return buildTargetGroup switch
|
||||
{
|
||||
BuildTargetGroup.Android => BuildTarget.Android,
|
||||
BuildTargetGroup.Standalone => BuildTarget.StandaloneWindows64,
|
||||
_ => BuildTarget.NoTarget
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8c9cf42992bd9243b91495e0bee3883
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Oculus/VR/Editor/OVRProjectSetup/Tasks.meta
Normal file
8
Assets/Oculus/VR/Editor/OVRProjectSetup/Tasks.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe0a0d59f1f7e8f4f880b0e61e0488e3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b1b824db73a75642b72bb9ecff9c88e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
|
||||
[InitializeOnLoad]
|
||||
internal static class OVRProjectSetupCompatibilityTasks
|
||||
{
|
||||
public static bool IsTargetingARM64 =>
|
||||
(PlayerSettings.Android.targetArchitectures & AndroidArchitecture.ARM64) != 0;
|
||||
|
||||
public static readonly Action<BuildTargetGroup> SetARM64Target = (buildTargetGroup) =>
|
||||
PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARM64;
|
||||
|
||||
static OVRProjectSetupCompatibilityTasks()
|
||||
{
|
||||
var compatibilityTaskGroup = OVRProjectSetup.TaskGroup.Compatibility;
|
||||
|
||||
// [Required] Platform has to be supported
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: compatibilityTaskGroup,
|
||||
isDone: OVRProjectSetup.IsPlatformSupported,
|
||||
conditionalMessage: buildTargetGroup =>
|
||||
OVRProjectSetup.IsPlatformSupported(buildTargetGroup)
|
||||
? $"Build Target ({buildTargetGroup}) is supported"
|
||||
: $"Build Target ({buildTargetGroup}) is not supported"
|
||||
);
|
||||
|
||||
// [Required] Android minimum level API
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: compatibilityTaskGroup,
|
||||
platform: BuildTargetGroup.Android,
|
||||
isDone: buildTargetGroup => PlayerSettings.Android.minSdkVersion >= AndroidSdkVersions.AndroidApiLevel29,
|
||||
message: "Minimum Android API Level must be at least 29",
|
||||
fix: buildTargetGroup => PlayerSettings.Android.minSdkVersion = AndroidSdkVersions.AndroidApiLevel29,
|
||||
fixMessage: "PlayerSettings.Android.minSdkVersion = AndroidSdkVersions.AndroidApiLevel29"
|
||||
);
|
||||
|
||||
// [Required] Android target level API
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: compatibilityTaskGroup,
|
||||
platform: BuildTargetGroup.Android,
|
||||
isDone: buildTargetGroup =>
|
||||
PlayerSettings.Android.targetSdkVersion == AndroidSdkVersions.AndroidApiLevelAuto ||
|
||||
PlayerSettings.Android.targetSdkVersion >= AndroidSdkVersions.AndroidApiLevel29,
|
||||
message: "Target API should be set to \"Automatic\" as to ensure latest version",
|
||||
fix: buildTargetGroup => PlayerSettings.Android.targetSdkVersion = AndroidSdkVersions.AndroidApiLevelAuto,
|
||||
fixMessage: "PlayerSettings.Android.targetSdkVersion = AndroidSdkVersions.AndroidApiLevelAuto"
|
||||
);
|
||||
|
||||
// [Required] Install Location
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: compatibilityTaskGroup,
|
||||
platform: BuildTargetGroup.Android,
|
||||
isDone: buildTargetGroup =>
|
||||
PlayerSettings.Android.preferredInstallLocation == AndroidPreferredInstallLocation.Auto,
|
||||
message: "Install Location should be set to \"Automatic\"",
|
||||
fix: buildTargetGroup =>
|
||||
PlayerSettings.Android.preferredInstallLocation = AndroidPreferredInstallLocation.Auto,
|
||||
fixMessage: "PlayerSettings.Android.preferredInstallLocation = AndroidPreferredInstallLocation.Auto"
|
||||
);
|
||||
|
||||
// [Required] Generate Android Manifest
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Optional,
|
||||
group: compatibilityTaskGroup,
|
||||
platform: BuildTargetGroup.Android,
|
||||
isDone: buildTargetGroup => OVRManifestPreprocessor.DoesAndroidManifestExist(),
|
||||
message: "An Android Manifest file is required",
|
||||
fix: buildTargetGroup => OVRManifestPreprocessor.GenerateManifestForSubmission(),
|
||||
fixMessage: "Generates a default Manifest file"
|
||||
);
|
||||
|
||||
// ConfigurationTask : IL2CPP when ARM64
|
||||
OVRProjectSetup.AddTask(
|
||||
conditionalLevel: buildTargetGroup =>
|
||||
IsTargetingARM64 ? OVRProjectSetup.TaskLevel.Required : OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: compatibilityTaskGroup,
|
||||
platform: BuildTargetGroup.Android,
|
||||
isDone: buildTargetGroup =>
|
||||
PlayerSettings.GetScriptingBackend(buildTargetGroup) == ScriptingImplementation.IL2CPP,
|
||||
conditionalMessage: buildTargetGroup =>
|
||||
IsTargetingARM64
|
||||
? "Building the ARM64 architecture requires using IL2CPP as the scripting backend"
|
||||
: "Using IL2CPP as the scripting backend is recommended",
|
||||
fix: buildTargetGroup =>
|
||||
PlayerSettings.SetScriptingBackend(buildTargetGroup, ScriptingImplementation.IL2CPP),
|
||||
fixMessage: "PlayerSettings.SetScriptingBackend(buildTargetGroup, ScriptingImplementation.IL2CPP)"
|
||||
);
|
||||
|
||||
// ConfigurationTask : ARM64 is recommended
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: compatibilityTaskGroup,
|
||||
platform: BuildTargetGroup.Android,
|
||||
isDone: buildTargetGroup => IsTargetingARM64,
|
||||
message: "Use ARM64 as target architecture",
|
||||
fix: SetARM64Target,
|
||||
fixMessage: "PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARM64"
|
||||
);
|
||||
|
||||
// ConfigurationTask : No Alpha or Beta for production
|
||||
// This is a task that CANNOT BE FIXED
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: compatibilityTaskGroup,
|
||||
isDone: group => !OVRManager.IsUnityAlphaOrBetaVersion(),
|
||||
message: "We recommend using a stable version for Oculus Development"
|
||||
);
|
||||
|
||||
// ConfigurationTask : Check that Android TV Compatibility is disabled
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
platform: BuildTargetGroup.Android,
|
||||
group: compatibilityTaskGroup,
|
||||
isDone: group => !PlayerSettings.Android.androidTVCompatibility,
|
||||
message: "Apps with Android TV Compatibility enabled are not accepted by the Oculus Store",
|
||||
fix: group => PlayerSettings.Android.androidTVCompatibility = false,
|
||||
fixMessage: "PlayerSettings.Android.androidTVCompatibility = false"
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f23b5d0d61a07874aa97d72200848188
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
That file was intentionally removed.
|
||||
*/
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc6140a65ceb57243bfbd2ffffe5fc98
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[InitializeOnLoad]
|
||||
internal static class OVRProjectSetupMovementSDKTasks2
|
||||
{
|
||||
private const OVRProjectSetup.TaskGroup Group = OVRProjectSetup.TaskGroup.Features;
|
||||
|
||||
static OVRProjectSetupMovementSDKTasks2()
|
||||
{
|
||||
AddMovementTrackingTasks<OVRBody>(
|
||||
"Body Tracking",
|
||||
() => OVRProjectConfig.CachedProjectConfig.bodyTrackingSupport,
|
||||
ovrManager => ovrManager.requestBodyTrackingPermissionOnStartup,
|
||||
projectConfig => projectConfig.bodyTrackingSupport = OVRProjectConfig.FeatureSupport.Supported,
|
||||
ovrManager => ovrManager.requestBodyTrackingPermissionOnStartup = true);
|
||||
|
||||
AddMovementTrackingTasks<OVRFaceExpressions>(
|
||||
"Face Tracking",
|
||||
() => OVRProjectConfig.CachedProjectConfig.faceTrackingSupport,
|
||||
ovrManager => ovrManager.requestFaceTrackingPermissionOnStartup,
|
||||
projectConfig => projectConfig.faceTrackingSupport = OVRProjectConfig.FeatureSupport.Supported,
|
||||
ovrManager => ovrManager.requestFaceTrackingPermissionOnStartup = true);
|
||||
|
||||
AddMovementTrackingTasks<OVREyeGaze>(
|
||||
"Eye Tracking",
|
||||
() => OVRProjectConfig.CachedProjectConfig.eyeTrackingSupport,
|
||||
ovrManager => ovrManager.requestEyeTrackingPermissionOnStartup,
|
||||
projectConfig => projectConfig.eyeTrackingSupport = OVRProjectConfig.FeatureSupport.Supported,
|
||||
ovrManager => ovrManager.requestEyeTrackingPermissionOnStartup = true);
|
||||
}
|
||||
|
||||
private static void AddMovementTrackingTasks<T>(string featureName,
|
||||
Func<OVRProjectConfig.FeatureSupport> supportLevel, Func<OVRManager, bool> permissionRequested,
|
||||
Action<OVRProjectConfig> enableSupport, Action<OVRManager> enablePermissionRequest) where T : Component
|
||||
{
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: Group,
|
||||
isDone: buildTargetGroup => OVRProjectSetupUtils.FindComponentInScene<T>() == null ||
|
||||
supportLevel() != OVRProjectConfig.FeatureSupport.None,
|
||||
message: $"When using {featureName} in your project it's required to enable its capability " +
|
||||
$"in the project config",
|
||||
fix: buildTargetGroup =>
|
||||
{
|
||||
var projectConfig = OVRProjectConfig.CachedProjectConfig;
|
||||
enableSupport(projectConfig);
|
||||
OVRProjectConfig.CommitProjectConfig(projectConfig);
|
||||
},
|
||||
fixMessage: $"Enable {featureName} support in the project config"
|
||||
);
|
||||
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: Group,
|
||||
isDone: buildTargetGroup =>
|
||||
{
|
||||
if (supportLevel() == OVRProjectConfig.FeatureSupport.None)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var ovrManager = OVRProjectSetupUtils.FindComponentInScene<OVRManager>();
|
||||
return !ovrManager || permissionRequested(ovrManager);
|
||||
},
|
||||
message: $"Automatically request the {featureName} permission on startup",
|
||||
fix: buildTargetGroup =>
|
||||
{
|
||||
var ovrManager = OVRProjectSetupUtils.FindComponentInScene<OVRManager>();
|
||||
if (ovrManager != null)
|
||||
{
|
||||
enablePermissionRequest(ovrManager);
|
||||
EditorUtility.SetDirty(ovrManager);
|
||||
}
|
||||
},
|
||||
fixMessage: $"Request {featureName} permission on startup"
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b59f40a4e9d6f340a944dbaa75354ca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
That file was intentionally removed.
|
||||
*/
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1cae49aff62b1d24abd59636906cf874
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using UnityEditor;
|
||||
|
||||
[InitializeOnLoad]
|
||||
internal static class OVRProjectSetupPassthrough
|
||||
{
|
||||
private const OVRProjectSetup.TaskGroup Group = OVRProjectSetup.TaskGroup.Features;
|
||||
|
||||
static OVRProjectSetupPassthrough()
|
||||
{
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: Group,
|
||||
isDone: buildTargetGroup => OVRProjectSetupUtils.FindComponentInScene<OVRPassthroughLayer>() == null ||
|
||||
OVRProjectConfig.CachedProjectConfig.insightPassthroughSupport !=
|
||||
OVRProjectConfig.FeatureSupport.None,
|
||||
message: "When using Passthrough in your project it's required to enable its capability " +
|
||||
"in the project config",
|
||||
fix: buildTargetGroup =>
|
||||
{
|
||||
var projectConfig = OVRProjectConfig.CachedProjectConfig;
|
||||
projectConfig.insightPassthroughSupport =
|
||||
OVRProjectConfig.FeatureSupport.Supported;
|
||||
OVRProjectConfig.CommitProjectConfig(projectConfig);
|
||||
},
|
||||
fixMessage: "Enable Passthrough support in the project config");
|
||||
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: Group,
|
||||
isDone: buildTargetGroup =>
|
||||
{
|
||||
if (OVRProjectSetupUtils.FindComponentInScene<OVRPassthroughLayer>() == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var ovrManager = OVRProjectSetupUtils.FindComponentInScene<OVRManager>();
|
||||
return ovrManager == null || ovrManager.isInsightPassthroughEnabled;
|
||||
},
|
||||
message: $"When using Passthrough in your project it's required to enable it in {nameof(OVRManager)}",
|
||||
fix: buildTargetGroup =>
|
||||
{
|
||||
var ovrManager = OVRProjectSetupUtils.FindComponentInScene<OVRManager>();
|
||||
ovrManager.isInsightPassthroughEnabled = true;
|
||||
EditorUtility.SetDirty(ovrManager.gameObject);
|
||||
},
|
||||
fixMessage: $"Enable Passthrough in the {nameof(OVRManager)}");
|
||||
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: Group,
|
||||
isDone: buildTargetGroup => OVRProjectSetupCompatibilityTasks.IsTargetingARM64,
|
||||
conditionalValidity: buildTargetGroup => OVRProjectConfig.CachedProjectConfig.insightPassthroughSupport !=
|
||||
OVRProjectConfig.FeatureSupport.None,
|
||||
message: "When enabling the Passthrough capability in your project it's required to use ARM64 as " +
|
||||
"the target architecture",
|
||||
fix: OVRProjectSetupCompatibilityTasks.SetARM64Target,
|
||||
fixMessage: "PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARM64"
|
||||
);
|
||||
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: Group,
|
||||
isDone: _ =>
|
||||
{
|
||||
var ovrCameraRig = OVRProjectSetupUtils.FindComponentInScene<OVRCameraRig>();
|
||||
return ovrCameraRig != null &&
|
||||
OVRPassthroughHelper.HasCentralCamera(ovrCameraRig) &&
|
||||
OVRPassthroughHelper.IsBackgroundClear(ovrCameraRig);
|
||||
},
|
||||
conditionalValidity: _ =>
|
||||
{
|
||||
var ovrCameraRig = OVRProjectSetupUtils.FindComponentInScene<OVRCameraRig>();
|
||||
return ovrCameraRig != null &&
|
||||
OVRPassthroughHelper.HasCentralCamera(ovrCameraRig) &&
|
||||
OVRPassthroughHelper.IsAnyPassthroughLayerUnderlay();
|
||||
},
|
||||
message: "When using Passthrough as an underlay it's required set the camera background to transparent",
|
||||
fix: _ =>
|
||||
{
|
||||
var ovrCameraRig = OVRProjectSetupUtils.FindComponentInScene<OVRCameraRig>();
|
||||
if (ovrCameraRig != null && OVRPassthroughHelper.HasCentralCamera(ovrCameraRig))
|
||||
{
|
||||
OVRPassthroughHelper.ClearBackground(ovrCameraRig);
|
||||
}
|
||||
},
|
||||
fixMessage: "Clear background of OVRCameraRig"
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 340956b8fb5e08e409aeab1bfc3a627d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[InitializeOnLoad]
|
||||
internal static class OVRProjectSetupPhysicsTasks
|
||||
{
|
||||
static OVRProjectSetupPhysicsTasks()
|
||||
{
|
||||
// [Recommended] Default Contact Offset >= 0.01f
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: OVRProjectSetup.TaskGroup.Physics,
|
||||
isDone: group => Physics.defaultContactOffset >= 0.01f,
|
||||
message: $"Use Default Context Offset above or equal to 0.01",
|
||||
fix: group => Physics.defaultContactOffset = 0.01f,
|
||||
fixMessage: "Physics.defaultContactOffset = 0.01f"
|
||||
);
|
||||
|
||||
// [Recommended] Sleep Threshold >= 0.005f
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: OVRProjectSetup.TaskGroup.Physics,
|
||||
isDone: group => Physics.sleepThreshold >= 0.005f,
|
||||
message: $"Use Sleep Threshold above or equal to 0.005",
|
||||
fix: group => Physics.sleepThreshold = 0.005f,
|
||||
fixMessage: "Physics.sleepThreshold = 0.005f"
|
||||
);
|
||||
|
||||
// [Recommended] Default Solver Iterations <= 8
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: OVRProjectSetup.TaskGroup.Physics,
|
||||
isDone: group => Physics.defaultSolverIterations <= 8,
|
||||
message: $"Use Default Solver Iteration below or equal to 8",
|
||||
fix: group => Physics.defaultSolverIterations = 8,
|
||||
fixMessage: "Physics.defaultSolverIterations = 8"
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f88d78901e142de81bcf89db9d8499b
|
||||
timeCreated: 1664783258
|
||||
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[InitializeOnLoad]
|
||||
internal static class OVRProjectSetupQualityTasks
|
||||
{
|
||||
private static readonly int RecommendedPixelLightCountAndroid = 1;
|
||||
private static readonly int RecommendedPixelLightCountStandalone = 3;
|
||||
|
||||
private static int GetRecommendedPixelLightCount(BuildTargetGroup buildTargetGroup)
|
||||
=> buildTargetGroup == BuildTargetGroup.Standalone
|
||||
? RecommendedPixelLightCountStandalone
|
||||
: RecommendedPixelLightCountAndroid;
|
||||
|
||||
static OVRProjectSetupQualityTasks()
|
||||
{
|
||||
var taskGroup = OVRProjectSetup.TaskGroup.Quality;
|
||||
|
||||
// [Recommended] Set Pixel Light Count
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: taskGroup,
|
||||
isDone: buildTargetGroup =>
|
||||
QualitySettings.pixelLightCount <= GetRecommendedPixelLightCount(buildTargetGroup),
|
||||
conditionalMessage: buildTargetGroup =>
|
||||
$"Set maximum pixel lights count to {GetRecommendedPixelLightCount(buildTargetGroup)}",
|
||||
fix: buildTargetGroup => QualitySettings.pixelLightCount = GetRecommendedPixelLightCount(buildTargetGroup),
|
||||
conditionalFixMessage: buildTargetGroup =>
|
||||
$"QualitySettings.pixelLightCount = {GetRecommendedPixelLightCount(buildTargetGroup)}"
|
||||
);
|
||||
|
||||
// [Recommended] Set Texture Quality to Full Res
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: taskGroup,
|
||||
message: "Set Texture Quality to Full Res",
|
||||
#if UNITY_2022_2_OR_NEWER // masterTextureLimit has become obsolete with 2022.2
|
||||
isDone: buildTargetGroup => QualitySettings.globalTextureMipmapLimit == 0,
|
||||
fix: buildTargetGroup => QualitySettings.globalTextureMipmapLimit = 0,
|
||||
fixMessage: "QualitySettings.globalTextureMipmapLimit = 0"
|
||||
#else
|
||||
isDone: buildTargetGroup => QualitySettings.masterTextureLimit == 0,
|
||||
fix: buildTargetGroup => QualitySettings.masterTextureLimit = 0,
|
||||
fixMessage: "QualitySettings.masterTextureLimit = 0"
|
||||
#endif
|
||||
);
|
||||
|
||||
// [Recommended] Enable Anisotropic Filtering
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: taskGroup,
|
||||
isDone: buildTargetGroup => QualitySettings.anisotropicFiltering == AnisotropicFiltering.Enable,
|
||||
message: "Enable Anisotropic Filtering on a per-texture basis",
|
||||
fix: buildTargetGroup => QualitySettings.anisotropicFiltering = AnisotropicFiltering.Enable,
|
||||
fixMessage: "QualitySettings.anisotropicFiltering = AnisotropicFiltering.Enable"
|
||||
);
|
||||
|
||||
// Texture compression : Use ASTC
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: taskGroup,
|
||||
platform: BuildTargetGroup.Android,
|
||||
isDone: group => EditorUserBuildSettings.androidBuildSubtarget == MobileTextureSubtarget.ASTC ||
|
||||
EditorUserBuildSettings.androidBuildSubtarget == MobileTextureSubtarget.ETC2,
|
||||
message: "Optimize Texture Compression : For GPU performance, please use ETC2. In some cases, " +
|
||||
"ASTC may produce better visuals and is also a viable solution",
|
||||
fix: group => EditorUserBuildSettings.androidBuildSubtarget = MobileTextureSubtarget.ETC2,
|
||||
fixMessage: "EditorUserBuildSettings.androidBuildSubtarget = MobileTextureSubtarget.ETC2"
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9f06298f32b7b54985a5a7464381e8d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,368 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Rendering;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
#if USING_URP
|
||||
using UnityEngine.Rendering.Universal;
|
||||
#endif
|
||||
|
||||
|
||||
[InitializeOnLoad]
|
||||
internal static class OVRProjectSetupRenderingTasks
|
||||
{
|
||||
#if USING_XR_SDK_OCULUS
|
||||
private static Unity.XR.Oculus.OculusSettings OculusSettings
|
||||
{
|
||||
get
|
||||
{
|
||||
UnityEditor.EditorBuildSettings.TryGetConfigObject<Unity.XR.Oculus.OculusSettings>(
|
||||
"Unity.XR.Oculus.Settings", out var settings);
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USING_URP && UNITY_2022_2_OR_NEWER
|
||||
// Call action for all UniversalRendererData being used, return true if all the return value of action is true
|
||||
private static bool ForEachRendererData(Func<UniversalRendererData, bool> action)
|
||||
{
|
||||
var ret = true;
|
||||
var pipelineAssets = new System.Collections.Generic.List<RenderPipelineAsset>();
|
||||
QualitySettings.GetAllRenderPipelineAssetsForPlatform("Android", ref pipelineAssets);
|
||||
foreach (var pipelineAsset in pipelineAssets)
|
||||
{
|
||||
var urpPipelineAsset = pipelineAsset as UniversalRenderPipelineAsset;
|
||||
// If using URP pipeline
|
||||
if (urpPipelineAsset)
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(urpPipelineAsset);
|
||||
var dependency = AssetDatabase.GetDependencies(path);
|
||||
for (int i = 0; i < dependency.Length; i++)
|
||||
{
|
||||
// Try to read the dependency as UniversalRendererData
|
||||
if (AssetDatabase.GetMainAssetTypeAtPath(dependency[i]) != typeof(UniversalRendererData))
|
||||
continue;
|
||||
|
||||
UniversalRendererData renderData =
|
||||
(UniversalRendererData)AssetDatabase.LoadAssetAtPath(dependency[i],
|
||||
typeof(UniversalRendererData));
|
||||
if (renderData)
|
||||
{
|
||||
ret = ret && action(renderData);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
private static GraphicsDeviceType[] GetGraphicsAPIs(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
var buildTarget = buildTargetGroup.GetBuildTarget();
|
||||
if (PlayerSettings.GetUseDefaultGraphicsAPIs(buildTarget))
|
||||
{
|
||||
return Array.Empty<GraphicsDeviceType>();
|
||||
}
|
||||
|
||||
// Recommends OpenGL ES 3 or Vulkan
|
||||
return PlayerSettings.GetGraphicsAPIs(buildTarget);
|
||||
}
|
||||
|
||||
static OVRProjectSetupRenderingTasks()
|
||||
{
|
||||
const OVRProjectSetup.TaskGroup targetGroup = OVRProjectSetup.TaskGroup.Rendering;
|
||||
|
||||
//[Required] Set the color space to linear
|
||||
OVRProjectSetup.AddTask(
|
||||
conditionalLevel: buildTargetGroup =>
|
||||
OVRProjectSetupUtils.IsPackageInstalled(OVRProjectSetupXRTasks.UnityXRPackage)
|
||||
? OVRProjectSetup.TaskLevel.Required
|
||||
: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup => PlayerSettings.colorSpace == ColorSpace.Linear,
|
||||
message: "Color Space is required to be Linear",
|
||||
fix: buildTargetGroup => PlayerSettings.colorSpace = ColorSpace.Linear,
|
||||
fixMessage: "PlayerSettings.colorSpace = ColorSpace.Linear"
|
||||
);
|
||||
|
||||
|
||||
#if USING_XR_SDK_OCULUS && OCULUS_XR_EYE_TRACKED_FOVEATED_RENDERING && UNITY_2021_3_OR_NEWER
|
||||
//[Required] Use Vulkan and IL2CPP/ARM64 when using ETFR
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup =>
|
||||
{
|
||||
var useIL2CPP = PlayerSettings.GetScriptingBackend(buildTargetGroup) == ScriptingImplementation.IL2CPP;
|
||||
var useARM64 = PlayerSettings.Android.targetArchitectures == AndroidArchitecture.ARM64;
|
||||
var useVK = GetGraphicsAPIs(buildTargetGroup).Any(item => item == GraphicsDeviceType.Vulkan);
|
||||
return useVK && useARM64 && useIL2CPP;
|
||||
},
|
||||
message: "Need to use Vulkan for Graphics APIs, IL2CPP for scripting backend, and ARM64 for target architectures when using eye-tracked foveated rendering",
|
||||
fix: buildTargetGroup =>
|
||||
{
|
||||
var buildTarget = buildTargetGroup.GetBuildTarget();
|
||||
PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARM64;
|
||||
PlayerSettings.SetScriptingBackend(buildTargetGroup, ScriptingImplementation.IL2CPP);
|
||||
PlayerSettings.SetGraphicsAPIs(buildTarget, new[] { GraphicsDeviceType.Vulkan });
|
||||
},
|
||||
fixMessage: "Set target architectures to ARM64, scripting backend to IL2CPP, and Graphics APIs to Vulkan for this build.",
|
||||
conditionalValidity: buildTargetGroup => OculusSettings?.FoveatedRenderingMethod == Unity.XR.Oculus.OculusSettings.FoveationMethod.EyeTrackedFoveatedRendering
|
||||
);
|
||||
#endif
|
||||
|
||||
//[Required] Disable Graphics Jobs
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup => !PlayerSettings.graphicsJobs,
|
||||
message: "Disable Graphics Jobs",
|
||||
fix: buildTargetGroup => PlayerSettings.graphicsJobs = false,
|
||||
fixMessage: "PlayerSettings.graphicsJobs = false"
|
||||
);
|
||||
|
||||
//[Recommended] Set the Graphics API order for Android
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
platform: BuildTargetGroup.Android,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup =>
|
||||
GetGraphicsAPIs(buildTargetGroup).Any(item =>
|
||||
item == GraphicsDeviceType.OpenGLES3 || item == GraphicsDeviceType.Vulkan),
|
||||
message: "Manual selection of Graphic API, favoring Vulkan (or OpenGLES3)",
|
||||
fix: buildTargetGroup =>
|
||||
{
|
||||
var buildTarget = buildTargetGroup.GetBuildTarget();
|
||||
PlayerSettings.SetUseDefaultGraphicsAPIs(buildTarget, false);
|
||||
PlayerSettings.SetGraphicsAPIs(buildTarget, new[] { GraphicsDeviceType.Vulkan });
|
||||
},
|
||||
fixMessage: "Set Graphics APIs for this build target to Vulkan"
|
||||
);
|
||||
//[Required] Set the Graphics API order for Windows
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
platform: BuildTargetGroup.Standalone,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup =>
|
||||
GetGraphicsAPIs(buildTargetGroup).Any(item =>
|
||||
item == GraphicsDeviceType.Direct3D11),
|
||||
message: "Manual selection of Graphic API, favoring Direct3D11",
|
||||
fix: buildTargetGroup =>
|
||||
{
|
||||
var buildTarget = buildTargetGroup.GetBuildTarget();
|
||||
PlayerSettings.SetUseDefaultGraphicsAPIs(buildTarget, false);
|
||||
PlayerSettings.SetGraphicsAPIs(buildTarget, new[] { GraphicsDeviceType.Direct3D11 });
|
||||
},
|
||||
fixMessage: "Set Graphics APIs for this build target to Direct3D11"
|
||||
);
|
||||
|
||||
//[Recommended] Enable Multithreaded Rendering
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup => PlayerSettings.MTRendering &&
|
||||
(buildTargetGroup != BuildTargetGroup.Android
|
||||
|| PlayerSettings.GetMobileMTRendering(buildTargetGroup)),
|
||||
message: "Enable Multithreaded Rendering",
|
||||
fix: buildTargetGroup =>
|
||||
{
|
||||
PlayerSettings.MTRendering = true;
|
||||
if (buildTargetGroup == BuildTargetGroup.Android)
|
||||
{
|
||||
PlayerSettings.SetMobileMTRendering(buildTargetGroup, true);
|
||||
}
|
||||
},
|
||||
conditionalFixMessage: buildTargetGroup =>
|
||||
buildTargetGroup == BuildTargetGroup.Android
|
||||
? "PlayerSettings.MTRendering = true and PlayerSettings.SetMobileMTRendering(buildTargetGroup, true)"
|
||||
: "PlayerSettings.MTRendering = true"
|
||||
);
|
||||
|
||||
#if USING_XR_SDK_OCULUS
|
||||
//[Recommended] Select Low Overhead Mode
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
conditionalValidity: buildTargetGroup =>
|
||||
GetGraphicsAPIs(buildTargetGroup).Contains(GraphicsDeviceType.OpenGLES3),
|
||||
group: targetGroup,
|
||||
platform: BuildTargetGroup.Android,
|
||||
isDone: buildTargetGroup => OculusSettings?.LowOverheadMode ?? true,
|
||||
message: "Use Low Overhead Mode",
|
||||
fix: buildTargetGroup =>
|
||||
{
|
||||
var setting = OculusSettings;
|
||||
if (setting != null)
|
||||
{
|
||||
setting.LowOverheadMode = true;
|
||||
EditorUtility.SetDirty(setting);
|
||||
}
|
||||
},
|
||||
fixMessage: "OculusSettings.LowOverheadMode = true"
|
||||
);
|
||||
|
||||
//[Recommended] Enable Dash Support
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: targetGroup,
|
||||
platform: BuildTargetGroup.Standalone,
|
||||
isDone: buildTargetGroup => OculusSettings?.DashSupport ?? true,
|
||||
message: "Enable Dash Support",
|
||||
fix: buildTargetGroup =>
|
||||
{
|
||||
var setting = OculusSettings;
|
||||
if (setting != null)
|
||||
{
|
||||
setting.DashSupport = true;
|
||||
EditorUtility.SetDirty(setting);
|
||||
}
|
||||
},
|
||||
fixMessage: "OculusSettings.DashSupport = true"
|
||||
);
|
||||
#endif
|
||||
|
||||
//[Recommended] Set the Display Buffer Format to 32 bit
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup =>
|
||||
PlayerSettings.use32BitDisplayBuffer,
|
||||
message: "Use 32Bit Display Buffer",
|
||||
fix: buildTargetGroup => PlayerSettings.use32BitDisplayBuffer = true,
|
||||
fixMessage: "PlayerSettings.use32BitDisplayBuffer = true"
|
||||
);
|
||||
|
||||
//[Recommended] Set the Rendering Path to Forward
|
||||
// TODO : Support Scripted Rendering Pipeline?
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup =>
|
||||
EditorGraphicsSettings.GetTierSettings(buildTargetGroup, Graphics.activeTier).renderingPath ==
|
||||
RenderingPath.Forward,
|
||||
message: "Use Forward Rendering Path",
|
||||
fix: buildTargetGroup =>
|
||||
{
|
||||
var renderingTier = EditorGraphicsSettings.GetTierSettings(buildTargetGroup, Graphics.activeTier);
|
||||
renderingTier.renderingPath =
|
||||
RenderingPath.Forward;
|
||||
EditorGraphicsSettings.SetTierSettings(buildTargetGroup, Graphics.activeTier, renderingTier);
|
||||
},
|
||||
fixMessage: "renderingTier.renderingPath = RenderingPath.Forward"
|
||||
);
|
||||
|
||||
//[Recommended] Set the Stereo Rendering to Instancing
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup =>
|
||||
PlayerSettings.stereoRenderingPath == StereoRenderingPath.Instancing,
|
||||
message: "Use Stereo Rendering Instancing",
|
||||
fix: buildTargetGroup => PlayerSettings.stereoRenderingPath = StereoRenderingPath.Instancing,
|
||||
fixMessage: "PlayerSettings.stereoRenderingPath = StereoRenderingPath.Instancing"
|
||||
);
|
||||
|
||||
#if USING_URP && UNITY_2022_2_OR_NEWER
|
||||
//[Recommended] When using URP, set Intermediate texture to "Auto"
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup =>
|
||||
ForEachRendererData(rd => { return rd.intermediateTextureMode == IntermediateTextureMode.Auto; }),
|
||||
message: "Setting the intermate texture mode to \"Always\" might have a performance impact, it is recommended to use \"Auto\"",
|
||||
fix: buildTargetGroup =>
|
||||
ForEachRendererData(rd => { rd.intermediateTextureMode = IntermediateTextureMode.Auto; return true; }),
|
||||
fixMessage: "Set Intermediate texture to \"Auto\""
|
||||
);
|
||||
|
||||
//[Recommended] When using URP, disable SSAO
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup =>
|
||||
ForEachRendererData(rd =>
|
||||
{
|
||||
return rd.rendererFeatures.Count == 0
|
||||
|| !rd.rendererFeatures.Any(
|
||||
feature => feature != null && (feature.isActive && feature.GetType().Name == "ScreenSpaceAmbientOcclusion"));
|
||||
}),
|
||||
message: "SSAO will have some performace impact, it is recommended to disable SSAO",
|
||||
fix: buildTargetGroup =>
|
||||
ForEachRendererData(rd =>
|
||||
{
|
||||
rd.rendererFeatures.ForEach(feature =>
|
||||
{
|
||||
if (feature != null && feature.GetType().Name == "ScreenSpaceAmbientOcclusion")
|
||||
feature.SetActive(false);
|
||||
}
|
||||
);
|
||||
return true;
|
||||
}),
|
||||
fixMessage: "Disable SSAO"
|
||||
);
|
||||
#endif
|
||||
|
||||
//[Optional] Use Non-Directional Lightmaps
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Optional,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup =>
|
||||
{
|
||||
return LightmapSettings.lightmaps.Length == 0 ||
|
||||
LightmapSettings.lightmapsMode == LightmapsMode.NonDirectional;
|
||||
},
|
||||
message: "Use Non-Directional lightmaps",
|
||||
fix: buildTargetGroup => LightmapSettings.lightmapsMode = LightmapsMode.NonDirectional,
|
||||
fixMessage: "LightmapSettings.lightmapsMode = LightmapsMode.NonDirectional"
|
||||
);
|
||||
|
||||
//[Optional] Disable Realtime GI
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Optional,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup => !Lightmapping.realtimeGI,
|
||||
message: "Disable Realtime Global Illumination",
|
||||
fix: buildTargetGroup => Lightmapping.realtimeGI = false,
|
||||
fixMessage: "Lightmapping.realtimeGI = false"
|
||||
);
|
||||
|
||||
//[Optional] GPU Skinning
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Optional,
|
||||
platform: BuildTargetGroup.Android,
|
||||
group: targetGroup,
|
||||
isDone: buildTargetGroup => PlayerSettings.gpuSkinning,
|
||||
message: "Consider using GPU Skinning if your application is CPU bound",
|
||||
fix: buildTargetGroup => PlayerSettings.gpuSkinning = true,
|
||||
fixMessage: "PlayerSettings.gpuSkinning = true"
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93a7b0b65ecd19943b6eaef8cf457167
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using UnityEditor;
|
||||
|
||||
[InitializeOnLoad]
|
||||
internal static class OVRProjectSetupSceneTasks
|
||||
{
|
||||
private const OVRProjectSetup.TaskGroup Group = OVRProjectSetup.TaskGroup.Features;
|
||||
|
||||
static OVRProjectSetupSceneTasks()
|
||||
{
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: Group,
|
||||
isDone: buildTargetGroup => OVRProjectSetupUtils.FindComponentInScene<OVRSceneManager>() == null ||
|
||||
OVRProjectConfig.CachedProjectConfig.anchorSupport ==
|
||||
OVRProjectConfig.AnchorSupport.Enabled,
|
||||
message: "When using Scene in your project it's required to enable its capability in the project config",
|
||||
fix: buildTargetGroup =>
|
||||
{
|
||||
var projectConfig = OVRProjectConfig.CachedProjectConfig;
|
||||
projectConfig.anchorSupport = OVRProjectConfig.AnchorSupport.Enabled;
|
||||
OVRProjectConfig.CommitProjectConfig(projectConfig);
|
||||
},
|
||||
fixMessage: "Enable Anchor Support in the project config"
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 821c95a26dbfb3f40b9c76b776d3c661
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using UnityEditor;
|
||||
|
||||
[InitializeOnLoad]
|
||||
internal static class OVRProjectSetupVirtualKeyboard
|
||||
{
|
||||
private const OVRProjectSetup.TaskGroup Group = OVRProjectSetup.TaskGroup.Features;
|
||||
|
||||
static OVRProjectSetupVirtualKeyboard()
|
||||
{
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: Group,
|
||||
isDone: _ => OVRProjectSetupUtils.FindComponentInScene<OVRVirtualKeyboard>() == null ||
|
||||
OVRProjectConfig.CachedProjectConfig.renderModelSupport == OVRProjectConfig.RenderModelSupport.Enabled,
|
||||
message: "When using Virtual Keyboard in your project it's required to enable Render Model Support",
|
||||
fix: _ =>
|
||||
{
|
||||
var projectConfig = OVRProjectConfig.CachedProjectConfig;
|
||||
projectConfig.renderModelSupport = OVRProjectConfig.RenderModelSupport.Enabled;
|
||||
OVRProjectConfig.CommitProjectConfig(projectConfig);
|
||||
},
|
||||
fixMessage: "Enable Render Model Support");
|
||||
|
||||
OVRProjectSetup.AddTask(
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: Group,
|
||||
isDone: _ => OVRProjectSetupUtils.FindComponentInScene<OVRVirtualKeyboard>() == null ||
|
||||
OVRProjectConfig.CachedProjectConfig.virtualKeyboardSupport != OVRProjectConfig.FeatureSupport.None,
|
||||
message: "When using Virtual Keyboard in your project it's required to enable its capability",
|
||||
fix: _ =>
|
||||
{
|
||||
var projectConfig = OVRProjectConfig.CachedProjectConfig;
|
||||
projectConfig.virtualKeyboardSupport = OVRProjectConfig.FeatureSupport.Supported;
|
||||
OVRProjectConfig.CommitProjectConfig(projectConfig);
|
||||
},
|
||||
fixMessage: "Enable Virtual Keyboard Support");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82d658a2879ff5445a9566cdc87ed59b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
#if USING_XR_MANAGEMENT
|
||||
using UnityEditor.XR.Management;
|
||||
#endif
|
||||
|
||||
#if USING_XR_SDK_OCULUS
|
||||
using Unity.XR.Oculus;
|
||||
#endif
|
||||
|
||||
[InitializeOnLoad]
|
||||
internal static class OVRProjectSetupXRTasks
|
||||
{
|
||||
internal const string OculusXRPackageName = "com.unity.xr.oculus";
|
||||
internal const string XRPluginManagementPackageName = "com.unity.xr.management";
|
||||
internal const string UnityXRPackage = "com.unity.xr.openxr";
|
||||
|
||||
private const OVRProjectSetup.TaskGroup XRTaskGroup = OVRProjectSetup.TaskGroup.Packages;
|
||||
|
||||
static OVRProjectSetupXRTasks()
|
||||
{
|
||||
OVRProjectSetup.AddTask(
|
||||
conditionalValidity: buildTargetGroup => OVRProjectSetupUtils.PackageManagerListAvailable,
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: XRTaskGroup,
|
||||
isDone: buildTargetGroup => OVRProjectSetupUtils.IsPackageInstalled(OculusXRPackageName),
|
||||
message: "The Oculus XR Plug-in package must be installed",
|
||||
fix: buildTargetGroup => OVRProjectSetupUtils.InstallPackage(OculusXRPackageName),
|
||||
fixMessage: $"Install {OculusXRPackageName} package"
|
||||
);
|
||||
|
||||
OVRProjectSetup.AddTask(
|
||||
conditionalValidity: buildTargetGroup => OVRProjectSetupUtils.PackageManagerListAvailable,
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: XRTaskGroup,
|
||||
isDone: buildTargetGroup => OVRProjectSetupUtils.IsPackageInstalled(XRPluginManagementPackageName),
|
||||
message: "The XR Plug-in Management package must be installed",
|
||||
fix: buildTargetGroup => OVRProjectSetupUtils.InstallPackage(XRPluginManagementPackageName),
|
||||
fixMessage: $"Install {XRPluginManagementPackageName} package"
|
||||
);
|
||||
|
||||
OVRProjectSetup.AddTask(
|
||||
conditionalValidity: buildTargetGroup => OVRProjectSetupUtils.PackageManagerListAvailable,
|
||||
level: OVRProjectSetup.TaskLevel.Recommended,
|
||||
group: XRTaskGroup,
|
||||
isDone: buildTargetGroup => !OVRProjectSetupUtils.IsPackageInstalled(UnityXRPackage),
|
||||
message: "Unity's OpenXR Plugin is not recommended when using the Oculus SDK, " +
|
||||
"please use Oculus XR Plug-in instead",
|
||||
fix: buildTargetGroup => OVRProjectSetupUtils.UninstallPackage(UnityXRPackage),
|
||||
fixMessage: $"Remove the {UnityXRPackage} package"
|
||||
);
|
||||
|
||||
AddXrPluginManagementTasks();
|
||||
}
|
||||
|
||||
private static void AddXrPluginManagementTasks()
|
||||
{
|
||||
#if USING_XR_MANAGEMENT && USING_XR_SDK_OCULUS
|
||||
OVRProjectSetup.AddTask(
|
||||
conditionalValidity: buildTargetGroup =>
|
||||
OVRProjectSetupUtils.IsPackageInstalled(XRPluginManagementPackageName),
|
||||
level: OVRProjectSetup.TaskLevel.Required,
|
||||
group: XRTaskGroup,
|
||||
isDone: buildTargetGroup =>
|
||||
{
|
||||
var settings = GetXRGeneralSettingsForBuildTarget(buildTargetGroup, false);
|
||||
if (settings == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var loader in settings.Manager.activeLoaders)
|
||||
{
|
||||
if (loader as OculusLoader != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
message: "Oculus must be added to the XR Plugin active loaders",
|
||||
fix: buildTargetGroup =>
|
||||
{
|
||||
var settings = GetXRGeneralSettingsForBuildTarget(buildTargetGroup, true);
|
||||
if (settings == null)
|
||||
{
|
||||
throw new OVRConfigurationTaskException("Could not find XR Plugin Manager settings");
|
||||
}
|
||||
|
||||
var loadersList = AssetDatabase.FindAssets($"t: {nameof(OculusLoader)}")
|
||||
.Select(AssetDatabase.GUIDToAssetPath)
|
||||
.Select(AssetDatabase.LoadAssetAtPath<OculusLoader>).ToList();
|
||||
OculusLoader oculusLoader;
|
||||
if (loadersList.Count > 0)
|
||||
{
|
||||
oculusLoader = loadersList[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
oculusLoader = ScriptableObject.CreateInstance<OculusLoader>();
|
||||
AssetDatabase.CreateAsset(oculusLoader, "Assets/XR/Loaders/Oculus Loader.asset");
|
||||
}
|
||||
|
||||
settings.Manager.TryAddLoader(oculusLoader);
|
||||
},
|
||||
fixMessage: "Add Oculus to the XR Plugin active loaders"
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USING_XR_MANAGEMENT && USING_XR_SDK_OCULUS
|
||||
private static UnityEngine.XR.Management.XRGeneralSettings GetXRGeneralSettingsForBuildTarget(
|
||||
BuildTargetGroup buildTargetGroup, bool create)
|
||||
{
|
||||
var settings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(buildTargetGroup);
|
||||
if (!create || settings != null)
|
||||
{
|
||||
return settings;
|
||||
}
|
||||
|
||||
// we have to create these settings ourselves as
|
||||
// long as Unity doesn't expose the internal function
|
||||
// XRGeneralSettingsPerBuildTarget.GetOrCreate()
|
||||
var settingsKey = UnityEngine.XR.Management.XRGeneralSettings.k_SettingsKey;
|
||||
EditorBuildSettings.TryGetConfigObject<XRGeneralSettingsPerBuildTarget>(
|
||||
settingsKey, out var settingsPerBuildTarget);
|
||||
|
||||
if (settingsPerBuildTarget == null)
|
||||
{
|
||||
settingsPerBuildTarget = ScriptableObject.CreateInstance<XRGeneralSettingsPerBuildTarget>();
|
||||
if (!AssetDatabase.IsValidFolder("Assets/XR"))
|
||||
AssetDatabase.CreateFolder("Assets", "XR");
|
||||
const string assetPath = "Assets/XR/XRGeneralSettingsPerBuildTarget.asset";
|
||||
AssetDatabase.CreateAsset(settingsPerBuildTarget, assetPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
EditorBuildSettings.AddConfigObject(settingsKey, settingsPerBuildTarget, true);
|
||||
}
|
||||
|
||||
if (!settingsPerBuildTarget.HasManagerSettingsForBuildTarget(buildTargetGroup))
|
||||
{
|
||||
settingsPerBuildTarget.CreateDefaultManagerSettingsForBuildTarget(buildTargetGroup);
|
||||
}
|
||||
|
||||
return XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(buildTargetGroup);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: beb76c27b37f99e43a27f9d2656dafc6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
internal class OVRConfigurationTask
|
||||
{
|
||||
internal static readonly string ConsoleLinkHref = "OpenOculusProjectSettings";
|
||||
|
||||
public Hash128 Uid { get; }
|
||||
public OVRProjectSetup.TaskGroup Group { get; }
|
||||
public BuildTargetGroup Platform { get; }
|
||||
|
||||
public OptionalLambdaType<BuildTargetGroup, bool> Valid { get; }
|
||||
public OptionalLambdaType<BuildTargetGroup, OVRProjectSetup.TaskLevel> Level { get; }
|
||||
public OptionalLambdaType<BuildTargetGroup, string> Message { get; }
|
||||
public OptionalLambdaType<BuildTargetGroup, string> FixMessage { get; }
|
||||
public OptionalLambdaType<BuildTargetGroup, string> URL { get; }
|
||||
public OVRConfigurationTaskSourceCode SourceCode { get; set; }
|
||||
|
||||
private Func<BuildTargetGroup, bool> _isDone;
|
||||
|
||||
public Func<BuildTargetGroup, bool> IsDone
|
||||
{
|
||||
get => GetDoneState;
|
||||
private set => _isDone = value;
|
||||
}
|
||||
|
||||
public Action<BuildTargetGroup> FixAction { get; }
|
||||
|
||||
private readonly Dictionary<BuildTargetGroup, OVRProjectSetupSettingBool> _ignoreSettings =
|
||||
new Dictionary<BuildTargetGroup, OVRProjectSetupSettingBool>();
|
||||
|
||||
private readonly Dictionary<BuildTargetGroup, bool> _isDoneCache = new Dictionary<BuildTargetGroup, bool>();
|
||||
|
||||
public OVRConfigurationTask(
|
||||
OVRProjectSetup.TaskGroup group,
|
||||
BuildTargetGroup platform,
|
||||
Func<BuildTargetGroup, bool> isDone,
|
||||
Action<BuildTargetGroup> fix,
|
||||
OptionalLambdaType<BuildTargetGroup, OVRProjectSetup.TaskLevel> level,
|
||||
OptionalLambdaType<BuildTargetGroup, string> message,
|
||||
OptionalLambdaType<BuildTargetGroup, string> fixMessage,
|
||||
OptionalLambdaType<BuildTargetGroup, string> url,
|
||||
OptionalLambdaType<BuildTargetGroup, bool> valid)
|
||||
{
|
||||
Platform = platform;
|
||||
Group = group;
|
||||
IsDone = isDone;
|
||||
FixAction = fix;
|
||||
Level = level;
|
||||
Message = message;
|
||||
|
||||
// If parameters are null, we're creating a OptionalLambdaType that points to default values
|
||||
// We don't want a null OptionalLambdaType, but we may be okay with an OptionalLambdaType containing a null value
|
||||
// For the URL for instance
|
||||
// Mandatory parameters will be checked on the Validate method down below
|
||||
URL = url ?? new OptionalLambdaTypeWithoutLambda<BuildTargetGroup, string>(null);
|
||||
FixMessage = fixMessage ?? new OptionalLambdaTypeWithoutLambda<BuildTargetGroup, string>(null);
|
||||
Valid = valid ?? new OptionalLambdaTypeWithoutLambda<BuildTargetGroup, bool>(true);
|
||||
|
||||
// We may want to throw in case of some invalid parameters
|
||||
Validate();
|
||||
|
||||
var hash = new Hash128();
|
||||
hash.Append(Message.Default);
|
||||
Uid = hash;
|
||||
|
||||
SourceCode = new OVRConfigurationTaskSourceCode(this);
|
||||
}
|
||||
|
||||
private void Validate()
|
||||
{
|
||||
if (Group == OVRProjectSetup.TaskGroup.All)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"[{nameof(OVRConfigurationTask)}] {nameof(OVRProjectSetup.TaskGroup.All)} is not meant to be used as a {nameof(OVRProjectSetup.TaskGroup)} type");
|
||||
}
|
||||
|
||||
if (_isDone == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(_isDone));
|
||||
}
|
||||
|
||||
|
||||
if (Level == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(Level));
|
||||
}
|
||||
|
||||
|
||||
if (Message == null || !Message.Valid || string.IsNullOrEmpty(Message.Default))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(Message));
|
||||
}
|
||||
}
|
||||
|
||||
public void InvalidateCache(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
Level.InvalidateCache(buildTargetGroup);
|
||||
Message.InvalidateCache(buildTargetGroup);
|
||||
URL.InvalidateCache(buildTargetGroup);
|
||||
Valid.InvalidateCache(buildTargetGroup);
|
||||
}
|
||||
|
||||
public bool IsIgnored(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
return GetIgnoreSetting(buildTargetGroup).Value;
|
||||
}
|
||||
|
||||
public void SetIgnored(BuildTargetGroup buildTargetGroup, bool ignored)
|
||||
{
|
||||
GetIgnoreSetting(buildTargetGroup).Value = ignored;
|
||||
}
|
||||
|
||||
public bool Fix(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
try
|
||||
{
|
||||
FixAction(buildTargetGroup);
|
||||
}
|
||||
catch (OVRConfigurationTaskException exception)
|
||||
{
|
||||
Debug.LogWarning(
|
||||
$"[Oculus Settings] Failed to fix task \"{Message.GetValue(buildTargetGroup)}\" : {exception}");
|
||||
}
|
||||
|
||||
var hasChanged = UpdateAndGetStateChanged(buildTargetGroup);
|
||||
if (hasChanged)
|
||||
{
|
||||
var fixMessage = FixMessage.GetValue(buildTargetGroup);
|
||||
Debug.Log(
|
||||
fixMessage != null
|
||||
? $"[Oculus Settings] Fixed task \"{Message.GetValue(buildTargetGroup)}\" : {fixMessage}"
|
||||
: $"[Oculus Settings] Fixed task \"{Message.GetValue(buildTargetGroup)}\"");
|
||||
}
|
||||
|
||||
var isDone = IsDone(buildTargetGroup);
|
||||
|
||||
OVRTelemetry.Start(OVRProjectSetupTelemetryEvent.EventTypes.Fix)
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Uid, Uid.ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Level,
|
||||
Level.GetValue(buildTargetGroup).ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Group, Group.ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.BuildTargetGroup, buildTargetGroup.ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Value, isDone ? "true" : "false")
|
||||
.Send();
|
||||
|
||||
return isDone;
|
||||
}
|
||||
|
||||
public string ComputeIgnoreUid(BuildTargetGroup buildTargetGroup)
|
||||
=> $"{OVRProjectSetup.KeyPrefix}.{GetType().Name}.{Uid}.Ignored.{buildTargetGroup.ToString()}";
|
||||
|
||||
private OVRProjectSetupSettingBool GetIgnoreSetting(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
if (!_ignoreSettings.TryGetValue(buildTargetGroup, out var item))
|
||||
{
|
||||
var uid = ComputeIgnoreUid(buildTargetGroup);
|
||||
item = new OVRProjectSetupProjectSettingBool(uid, false);
|
||||
_ignoreSettings.Add(buildTargetGroup, item);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
internal bool UpdateAndGetStateChanged(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
var newState = _isDone(buildTargetGroup);
|
||||
var didStateChange = true;
|
||||
if (_isDoneCache.TryGetValue(buildTargetGroup, out var previousState))
|
||||
{
|
||||
didStateChange = newState != previousState;
|
||||
}
|
||||
|
||||
_isDoneCache[buildTargetGroup] = newState;
|
||||
|
||||
return didStateChange;
|
||||
}
|
||||
|
||||
internal void LogMessage(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
var logMessage = GetFullLogMessage(buildTargetGroup);
|
||||
|
||||
switch (Level.GetValue(buildTargetGroup))
|
||||
{
|
||||
case OVRProjectSetup.TaskLevel.Optional:
|
||||
break;
|
||||
case OVRProjectSetup.TaskLevel.Recommended:
|
||||
Debug.LogWarning(logMessage);
|
||||
break;
|
||||
case OVRProjectSetup.TaskLevel.Required:
|
||||
if (OVRProjectSetup.RequiredThrowErrors.Value)
|
||||
{
|
||||
Debug.LogError(logMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning(logMessage);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
internal string GetFullLogMessage(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
return $"{GetLogMessage(buildTargetGroup)}.\nYou can fix this by going to " +
|
||||
$"<a href=\"{ConsoleLinkHref}\">Edit > Project Settings > {OVRProjectSetupSettingsProvider.SettingsName}</a>";
|
||||
}
|
||||
|
||||
internal string GetLogMessage(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
return $"[{Group}] {Message.GetValue(buildTargetGroup)}";
|
||||
}
|
||||
|
||||
private bool GetDoneState(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
if (_isDoneCache.TryGetValue(buildTargetGroup, out var cachedState))
|
||||
{
|
||||
return cachedState;
|
||||
}
|
||||
|
||||
return _isDone(buildTargetGroup);
|
||||
}
|
||||
|
||||
#if UNITY_XR_CORE_UTILS
|
||||
internal Unity.XR.CoreUtils.Editor.BuildValidationRule ToValidationRule(BuildTargetGroup platform)
|
||||
{
|
||||
var validationRule = new Unity.XR.CoreUtils.Editor.BuildValidationRule
|
||||
{
|
||||
IsRuleEnabled = () => Valid.GetValue(platform),
|
||||
Category = Group.ToString(),
|
||||
Message = Message.GetValue(platform),
|
||||
CheckPredicate = () => IsDone(platform),
|
||||
FixIt = () => FixAction(platform),
|
||||
FixItAutomatic = true,
|
||||
FixItMessage = FixMessage.GetValue(platform),
|
||||
HelpText = null,
|
||||
HelpLink = null,
|
||||
SceneOnlyValidation = false,
|
||||
OnClick = null,
|
||||
Error = Level.GetValue(platform) == OVRProjectSetup.TaskLevel.Required
|
||||
};
|
||||
return validationRule;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23cf0a62a13a153468744c574d80aab8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public class OVRConfigurationTaskException : Exception
|
||||
{
|
||||
public OVRConfigurationTaskException()
|
||||
{
|
||||
}
|
||||
|
||||
public OVRConfigurationTaskException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public OVRConfigurationTaskException(string message, Exception inner)
|
||||
: base(message, inner)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d5dcbd522a347fca62378e9e47b9893
|
||||
timeCreated: 1664378185
|
||||
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
internal class OVRConfigurationTaskRegistry
|
||||
{
|
||||
private static readonly List<OVRConfigurationTask> EmptyTasksList = new List<OVRConfigurationTask>(0);
|
||||
|
||||
private readonly Dictionary<Hash128, OVRConfigurationTask> _tasksPerUid =
|
||||
new Dictionary<Hash128, OVRConfigurationTask>();
|
||||
|
||||
private readonly List<OVRConfigurationTask> _tasks = new List<OVRConfigurationTask>();
|
||||
|
||||
private List<OVRConfigurationTask> Tasks => _tasks;
|
||||
|
||||
public void AddTask(OVRConfigurationTask task)
|
||||
{
|
||||
var uid = task.Uid;
|
||||
if (_tasksPerUid.ContainsKey(uid))
|
||||
{
|
||||
// This task is already registered
|
||||
return;
|
||||
}
|
||||
|
||||
_tasks.Add(task);
|
||||
_tasksPerUid.Add(uid, task);
|
||||
|
||||
#if UNITY_XR_CORE_UTILS
|
||||
RegisterToBuildValidator(task);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_XR_CORE_UTILS
|
||||
private void RegisterToBuildValidator(OVRConfigurationTask task)
|
||||
{
|
||||
if (task.Platform == BuildTargetGroup.Unknown)
|
||||
{
|
||||
var buildTargetGroups = Enum.GetValues(typeof(BuildTargetGroup));
|
||||
foreach (var buildTargetGroup in buildTargetGroups)
|
||||
{
|
||||
var targetGroup = (BuildTargetGroup)buildTargetGroup;
|
||||
RegisterToBuildValidator(targetGroup, task);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RegisterToBuildValidator(task.Platform, task);
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterToBuildValidator(BuildTargetGroup targetGroup, OVRConfigurationTask task)
|
||||
{
|
||||
if (task.Level.GetValue(targetGroup) == OVRProjectSetup.TaskLevel.Optional)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Unity.XR.CoreUtils.Editor.BuildValidator.AddRules(targetGroup, new []{task.ToValidationRule(task.Platform)});
|
||||
}
|
||||
#endif
|
||||
|
||||
public void RemoveTask(Hash128 uid)
|
||||
{
|
||||
var task = GetTask(uid);
|
||||
RemoveTask(task);
|
||||
|
||||
}
|
||||
|
||||
public void RemoveTask(OVRConfigurationTask task)
|
||||
{
|
||||
_tasks.Remove(task);
|
||||
_tasksPerUid.Remove(task.Uid);
|
||||
}
|
||||
|
||||
public OVRConfigurationTask GetTask(Hash128 uid)
|
||||
{
|
||||
_tasksPerUid.TryGetValue(uid, out var task);
|
||||
return task;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_tasksPerUid.Clear();
|
||||
_tasks.Clear();
|
||||
}
|
||||
|
||||
internal IEnumerable<OVRConfigurationTask> GetTasks(BuildTargetGroup buildTargetGroup, bool refresh)
|
||||
{
|
||||
if (refresh)
|
||||
{
|
||||
foreach (var task in Tasks)
|
||||
{
|
||||
task.InvalidateCache(buildTargetGroup);
|
||||
}
|
||||
}
|
||||
|
||||
return Tasks.Where
|
||||
(
|
||||
task => (task.Platform == BuildTargetGroup.Unknown || task.Platform == buildTargetGroup)
|
||||
&& task.Valid.GetValue(buildTargetGroup)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fef3c9d3bbb64a21ac221b2b3fbca1ef
|
||||
timeCreated: 1662024023
|
||||
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
internal class OVRConfigurationTaskSourceCode
|
||||
{
|
||||
private static Func<Object, int, bool> OpenAssetDelegate = AssetDatabase.OpenAsset;
|
||||
|
||||
public static void Mock()
|
||||
{
|
||||
OpenAssetDelegate = null;
|
||||
}
|
||||
|
||||
public static void Unmock()
|
||||
{
|
||||
OpenAssetDelegate = AssetDatabase.OpenAsset;
|
||||
}
|
||||
|
||||
private static IEnumerable<MethodInfo> _expectedMethods;
|
||||
|
||||
private static IEnumerable<MethodInfo> ExpectedMethods
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_expectedMethods == null)
|
||||
{
|
||||
_expectedMethods = typeof(OVRProjectSetup).GetMethods(BindingFlags.Public | BindingFlags.Static)
|
||||
.Where(method => method.Name == "AddTask");
|
||||
}
|
||||
|
||||
return _expectedMethods;
|
||||
}
|
||||
}
|
||||
|
||||
private OVRConfigurationTask _task;
|
||||
private readonly StackTrace _stackTrace;
|
||||
private Object _object;
|
||||
private bool _processed;
|
||||
|
||||
public bool Valid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_processed)
|
||||
{
|
||||
ProcessStackTrace();
|
||||
}
|
||||
|
||||
return _object != null;
|
||||
}
|
||||
}
|
||||
|
||||
public int Line { get; private set; }
|
||||
public string FilePath { get; private set; }
|
||||
|
||||
public OVRConfigurationTaskSourceCode(OVRConfigurationTask task)
|
||||
{
|
||||
_task = task;
|
||||
_stackTrace = new StackTrace(true);
|
||||
}
|
||||
|
||||
public void ProcessStackTrace()
|
||||
{
|
||||
if (FindPathAndLine(out var path, out var line))
|
||||
{
|
||||
path = path.Replace("\\", "/");
|
||||
|
||||
if (path.StartsWith(Application.dataPath))
|
||||
{
|
||||
FilePath = Path.Combine("Assets/", path.Substring(Application.dataPath.Length + 1));
|
||||
Line = line;
|
||||
_object = AssetDatabase.LoadAssetAtPath(FilePath, typeof(Object));
|
||||
}
|
||||
}
|
||||
|
||||
_processed = true;
|
||||
}
|
||||
|
||||
public bool Open()
|
||||
{
|
||||
if (Valid)
|
||||
{
|
||||
OpenAssetDelegate?.Invoke(_object, Line);
|
||||
}
|
||||
|
||||
OVRTelemetry.Start(OVRProjectSetupTelemetryEvent.EventTypes.GoToSource)
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Uid, _task.Uid.ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.BuildTargetGroup,
|
||||
BuildTargetGroup.Unknown.ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Value, Valid ? "true" : "false")
|
||||
.Send();
|
||||
|
||||
return Valid;
|
||||
}
|
||||
|
||||
private StackFrame FindStackFrame()
|
||||
{
|
||||
// Depth 2, Just before the constructor
|
||||
StackFrame frame = _stackTrace.GetFrame(2);
|
||||
var method = frame.GetMethod();
|
||||
if (ExpectedMethods.Contains(method))
|
||||
{
|
||||
// Depth 3, Just before OVRProjectSetup AddTask
|
||||
frame = _stackTrace.GetFrame(3);
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
private bool FindPathAndLine(out string path, out int line)
|
||||
{
|
||||
var frame = FindStackFrame();
|
||||
if (frame == null)
|
||||
{
|
||||
path = null;
|
||||
line = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
path = frame.GetFileName();
|
||||
line = frame.GetFileLineNumber();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b25802328957400cb1180db46a429f8b
|
||||
timeCreated: 1665496546
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae567593b4a0438c80fd037782a57588
|
||||
timeCreated: 1663596823
|
||||
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
internal class OVRConfigurationTaskFixer : OVRConfigurationTaskProcessor
|
||||
{
|
||||
public override int AllocatedTimeInMs => 10;
|
||||
public override ProcessorType Type => ProcessorType.Fixer;
|
||||
|
||||
protected override Func<IEnumerable<OVRConfigurationTask>, List<OVRConfigurationTask>> OpenTasksFilter =>
|
||||
(Func<IEnumerable<OVRConfigurationTask>, List<OVRConfigurationTask>>)(tasksToFilter => tasksToFilter
|
||||
.Where(task => task.FixAction != null
|
||||
&& !task.IsDone(BuildTargetGroup)
|
||||
&& !task.IsIgnored(BuildTargetGroup))
|
||||
.ToList());
|
||||
|
||||
private const int LoopExitCount = 4;
|
||||
|
||||
private bool _hasFixedSome = false;
|
||||
private int _counter = LoopExitCount;
|
||||
|
||||
public OVRConfigurationTaskFixer(
|
||||
OVRConfigurationTaskRegistry registry,
|
||||
BuildTargetGroup buildTargetGroup,
|
||||
Func<IEnumerable<OVRConfigurationTask>, List<OVRConfigurationTask>> filter,
|
||||
OVRProjectSetup.LogMessages logMessages,
|
||||
bool blocking,
|
||||
Action<OVRConfigurationTaskProcessor> onCompleted)
|
||||
: base(registry, buildTargetGroup, filter, logMessages, blocking, onCompleted)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void ProcessTask(OVRConfigurationTask task)
|
||||
{
|
||||
_hasFixedSome |= task.Fix(BuildTargetGroup);
|
||||
}
|
||||
|
||||
protected override void PrepareTasks()
|
||||
{
|
||||
_hasFixedSome = false;
|
||||
base.PrepareTasks();
|
||||
}
|
||||
|
||||
protected override void Validate()
|
||||
{
|
||||
_counter--;
|
||||
|
||||
if (_counter <= 0)
|
||||
{
|
||||
Debug.LogWarning("[Oculus Settings] Fixing Tasks has exited after too many iterations. " +
|
||||
"(There might be some contradictory rules leading to a loop)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_hasFixedSome)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Preparing a new Run
|
||||
PrepareTasks();
|
||||
if (Blocking)
|
||||
{
|
||||
Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e1fe0a245064a44b8b080a115da8c1d
|
||||
timeCreated: 1663596864
|
||||
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
internal abstract class OVRConfigurationTaskProcessor
|
||||
{
|
||||
public enum ProcessorType
|
||||
{
|
||||
Updater,
|
||||
Fixer
|
||||
}
|
||||
|
||||
public virtual int AllocatedTimeInMs => 10;
|
||||
protected abstract void ProcessTask(OVRConfigurationTask task);
|
||||
public abstract ProcessorType Type { get; }
|
||||
|
||||
private BuildTargetGroup _buildTargetGroup;
|
||||
private OVRProjectSetup.LogMessages _logMessages;
|
||||
private readonly OVRConfigurationTaskRegistry _registry;
|
||||
private Func<IEnumerable<OVRConfigurationTask>, List<OVRConfigurationTask>> _filter;
|
||||
protected abstract Func<IEnumerable<OVRConfigurationTask>, List<OVRConfigurationTask>> OpenTasksFilter { get; }
|
||||
private List<OVRConfigurationTask> _tasks;
|
||||
private IEnumerator<OVRConfigurationTask> _enumerator;
|
||||
private int _startTime;
|
||||
|
||||
public bool Blocking { get; set; }
|
||||
public event Action<OVRConfigurationTaskProcessor> OnComplete;
|
||||
|
||||
public BuildTargetGroup BuildTargetGroup => _buildTargetGroup;
|
||||
public OVRProjectSetup.LogMessages LogMessages => _logMessages;
|
||||
|
||||
// Status
|
||||
public bool Started => _startTime != -1;
|
||||
public bool Processing => _enumerator != null;
|
||||
public bool Completed => Started && (_enumerator == null || _enumerator.Current == null);
|
||||
public List<OVRConfigurationTask> Tasks => _tasks;
|
||||
|
||||
protected OVRConfigurationTaskProcessor(OVRConfigurationTaskRegistry registry, BuildTargetGroup buildTargetGroup,
|
||||
Func<IEnumerable<OVRConfigurationTask>, List<OVRConfigurationTask>> filter,
|
||||
OVRProjectSetup.LogMessages logMessages,
|
||||
bool blocking,
|
||||
Action<OVRConfigurationTaskProcessor> onCompleted)
|
||||
{
|
||||
_registry = registry;
|
||||
_enumerator = null;
|
||||
_buildTargetGroup = buildTargetGroup;
|
||||
_logMessages = logMessages;
|
||||
Blocking = blocking;
|
||||
_filter = filter;
|
||||
_startTime = -1;
|
||||
|
||||
OnComplete += onCompleted;
|
||||
}
|
||||
|
||||
protected virtual void PrepareTasks()
|
||||
{
|
||||
// Get all the tasks from the Setup Tool
|
||||
var tasks = _registry.GetTasks(_buildTargetGroup, true);
|
||||
|
||||
// Apply the caller-provided filter
|
||||
_tasks = _filter != null ? _filter(tasks) : tasks.ToList();
|
||||
// When not forced, apply the OpenTaskFilter as well
|
||||
_tasks = (OpenTasksFilter != null) ? OpenTasksFilter(_tasks) : _tasks;
|
||||
|
||||
// Prepare the Enumerator
|
||||
_enumerator = _tasks.GetEnumerator();
|
||||
_enumerator.MoveNext();
|
||||
}
|
||||
|
||||
public virtual void OnRequested()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
PrepareTasks();
|
||||
_startTime = Environment.TickCount;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
var updateTime = Environment.TickCount;
|
||||
var currentTime = updateTime;
|
||||
while ((Blocking || (currentTime - updateTime < AllocatedTimeInMs)) && _enumerator?.Current != null)
|
||||
{
|
||||
ProcessTask(_enumerator.Current);
|
||||
currentTime = Environment.TickCount;
|
||||
_enumerator.MoveNext();
|
||||
}
|
||||
|
||||
if (Completed)
|
||||
{
|
||||
Validate();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Validate()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Complete()
|
||||
{
|
||||
_enumerator = null;
|
||||
OnComplete?.Invoke(this);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da7a8c3cbcb14aba8b02a89bc05e136f
|
||||
timeCreated: 1663596850
|
||||
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
internal class OVRConfigurationTaskProcessorQueue
|
||||
{
|
||||
public event Action<OVRConfigurationTaskProcessor> OnProcessorCompleted;
|
||||
|
||||
private readonly Queue<OVRConfigurationTaskProcessor> _queue = new Queue<OVRConfigurationTaskProcessor>();
|
||||
|
||||
public bool Busy => _queue.Count > 0;
|
||||
public bool Blocked => Busy && _queue.Peek().Blocking;
|
||||
|
||||
public bool BlockedBy(OVRConfigurationTaskProcessor.ProcessorType processorType)
|
||||
{
|
||||
foreach (var processor in _queue)
|
||||
{
|
||||
if (processor.Type == processorType && processor.Blocking)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool BusyWith(OVRConfigurationTaskProcessor.ProcessorType processorType)
|
||||
{
|
||||
foreach (var processor in _queue)
|
||||
{
|
||||
if (processor.Type == processorType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Request(OVRConfigurationTaskProcessor processor)
|
||||
{
|
||||
if (!OVRProjectSetup.Enabled.Value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Enqueue(processor);
|
||||
}
|
||||
|
||||
private void Enqueue(OVRConfigurationTaskProcessor processor)
|
||||
{
|
||||
if (!Busy)
|
||||
{
|
||||
// If was empty, then register to editor update
|
||||
EditorApplication.update += Update;
|
||||
}
|
||||
|
||||
// Enqueue
|
||||
_queue.Enqueue(processor);
|
||||
|
||||
processor.OnRequested();
|
||||
|
||||
if (processor.Blocking)
|
||||
{
|
||||
// In the case where the newly added processor is blocking
|
||||
// we'll make all the previously queued processor blocking as well
|
||||
foreach (var otherProcessor in _queue)
|
||||
{
|
||||
otherProcessor.Blocking = true;
|
||||
}
|
||||
|
||||
// Force an update, this will be The blocking update
|
||||
Update();
|
||||
}
|
||||
}
|
||||
|
||||
private void Dequeue(OVRConfigurationTaskProcessor processor)
|
||||
{
|
||||
// We should only dequeue the current processor
|
||||
if (processor != _queue.Peek())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Dequeue
|
||||
_queue.Dequeue();
|
||||
|
||||
if (!Busy)
|
||||
{
|
||||
// Now that it is empty, unregister to editor update
|
||||
EditorApplication.update -= Update;
|
||||
}
|
||||
|
||||
// Trigger specific callbacks
|
||||
processor.Complete();
|
||||
|
||||
// Trigger global callbacks
|
||||
OnProcessorCompleted?.Invoke(processor);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
var processor = _queue.Count > 0 ? _queue.Peek() : null;
|
||||
|
||||
while (processor != null)
|
||||
{
|
||||
if (!processor.Started)
|
||||
{
|
||||
processor.Start();
|
||||
}
|
||||
|
||||
processor.Update();
|
||||
|
||||
if (processor.Completed)
|
||||
{
|
||||
Dequeue(processor);
|
||||
|
||||
// Move to the next processor
|
||||
processor = _queue.Count > 0 ? _queue.Peek() : null;
|
||||
}
|
||||
|
||||
if (!(processor?.Blocking ?? false))
|
||||
{
|
||||
// Is the processor is not blocking, we can stop the update until the next update call
|
||||
processor = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97ad6b63e1e34a329c0b5b3a69e7d8e7
|
||||
timeCreated: 1663597510
|
||||
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
internal class OVRConfigurationTaskUpdater : OVRConfigurationTaskProcessor
|
||||
{
|
||||
public override int AllocatedTimeInMs => 10;
|
||||
private readonly OVRConfigurationTaskUpdaterSummary _summary;
|
||||
|
||||
protected override Func<IEnumerable<OVRConfigurationTask>, List<OVRConfigurationTask>> OpenTasksFilter =>
|
||||
(Func<IEnumerable<OVRConfigurationTask>, List<OVRConfigurationTask>>)(tasksToFilter => tasksToFilter
|
||||
.Where(task => !task.IsIgnored(BuildTargetGroup))
|
||||
.ToList());
|
||||
|
||||
public override ProcessorType Type => ProcessorType.Updater;
|
||||
public OVRConfigurationTaskUpdaterSummary Summary => _summary;
|
||||
|
||||
public OVRConfigurationTaskUpdater(
|
||||
OVRConfigurationTaskRegistry registry,
|
||||
BuildTargetGroup buildTargetGroup,
|
||||
Func<IEnumerable<OVRConfigurationTask>, List<OVRConfigurationTask>> filter,
|
||||
OVRProjectSetup.LogMessages logMessages,
|
||||
bool blocking,
|
||||
Action<OVRConfigurationTaskProcessor> onCompleted)
|
||||
: base(registry, buildTargetGroup, filter, logMessages, blocking, onCompleted)
|
||||
{
|
||||
_summary = new OVRConfigurationTaskUpdaterSummary(BuildTargetGroup);
|
||||
}
|
||||
|
||||
protected override void PrepareTasks()
|
||||
{
|
||||
_summary.Reset();
|
||||
base.PrepareTasks();
|
||||
}
|
||||
|
||||
protected override void ProcessTask(OVRConfigurationTask task)
|
||||
{
|
||||
var changedState = task.UpdateAndGetStateChanged(BuildTargetGroup);
|
||||
Summary.AddTask(task, changedState);
|
||||
|
||||
if (task.IsDone(BuildTargetGroup))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (LogMessages == OVRProjectSetup.LogMessages.All
|
||||
|| (LogMessages == OVRProjectSetup.LogMessages.Changed && changedState))
|
||||
{
|
||||
task.LogMessage(BuildTargetGroup);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Complete()
|
||||
{
|
||||
Summary.Validate();
|
||||
|
||||
if (LogMessages >= OVRProjectSetup.LogMessages.Summary)
|
||||
{
|
||||
Summary.Log();
|
||||
}
|
||||
|
||||
base.Complete();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36d246eb26384ec88c5d849668cf29a7
|
||||
timeCreated: 1663591461
|
||||
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
internal class OVRConfigurationTaskUpdaterSummary
|
||||
{
|
||||
private readonly List<OVRConfigurationTask> _doneTasks;
|
||||
private readonly List<OVRConfigurationTask> _outstandingTasks;
|
||||
private readonly Dictionary<OVRProjectSetup.TaskLevel, List<OVRConfigurationTask>> _outstandingTasksPerLevel;
|
||||
private bool HasNewOutstandingTasks { get; set; }
|
||||
private bool HasAnyChange { get; set; }
|
||||
|
||||
public bool HasAvailableFixes => _outstandingTasks.Count > 0;
|
||||
public bool HasFixes(OVRProjectSetup.TaskLevel taskLevel) => _outstandingTasksPerLevel[taskLevel].Count > 0;
|
||||
public int GetNumberOfFixes(OVRProjectSetup.TaskLevel taskLevel) => _outstandingTasksPerLevel[taskLevel].Count;
|
||||
public int GetTotalNumberOfFixes() => _outstandingTasks.Count;
|
||||
private readonly BuildTargetGroup _buildTargetGroup;
|
||||
|
||||
public BuildTargetGroup BuildTargetGroup => _buildTargetGroup;
|
||||
|
||||
public OVRConfigurationTaskUpdaterSummary(BuildTargetGroup buildTargetGroup)
|
||||
{
|
||||
_buildTargetGroup = buildTargetGroup;
|
||||
_doneTasks = new List<OVRConfigurationTask>();
|
||||
_outstandingTasks = new List<OVRConfigurationTask>();
|
||||
_outstandingTasksPerLevel = new Dictionary<OVRProjectSetup.TaskLevel, List<OVRConfigurationTask>>();
|
||||
for (var i = OVRProjectSetup.TaskLevel.Required; i >= OVRProjectSetup.TaskLevel.Optional; i--)
|
||||
{
|
||||
_outstandingTasksPerLevel.Add(i, new List<OVRConfigurationTask>());
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_doneTasks.Clear();
|
||||
_outstandingTasks.Clear();
|
||||
for (var i = OVRProjectSetup.TaskLevel.Required; i >= OVRProjectSetup.TaskLevel.Optional; i--)
|
||||
{
|
||||
_outstandingTasksPerLevel[i].Clear();
|
||||
}
|
||||
|
||||
HasNewOutstandingTasks = false;
|
||||
HasAnyChange = false;
|
||||
}
|
||||
|
||||
public void AddTask(OVRConfigurationTask task, bool changedState)
|
||||
{
|
||||
if (task.IsDone(_buildTargetGroup))
|
||||
{
|
||||
_doneTasks.Add(task);
|
||||
}
|
||||
else
|
||||
{
|
||||
_outstandingTasks.Add(task);
|
||||
_outstandingTasksPerLevel[task.Level.GetValue(_buildTargetGroup)].Add(task);
|
||||
HasNewOutstandingTasks |= changedState;
|
||||
}
|
||||
|
||||
HasAnyChange |= changedState;
|
||||
}
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if (HasAnyChange)
|
||||
{
|
||||
LogEvent();
|
||||
}
|
||||
|
||||
var interactionFlowEvent = OVRProjectSetupSettingsProvider.InteractionFlowEvent;
|
||||
if (interactionFlowEvent == null)
|
||||
{
|
||||
if (GetTotalNumberOfFixes() > 0)
|
||||
{
|
||||
interactionFlowEvent = OVRTelemetry
|
||||
.Start(OVRProjectSetupTelemetryEvent.EventTypes.InteractionFlow)
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Level,
|
||||
HighestFixLevel?.ToString() ?? "None")
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Count,
|
||||
GetNumberOfFixes(HighestFixLevel ?? OVRProjectSetup.TaskLevel.Required).ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Level,
|
||||
HighestFixLevel?.ToString() ?? "None")
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Value,
|
||||
GetTotalNumberOfFixes().ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.BuildTargetGroup,
|
||||
BuildTargetGroup.ToString());
|
||||
|
||||
OVRProjectSetupSettingsProvider.InteractionFlowEvent = interactionFlowEvent;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
interactionFlowEvent = interactionFlowEvent?.AddAnnotation(
|
||||
OVRProjectSetupTelemetryEvent.AnnotationTypes.BuildTargetGroupAfter,
|
||||
BuildTargetGroup.ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.ValueAfter,
|
||||
GetTotalNumberOfFixes().ToString());
|
||||
|
||||
OVRProjectSetupSettingsProvider.InteractionFlowEvent = interactionFlowEvent;
|
||||
}
|
||||
}
|
||||
|
||||
public OVRProjectSetup.TaskLevel? HighestFixLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
for (var i = OVRProjectSetup.TaskLevel.Required; i >= OVRProjectSetup.TaskLevel.Optional; i--)
|
||||
{
|
||||
if (HasFixes(i))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string GenerateReport(string outputPath = null, string fileName = null)
|
||||
{
|
||||
var sortedTasks = _outstandingTasks.Concat(_doneTasks);
|
||||
return OVRProjectSetupReport.GenerateJson(
|
||||
sortedTasks,
|
||||
_buildTargetGroup,
|
||||
outputPath,
|
||||
fileName
|
||||
);
|
||||
}
|
||||
|
||||
public string ComputeNoticeMessage()
|
||||
{
|
||||
var highestLevel = HighestFixLevel;
|
||||
var level = highestLevel ?? OVRProjectSetup.TaskLevel.Optional;
|
||||
var count = GetNumberOfFixes(level);
|
||||
if (count == 0)
|
||||
{
|
||||
return $"Oculus-Ready for {_buildTargetGroup}";
|
||||
}
|
||||
else
|
||||
{
|
||||
var message = GetLogMessage(level, count);
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
public string ComputeLogMessage()
|
||||
{
|
||||
var highestLevel = HighestFixLevel;
|
||||
var level = highestLevel ?? OVRProjectSetup.TaskLevel.Optional;
|
||||
var count = GetNumberOfFixes(level);
|
||||
var message = GetFullLogMessage(level, count);
|
||||
return message;
|
||||
}
|
||||
|
||||
public void LogEvent()
|
||||
{
|
||||
OVRTelemetry.Start(OVRProjectSetupTelemetryEvent.EventTypes.Summary)
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Level, HighestFixLevel?.ToString() ?? "None")
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Count,
|
||||
GetNumberOfFixes(HighestFixLevel ?? OVRProjectSetup.TaskLevel.Required).ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.BuildTargetGroup, BuildTargetGroup.ToString())
|
||||
.AddAnnotation(OVRProjectSetupTelemetryEvent.AnnotationTypes.Value, GetTotalNumberOfFixes().ToString())
|
||||
.Send();
|
||||
}
|
||||
|
||||
|
||||
public void Log()
|
||||
{
|
||||
if (!HasNewOutstandingTasks)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var highestLevel = HighestFixLevel;
|
||||
var message = ComputeLogMessage();
|
||||
|
||||
switch (highestLevel)
|
||||
{
|
||||
case OVRProjectSetup.TaskLevel.Optional:
|
||||
{
|
||||
Debug.Log(message);
|
||||
}
|
||||
break;
|
||||
|
||||
case OVRProjectSetup.TaskLevel.Recommended:
|
||||
{
|
||||
Debug.LogWarning(message);
|
||||
}
|
||||
break;
|
||||
|
||||
case OVRProjectSetup.TaskLevel.Required:
|
||||
{
|
||||
if (OVRProjectSetup.RequiredThrowErrors.Value)
|
||||
{
|
||||
Debug.LogError(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning(message);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetLogMessage(OVRProjectSetup.TaskLevel level, int count)
|
||||
{
|
||||
switch (count)
|
||||
{
|
||||
case 0:
|
||||
return $"There are no outstanding {level.ToString()} fixes.";
|
||||
|
||||
case 1:
|
||||
return $"There is 1 outstanding {level.ToString()} fix.";
|
||||
|
||||
default:
|
||||
return $"There are {count} outstanding {level.ToString()} fixes.";
|
||||
}
|
||||
}
|
||||
|
||||
internal static string GetFullLogMessage(OVRProjectSetup.TaskLevel level, int count)
|
||||
{
|
||||
return
|
||||
$"[Oculus Settings] {GetLogMessage(level, count)}\nFor more information, go to <a href=\"{OVRConfigurationTask.ConsoleLinkHref}\">Edit > Project Settings > {OVRProjectSetupSettingsProvider.SettingsName}</a>";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c1baa7891a0f4c63ad746d7e1b35faef
|
||||
timeCreated: 1660745160
|
||||
3
Assets/Oculus/VR/Editor/OVRProjectSetup/Telemetry.meta
Normal file
3
Assets/Oculus/VR/Editor/OVRProjectSetup/Telemetry.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36ee7ddd85174b59ad43e9bdb151fedd
|
||||
timeCreated: 1666883993
|
||||
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using static OVRTelemetry;
|
||||
|
||||
internal static class OVRProjectSetupTelemetryEvent
|
||||
{
|
||||
public static class EventTypes
|
||||
{
|
||||
// Attention : Need to be kept in sync with QPL Event Ids
|
||||
public const int Fix = 163058027;
|
||||
public const int Option = 163058846;
|
||||
public const int GoToSource = 163056520;
|
||||
public const int Summary = 163063879;
|
||||
public const int Open = 163056010;
|
||||
public const int Close = 163056958;
|
||||
public const int InteractionFlow = 163069594;
|
||||
}
|
||||
|
||||
public static class AnnotationTypes
|
||||
{
|
||||
public const string Uid = "Uid";
|
||||
public const string Level = "Level";
|
||||
public const string Type = "Type";
|
||||
public const string Value = "Value";
|
||||
public const string BuildTargetGroup = "BuildTargetGroup";
|
||||
public const string Group = "Group";
|
||||
public const string Blocking = "Blocking";
|
||||
public const string Count = "Count";
|
||||
public const string Origin = "Origin";
|
||||
public const string TimeSpent = "TimeSpent";
|
||||
public const string Interaction = "Interaction";
|
||||
public const string ValueAfter = "ValueAfter";
|
||||
public const string BuildTargetGroupAfter = "BuildTargetGroupAfter";
|
||||
}
|
||||
|
||||
public static class MarkerPoints
|
||||
{
|
||||
public static readonly MarkerPoint Process = new MarkerPoint("Process");
|
||||
public static readonly MarkerPoint Open = new MarkerPoint("Open");
|
||||
public static readonly MarkerPoint Interact = new MarkerPoint("Interact");
|
||||
public static readonly MarkerPoint Close = new MarkerPoint("Close");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3d69e61ddc14e19ac7aca4bd186f5e1
|
||||
timeCreated: 1666884008
|
||||
3
Assets/Oculus/VR/Editor/OVRProjectSetup/Utils.meta
Normal file
3
Assets/Oculus/VR/Editor/OVRProjectSetup/Utils.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 00c568f16a61407fa12c2e7e67a29f67
|
||||
timeCreated: 1663063024
|
||||
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
|
||||
[InitializeOnLoad]
|
||||
internal static class ConsoleLinkEventHandler
|
||||
{
|
||||
public static event Action<Dictionary<string, string>> OnConsoleLink;
|
||||
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
// Much simpler code in 2021 as the API became public
|
||||
static ConsoleLinkEventHandler()
|
||||
{
|
||||
EditorGUI.hyperLinkClicked += OnConsoleLinkInternal;
|
||||
}
|
||||
|
||||
private static void OnConsoleLinkInternal(EditorWindow window, HyperLinkClickedEventArgs arguments)
|
||||
{
|
||||
OnConsoleLink?.Invoke(arguments.hyperLinkData);
|
||||
}
|
||||
#else
|
||||
// Using reflection to hack into the internal hyperLinkClicked event before 2021
|
||||
private static PropertyInfo _parametersProperty;
|
||||
|
||||
static ConsoleLinkEventHandler()
|
||||
{
|
||||
var evt = typeof(EditorGUI).GetEvent("hyperLinkClicked", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
if (evt != null)
|
||||
{
|
||||
var method = typeof(ConsoleLinkEventHandler).GetMethod("OnConsoleLinkInternal",
|
||||
BindingFlags.Static | BindingFlags.NonPublic);
|
||||
if (method != null)
|
||||
{
|
||||
var handler = Delegate.CreateDelegate(evt.EventHandlerType, method);
|
||||
evt.AddMethod.Invoke(null, new object[] { handler });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool InitialiseParametersProperty(EventArgs arguments)
|
||||
{
|
||||
if (_parametersProperty == null)
|
||||
{
|
||||
_parametersProperty = arguments.GetType()
|
||||
.GetProperty("hyperlinkInfos", BindingFlags.Instance | BindingFlags.Public);
|
||||
}
|
||||
|
||||
return _parametersProperty != null;
|
||||
}
|
||||
|
||||
private static void OnConsoleLinkInternal(object sender, EventArgs arguments)
|
||||
{
|
||||
if (!InitialiseParametersProperty(arguments))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_parametersProperty.GetValue(arguments) is Dictionary<string, string> argumentsAsDictionary)
|
||||
{
|
||||
OnConsoleLink?.Invoke(argumentsAsDictionary);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2508c18b7ce0d9a489afb99ff7088bd7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
internal abstract class OptionalLambdaType<TLambdaArgumentType, TValueType>
|
||||
{
|
||||
public static OptionalLambdaType<TLambdaArgumentType, TValueType> Create(TValueType value,
|
||||
Func<TLambdaArgumentType, TValueType> lambda, bool allowCache)
|
||||
{
|
||||
OptionalLambdaType<TLambdaArgumentType, TValueType> optionalLambdaType = null;
|
||||
if (lambda != null)
|
||||
{
|
||||
if (allowCache)
|
||||
{
|
||||
optionalLambdaType = new OptionalLambdaTypeWithCachedLambda<TLambdaArgumentType, TValueType>(lambda);
|
||||
}
|
||||
else
|
||||
{
|
||||
optionalLambdaType = new OptionalLambdaTypeWithLambda<TLambdaArgumentType, TValueType>(lambda);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
optionalLambdaType = new OptionalLambdaTypeWithoutLambda<TLambdaArgumentType, TValueType>(value);
|
||||
}
|
||||
|
||||
return optionalLambdaType;
|
||||
}
|
||||
|
||||
public static implicit operator OptionalLambdaType<TLambdaArgumentType, TValueType>(TValueType value)
|
||||
{
|
||||
var optionalLambdaType = new OptionalLambdaTypeWithoutLambda<TLambdaArgumentType, TValueType>(value);
|
||||
return optionalLambdaType;
|
||||
}
|
||||
|
||||
public static implicit operator OptionalLambdaType<TLambdaArgumentType, TValueType>(
|
||||
Func<TLambdaArgumentType, TValueType> lambda)
|
||||
{
|
||||
var optionalLambdaType = new OptionalLambdaTypeWithLambda<TLambdaArgumentType, TValueType>(lambda);
|
||||
return optionalLambdaType;
|
||||
}
|
||||
|
||||
public abstract bool Valid { get; }
|
||||
public abstract TValueType GetValue(TLambdaArgumentType arg);
|
||||
public abstract TValueType Default { get; }
|
||||
|
||||
public virtual void InvalidateCache(TLambdaArgumentType arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
internal class OptionalLambdaTypeWithoutLambda<TLambdaArgumentType, TValueType>
|
||||
: OptionalLambdaType<TLambdaArgumentType, TValueType>
|
||||
{
|
||||
private readonly TValueType _value;
|
||||
|
||||
public OptionalLambdaTypeWithoutLambda(TValueType value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public override TValueType GetValue(TLambdaArgumentType arg) => _value;
|
||||
public override TValueType Default => _value;
|
||||
public override bool Valid => _value != null;
|
||||
}
|
||||
|
||||
internal class OptionalLambdaTypeWithLambda<TLambdaArgumentType, TValueType>
|
||||
: OptionalLambdaType<TLambdaArgumentType, TValueType>
|
||||
{
|
||||
protected readonly Func<TLambdaArgumentType, TValueType> Lambda;
|
||||
|
||||
public OptionalLambdaTypeWithLambda(Func<TLambdaArgumentType, TValueType> lambda)
|
||||
{
|
||||
Lambda = lambda;
|
||||
}
|
||||
|
||||
public override TValueType GetValue(TLambdaArgumentType arg) => Lambda.Invoke(arg);
|
||||
|
||||
public override TValueType Default => Lambda.Invoke(default(TLambdaArgumentType));
|
||||
public override bool Valid => Lambda != null && Default != null;
|
||||
}
|
||||
|
||||
internal class OptionalLambdaTypeWithCachedLambda<TLambdaArgumentType, TValueType>
|
||||
: OptionalLambdaTypeWithLambda<TLambdaArgumentType, TValueType>
|
||||
{
|
||||
private readonly Dictionary<TLambdaArgumentType, TValueType> _cachedValues =
|
||||
new Dictionary<TLambdaArgumentType, TValueType>();
|
||||
|
||||
public OptionalLambdaTypeWithCachedLambda(Func<TLambdaArgumentType, TValueType> lambda) : base(lambda)
|
||||
{
|
||||
}
|
||||
|
||||
public override TValueType GetValue(TLambdaArgumentType arg)
|
||||
{
|
||||
if (!_cachedValues.TryGetValue(arg, out var value))
|
||||
{
|
||||
value = base.GetValue(arg);
|
||||
_cachedValues.Add(arg, value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public override void InvalidateCache(TLambdaArgumentType arg)
|
||||
{
|
||||
_cachedValues.Remove(arg);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eeb765bc919545b893b0c57629625f14
|
||||
timeCreated: 1662026667
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Oculus SDK License Agreement (the "License");
|
||||
* you may not use the Oculus SDK except in compliance with the License,
|
||||
* which is provided at the time of installation or download, or which
|
||||
* otherwise accompanies this software in either electronic or hard copy form.
|
||||
*
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://developer.oculus.com/licenses/oculussdk/
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[Serializable]
|
||||
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ISerializationCallbackReceiver
|
||||
{
|
||||
[SerializeField]
|
||||
private List<TKey> keys = new List<TKey>();
|
||||
|
||||
[SerializeField]
|
||||
private List<TValue> values = new List<TValue>();
|
||||
|
||||
// save the dictionary to lists
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
keys.Clear();
|
||||
values.Clear();
|
||||
foreach (var pair in this)
|
||||
{
|
||||
keys.Add(pair.Key);
|
||||
values.Add(pair.Value);
|
||||
}
|
||||
}
|
||||
|
||||
// load dictionary from lists
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
this.Clear();
|
||||
|
||||
if (keys.Count != values.Count)
|
||||
{
|
||||
throw new System.Exception(string.Format(
|
||||
"there are {0} keys and {1} values after deserialization. Make sure that both key and value types are serializable."));
|
||||
}
|
||||
|
||||
for (var i = 0; i < keys.Count; i++)
|
||||
{
|
||||
this.Add(keys[i], values[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65ebc4746fe6453ba8e7d3433ba52579
|
||||
timeCreated: 1663063037
|
||||
Reference in New Issue
Block a user