插件添加
30
EintooAR/Assets/Plugins/Com.ForbiddenByte/OSA.meta
Normal file
@ -0,0 +1,30 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c0b533a2ac759b4084c63f61f9a4a29
|
||||
labels:
|
||||
- Chat
|
||||
- Tableview
|
||||
- chat
|
||||
- date
|
||||
- drag
|
||||
- drop
|
||||
- gridlayout
|
||||
- gridview
|
||||
- listbox
|
||||
- listview
|
||||
- nested
|
||||
- optimized
|
||||
- picker
|
||||
- scroll
|
||||
- scrollable
|
||||
- scroller
|
||||
- scrolling
|
||||
- scrollview
|
||||
- table
|
||||
- ugui
|
||||
folderAsset: yes
|
||||
timeCreated: 1457890603
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
10
EintooAR/Assets/Plugins/Com.ForbiddenByte/OSA/Common.meta
Normal file
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f439632ab693d24b8abe7f3ee455425
|
||||
folderAsset: yes
|
||||
timeCreated: 1638563856
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b99437f29a8f5c44192c60f998941fd1
|
||||
folderAsset: yes
|
||||
timeCreated: 1638563861
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,88 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e8722b72189fcb14f893b060e48157e0
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
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
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
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: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 1f030ebcbbde7bc4a9946bad842db187
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 2.1 KiB |
@ -0,0 +1,110 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 078087355e21ddc4a87a3ea8ca4cdd21
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
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
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
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: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: e1e0ac571ba200944a613d07873fe599
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1,110 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 787578eb3a0ae5446999ae02ec0a4f19
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
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
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
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: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 1d9b9fff266e798498e25f8599f284bf
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,88 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3791f06fd42a8345a2b157e3f44c5e4
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
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
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 16
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
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: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 1e452f943eecbb44b8920929738b0de9
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 1.8 KiB |
@ -0,0 +1,110 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f64cb52923eb7344bed9cf13ec2b40f
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
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
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
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: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 95b9bc71ef76ad94e8080332217377a4
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f1bee80cfafa7f4099d2816ac475adb
|
||||
folderAsset: yes
|
||||
timeCreated: 1638559798
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 322 B |
@ -0,0 +1,110 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5f92795d49795a4bbdb0c5d11adb181
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
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
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
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: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: e694954661324864781d51b94c31307a
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 182 B |
@ -0,0 +1,110 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 530a50bdccc352b448e5e05c1a8a8759
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
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
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
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: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: f427c477e8b483b4f8513d1ba1ee186c
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
10
EintooAR/Assets/Plugins/Com.ForbiddenByte/OSA/Core.meta
Normal file
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e2b9e0b05cd46742b7335534c9e4c79
|
||||
folderAsset: yes
|
||||
timeCreated: 1638563677
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d54514acc81b2a145a0e00ee72f2e788
|
||||
folderAsset: yes
|
||||
timeCreated: 1638553694
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,13 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 0f07c1bce198ce940a650e38262e0e5c, type: 3}
|
||||
m_Name: PluginPathTracker
|
||||
m_EditorClassIdentifier:
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4be13f8984dfa54fb36f11769052e6f
|
||||
timeCreated: 1638551995
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac20f410e37ade84db5ee4df0fa3d532
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8110e5b59d0a8d040a983dee046150c9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a73dc4969019c44fb118bab0c6295a2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2affa7ba87dc90548b51e9a3eeda034a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
@ -0,0 +1,270 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &143082
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22443082}
|
||||
- component: {fileID: 22243082}
|
||||
- component: {fileID: 11443082}
|
||||
m_Layer: 5
|
||||
m_Name: BackgroundImage
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &143084
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22443084}
|
||||
- component: {fileID: 22243084}
|
||||
- component: {fileID: 11443084}
|
||||
- component: {fileID: 11443086}
|
||||
m_Layer: 5
|
||||
m_Name: TitleText
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &155790
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22455790}
|
||||
- component: {fileID: 11420018}
|
||||
m_Layer: 5
|
||||
m_Name: Views
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &155796
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22455796}
|
||||
- component: {fileID: 11455802}
|
||||
m_Layer: 5
|
||||
m_Name: BasicGridAdapterItem
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &11420018
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 155790}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -146154839, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!114 &11443082
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 143082}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 0.39215687}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!114 &11443084
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 143084}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 18
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 1
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 23
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Grid item
|
||||
--- !u!114 &11443086
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 143084}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1573420865, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_EffectColor: {r: 0, g: 0, b: 0, a: 0.5}
|
||||
m_EffectDistance: {x: 1, y: -1}
|
||||
m_UseGraphicAlpha: 1
|
||||
--- !u!114 &11455802
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 155796}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1679637790, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreLayout: 0
|
||||
m_MinWidth: -1
|
||||
m_MinHeight: -1
|
||||
m_PreferredWidth: 204.03
|
||||
m_PreferredHeight: 165.62314
|
||||
m_FlexibleWidth: -1
|
||||
m_FlexibleHeight: -1
|
||||
--- !u!222 &22243082
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 143082}
|
||||
--- !u!222 &22243084
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 143084}
|
||||
--- !u!224 &22443082
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 143082}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 22455790}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!224 &22443084
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 143084}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 22455790}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -0.00003194809}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!224 &22455790
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 155790}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 22443082}
|
||||
- {fileID: 22443084}
|
||||
m_Father: {fileID: 22455796}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!224 &22455796
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 155796}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 22455790}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.38700002, y: -1.025677}
|
||||
m_AnchorMax: {x: 0.61300004, y: -0.69832313}
|
||||
m_AnchoredPosition: {x: -0.2, y: 0.5}
|
||||
m_SizeDelta: {x: -0.5, y: -0.99997}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 155796}
|
||||
m_IsPrefabParent: 1
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0fcae5defad2dcf4c8805a5d43f70d28
|
||||
NativeFormatImporter:
|
||||
userData:
|
@ -0,0 +1,205 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &107932
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22407932}
|
||||
m_Layer: 5
|
||||
m_Name: BasicListAdapterItem
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &107934
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22407934}
|
||||
- component: {fileID: 22207934}
|
||||
- component: {fileID: 11407932}
|
||||
m_Layer: 5
|
||||
m_Name: BackgroundImage
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &107936
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22407936}
|
||||
- component: {fileID: 22207936}
|
||||
- component: {fileID: 11407934}
|
||||
- component: {fileID: 11407936}
|
||||
m_Layer: 5
|
||||
m_Name: TitleText
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &11407932
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 107934}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 0.39215687}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!114 &11407934
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 107936}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 18
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 1
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 23
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: List item
|
||||
--- !u!114 &11407936
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 107936}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1573420865, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_EffectColor: {r: 0, g: 0, b: 0, a: 0.5}
|
||||
m_EffectDistance: {x: 1, y: -1}
|
||||
m_UseGraphicAlpha: 1
|
||||
--- !u!222 &22207934
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 107934}
|
||||
--- !u!222 &22207936
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 107936}
|
||||
--- !u!224 &22407932
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 107932}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 22407934}
|
||||
- {fileID: 22407936}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.38700002, y: -0.632}
|
||||
m_AnchorMax: {x: 0.61300004, y: -0.3097744}
|
||||
m_AnchoredPosition: {x: 0.020004272, y: 0.5}
|
||||
m_SizeDelta: {x: 0, y: -2}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!224 &22407934
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 107934}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 22407932}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!224 &22407936
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 107936}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 22407932}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 107932}
|
||||
m_IsPrefabParent: 1
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef9d112c3d8fccd4a8acad4338a5a979
|
||||
NativeFormatImporter:
|
||||
userData:
|
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ab16386025073b43a58bcfae036909d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
@ -0,0 +1,207 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using frame8.Logic.Misc.Other.Extensions;
|
||||
using Com.ForbiddenByte.OSA.CustomAdapters.GridView;
|
||||
using Com.ForbiddenByte.OSA.DataHelpers;
|
||||
|
||||
// You should modify the namespace to your own or - if you're sure there won't ever be conflicts - remove it altogether
|
||||
namespace Your.Namespace.Here.Grids
|
||||
{
|
||||
// There is 1 important callback you need to implement, apart from Start(): UpdateCellViewsHolder()
|
||||
// See explanations below
|
||||
public class BasicGridAdapter : GridAdapter<GridParams, MyGridItemViewsHolder>
|
||||
{
|
||||
// Helper that stores data and notifies the adapter when items count changes
|
||||
// Can be iterated and can also have its elements accessed by the [] operator
|
||||
public SimpleDataHelper<MyGridItemModel> Data { get; private set; }
|
||||
|
||||
|
||||
#region GridAdapter implementation
|
||||
protected override void Start()
|
||||
{
|
||||
Data = new SimpleDataHelper<MyGridItemModel>(this);
|
||||
|
||||
// Calling this initializes internal data and prepares the adapter to handle item count changes
|
||||
base.Start();
|
||||
|
||||
// Retrieve the models from your data source and set the items count
|
||||
/*
|
||||
RetrieveDataAndUpdate(1500);
|
||||
*/
|
||||
}
|
||||
|
||||
// This is called anytime a previously invisible item become visible, or after it's created,
|
||||
// or when anything that requires a refresh happens
|
||||
// Here you bind the data from the model to the item's views
|
||||
// *For the method's full description check the base implementation
|
||||
protected override void UpdateCellViewsHolder(MyGridItemViewsHolder newOrRecycled)
|
||||
{
|
||||
// In this callback, "newOrRecycled.ItemIndex" is guaranteed to always reflect the
|
||||
// index of item that should be represented by this views holder. You'll use this index
|
||||
// to retrieve the model from your data set
|
||||
/*
|
||||
MyGridItemModel model = Data[newOrRecycled.ItemIndex];
|
||||
|
||||
newOrRecycled.backgroundImage.color = model.color;
|
||||
newOrRecycled.titleText.text = model.title + " #" + newOrRecycled.ItemIndex;
|
||||
*/
|
||||
}
|
||||
|
||||
// This is the best place to clear an item's views in order to prepare it from being recycled, but this is not always needed,
|
||||
// especially if the views' values are being overwritten anyway. Instead, this can be used to, for example, cancel an image
|
||||
// download request, if it's still in progress when the item goes out of the viewport.
|
||||
// <newItemIndex> will be non-negative if this item will be recycled as opposed to just being disabled
|
||||
// *For the method's full description check the base implementation
|
||||
/*
|
||||
protected override void OnBeforeRecycleOrDisableCellViewsHolder(MyGridItemViewsHolder inRecycleBinOrVisible, int newItemIndex)
|
||||
{
|
||||
base.OnBeforeRecycleOrDisableCellViewsHolder(inRecycleBinOrVisible, newItemIndex);
|
||||
}
|
||||
*/
|
||||
#endregion
|
||||
|
||||
// These are common data manipulation methods
|
||||
// The list containing the models is managed by you. The adapter only manages the items' sizes and the count
|
||||
// The adapter needs to be notified of any change that occurs in the data list.
|
||||
// For GridAdapters, only Refresh and ResetItems work for now
|
||||
#region data manipulation
|
||||
public void AddItemsAt(int index, IList<MyGridItemModel> items)
|
||||
{
|
||||
//Commented: this only works with Lists. ATM, Insert for Grids only works by manually changing the list and calling NotifyListChangedExternally() after
|
||||
//Data.InsertItems(index, items);
|
||||
Data.List.InsertRange(index, items);
|
||||
Data.NotifyListChangedExternally();
|
||||
}
|
||||
|
||||
public void RemoveItemsFrom(int index, int count)
|
||||
{
|
||||
//Commented: this only works with Lists. ATM, Remove for Grids only works by manually changing the list and calling NotifyListChangedExternally() after
|
||||
//Data.RemoveRange(index, count);
|
||||
Data.List.RemoveRange(index, count);
|
||||
Data.NotifyListChangedExternally();
|
||||
}
|
||||
|
||||
public void SetItems(IList<MyGridItemModel> items)
|
||||
{
|
||||
Data.ResetItems(items);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
// Here, we're requesting <count> items from the data source
|
||||
void RetrieveDataAndUpdate(int count)
|
||||
{
|
||||
StartCoroutine(FetchMoreItemsFromDataSourceAndUpdate(count));
|
||||
}
|
||||
|
||||
// Retrieving <count> models from the data source and calling OnDataRetrieved after.
|
||||
// In a real case scenario, you'd query your server, your database or whatever is your data source and call OnDataRetrieved after
|
||||
IEnumerator FetchMoreItemsFromDataSourceAndUpdate(int count)
|
||||
{
|
||||
// Simulating data retrieving delay
|
||||
yield return new WaitForSeconds(.5f);
|
||||
|
||||
var newItems = new MyGridItemModel[count];
|
||||
|
||||
// Retrieve your data here
|
||||
/*
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
var model = new MyGridItemModel()
|
||||
{
|
||||
title = "Random item ",
|
||||
color = new Color(
|
||||
UnityEngine.Random.Range(0f, 1f),
|
||||
UnityEngine.Random.Range(0f, 1f),
|
||||
UnityEngine.Random.Range(0f, 1f),
|
||||
UnityEngine.Random.Range(0f, 1f)
|
||||
)
|
||||
};
|
||||
newItems[i] = model;
|
||||
}
|
||||
*/
|
||||
|
||||
OnDataRetrieved(newItems);
|
||||
}
|
||||
|
||||
void OnDataRetrieved(MyGridItemModel[] newItems)
|
||||
{
|
||||
//Commented: this only works with Lists. ATM, Insert for Grids only works by manually changing the list and calling NotifyListChangedExternally() after
|
||||
// Data.InsertItemsAtEnd(newItems);
|
||||
|
||||
Data.List.AddRange(newItems);
|
||||
Data.NotifyListChangedExternally();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Class containing the data associated with an item
|
||||
public class MyGridItemModel
|
||||
{
|
||||
/*
|
||||
public string title;
|
||||
public Color color;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// This class keeps references to an item's views.
|
||||
// Your views holder should extend BaseItemViewsHolder for ListViews and CellViewsHolder for GridViews
|
||||
// The cell views holder should have a single child (usually named "Views"), which contains the actual
|
||||
// UI elements. A cell's root is never disabled - when a cell is removed, only its "views" GameObject will be disabled
|
||||
public class MyGridItemViewsHolder : CellViewsHolder
|
||||
{
|
||||
/*
|
||||
public Text titleText;
|
||||
public Image backgroundImage;
|
||||
*/
|
||||
|
||||
|
||||
// Retrieving the views from the item's root GameObject
|
||||
public override void CollectViews()
|
||||
{
|
||||
base.CollectViews();
|
||||
|
||||
// GetComponentAtPath is a handy extension method from frame8.Logic.Misc.Other.Extensions
|
||||
// which infers the variable's component from its type, so you won't need to specify it yourself
|
||||
/*
|
||||
views.GetComponentAtPath("TitleText", out titleText);
|
||||
views.GetComponentAtPath("BackgroundImage", out backgroundImage);
|
||||
*/
|
||||
}
|
||||
|
||||
// This is usually the only child of the item's root and it's called "Views".
|
||||
// That's what the default implementation will look for, but just for flexibility,
|
||||
// this callback is provided, in case it's named differently or there's more than 1 child
|
||||
// *See GridExample.cs for more info
|
||||
/*
|
||||
protected override RectTransform GetViews()
|
||||
{ return root.Find("Views").transform as RectTransform; }
|
||||
*/
|
||||
|
||||
// Override this if you have children layout groups. They need to be marked for rebuild when this callback is fired
|
||||
/*
|
||||
public override void MarkForRebuild()
|
||||
{
|
||||
base.MarkForRebuild();
|
||||
|
||||
LayoutRebuilder.MarkLayoutForRebuild(yourChildLayout1);
|
||||
LayoutRebuilder.MarkLayoutForRebuild(yourChildLayout2);
|
||||
AChildSizeFitter.enabled = true;
|
||||
}
|
||||
*/
|
||||
|
||||
// Override this if you've also overridden MarkForRebuild()
|
||||
/*
|
||||
public override void UnmarkForRebuild()
|
||||
{
|
||||
AChildSizeFitter.enabled = false;
|
||||
|
||||
base.UnmarkForRebuild();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b9fd2b610616ca41b27dfa3618201f2
|
||||
timeCreated: 1532019203
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,235 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using frame8.Logic.Misc.Other.Extensions;
|
||||
using Com.ForbiddenByte.OSA.Core;
|
||||
using Com.ForbiddenByte.OSA.CustomParams;
|
||||
using Com.ForbiddenByte.OSA.DataHelpers;
|
||||
|
||||
// You should modify the namespace to your own or - if you're sure there won't ever be conflicts - remove it altogether
|
||||
namespace Your.Namespace.Here.Lists
|
||||
{
|
||||
// There are 2 important callbacks you need to implement, apart from Start(): CreateViewsHolder() and UpdateViewsHolder()
|
||||
// See explanations below
|
||||
public class BasicListAdapter : OSA<BaseParamsWithPrefab, MyListItemViewsHolder>
|
||||
{
|
||||
// Helper that stores data and notifies the adapter when items count changes
|
||||
// Can be iterated and can also have its elements accessed by the [] operator
|
||||
public SimpleDataHelper<MyListItemModel> Data { get; private set; }
|
||||
|
||||
|
||||
#region OSA implementation
|
||||
protected override void Start()
|
||||
{
|
||||
Data = new SimpleDataHelper<MyListItemModel>(this);
|
||||
|
||||
// Calling this initializes internal data and prepares the adapter to handle item count changes
|
||||
base.Start();
|
||||
|
||||
// Retrieve the models from your data source and set the items count
|
||||
/*
|
||||
RetrieveDataAndUpdate(500);
|
||||
*/
|
||||
}
|
||||
|
||||
// This is called initially, as many times as needed to fill the viewport,
|
||||
// and anytime the viewport's size grows, thus allowing more items to be displayed
|
||||
// Here you create the "ViewsHolder" instance whose views will be re-used
|
||||
// *For the method's full description check the base implementation
|
||||
protected override MyListItemViewsHolder CreateViewsHolder(int itemIndex)
|
||||
{
|
||||
var instance = new MyListItemViewsHolder();
|
||||
|
||||
// Using this shortcut spares you from:
|
||||
// - instantiating the prefab yourself
|
||||
// - enabling the instance game object
|
||||
// - setting its index
|
||||
// - calling its CollectViews()
|
||||
instance.Init(_Params.ItemPrefab, _Params.Content, itemIndex);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
// This is called anytime a previously invisible item become visible, or after it's created,
|
||||
// or when anything that requires a refresh happens
|
||||
// Here you bind the data from the model to the item's views
|
||||
// *For the method's full description check the base implementation
|
||||
protected override void UpdateViewsHolder(MyListItemViewsHolder newOrRecycled)
|
||||
{
|
||||
// In this callback, "newOrRecycled.ItemIndex" is guaranteed to always reflect the
|
||||
// index of item that should be represented by this views holder. You'll use this index
|
||||
// to retrieve the model from your data set
|
||||
/*
|
||||
MyListItemModel model = Data[newOrRecycled.ItemIndex];
|
||||
|
||||
newOrRecycled.backgroundImage.color = model.color;
|
||||
newOrRecycled.titleText.text = model.title + " #" + newOrRecycled.ItemIndex;
|
||||
*/
|
||||
}
|
||||
|
||||
// This is the best place to clear an item's views in order to prepare it from being recycled, but this is not always needed,
|
||||
// especially if the views' values are being overwritten anyway. Instead, this can be used to, for example, cancel an image
|
||||
// download request, if it's still in progress when the item goes out of the viewport.
|
||||
// <newItemIndex> will be non-negative if this item will be recycled as opposed to just being disabled
|
||||
// *For the method's full description check the base implementation
|
||||
/*
|
||||
protected override void OnBeforeRecycleOrDisableViewsHolder(MyListItemViewsHolder inRecycleBinOrVisible, int newItemIndex)
|
||||
{
|
||||
base.OnBeforeRecycleOrDisableViewsHolder(inRecycleBinOrVisible, newItemIndex);
|
||||
}
|
||||
*/
|
||||
|
||||
// You only need to care about this if changing the item count by other means than ResetItems,
|
||||
// case in which the existing items will not be re-created, but only their indices will change.
|
||||
// Even if you do this, you may still not need it if your item's views don't depend on the physical position
|
||||
// in the content, but they depend exclusively to the data inside the model (this is the most common scenario).
|
||||
// In this particular case, we want the item's index to be displayed and also to not be stored inside the model,
|
||||
// so we update its title when its index changes. At this point, the Data list is already updated and
|
||||
// shiftedViewsHolder.ItemIndex was correctly shifted so you can use it to retrieve the associated model
|
||||
// Also check the base implementation for complementary info
|
||||
/*
|
||||
protected override void OnItemIndexChangedDueInsertOrRemove(MyListItemViewsHolder shiftedViewsHolder, int oldIndex, bool wasInsert, int removeOrInsertIndex)
|
||||
{
|
||||
base.OnItemIndexChangedDueInsertOrRemove(shiftedViewsHolder, oldIndex, wasInsert, removeOrInsertIndex);
|
||||
|
||||
shiftedViewsHolder.titleText.text = Data[shiftedViewsHolder.ItemIndex].title + " #" + shiftedViewsHolder.ItemIndex;
|
||||
}
|
||||
*/
|
||||
#endregion
|
||||
|
||||
// These are common data manipulation methods
|
||||
// The list containing the models is managed by you. The adapter only manages the items' sizes and the count
|
||||
// The adapter needs to be notified of any change that occurs in the data list. Methods for each
|
||||
// case are provided: Refresh, ResetItems, InsertItems, RemoveItems
|
||||
#region data manipulation
|
||||
public void AddItemsAt(int index, IList<MyListItemModel> items)
|
||||
{
|
||||
// Commented: the below 2 lines exemplify how you can use a plain list to manage the data, instead of a DataHelper, in case you need full control
|
||||
//YourList.InsertRange(index, items);
|
||||
//InsertItems(index, items.Length);
|
||||
|
||||
Data.InsertItems(index, items);
|
||||
}
|
||||
|
||||
public void RemoveItemsFrom(int index, int count)
|
||||
{
|
||||
// Commented: the below 2 lines exemplify how you can use a plain list to manage the data, instead of a DataHelper, in case you need full control
|
||||
//YourList.RemoveRange(index, count);
|
||||
//RemoveItems(index, count);
|
||||
|
||||
Data.RemoveItems(index, count);
|
||||
}
|
||||
|
||||
public void SetItems(IList<MyListItemModel> items)
|
||||
{
|
||||
// Commented: the below 3 lines exemplify how you can use a plain list to manage the data, instead of a DataHelper, in case you need full control
|
||||
//YourList.Clear();
|
||||
//YourList.AddRange(items);
|
||||
//ResetItems(YourList.Count);
|
||||
|
||||
Data.ResetItems(items);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
// Here, we're requesting <count> items from the data source
|
||||
void RetrieveDataAndUpdate(int count)
|
||||
{
|
||||
StartCoroutine(FetchMoreItemsFromDataSourceAndUpdate(count));
|
||||
}
|
||||
|
||||
// Retrieving <count> models from the data source and calling OnDataRetrieved after.
|
||||
// In a real case scenario, you'd query your server, your database or whatever is your data source and call OnDataRetrieved after
|
||||
IEnumerator FetchMoreItemsFromDataSourceAndUpdate(int count)
|
||||
{
|
||||
// Simulating data retrieving delay
|
||||
yield return new WaitForSeconds(.5f);
|
||||
|
||||
var newItems = new MyListItemModel[count];
|
||||
|
||||
// Retrieve your data here
|
||||
/*
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
var model = new MyListItemModel()
|
||||
{
|
||||
title = "Random item ",
|
||||
color = new Color(
|
||||
UnityEngine.Random.Range(0f, 1f),
|
||||
UnityEngine.Random.Range(0f, 1f),
|
||||
UnityEngine.Random.Range(0f, 1f),
|
||||
UnityEngine.Random.Range(0f, 1f)
|
||||
)
|
||||
};
|
||||
newItems[i] = model;
|
||||
}
|
||||
*/
|
||||
|
||||
OnDataRetrieved(newItems);
|
||||
}
|
||||
|
||||
void OnDataRetrieved(MyListItemModel[] newItems)
|
||||
{
|
||||
Data.InsertItemsAtEnd(newItems);
|
||||
}
|
||||
}
|
||||
|
||||
// Class containing the data associated with an item
|
||||
public class MyListItemModel
|
||||
{
|
||||
/*
|
||||
public string title;
|
||||
public Color color;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// This class keeps references to an item's views.
|
||||
// Your views holder should extend BaseItemViewsHolder for ListViews and CellViewsHolder for GridViews
|
||||
public class MyListItemViewsHolder : BaseItemViewsHolder
|
||||
{
|
||||
/*
|
||||
public Text titleText;
|
||||
public Image backgroundImage;
|
||||
*/
|
||||
|
||||
|
||||
// Retrieving the views from the item's root GameObject
|
||||
public override void CollectViews()
|
||||
{
|
||||
base.CollectViews();
|
||||
|
||||
// GetComponentAtPath is a handy extension method from frame8.Logic.Misc.Other.Extensions
|
||||
// which infers the variable's component from its type, so you won't need to specify it yourself
|
||||
/*
|
||||
root.GetComponentAtPath("TitleText", out titleText);
|
||||
root.GetComponentAtPath("BackgroundImage", out backgroundImage);
|
||||
*/
|
||||
}
|
||||
|
||||
// Override this if you have children layout groups or a ContentSizeFitter on root that you'll use.
|
||||
// They need to be marked for rebuild when this callback is fired
|
||||
/*
|
||||
public override void MarkForRebuild()
|
||||
{
|
||||
base.MarkForRebuild();
|
||||
|
||||
LayoutRebuilder.MarkLayoutForRebuild(yourChildLayout1);
|
||||
LayoutRebuilder.MarkLayoutForRebuild(yourChildLayout2);
|
||||
YourSizeFitterOnRoot.enabled = true;
|
||||
}
|
||||
*/
|
||||
|
||||
// Override this if you've also overridden MarkForRebuild() and you have enabled size fitters there (like a ContentSizeFitter)
|
||||
/*
|
||||
public override void UnmarkForRebuild()
|
||||
{
|
||||
YourSizeFitterOnRoot.enabled = false;
|
||||
|
||||
base.UnmarkForRebuild();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a44004e7fcd6994087020b2b5a1340b
|
||||
timeCreated: 1532019203
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 512afcf64a8e1ac4fa94859bac18bf35
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* * * * This bare-bones script was auto-generated * * * *
|
||||
* The code commented with "/ * * /" demonstrates how data is retrieved and passed to the adapter, plus other common commands. You can remove/replace it once you've got the idea
|
||||
* Complete it according to your specific use-case
|
||||
* Consult the Example scripts if you get stuck, as they provide solutions to most common scenarios
|
||||
*
|
||||
* Main terms to understand:
|
||||
* Model = class that contains the data associated with an item (title, content, icon etc.)
|
||||
* Views Holder = class that contains references to your views (Text, Image, MonoBehavior, etc.)
|
||||
*
|
||||
* Default expected UI hiererchy:
|
||||
* ...
|
||||
* -Canvas
|
||||
* ...
|
||||
* -MyScrollViewAdapter
|
||||
* -Viewport
|
||||
* -Content
|
||||
* -Scrollbar (Optional)
|
||||
* -ItemPrefab (Optional)
|
||||
*
|
||||
* Note: If using Visual Studio and opening generated scripts for the first time, sometimes Intellisense (autocompletion)
|
||||
* won't work. This is a well-known bug and the solution is here: https://developercommunity.visualstudio.com/content/problem/130597/unity-intellisense-not-working-after-creating-new-1.html (or google "unity intellisense not working new script")
|
||||
*
|
||||
*
|
||||
* Please read the manual under "/Docs", as it contains everything you need to know in order to get started, including FAQ
|
||||
*/
|
||||
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 075637a35aaed5d47b2bba6de7f13727
|
||||
TextScriptImporter:
|
||||
userData:
|
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5de91300a8c31b447afe548747ab2559
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
@ -0,0 +1,260 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &162318
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22462318}
|
||||
- component: {fileID: 22262316}
|
||||
- component: {fileID: 11462318}
|
||||
m_Layer: 0
|
||||
m_Name: Handle
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &162320
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22462320}
|
||||
- component: {fileID: 22262318}
|
||||
- component: {fileID: 11462320}
|
||||
- component: {fileID: 11462322}
|
||||
- component: {fileID: 11462324}
|
||||
m_Layer: 0
|
||||
m_Name: HorizontalScrollbar
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &162322
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22462322}
|
||||
m_Layer: 0
|
||||
m_Name: Sliding Area
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &11462318
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 162318}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 0.6666667}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!114 &11462320
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 162320}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.20784314, g: 0.20784314, b: 0.20784314, a: 0.6666667}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!114 &11462322
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 162320}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -2061169968, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 11462318}
|
||||
m_HandleRect: {fileID: 22462318}
|
||||
m_Direction: 0
|
||||
m_Value: 0
|
||||
m_Size: 1
|
||||
m_NumberOfSteps: 0
|
||||
m_OnValueChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.Scrollbar+ScrollEvent, UnityEngine.UI, Version=1.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
--- !u!114 &11462324
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 162320}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 44e790c2efca8bf4bad58426460858d9, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
hideWhenNotNeeded: 1
|
||||
autoHide: 1
|
||||
autoHideFadeEffect: 1
|
||||
autoHideCollapseEffect: 1
|
||||
autoHideTime: 1
|
||||
autoHideFadeEffectMinAlpha: 0.8
|
||||
autoHideCollapseEffectMinScale: 0.2
|
||||
minSize: 0.1
|
||||
sizeUpdateInterval: 0.015
|
||||
skippedFramesBetweenPositionChanges: 0
|
||||
scrollRect: {fileID: 0}
|
||||
viewport: {fileID: 0}
|
||||
OnScrollbarSizeChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
--- !u!222 &22262316
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 162318}
|
||||
--- !u!222 &22262318
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 162320}
|
||||
--- !u!224 &22462318
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 162318}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 22462322}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!224 &22462320
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 162320}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 22462322}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 0}
|
||||
m_AnchoredPosition: {x: -0.000064135, y: -8}
|
||||
m_SizeDelta: {x: -0.000091553, y: 27}
|
||||
m_Pivot: {x: 0.5, y: 1}
|
||||
--- !u!224 &22462322
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 162322}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 22462318}
|
||||
m_Father: {fileID: 22462320}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 162320}
|
||||
m_IsPrefabParent: 1
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d85e94d622847e448adf52587789df2
|
||||
NativeFormatImporter:
|
||||
userData:
|
@ -0,0 +1,260 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &120364
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22420364}
|
||||
m_Layer: 0
|
||||
m_Name: Sliding Area
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &120366
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22420366}
|
||||
- component: {fileID: 22220366}
|
||||
- component: {fileID: 11420362}
|
||||
m_Layer: 0
|
||||
m_Name: Handle
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!1 &120368
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 22420368}
|
||||
- component: {fileID: 22220368}
|
||||
- component: {fileID: 11420366}
|
||||
- component: {fileID: 11420364}
|
||||
- component: {fileID: 11420368}
|
||||
m_Layer: 0
|
||||
m_Name: VerticalScrollbar
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &11420362
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 120366}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 0.6666667}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!114 &11420364
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 120368}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -2061169968, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 11420362}
|
||||
m_HandleRect: {fileID: 22420366}
|
||||
m_Direction: 2
|
||||
m_Value: 0
|
||||
m_Size: 1
|
||||
m_NumberOfSteps: 0
|
||||
m_OnValueChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.Scrollbar+ScrollEvent, UnityEngine.UI, Version=1.0.0.0,
|
||||
Culture=neutral, PublicKeyToken=null
|
||||
--- !u!114 &11420366
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 120368}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.20784314, g: 0.20784314, b: 0.20784314, a: 0.6666667}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
|
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
--- !u!114 &11420368
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 120368}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 44e790c2efca8bf4bad58426460858d9, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
hideWhenNotNeeded: 1
|
||||
autoHide: 1
|
||||
autoHideFadeEffect: 1
|
||||
autoHideCollapseEffect: 1
|
||||
autoHideTime: 1
|
||||
autoHideFadeEffectMinAlpha: 0.8
|
||||
autoHideCollapseEffectMinScale: 0.2
|
||||
minSize: 0.1
|
||||
sizeUpdateInterval: 0.015
|
||||
skippedFramesBetweenPositionChanges: 0
|
||||
scrollRect: {fileID: 0}
|
||||
viewport: {fileID: 0}
|
||||
OnScrollbarSizeChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_TypeName: UnityEngine.Events.UnityEvent, UnityEngine, Version=0.0.0.0, Culture=neutral,
|
||||
PublicKeyToken=null
|
||||
--- !u!222 &22220366
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 120366}
|
||||
--- !u!222 &22220368
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 120368}
|
||||
--- !u!224 &22420364
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 120364}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 22420366}
|
||||
m_Father: {fileID: 22420368}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!224 &22420366
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 120366}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 22420364}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!224 &22420368
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 120368}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 22420364}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 8, y: 0}
|
||||
m_SizeDelta: {x: 27, y: 0}
|
||||
m_Pivot: {x: 0.000000044703484, y: 0.5}
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 120368}
|
||||
m_IsPrefabParent: 1
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee2574d0ef4f55544acf5a78b1718fe8
|
||||
NativeFormatImporter:
|
||||
userData:
|
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff4a37c1de424a6438ff8917bc93f29c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eacaec4748b083e4d8e0a918ba2e14a0
|
||||
folderAsset: yes
|
||||
timeCreated: 1606650806
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,36 @@
|
||||
using UnityEditor;
|
||||
using Com.ForbiddenByte.OSA.AdditionalComponents;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Editor.Util
|
||||
{
|
||||
[CustomEditor(typeof(OSAProactiveNavigator), true)]
|
||||
public class OSAProactiveNavigatorCustomEditor : UnityEditor.Editor
|
||||
{
|
||||
SerializedProperty _Selectables;
|
||||
SerializedProperty _OnNoSelectableSpecified;
|
||||
SerializedProperty _JoystickInputMultiplier;
|
||||
SerializedProperty _ArrowsInputMultiplier;
|
||||
SerializedProperty _LoopAtExtremity;
|
||||
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
_Selectables = serializedObject.FindProperty("_Selectables");
|
||||
_OnNoSelectableSpecified = serializedObject.FindProperty("_OnNoSelectableSpecified");
|
||||
_JoystickInputMultiplier = serializedObject.FindProperty("_JoystickInputMultiplier");
|
||||
_ArrowsInputMultiplier = serializedObject.FindProperty("_ArrowsInputMultiplier");
|
||||
_LoopAtExtremity = serializedObject.FindProperty("_LoopAtExtremity");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
EditorGUILayout.PropertyField(_Selectables, true);
|
||||
EditorGUILayout.PropertyField(_OnNoSelectableSpecified);
|
||||
EditorGUILayout.PropertyField(_JoystickInputMultiplier);
|
||||
EditorGUILayout.PropertyField(_ArrowsInputMultiplier);
|
||||
EditorGUILayout.PropertyField(_LoopAtExtremity);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f111eb5a081457499a1e08ccfc3b03a
|
||||
timeCreated: 1606650839
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,41 @@
|
||||
using frame8.Logic.Misc.Other.Extensions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Editor
|
||||
{
|
||||
public static class CEditor
|
||||
{
|
||||
public static List<GameObject> GetSceneRootGameObjects()
|
||||
{
|
||||
List<GameObject> results = new List<GameObject>();
|
||||
// // Introduced in 5.3.2 : https://unity3d.com/unity/whats-new/unity-5.3.2
|
||||
//#if UNITY_5_3_2 || UNITY_5_3_3 || UNITY_5_3_4 || UNITY_5_3_5 || UNITY_5_3_6 || UNITY_5_4_OR_NEWER
|
||||
UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects(results);
|
||||
//#else
|
||||
// var prop = new HierarchyProperty(HierarchyType.GameObjects);
|
||||
// var expanded = new int[0];
|
||||
// while (prop.Next(expanded))
|
||||
// results.Add(prop.pptrValue as GameObject);
|
||||
//#endif
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<GameObject> GetAllGameObjectsInScene()
|
||||
{
|
||||
var rootGOs = GetSceneRootGameObjects();
|
||||
|
||||
var allGOS = new List<GameObject>();
|
||||
foreach (var rootGO in rootGOs)
|
||||
foreach (var tr in rootGO.transform.GetDescendants())
|
||||
allGOS.Add(tr.gameObject);
|
||||
|
||||
|
||||
return allGOS;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ab805d28a64d72145aa5977828836efd
|
||||
timeCreated: 1529878889
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEditor;
|
||||
using Com.ForbiddenByte.OSA.Core;
|
||||
using Com.ForbiddenByte.OSA.Editor.OSAWizard;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Editor
|
||||
{
|
||||
static class MenuItems
|
||||
{
|
||||
[MenuItem("Tools/Com.ForbiddenByte/OSA/Code reference")]
|
||||
public static void OpenOnlineCodeReference()
|
||||
{ Application.OpenURL("http://forbiddenbyte.com/unityassetstore/optimizedscrollviewadapter/doc"); }
|
||||
|
||||
[MenuItem("Tools/Com.ForbiddenByte/OSA/Manual and FAQ")]
|
||||
public static void OpenOnlineManual()
|
||||
{ Application.OpenURL("https://docs.google.com/document/d/1tlMIzRX1OFEusVAoHm14_wloXukOt9llohCQzmnNbts"); }
|
||||
|
||||
[MenuItem("Tools/Com.ForbiddenByte/OSA/OSA wizard video")]
|
||||
public static void OpenWizardVideo()
|
||||
{ Application.OpenURL("https://youtu.be/BnA32GV13ws"); }
|
||||
|
||||
[MenuItem("Tools/Com.ForbiddenByte/OSA/Changelog")]
|
||||
public static void OpenOnlineChangelog()
|
||||
{ Application.OpenURL("http://forbiddenbyte.com/unityassetstore/optimizedscrollviewadapter/Changelog.txt"); }
|
||||
|
||||
[MenuItem("Tools/Com.ForbiddenByte/OSA/Ask something (discord)")]
|
||||
public static void AskQuestionDiscord()
|
||||
{ Application.OpenURL("https://discord.gg/qjwjBYy"); }
|
||||
|
||||
[MenuItem("Tools/Com.ForbiddenByte/OSA/Ask something (forum)")]
|
||||
public static void AskQuestionForum()
|
||||
{ Application.OpenURL("https://forum.unity.com/threads/30-off-optimized-scrollview-adapter-listview-gridview.395224"); }
|
||||
|
||||
[MenuItem("Tools/Com.ForbiddenByte/OSA/About")]
|
||||
public static void OpenAbout()
|
||||
{
|
||||
EditorUtility.DisplayDialog(
|
||||
"OSA " + OSAConst.OSA_VERSION_STRING,
|
||||
"May the fruits of our hard work enhance your creative journey!" +
|
||||
"\r\n\r\nOptimized ScrollView Adapter by Forbidden Byte" +
|
||||
"\r\nyum@forbiddenbyte.com",
|
||||
"Close"
|
||||
);
|
||||
}
|
||||
|
||||
[MenuItem("CONTEXT/ScrollRect/Optimize with OSA")]
|
||||
static void OptimizeSelectedScrollRectWithOSA(MenuCommand command)
|
||||
{
|
||||
ScrollRect scrollRect = (ScrollRect)command.context;
|
||||
var validationResult = InitOSAWindow.Validate(true, scrollRect, false);
|
||||
// Manually checking for validation, as this provides richer info about the case when initialization is not possible
|
||||
if (!validationResult.isValid)
|
||||
{
|
||||
CWiz.ShowCouldNotExecuteCommandNotification(null);
|
||||
Debug.Log("OSA: Could not optimize '" + scrollRect.name + "': " + validationResult.reasonIfNotValid);
|
||||
return;
|
||||
}
|
||||
|
||||
InitOSAWindow.Open(InitOSAWindow.Parameters.Create(validationResult, false, true, true, false));
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/UI/Optimized ScrollView (OSA)", false, 10)]
|
||||
static void CreateOSA(MenuCommand menuCommand)
|
||||
{
|
||||
if (!CheckForCreateOSAViaWizard())
|
||||
return;
|
||||
|
||||
CreateOSAWindow.Open(new CreateOSAWindow.Parameters());
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/UI/Optimized TableView (OSA)", false, 11)]
|
||||
static void CreateTableViewOSA(MenuCommand menuCommand)
|
||||
{
|
||||
if (CWiz.GetTypeFromAllAssemblies(CWiz.TV.TABLE_ADAPTER_INTERFACE_FULL_NAME) == null)
|
||||
{
|
||||
CWiz.ShowCouldNotExecuteCommandNotification(null);
|
||||
Debug.Log("OSA: Import the TableView.unitypackage first");
|
||||
return;
|
||||
}
|
||||
#if OSA_TV_TMPRO
|
||||
if (Resources.Load<GameObject>(CWiz.TV.Paths.INPUT__FLOATING_DROPDOWN) == null)
|
||||
{
|
||||
CWiz.ShowCouldNotExecuteCommandNotification(null);
|
||||
Debug.Log("OSA: Found 'OSA_TV_TMPRO' scripting define, but package 'TMPro/TableViewTMProSupport.unitypackage' wasn't imported. Please import the package");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!CheckForCreateOSAViaWizard())
|
||||
return;
|
||||
|
||||
var resPath = CWiz.TV.Paths.SCROLL_VIEW;
|
||||
var tvPrefab = Resources.Load<GameObject>(resPath);
|
||||
var go = UnityEngine.Object.Instantiate(tvPrefab);
|
||||
go.name = go.name.Replace("(Clone)", "");
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
// Register the creation in the undo system
|
||||
Undo.RegisterCreatedObjectUndo(go, "Create " + go.name);
|
||||
Selection.activeObject = go;
|
||||
GameObjectUtility.SetParentAndAlign(go, menuCommand.context as GameObject);
|
||||
|
||||
// Adding this just so the validation will pass, but we don't need it
|
||||
var scrollRect = go.AddComponent<ScrollRect>();
|
||||
scrollRect.horizontal = false;
|
||||
scrollRect.vertical = true;
|
||||
scrollRect.viewport = go.transform.Find("Viewport") as RectTransform;
|
||||
scrollRect.content = scrollRect.viewport.Find("Content") as RectTransform;
|
||||
|
||||
var validationResult = InitOSAWindow.Validate(true, scrollRect, true);
|
||||
// Manually checking for validation, as this provides richer info about the case when initialization is not possible
|
||||
if (!validationResult.isValid)
|
||||
{
|
||||
CWiz.ShowCouldNotExecuteCommandNotification(null);
|
||||
Debug.Log("OSA: Could not configure instantiated TableView '" + scrollRect.name + "': " + validationResult.reasonIfNotValid);
|
||||
return;
|
||||
}
|
||||
|
||||
InitOSAWindow.Parameters p = InitOSAWindow.Parameters.Create(
|
||||
validationResult,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
CWiz.TV.IMPLEMENTATION_TEMPLATE_NAME,
|
||||
CWiz.GetTypeFromAllAssemblies(CWiz.TV.TABLE_ADAPTER_INTERFACE_FULL_NAME)
|
||||
);
|
||||
InitOSAWindow.Open(p);
|
||||
}
|
||||
|
||||
static bool CheckForCreateOSAViaWizard()
|
||||
{
|
||||
string reasonIfNotValid;
|
||||
// Manually checking for validation, as this provides richer info about the case when creation is not possible
|
||||
if (!CreateOSAWindow.Validate(true, out reasonIfNotValid))
|
||||
{
|
||||
CWiz.ShowCouldNotExecuteCommandNotification(null);
|
||||
Debug.Log("OSA: Could not create ScrollView on the selected object: " + reasonIfNotValid);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e27ab58c909df14dbf4a9f21dd2d3a7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "OSA.Core.Editor",
|
||||
"references": [
|
||||
"OSA.Core"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": []
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ba77581478a56c45af946447abe2bba
|
||||
timeCreated: 1552496779
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,21 @@
|
||||
using Com.ForbiddenByte.OSA.Editor.Util;
|
||||
using System.IO;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Editor
|
||||
{
|
||||
public class OSAEditorConst
|
||||
{
|
||||
/// <summary>The path of the OSA folder relative to Unity's project folder</summary>
|
||||
public static string OSA_PATH_IN_PROJECT
|
||||
{
|
||||
get
|
||||
{
|
||||
// Expecting the tracker asset to be under '[OSA dir]/Core/Editor/', so we get the parent of the parent folder of that to return the OSA's folder.
|
||||
var dir = PluginPathTracker.DirectoryPathInAssets;
|
||||
dir = Path.GetDirectoryName(dir);
|
||||
dir = Path.GetDirectoryName(dir);
|
||||
return dir.Replace("\\", "/");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa28cc9dcc46e4b45b21313db0d704a8
|
||||
timeCreated: 1638551984
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 616bf5076356e6c4d8f91b62d35eac78
|
||||
folderAsset: yes
|
||||
timeCreated: 1563725050
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,417 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEditor;
|
||||
using frame8.Logic.Misc.Visual.UI.MonoBehaviours;
|
||||
using Com.ForbiddenByte.OSA.Core;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Editor.OSAWizard
|
||||
{
|
||||
public abstract class BaseOSAWindow<TWindowParams> : EditorWindow where TWindowParams : BaseWindowParams
|
||||
{
|
||||
[SerializeField]
|
||||
protected TWindowParams _WindowParams = null;
|
||||
|
||||
[NonSerialized]
|
||||
protected int _CurrentFrameInSlowUpdateCycle;
|
||||
[NonSerialized]
|
||||
protected GUIStyle _RootGUIStyle, _BoxGUIStyle;
|
||||
[NonSerialized]
|
||||
bool _GUIResourcesInitialized;
|
||||
[NonSerialized]
|
||||
Texture2D _Icon;
|
||||
[NonSerialized]
|
||||
Texture2D _TopToBottomGradient;
|
||||
|
||||
string EDITORONLY_TEXTURES_PATH { get { return OSAEditorConst.OSA_PATH_IN_PROJECT + "/Core/Editor/Textures"; } }
|
||||
|
||||
Color _MainColor = new Color(219 / 255f, 195 / 255f, 166 / 255f, .2f);
|
||||
|
||||
|
||||
protected virtual string CompilingScriptsText { get { return "Compiling scripts..."; } }
|
||||
|
||||
|
||||
protected static bool BaseValidate(out string reasonIfNotValid)
|
||||
{
|
||||
if (EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
reasonIfNotValid = "OSA wizard closed: Cannot be used in play mode";
|
||||
return false;
|
||||
}
|
||||
|
||||
reasonIfNotValid = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#region Unity methods
|
||||
protected void OnEnable()
|
||||
{
|
||||
if (_WindowParams != null) // most probably, after a script re-compilation
|
||||
InitWithExistingParams();
|
||||
}
|
||||
|
||||
protected void OnDisable()
|
||||
{
|
||||
ReleaseOnGUIResources();
|
||||
}
|
||||
|
||||
protected void Update()
|
||||
{
|
||||
if (EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
// Not allowed in play mode
|
||||
CWiz.ShowNotification("Cannot use OSA wizard during play mode", false, false);
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateImplWithoutChecks();
|
||||
|
||||
// Wait for scripts recompilation
|
||||
if (EditorApplication.isCompiling)
|
||||
return;
|
||||
|
||||
// It's ok to delay the starting of updates until the gui resources are initialized, in order to have averything prepared
|
||||
if (_GUIResourcesInitialized)
|
||||
UpdateImpl();
|
||||
|
||||
// SlowUpdate calling
|
||||
if (_CurrentFrameInSlowUpdateCycle % CWiz.SLOW_UPDATE_SKIPPED_FRAMES == 0)
|
||||
{
|
||||
_CurrentFrameInSlowUpdateCycle = 0;
|
||||
SlowUpdate();
|
||||
}
|
||||
else
|
||||
++_CurrentFrameInSlowUpdateCycle;
|
||||
}
|
||||
|
||||
protected void OnGUI()
|
||||
{
|
||||
if (!_GUIResourcesInitialized)
|
||||
{
|
||||
InitOnGUIResources();
|
||||
_GUIResourcesInitialized = true;
|
||||
}
|
||||
|
||||
var prevColor = GUI.color;
|
||||
GUI.color = _MainColor;
|
||||
var r = position;
|
||||
r.position = Vector2.zero;
|
||||
GUI.DrawTexture(r, EditorGUIUtility.whiteTexture);
|
||||
GUI.color = prevColor;
|
||||
|
||||
DrawIcon();
|
||||
|
||||
// Wait for scripts recompilation
|
||||
if (EditorApplication.isCompiling)
|
||||
{
|
||||
var style = new GUIStyle();
|
||||
style.alignment = TextAnchor.MiddleCenter;
|
||||
style.normal = new GUIStyleState();
|
||||
style.normal.textColor = Color.gray;
|
||||
EditorGUILayout.LabelField(CompilingScriptsText, style, GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true));
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginVertical(_RootGUIStyle);
|
||||
{
|
||||
OnGUIImpl();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected virtual void InitWithNewParams(TWindowParams windowParams)
|
||||
{
|
||||
//title = GetType().Name.Replace("OSAWindow", " OSA");
|
||||
string titleString = "OSA Wizard";
|
||||
#if UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4_OR_NEWER
|
||||
titleContent = new GUIContent(titleString);
|
||||
#else
|
||||
title = titleString;
|
||||
#endif
|
||||
minSize = windowParams.MinSize;
|
||||
_WindowParams = windowParams;
|
||||
}
|
||||
|
||||
protected virtual void InitWithExistingParams()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void InitOnGUIResources()
|
||||
{
|
||||
_Icon = AssetDatabase.LoadAssetAtPath(EDITORONLY_TEXTURES_PATH + "/osa-icon.png", typeof(Texture2D)) as Texture2D;
|
||||
_TopToBottomGradient = AssetDatabase.LoadAssetAtPath(EDITORONLY_TEXTURES_PATH + "/gradient.png", typeof(Texture2D)) as Texture2D;
|
||||
|
||||
_RootGUIStyle = new GUIStyle();
|
||||
_RootGUIStyle.padding = new RectOffset(20, 20, 15, 25);
|
||||
_RootGUIStyle.alignment = TextAnchor.UpperCenter;
|
||||
|
||||
_BoxGUIStyle = new GUIStyle(EditorStyles.textArea);
|
||||
_BoxGUIStyle.normal = new GUIStyleState();
|
||||
_BoxGUIStyle.normal.background = _TopToBottomGradient;
|
||||
_BoxGUIStyle.padding = new RectOffset(5, 5, 5, 5);
|
||||
}
|
||||
|
||||
protected virtual void ReleaseOnGUIResources()
|
||||
{
|
||||
if (_Icon)
|
||||
{
|
||||
Resources.UnloadAsset(_Icon);
|
||||
_Icon = null;
|
||||
}
|
||||
if (_TopToBottomGradient)
|
||||
{
|
||||
Resources.UnloadAsset(_TopToBottomGradient);
|
||||
_TopToBottomGradient = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void UpdateImplWithoutChecks() { }
|
||||
|
||||
protected virtual void UpdateImpl() { }
|
||||
|
||||
protected abstract void OnGUIImpl();
|
||||
|
||||
protected virtual void ConfigureScrollView(ScrollRect scrollRect, RectTransform viewport, params Transform[] objectsToSkipDisabling)
|
||||
{
|
||||
scrollRect.horizontal = _WindowParams.isHorizontal;
|
||||
scrollRect.vertical = !scrollRect.horizontal;
|
||||
scrollRect.verticalScrollbar = scrollRect.horizontalScrollbar = null;
|
||||
|
||||
if (!_WindowParams.checkForMiscComponents)
|
||||
return;
|
||||
|
||||
DisableOrNotifyAboutMiscComponents(scrollRect.gameObject, "ScrollRect", typeof(ScrollRect));
|
||||
foreach (Transform child in scrollRect.transform)
|
||||
{
|
||||
if (child.name == "Viewport")
|
||||
continue;
|
||||
if (child.GetComponent<ScrollbarFixer8>())
|
||||
continue;
|
||||
|
||||
if (child.gameObject.activeSelf)
|
||||
{
|
||||
if (Array.IndexOf(objectsToSkipDisabling, child) != -1)
|
||||
continue;
|
||||
|
||||
string scrollbarFixer = typeof(ScrollbarFixer8).Name;
|
||||
bool isScrollbar = child.name.ToLower().Contains("scrollbar") && child.GetComponent<Scrollbar>();
|
||||
string suffix = !isScrollbar ? "You can activate it back if it doesn't interfere with OSA"
|
||||
:
|
||||
("This appears to be a Scrollbar, but it wasn't added by the OSA wizard. If you want to use it, activate it back " +
|
||||
(child.GetComponent<ScrollbarFixer8>() != null ?
|
||||
(" and make sure its " + scrollbarFixer + " component is properly configured in inspector")
|
||||
: (", add a " + scrollbarFixer + " component and make sure it's properly configured in inspector")
|
||||
)
|
||||
);
|
||||
Debug.Log("OSA: De-activating ScrollRect's unknown child '" + child.name + "'. " + suffix);
|
||||
child.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
DisableOrNotifyAboutMiscComponents(viewport.gameObject, "Viewport", typeof(Mask));
|
||||
foreach (Transform child in viewport.transform)
|
||||
{
|
||||
if (child == scrollRect.content)
|
||||
continue;
|
||||
|
||||
if (child.gameObject.activeSelf)
|
||||
{
|
||||
if (Array.IndexOf(objectsToSkipDisabling, child) != -1)
|
||||
continue;
|
||||
|
||||
Debug.Log("OSA: De-activating Viewport's unknown child '" + child.name + "'. You can activate it back if it doesn't interfere with OSA");
|
||||
child.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
DisableOrNotifyAboutMiscComponents(scrollRect.content.gameObject, "Content");
|
||||
foreach (Transform child in scrollRect.content)
|
||||
{
|
||||
if (child.gameObject.activeSelf)
|
||||
{
|
||||
if (Array.IndexOf(objectsToSkipDisabling, child) != -1)
|
||||
continue;
|
||||
|
||||
Debug.Log("OSA: De-activating Content's unknown child '" + child.name + "'. You can activate it back if it doesn't interfere with OSA");
|
||||
child.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void GetErrorAndWarning(out string error, out string warning);
|
||||
|
||||
protected virtual void OnSubmitClicked()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected void SlowUpdate()
|
||||
{
|
||||
//if (FullyInitialized)
|
||||
Repaint();
|
||||
}
|
||||
|
||||
protected void DrawIcon()
|
||||
{
|
||||
float iconSize = 55f;
|
||||
float padding_icon = 10f;
|
||||
float padding_text = 0f;
|
||||
var r = new Rect();
|
||||
float labelHeight = 15f;
|
||||
r.width = r.height = iconSize;
|
||||
r.position = new Vector2(position.width - iconSize - padding_icon, position.height - iconSize - labelHeight - padding_icon);
|
||||
var prevColor = GUI.color;
|
||||
var newColor = Color.white;
|
||||
newColor.a = .6f;
|
||||
GUI.color = newColor;
|
||||
GUI.DrawTexture(r, _Icon);
|
||||
r.position = new Vector3(r.position.x - padding_text / 2f, r.position.y + r.height + 3f);
|
||||
r.height = labelHeight;
|
||||
var style = new GUIStyle();
|
||||
style.fontSize = 9;
|
||||
style.fontStyle = FontStyle.Bold;
|
||||
style.normal = new GUIStyleState();
|
||||
style.normal.textColor = Color.white;
|
||||
newColor.a = .95f;
|
||||
GUI.color = newColor;
|
||||
GUI.Label(r, "OSA v" + OSAConst.OSA_VERSION_STRING, style);
|
||||
GUI.color = prevColor;
|
||||
}
|
||||
|
||||
protected void DrawSectionTitle(string title)
|
||||
{
|
||||
var titleStyle = new GUIStyle(EditorStyles.label);
|
||||
titleStyle.alignment = TextAnchor.MiddleCenter;
|
||||
titleStyle.fontStyle = FontStyle.Bold;
|
||||
titleStyle.fontSize = 20;
|
||||
EditorGUILayout.LabelField(title, titleStyle, GUILayout.Height(25f));
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
protected void DrawObjectWithPath<T>(GUIStyle style, string title, T objectToDraw) where T : UnityEngine.Object
|
||||
{
|
||||
EditorGUILayout.BeginVertical(style);
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField(title, EditorStyles.boldLabel, CWiz.LABEL_WIDTH);
|
||||
|
||||
if (objectToDraw)
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUILayout.ObjectField(objectToDraw, typeof(T), true, CWiz.VALUE_WIDTH);
|
||||
EditorGUILayout.LabelField("(ReadOnly)");
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (objectToDraw)
|
||||
{
|
||||
string s = "";
|
||||
s = objectToDraw.name;
|
||||
var asGO = objectToDraw as GameObject;
|
||||
var asComponent = objectToDraw as Component;
|
||||
var tr = asGO == null ? asComponent.transform : asGO.transform;
|
||||
while (tr = tr.parent)
|
||||
s = tr.name + "/" + s;
|
||||
s = "Path: " + s;
|
||||
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUILayout.TextArea(s, EditorStyles.label);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
protected void DrawSubmitButon(string title)
|
||||
{
|
||||
Rect buttonCRect = new Rect();
|
||||
buttonCRect.width = 200f;
|
||||
buttonCRect.height = 30f;
|
||||
buttonCRect.x = (position.width - buttonCRect.width) / 2;
|
||||
buttonCRect.y = position.height - buttonCRect.height - _RootGUIStyle.padding.bottom;
|
||||
string error, warning;
|
||||
GetErrorAndWarning(out error, out warning);
|
||||
bool isError = !string.IsNullOrEmpty(error);
|
||||
if (isError)
|
||||
EditorGUILayout.HelpBox(error, MessageType.Error);
|
||||
if (!string.IsNullOrEmpty(warning))
|
||||
EditorGUILayout.HelpBox(warning, MessageType.Warning);
|
||||
EditorGUI.BeginDisabledGroup(isError);
|
||||
{
|
||||
if (GUI.Button(buttonCRect, title))
|
||||
OnSubmitClicked();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
|
||||
protected RectTransform CreateRTAndSetParent(string name, Transform parent)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform));
|
||||
var rt = go.transform as RectTransform;
|
||||
rt.SetParent(parent, false);
|
||||
rt.anchorMin = Vector2.zero;
|
||||
rt.anchorMax = Vector2.one;
|
||||
rt.sizeDelta = Vector2.zero;
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
protected void DisableOrNotifyAboutMiscComponents(GameObject go, string nameToUse, params System.Type[] typesToIgnore)
|
||||
{
|
||||
var components = go.GetComponents<Component>();
|
||||
foreach (var comp in components)
|
||||
{
|
||||
if (comp is Transform)
|
||||
continue;
|
||||
if (comp is CanvasRenderer)
|
||||
continue;
|
||||
if (comp is Image)
|
||||
continue;
|
||||
if (System.Array.Exists(typesToIgnore, t => OSAUtil.DotNETCoreCompat_IsAssignableFrom(t, comp.GetType())))
|
||||
continue;
|
||||
var mb = comp as MonoBehaviour;
|
||||
if (mb)
|
||||
{
|
||||
if (mb.enabled)
|
||||
{
|
||||
Debug.Log("OSA: Disabling unknown component " + mb.GetType().Name + " on " + nameToUse + ". You can enable it back if it doesn't interfere with OSA");
|
||||
mb.enabled = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug.Log("OSA: Found unknown component '" + comp.GetType().Name + "' on " + nameToUse + ". Make sure it doesn't interfere with OSA");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class BaseWindowParams
|
||||
{
|
||||
public bool isHorizontal;
|
||||
public bool checkForMiscComponents;
|
||||
|
||||
public virtual Vector2 MinSize { get { return new Vector2(480f, 300f); } }
|
||||
|
||||
public int Hor0_Vert1 { get { return isHorizontal ? 0 : 1; } }
|
||||
|
||||
|
||||
public virtual void ResetValues()
|
||||
{
|
||||
isHorizontal = false;
|
||||
checkForMiscComponents = true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14ba41aae4d93c24aa91797b057972e1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,245 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using Com.ForbiddenByte.OSA.Core;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Editor.OSAWizard
|
||||
{
|
||||
public static class CWiz
|
||||
{
|
||||
public const string TEMPLATES_RESPATH = OSAConst.OSA_PATH_IN_RESOURCES + "/Templates";
|
||||
public const string HOR_SCROLLBAR_RESPATH = TEMPLATES_RESPATH + "/Scrollbars/HorizontalScrollbar";
|
||||
public const string VERT_SCROLLBAR_RESPATH = TEMPLATES_RESPATH + "/Scrollbars/VerticalScrollbar";
|
||||
public const string TEMPLATE_TEXT_CLASSNAME_PREFIX = "public class ";
|
||||
public const string TEMPLATE_DEFAULT_NAMESPACE = "Your.Namespace.Here";
|
||||
|
||||
public const string TEMPLATE_SCRIPTS_RESPATH = TEMPLATES_RESPATH + "/Scripts";
|
||||
public const string TEMPLATE_SCRIPTS_HEADERCOMMENT_RESPATH = TEMPLATES_RESPATH + "/ScriptsChunks/HeaderComment";
|
||||
public const string TEMPLATE_ITEM_PREFABS_DIR_RESPATH = TEMPLATES_RESPATH + "/ExampleItemPrefabs";
|
||||
public const string TEMPLATE_SCROLLVIEW_PREFABS_DIR_RESPATH = TEMPLATES_RESPATH + "/ScrollViews";
|
||||
#if OSA_PLAYMAKER
|
||||
public const string TEMPLATES_PLAYMAKER_CONTROLLER_PREFABS_RESPATH = TEMPLATES_RESPATH + "/ExampleControllers/Playmaker";
|
||||
public const string TEMPLATES_PLAYMAKER_ITEM_PREFABS_RESPATH = TEMPLATES_RESPATH + "/ExampleItemPrefabs/Playmaker";
|
||||
public const string TEMPLATES_PLAYMAKER_GRID_ITEM_PREFABS_RESPATH = TEMPLATES_PLAYMAKER_ITEM_PREFABS_RESPATH + "/Grid";
|
||||
public const string TEMPLATES_PLAYMAKER_LIST_ITEM_PREFABS_RESPATH = TEMPLATES_PLAYMAKER_ITEM_PREFABS_RESPATH + "/List";
|
||||
#endif
|
||||
public const int SLOW_UPDATE_SKIPPED_FRAMES = 5;
|
||||
public const float SPACE_FOR_SCROLLBAR = 27 + 20;
|
||||
public const float VALUE_WIDTH_FLOAT = 200f;
|
||||
public const float VALUE_WIDTH2_FLOAT = 250f;
|
||||
public static GUILayoutOption LABEL_WIDTH = GUILayout.Width(150f);
|
||||
public static GUILayoutOption VALUE_WIDTH = GUILayout.Width(VALUE_WIDTH_FLOAT);
|
||||
|
||||
|
||||
public static string GetExampleItemPrefabResPath(string templateName)
|
||||
{
|
||||
//templateName = templateName.Replace("Adapter", "");
|
||||
string prefabName = templateName + "Item";
|
||||
return TEMPLATE_ITEM_PREFABS_DIR_RESPATH + "/" + prefabName;
|
||||
}
|
||||
|
||||
public static EditorWindow GetBestEditorWindowToShowNotification(bool allowFocusedWindow = true)
|
||||
{
|
||||
EditorWindow editorWindow = EditorWindow.focusedWindow;
|
||||
if (!editorWindow)
|
||||
{
|
||||
editorWindow = EditorWindow.mouseOverWindow;
|
||||
if (!editorWindow)
|
||||
editorWindow = EditorWindow.GetWindow<SceneView>();
|
||||
}
|
||||
|
||||
return editorWindow;
|
||||
}
|
||||
|
||||
public static void ShowNotification(string msg, bool beep, bool allowFocusedWindow) { ShowNotification(msg, beep, null, allowFocusedWindow); }
|
||||
|
||||
public static void ShowNotification(string msg, bool beep, EditorWindow editorWindow, bool allowFocusedWindow)
|
||||
{
|
||||
if (!editorWindow)
|
||||
editorWindow = GetBestEditorWindowToShowNotification(allowFocusedWindow);
|
||||
|
||||
if (!editorWindow)
|
||||
return;
|
||||
|
||||
try { editorWindow.ShowNotification(new GUIContent(msg)); } catch { }
|
||||
|
||||
if (beep)
|
||||
try { EditorApplication.Beep(); } catch { }
|
||||
}
|
||||
|
||||
public static void ShowCouldNotExecuteCommandNotification(EditorWindow editorWindow) { ShowNotification("Invalid state. Check console for details", true, editorWindow); }
|
||||
|
||||
public static bool IsSubclassOfRawGeneric(Type baseType, Type derivedType)
|
||||
{
|
||||
while (derivedType != null && derivedType != typeof(object))
|
||||
{
|
||||
var currentType = derivedType.IsGenericType ? derivedType.GetGenericTypeDefinition() : derivedType;
|
||||
if (baseType == currentType)
|
||||
return true;
|
||||
|
||||
derivedType = derivedType.BaseType;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsSubclassOfOSA(Type derivedType) { return IsSubclassOfRawGeneric(typeof(OSA<,>), derivedType); }
|
||||
|
||||
public static void ReplaceTemplateDefaultNamespaceWithUnique(ref string template)
|
||||
{
|
||||
//template = template.Replace(TEMPLATE_DEFAULT_NAMESPACE, TEMPLATE_DEFAULT_NAMESPACE + DateTime.Now.ToString("yyMMMddhhmmssfff", CultureInfo.InvariantCulture));
|
||||
template = template.Replace(TEMPLATE_DEFAULT_NAMESPACE, TEMPLATE_DEFAULT_NAMESPACE + ".UniqueStringHereToAvoidNamespaceConflicts");
|
||||
}
|
||||
|
||||
public static class TV
|
||||
{
|
||||
public const string TABLE_ADAPTER_INTERFACE_FULL_NAME = "Com.ForbiddenByte.OSA.CustomAdapters.TableView.ITableAdapter";
|
||||
public const string IMPLEMENTATION_TEMPLATE_NAME = "BasicTableAdapter";
|
||||
public const string IMPLEMENTATION_TEMPLATE_NAME_WITH_EXTENSION = IMPLEMENTATION_TEMPLATE_NAME + ".txt";
|
||||
public const string TABLE_VIEW_NAME = "TableView";
|
||||
public const string DIR_RESPATH = TEMPLATE_SCROLLVIEW_PREFABS_DIR_RESPATH + "/" + TABLE_VIEW_NAME;
|
||||
|
||||
public const string TUPLE_PREFAB_SIMPLE_NAME = "TuplePrefab";
|
||||
public const string TUPLE_VALUE_PREFAB_SIMPLE_NAME = "TupleValuePrefab";
|
||||
public const string COLUMNS_TUPLE_PREFAB_SIMPLE_NAME = "ColumnsTuplePrefab";
|
||||
public const string COLUMNS_TUPLE_VALUE_PREFAB_SIMPLE_NAME = "ColumnsTupleValuePrefab";
|
||||
|
||||
public const string FLOATING_DROPDOWN_SIMPLE_NAME = "TVFloatingDropdown";
|
||||
public const string FLOATING_TEXT_INPUT_CONTROLLER_SIMPLE_NAME = "TVTextInputController";
|
||||
|
||||
#if OSA_TV_TMPRO
|
||||
public static TemplatePaths Paths = new TemplatePaths(DIR_RESPATH, true)
|
||||
{
|
||||
|
||||
};
|
||||
#else
|
||||
public static TemplatePaths Paths = new TemplatePaths(DIR_RESPATH, false)
|
||||
{
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
public class TemplatePaths
|
||||
{
|
||||
public readonly string SCROLL_VIEW;
|
||||
public readonly string IMPLEMENTATION_TEMPLATE_FILE;
|
||||
|
||||
public readonly string TUPLE_PREFAB;
|
||||
public readonly string TUPLE_VALUE_PREFAB;
|
||||
public readonly string COLUMNS_TUPLE_PREFAB;
|
||||
public readonly string COLUMNS_TUPLE_VALUE_PREFAB;
|
||||
|
||||
public readonly string INPUT__FLOATING_DROPDOWN;
|
||||
public readonly string INPUT__FLOATING_TEXT;
|
||||
|
||||
string BASE_PATH;
|
||||
|
||||
|
||||
public TemplatePaths(string basePath, bool isTMPro)
|
||||
{
|
||||
BASE_PATH = basePath;
|
||||
string itemPrefabsSubPathOriginal = "ItemPrefabs";
|
||||
string itemPrefabsSubPath = itemPrefabsSubPathOriginal;
|
||||
string inputPrefabsSubPath = "Input";
|
||||
string prefabsSuffix = "";
|
||||
|
||||
if (isTMPro)
|
||||
{
|
||||
prefabsSuffix = "-TMPro";
|
||||
itemPrefabsSubPath += "/TMPro";
|
||||
inputPrefabsSubPath += "/TMPro";
|
||||
}
|
||||
|
||||
SCROLL_VIEW = BASE_PATH + "/" + TABLE_VIEW_NAME;
|
||||
IMPLEMENTATION_TEMPLATE_FILE = TEMPLATE_SCRIPTS_RESPATH + "/" + IMPLEMENTATION_TEMPLATE_NAME;
|
||||
|
||||
TUPLE_PREFAB = BASE_PATH + "/" + itemPrefabsSubPath + "/" + TUPLE_PREFAB_SIMPLE_NAME + prefabsSuffix;
|
||||
TUPLE_VALUE_PREFAB = BASE_PATH + "/" + itemPrefabsSubPath + "/" + TUPLE_VALUE_PREFAB_SIMPLE_NAME + prefabsSuffix;
|
||||
// COLUMNS_PREFAB is the same for tmpro and non-tmpro setups
|
||||
COLUMNS_TUPLE_PREFAB = BASE_PATH + "/" + itemPrefabsSubPathOriginal + "/" + COLUMNS_TUPLE_PREFAB_SIMPLE_NAME;
|
||||
COLUMNS_TUPLE_VALUE_PREFAB = BASE_PATH + "/" + itemPrefabsSubPath + "/" + COLUMNS_TUPLE_VALUE_PREFAB_SIMPLE_NAME + prefabsSuffix;
|
||||
|
||||
INPUT__FLOATING_DROPDOWN = BASE_PATH + "/" + inputPrefabsSubPath + "/" + FLOATING_DROPDOWN_SIMPLE_NAME + prefabsSuffix;
|
||||
INPUT__FLOATING_TEXT = BASE_PATH + "/" + inputPrefabsSubPath + "/" + FLOATING_TEXT_INPUT_CONTROLLER_SIMPLE_NAME + prefabsSuffix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetAvailableOSAImplementations(List<Type> list, bool excludeExampleImplementations, Type implementedInterface = null, Type withoutImplementedInterface = null)
|
||||
{
|
||||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
foreach (var type in assembly.GetTypes())
|
||||
{
|
||||
if (type.IsAbstract)
|
||||
continue;
|
||||
if (!type.IsClass)
|
||||
continue;
|
||||
if (type.IsGenericType)
|
||||
continue;
|
||||
if (type.IsNested)
|
||||
continue;
|
||||
if (type.IsNotPublic)
|
||||
continue;
|
||||
if (!CWiz.IsSubclassOfOSA(type))
|
||||
continue;
|
||||
if (excludeExampleImplementations
|
||||
&& (
|
||||
type.Name.ToLower().Contains("example")
|
||||
////|| type.Name == typeof(Demos.SimpleExample.SimpleTutorial).Name
|
||||
//|| type.Name == "SimpleExample"
|
||||
//|| type.Name == typeof(CustomAdapters.DateTimePicker.DateTimePickerAdapter).Name
|
||||
|| type.Name == "DateTimePickerAdapter"
|
||||
))
|
||||
continue;
|
||||
|
||||
// Excluding TableView's base classes, which will be used automatically
|
||||
if (type.Name == "BasicHeaderTupleAdapter"
|
||||
|| type.Name == "BasicTupleAdapter")
|
||||
continue;
|
||||
|
||||
if (implementedInterface != null)
|
||||
{
|
||||
if (!OSAUtil.DotNETCoreCompat_IsAssignableFrom(implementedInterface, type))
|
||||
continue;
|
||||
}
|
||||
if (withoutImplementedInterface != null)
|
||||
{
|
||||
if (OSAUtil.DotNETCoreCompat_IsAssignableFrom(withoutImplementedInterface, type))
|
||||
continue;
|
||||
}
|
||||
|
||||
list.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Type GetTypeFromAllAssemblies(string typeFullName)
|
||||
{
|
||||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
var type = assembly.GetType(typeFullName);
|
||||
if (type != null)
|
||||
return type;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool IsInsidePrefabEditingScene()
|
||||
{
|
||||
// Requiring an EventSystem in scenes to make sure the UI is interactive, but allowing prefab-editing scenes to not have one, since these are just temporary scenes
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
// GetCurrentPrefabStage moved out of experimental in 2021.2: https://unity3d.com/unity/whats-new/2021.2.0
|
||||
return UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage() != null;
|
||||
#elif UNITY_2018_3_OR_NEWER
|
||||
// GetCurrentPrefabStage was introduced in 2018.3 as experimental: https://docs.unity3d.com/ScriptReference/Experimental.SceneManagement.PrefabStageUtility.html
|
||||
return UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage() != null;
|
||||
#else
|
||||
return false
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0709b76fd7bc2e4fa323fedb2038dc7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,222 @@
|
||||
#if UNITY_5_2 || UNITY_5_3 || UNITY_5_4_OR_NEWER
|
||||
#define SCROLLRECT_HAS_VIEWPORT
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Editor.OSAWizard
|
||||
{
|
||||
public class CreateOSAWindow : BaseOSAWindow<CreateOSAWindow.Parameters>
|
||||
{
|
||||
public static bool IsOpen() { return Resources.FindObjectsOfTypeAll(typeof(CreateOSAWindow)).Length > 0; }
|
||||
|
||||
public static void Open(Parameters windowParams)
|
||||
{
|
||||
CreateOSAWindow windowInstance = GetWindow<CreateOSAWindow>();
|
||||
windowInstance.InitWithNewParams(windowParams);
|
||||
}
|
||||
|
||||
public static bool Validate(bool forOpeningWindow, out string reasonIfNotValid)
|
||||
{
|
||||
if (!BaseValidate(out reasonIfNotValid))
|
||||
return false;
|
||||
|
||||
if (forOpeningWindow)
|
||||
{
|
||||
// Commented: it's safe to re-open the create window
|
||||
//if (IsOpen())
|
||||
//{
|
||||
// reasonIfNotValid = "Creation window already opened";
|
||||
// return false;
|
||||
//}
|
||||
if (InitOSAWindow.IsOpen())
|
||||
{
|
||||
reasonIfNotValid = "Initialization window already opened";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Selection.gameObjects.Length != 1)
|
||||
{
|
||||
reasonIfNotValid = "One UI Game Object needs to be selected";
|
||||
return false;
|
||||
}
|
||||
|
||||
var asRT = Selection.gameObjects[0].transform as RectTransform;
|
||||
if (!asRT)
|
||||
{
|
||||
reasonIfNotValid = "The selected Game Object doesn't have a RectTransform component";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (asRT.rect.height <= 0f)
|
||||
{
|
||||
reasonIfNotValid = "The selected Game Object has an invalid height";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (asRT.rect.width <= 0f)
|
||||
{
|
||||
reasonIfNotValid = "The selected Game Object has an invalid width";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Requiring an EventSystem in scenes to make sure the UI is interactive, but allowing prefab-editing scenes to not have one, since these are just temporary scenes
|
||||
if (!CWiz.IsInsidePrefabEditingScene() && !GameObject.FindObjectOfType<EventSystem>())
|
||||
{
|
||||
reasonIfNotValid = "No EventSystem was found in the scene. Please add one";
|
||||
return false;
|
||||
}
|
||||
|
||||
reasonIfNotValid = null;
|
||||
var tr = asRT as Transform;
|
||||
while (tr)
|
||||
{
|
||||
if (!(tr is RectTransform))
|
||||
{
|
||||
reasonIfNotValid =
|
||||
"Found a non-RectTransform intermediary parent before first Canvas ancestor. " +
|
||||
"Your hierarchy may be something like: ...Canvas->...->Transform->...-><SelectedObject>. " +
|
||||
"There should only be RectTransforms between the selected object and its most close Canvas ancestor";
|
||||
return false;
|
||||
}
|
||||
|
||||
var c = tr.GetComponent<Canvas>();
|
||||
if (c)
|
||||
return true;
|
||||
|
||||
tr = tr.parent;
|
||||
}
|
||||
|
||||
reasonIfNotValid = "Couldn't find a Canvas in the parents of the selected Game Object";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected override void InitWithNewParams(Parameters windowParams)
|
||||
{
|
||||
base.InitWithNewParams(windowParams);
|
||||
|
||||
_WindowParams.ResetValues();
|
||||
}
|
||||
|
||||
protected override void OnGUIImpl()
|
||||
{
|
||||
DrawSectionTitle("Create ScrollView");
|
||||
|
||||
string titleToSet;
|
||||
UnityEngine.Object obj = null;
|
||||
if (Selection.gameObjects.Length == 0)
|
||||
{
|
||||
titleToSet = "(Select a parent)";
|
||||
}
|
||||
else if (Selection.gameObjects.Length > 1)
|
||||
{
|
||||
titleToSet = "(Select only 1 parent)";
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = Selection.gameObjects[0];
|
||||
titleToSet = "ScrollView's parent";
|
||||
}
|
||||
DrawObjectWithPath(_BoxGUIStyle, titleToSet, obj);
|
||||
|
||||
EditorGUI.BeginDisabledGroup(!obj);
|
||||
{
|
||||
// Orientation
|
||||
EditorGUILayout.BeginVertical(_BoxGUIStyle);
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.LabelField("Orientation:", CWiz.LABEL_WIDTH);
|
||||
_WindowParams.isHorizontal = GUILayout.SelectionGrid(_WindowParams.Hor0_Vert1, new string[] { "Horizontal", "Vertical" }, 2, CWiz.VALUE_WIDTH) == 0 ? true : false;
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// Create button
|
||||
DrawSubmitButon("Create");
|
||||
}
|
||||
|
||||
protected override void GetErrorAndWarning(out string error, out string warning)
|
||||
{
|
||||
warning = null;
|
||||
Validate(false, out error);
|
||||
}
|
||||
|
||||
protected override void OnSubmitClicked()
|
||||
{
|
||||
// Commented: this is already checked and if there's and error, the submit button is disabled
|
||||
//string reasonIfNotValid;
|
||||
//// Validate again, to make sure the hierarchy wasn't modified
|
||||
//if (!Validate(out reasonIfNotValid))
|
||||
//{
|
||||
// DemosUtil.ShowCouldNotExecuteCommandNotification(this);
|
||||
// Debug.Log("OSA: Could not create ScrollView on the selected object: " + reasonIfNotValid);
|
||||
// return;
|
||||
//}
|
||||
var parentGO = Selection.gameObjects[0];
|
||||
GameObject go = new GameObject("OSA", typeof(RectTransform));
|
||||
var image = go.AddComponent<Image>();
|
||||
var c = Color.white;
|
||||
c.a = .13f;
|
||||
image.color = c;
|
||||
var scrollRect = go.AddComponent<ScrollRect>();
|
||||
var scrollRectRT = scrollRect.transform as RectTransform;
|
||||
var parentRT = parentGO.transform as RectTransform;
|
||||
scrollRectRT.anchorMin = new Vector2(Mathf.Clamp01(CWiz.SPACE_FOR_SCROLLBAR / parentRT.rect.width), Mathf.Clamp01(CWiz.SPACE_FOR_SCROLLBAR / parentRT.rect.height));
|
||||
scrollRectRT.anchorMax = Vector2.one - scrollRectRT.anchorMin;
|
||||
scrollRectRT.sizeDelta = Vector2.zero;
|
||||
|
||||
GameObjectUtility.SetParentAndAlign(go, parentGO);
|
||||
var viewportRT = CreateRTAndSetParent("Viewport", go.transform);
|
||||
viewportRT.gameObject.AddComponent<Image>();
|
||||
viewportRT.gameObject.AddComponent<Mask>().showMaskGraphic = false;
|
||||
var contentRT = CreateRTAndSetParent("Content", viewportRT);
|
||||
|
||||
scrollRect.content = contentRT;
|
||||
#if SCROLLRECT_HAS_VIEWPORT
|
||||
scrollRect.viewport = viewportRT;
|
||||
#endif
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
// Register the creation in the undo system
|
||||
Undo.RegisterCreatedObjectUndo(go, "Create " + go.name);
|
||||
Selection.activeObject = go;
|
||||
|
||||
ConfigureScrollView(scrollRect, viewportRT);
|
||||
Close();
|
||||
|
||||
var validationResult = InitOSAWindow.Validate(false, scrollRect, false); // checkForWindows=false, becase this windows is already opened
|
||||
if (!validationResult.isValid)
|
||||
{
|
||||
CWiz.ShowCouldNotExecuteCommandNotification(this);
|
||||
Debug.LogError("OSA: Unexpected internal error while trying to initialize. Details(next line):\n" + validationResult.reasonIfNotValid + "\n" + validationResult.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
InitOSAWindow.Open(InitOSAWindow.Parameters.Create(validationResult, false, true, true, true));
|
||||
}
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class Parameters : BaseWindowParams
|
||||
{
|
||||
|
||||
public override void ResetValues()
|
||||
{
|
||||
base.ResetValues();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68a8d3f524285644199caf4460fbcdc6
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c482f90f1ee754b4da08cae199ec2bdf
|
||||
folderAsset: yes
|
||||
timeCreated: 1563725050
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Editor.OSAWizard.CustomAdapterConfigurators
|
||||
{
|
||||
public class CustomAdapterConfiguratorAttribute : Attribute
|
||||
{
|
||||
public readonly Type ConfiguredType;
|
||||
|
||||
|
||||
public CustomAdapterConfiguratorAttribute(Type configuredType)
|
||||
{
|
||||
ConfiguredType = configuredType;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6deb5e935a58cdb4fad91efa1376591a
|
||||
timeCreated: 1563725050
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEditor;
|
||||
using frame8.Logic.Misc.Visual.UI.MonoBehaviours;
|
||||
using Com.ForbiddenByte.OSA.Core;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Editor.OSAWizard.CustomAdapterConfigurators
|
||||
{
|
||||
public interface ICustomAdapterConfigurator
|
||||
{
|
||||
void ConfigureNewAdapter(IOSA newAdapter);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 11f79c1dbccd7dc419f74c9a907f00a7
|
||||
timeCreated: 1563725050
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 501689534c65018409280bb239f0b15c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to keep track of the plugin's path, wherever you move it inside the project. This way, we don't need to hardcode paths.
|
||||
/// Do not move this file from its default location
|
||||
/// </summary>
|
||||
[CreateAssetMenu(fileName= CLASS_NAME + ".asset", menuName= "OSA/PluginPathTracker")]
|
||||
public class PluginPathTracker : ScriptableObject
|
||||
{
|
||||
const string CLASS_NAME = "PluginPathTracker";
|
||||
|
||||
public static string PathInAssets
|
||||
{
|
||||
get
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(Instance).Replace("\\", "/");
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
public static string DirectoryPathInAssets
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.GetDirectoryName(PathInAssets).Replace("\\", "/");
|
||||
}
|
||||
}
|
||||
|
||||
static PluginPathTracker Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_Instance != null)
|
||||
return _Instance;
|
||||
|
||||
var assets = AssetDatabase.FindAssets("t:" + CLASS_NAME);
|
||||
if (assets.Length == 0)
|
||||
throw new InvalidOperationException("No PluginPathTracker asset found! Did you delete it?");
|
||||
|
||||
if (assets.Length > 1)
|
||||
throw new InvalidOperationException("Found more than 1 asset with type PluginPathTracker");
|
||||
|
||||
var path = AssetDatabase.GUIDToAssetPath(assets[0]);
|
||||
_Instance = AssetDatabase.LoadAssetAtPath<PluginPathTracker>(path);
|
||||
|
||||
return _Instance;
|
||||
}
|
||||
}
|
||||
|
||||
static PluginPathTracker _Instance;
|
||||
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if (_Instance)
|
||||
throw new InvalidOperationException("Only one instance of PluginPath.asset is allowed");
|
||||
|
||||
_Instance = this;
|
||||
}
|
||||
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if (_Instance == this)
|
||||
_Instance = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f07c1bce198ce940a650e38262e0e5c
|
||||
timeCreated: 1638551984
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c24f5b7faae040646a58ba31fc6d8b07
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
After Width: | Height: | Size: 698 B |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d099d3ad89cc7c243966b25f833cdd58
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
linearTexture: 0
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: 2
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 0
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
After Width: | Height: | Size: 10 KiB |
@ -0,0 +1,47 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c20e8d8854da4b4ebd2784b670ebbb2
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 2
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
linearTexture: 1
|
||||
correctGamma: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: .25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 1024
|
||||
textureSettings:
|
||||
filterMode: 2
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: .5, y: .5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaIsTransparency: 1
|
||||
textureType: 2
|
||||
buildTargetSettings: []
|
||||
spriteSheet:
|
||||
sprites: []
|
||||
spritePackingTag:
|
||||
userData:
|
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7a943af8854c5f41b5affbb37960f1c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d04db0e060b8d14fae509af2b9c3e92
|
||||
folderAsset: yes
|
||||
timeCreated: 1553129474
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,321 @@
|
||||
using UnityEngine;
|
||||
using Com.ForbiddenByte.OSA.Core;
|
||||
using frame8.Logic.Misc.Other.Extensions;
|
||||
using frame8.Logic.Misc.Visual.UI;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.AdditionalComponents
|
||||
{
|
||||
/// <summary>
|
||||
/// Very useful script when you want to attach arbitrary content anywhere in an OSA and have it scrollable as any other item.
|
||||
/// Needs to be attached to a child of OSA's Viewport.
|
||||
/// <para>Note: If you use Unity 2019.3.5f1 (probably there are other buggy versions as well), this won't work properly if you don't bring the anchors together in the scrolling direction.
|
||||
/// It's a bug in Unity where a RectTransform's size isn't correctly reported in Awake(), and it affects all UI components, not only this one</para>
|
||||
/// </summary>
|
||||
public class OSAContentDecorator : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
InsetEdgeEnum _InsetEdge = InsetEdgeEnum.START;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("How far from the InsetEdge should this be positioned. Can be normalized ([0, 1]), if InsetIsNormalized=true, or raw. Default is 0")]
|
||||
float _Inset = 0f;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("If false, will interpret the Inset property as the raw distance from InsetEdge, rather than the normalized inset relative to the content's full size")]
|
||||
bool _InsetIsNormalized = true;
|
||||
|
||||
[SerializeField]
|
||||
bool _DisableWhenNotVisible = true;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("If false, won't be dragged together with the OSA's content when it's pulled when already at the scrolling limit")]
|
||||
bool _AffectedByElasticity = false;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip(
|
||||
"Sets when the OSA's padding from InsetEdge will be controlled to be the same as this object's size.\n" +
|
||||
"Once at initialization, or adapting continuously, or none (i.e. you'll probably set OSA's padding manually, in case the decorator shouldn't overlap with items).\n" +
|
||||
"Only works if Inset is 0")]
|
||||
ControlOSAPaddingMode _ControlOSAPaddingAtInsetEdge = ControlOSAPaddingMode.ONCE_AT_INIT;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("If null, will use the first an implementation of IOSA found in parents")]
|
||||
RectTransform _OSATransform = null;
|
||||
|
||||
RectTransform _ParentRT;
|
||||
RectTransform _RT;
|
||||
IOSA _OSA;
|
||||
bool _Initialized;
|
||||
double _LastKnownInset;
|
||||
double _MyLastKnownSize;
|
||||
RectOffset _OSALastKnownPadding = new RectOffset();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Only to be called if OSA is initialized manually via <see cref="OSA{TParams, TItemViewsHolder}.Init"/>. Call it before that.
|
||||
/// With the default setup, where OSA initializes itself in its Start(), you don't need to call this, as it's called from this.Awake()
|
||||
/// </summary>
|
||||
public void Init()
|
||||
{
|
||||
_RT = transform as RectTransform;
|
||||
_ParentRT = _RT.parent as RectTransform;
|
||||
if (_OSA == null)
|
||||
{
|
||||
_OSA = _ParentRT.GetComponentInParent(typeof(IOSA)) as IOSA;
|
||||
if (_OSA == null)
|
||||
throw new OSAException("Component implementing IOSA not found in parents");
|
||||
}
|
||||
else
|
||||
{
|
||||
_OSA = _OSATransform.GetComponent(typeof(IOSA)) as IOSA;
|
||||
if (_OSA == null)
|
||||
throw new OSAException("Component implementing IOSA not found on the specified object '" + _OSATransform.name + "'");
|
||||
}
|
||||
|
||||
if (_OSA.BaseParameters.Viewport != _ParentRT)
|
||||
throw new OSAException(typeof(OSAContentDecorator).Name + " can only work when attached to a direct child of OSA's Viewport.");
|
||||
|
||||
if (_ControlOSAPaddingAtInsetEdge != ControlOSAPaddingMode.DONT_CONTROL)
|
||||
{
|
||||
if (_OSA.IsInitialized)
|
||||
{
|
||||
Debug.Log(
|
||||
"OSA's content padding can't be set after OSA was initialized. " +
|
||||
"You're most probably calling OSA.Init manually(), in which case make sure to also manually call Init() on this decorator, before OSA.Init()"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetOSAPadding();
|
||||
}
|
||||
}
|
||||
|
||||
_OSA.ScrollPositionChanged += OSAScrollPositionChanged;
|
||||
|
||||
// Improvement 14.09.2020: this was limiting - each user should be able to set of their own anchors for maximum flexibility. OSA should only control the decorator's position
|
||||
//var aPos = _RT.localPosition;
|
||||
//_RT.anchorMin = _RT.anchorMax = new Vector2(0f, 1f); // top-right
|
||||
//_RT.localPosition = aPos;
|
||||
|
||||
_Initialized = true;
|
||||
}
|
||||
|
||||
|
||||
void Awake()
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
|
||||
if (!_Initialized)
|
||||
Init();
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if (_Initialized)
|
||||
{
|
||||
// Reason for unsubbing first: there's a combination of params and contexts where we're
|
||||
// still subbed during being disabled, so the easiest is to just unsub first
|
||||
_OSA.ScrollPositionChanged -= OSAScrollPositionChanged;
|
||||
_OSA.ScrollPositionChanged += OSAScrollPositionChanged;
|
||||
}
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
// Reason: if we're self-disabling this decorator based on whether it's inside the viewport
|
||||
// or not, then, if someone else enables/disables it externally, we'll mix intents
|
||||
// (information is destroyed), so we unsub from OSA's position changes when we know this
|
||||
// OnDisable() can only come from outside. If so, it's assumed the caller intends to
|
||||
// later manually enable the decorator
|
||||
bool doesntRelyOnSelfDisabling = !_DisableWhenNotVisible;
|
||||
if (_Initialized && doesntRelyOnSelfDisabling)
|
||||
_OSA.ScrollPositionChanged -= OSAScrollPositionChanged;
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if (_Initialized)
|
||||
_OSA.ScrollPositionChanged -= OSAScrollPositionChanged;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!_Initialized)
|
||||
return;
|
||||
|
||||
if (_ControlOSAPaddingAtInsetEdge == ControlOSAPaddingMode.ADAPTIVE)
|
||||
AdaptToPadding();
|
||||
}
|
||||
|
||||
public void SetInset(float newInset)
|
||||
{
|
||||
_Inset = newInset;
|
||||
|
||||
if (_OSA != null && _Initialized)
|
||||
OSAScrollPositionChanged(0d);
|
||||
}
|
||||
|
||||
public void AdaptToPadding()
|
||||
{
|
||||
if (_ControlOSAPaddingAtInsetEdge != ControlOSAPaddingMode.ADAPTIVE)
|
||||
return;
|
||||
|
||||
if (_OSA == null || !_OSA.IsInitialized) // make sure adapter wasn't disposed
|
||||
return;
|
||||
|
||||
var rect = _RT.rect;
|
||||
var li = _OSA.GetLayoutInfoReadonly();
|
||||
double mySize = rect.size[li.hor0_vert1];
|
||||
|
||||
// Update OSA's padding when either the decorator's size changes or when OSA's own padding is externally changed
|
||||
if (_LastKnownInset != _Inset || _MyLastKnownSize != mySize || !IsSamePadding(_OSALastKnownPadding, _OSA.BaseParameters.ContentPadding))
|
||||
{
|
||||
SetPadding(mySize);
|
||||
// Commented: updating sooner is better than later
|
||||
//_OSA.ScheduleForceRebuildLayout();
|
||||
_OSA.ForceRebuildLayoutNow();
|
||||
}
|
||||
}
|
||||
|
||||
void SetOSAPadding()
|
||||
{
|
||||
var rect = _RT.rect;
|
||||
// Commented: layout info may not be available
|
||||
//var li = _OSA.GetLayoutInfoReadonly();
|
||||
|
||||
double mySize = rect.size[_OSA.IsHorizontal ? 0 : 1];
|
||||
SetPadding(mySize);
|
||||
}
|
||||
|
||||
void SetPadding(double myNewSize)
|
||||
{
|
||||
var p = _OSA.BaseParameters;
|
||||
var paddingToSet = myNewSize + _Inset;
|
||||
int paddingToSetCeiling = (int)(paddingToSet + .6f);
|
||||
var pad = p.ContentPadding;
|
||||
if (_InsetEdge == InsetEdgeEnum.START)
|
||||
{
|
||||
if (p.IsHorizontal)
|
||||
pad.left = paddingToSetCeiling;
|
||||
else
|
||||
pad.top = paddingToSetCeiling;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p.IsHorizontal)
|
||||
pad.right = paddingToSetCeiling;
|
||||
else
|
||||
pad.bottom = paddingToSetCeiling;
|
||||
}
|
||||
_LastKnownInset = _Inset;
|
||||
_MyLastKnownSize = myNewSize;
|
||||
_OSALastKnownPadding = new RectOffset(pad.left, pad.right, pad.top, pad.bottom);
|
||||
}
|
||||
|
||||
bool IsSamePadding(RectOffset a, RectOffset b)
|
||||
{
|
||||
return
|
||||
a.left == b.left &&
|
||||
a.right == b.right &&
|
||||
a.top == b.top &&
|
||||
a.bottom == b.bottom;
|
||||
}
|
||||
|
||||
void OSAScrollPositionChanged(double scrollPos)
|
||||
{
|
||||
// The terms 'before' and 'after' mean what they should, if _InsetEdge is START,
|
||||
// but their meaning is swapped when _InsetEdge is END.
|
||||
|
||||
var li = _OSA.GetLayoutInfoReadonly();
|
||||
double osaInsetFromEdge;
|
||||
RectTransform.Edge edgeToInsetFrom;
|
||||
if (_InsetEdge == InsetEdgeEnum.START)
|
||||
{
|
||||
osaInsetFromEdge = _OSA.ContentVirtualInsetFromViewportStart;
|
||||
edgeToInsetFrom = li.startEdge;
|
||||
}
|
||||
else
|
||||
{
|
||||
osaInsetFromEdge = _OSA.ContentVirtualInsetFromViewportEnd;
|
||||
edgeToInsetFrom = li.endEdge;
|
||||
}
|
||||
|
||||
double myExpectedInsetFromVirtualContent = _Inset;
|
||||
var rect = _RT.rect;
|
||||
double mySize = rect.size[li.hor0_vert1];
|
||||
double osaViewportSize = li.vpSize;
|
||||
if (_InsetIsNormalized)
|
||||
{
|
||||
myExpectedInsetFromVirtualContent *= _OSA.GetContentSize() - mySize;
|
||||
}
|
||||
|
||||
double myExpectedInsetFromViewport = osaInsetFromEdge + myExpectedInsetFromVirtualContent;
|
||||
bool visible = true;
|
||||
if (myExpectedInsetFromViewport < 0d)
|
||||
{
|
||||
if (myExpectedInsetFromViewport <= -mySize) // completely 'before' the viewport
|
||||
{
|
||||
myExpectedInsetFromViewport = -mySize; // don't position it too far away
|
||||
visible = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (myExpectedInsetFromViewport >= osaViewportSize) // completely 'after' the viewport
|
||||
{
|
||||
myExpectedInsetFromViewport = osaViewportSize; // don't position it too far away
|
||||
visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool disable = false;
|
||||
if (!visible)
|
||||
disable = _DisableWhenNotVisible;
|
||||
|
||||
if (gameObject.activeSelf == disable)
|
||||
gameObject.SetActive(!disable);
|
||||
|
||||
if (disable)
|
||||
// No need to position it, since it's disabled now
|
||||
return;
|
||||
|
||||
if (!_AffectedByElasticity)
|
||||
{
|
||||
// If OSA's Content is pulled outside bounds (elasticity)
|
||||
if (osaInsetFromEdge > .1d)
|
||||
{
|
||||
if (myExpectedInsetFromViewport > 0d)
|
||||
{
|
||||
// Update: actually, it looks better to just keep it at the edge, no matter what
|
||||
// // only if the content is bigger than viewport, otherwise the decorator is forced to stay with the content
|
||||
//if (_OSA.GetContentSizeToViewportRatio() > 1d)
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
// Bugfix 30.09.2020: Actually, the decorator should take _Inset into account, no matter what
|
||||
//myExpectedInsetFromViewport = 0d;
|
||||
myExpectedInsetFromViewport = _Inset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_RT.SetInsetAndSizeFromParentEdgeWithCurrentAnchors(edgeToInsetFrom, (float)myExpectedInsetFromViewport, (float)mySize);
|
||||
}
|
||||
|
||||
|
||||
public enum InsetEdgeEnum
|
||||
{
|
||||
START,
|
||||
END
|
||||
}
|
||||
|
||||
|
||||
public enum ControlOSAPaddingMode
|
||||
{
|
||||
DONT_CONTROL,
|
||||
ONCE_AT_INIT,
|
||||
ADAPTIVE
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bd664d4291ceea43871caa33de07841
|
||||
timeCreated: 1564144910
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,154 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using Com.ForbiddenByte.OSA.Core;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.AdditionalComponents
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this when the content padding should be a function of the viewport size, rather than a constant decided at edit-time.
|
||||
/// In other words, use if you want to specify the padding as a percentage rather than in pixels. It also allows for fine adjustments of the first/last item, mostly useful for centering them.
|
||||
/// A use case is keeping the last/first element in the middle when the content's extremity is reached. This can be done by setting a constant padding,
|
||||
/// but having a percentage-specified padding allows for seamless screen size changes
|
||||
/// </summary>
|
||||
public class OSAPercentageContentPaddingSetter : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
[Range(0f, 1f)]
|
||||
[Tooltip("0 = none, .5f = half of the viewport, 1f = the entire viewport's size will be used for padding")]
|
||||
float _PaddingStartPercent = .5f;
|
||||
|
||||
[SerializeField]
|
||||
[Range(0f, 1f)]
|
||||
[Tooltip("Same rules as for PaddingStartPercent")]
|
||||
float _PaddingEndPercent = .5f;
|
||||
|
||||
[SerializeField]
|
||||
[Range(0f, 1f)]
|
||||
[Tooltip("After setting the padding, how much will this item approach the viewport's edge based on its size?. 0=none, i.e. full padding. 1=a distance equal to its size. \n" +
|
||||
"For example, a 0.5 value could be used along with PaddingStartPercent and PaddingEndPercent also set to 0.5, resulting in first/last items arriving exactly in the middle when you scroll in the extremities.\n" +
|
||||
"ItemSizeCustomSource must also be set for this to be accurate. Otherwise, OSA.Parameters.DefaultItemSize will be used")]
|
||||
float _FirstLastItemsInsidePercent = .5f;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("This object's width or height will be used to calculate the most accurate position to satisfy the FirstLastItemsInsidePercent property")]
|
||||
RectTransform _ItemSizeCustomSource = null;
|
||||
|
||||
IOSA _IOSA;
|
||||
bool _UseDefaultItemSize;
|
||||
bool _IsHorizontal;
|
||||
//float _LastItemSize = float.MinValue * 1.1f;
|
||||
//float _LastVPSize = float.MinValue * 1.1f;
|
||||
|
||||
|
||||
#region Unity
|
||||
void Awake()
|
||||
{
|
||||
enabled = false;
|
||||
_IOSA = GetComponent(typeof(IOSA)) as IOSA;
|
||||
if (_IOSA == null)
|
||||
{
|
||||
Debug.Log(typeof(OSAPercentageContentPaddingSetter).Name + " needs to be attached to a game object containing an OSA component");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_IOSA.IsInitialized)
|
||||
{
|
||||
Debug.Log(typeof(OSAPercentageContentPaddingSetter).Name + " needs the OSA component to not be initialized before it");
|
||||
return;
|
||||
}
|
||||
|
||||
var parameters = _IOSA.BaseParameters;
|
||||
_UseDefaultItemSize = _ItemSizeCustomSource == null;
|
||||
_IsHorizontal = _IOSA.BaseParameters.IsHorizontal;
|
||||
|
||||
_IOSA.ScrollViewSizeChanged += OnScrollViewSizeChanged;
|
||||
//_IOSA.ItemsRefreshed += OnItemsRefreshed;
|
||||
|
||||
parameters.PrepareForInit(true);
|
||||
parameters.InitIfNeeded(_IOSA);
|
||||
|
||||
UpdatePadding();
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>Each time the ScrollView's size changes, the padding needs to be recalculated. <see cref="OSA{TParams, TItemViewsHolder}.ScrollViewSizeChanged"/></summary>
|
||||
void OnScrollViewSizeChanged()
|
||||
{
|
||||
if (!_IOSA.IsInitialized)
|
||||
{
|
||||
Debug.LogError(typeof(OSAPercentageContentPaddingSetter).Name + ".OnScrollViewSizeChanged() called, but OSA not initialized. This shouldn't happen if implemented correctly");
|
||||
return;
|
||||
}
|
||||
|
||||
_IOSA.BaseParameters.PrepareForInit(false);
|
||||
_IOSA.BaseParameters.InitIfNeeded(_IOSA);
|
||||
|
||||
UpdatePadding();
|
||||
}
|
||||
|
||||
//void OnItemsRefreshed(int _, int __)
|
||||
//{
|
||||
// float curSize;
|
||||
// if (_UseDefaultItemSize)
|
||||
// curSize = _IOSA.BaseParameters.DefaultItemSize;
|
||||
// else
|
||||
// curSize = GetSourceItemSize();
|
||||
|
||||
// if (Mathf.Abs(curSize - _LastItemSize) < .01f)
|
||||
// return;
|
||||
|
||||
// float curVPSize = GetVPSize();
|
||||
// if (Mathf.Abs(curVPSize - _LastVPSize) < .01f)
|
||||
// return;
|
||||
|
||||
// SetPaddingWith(curVPSize, curSize);
|
||||
|
||||
// _IOSA.asdasdas
|
||||
// _IOSA.Refresh(false, true);
|
||||
//}
|
||||
|
||||
void UpdatePadding()
|
||||
{
|
||||
if (_UseDefaultItemSize)
|
||||
SetPaddingFromDefaultItemSize();
|
||||
else
|
||||
SetPaddingFromCustomItemSource();
|
||||
}
|
||||
|
||||
void SetPaddingFromCustomItemSource()
|
||||
{
|
||||
SetPaddingWith(GetVPSize(), GetSourceItemSize());
|
||||
}
|
||||
|
||||
void SetPaddingFromDefaultItemSize()
|
||||
{
|
||||
SetPaddingWith(GetVPSize(), _IOSA.BaseParameters.DefaultItemSize);
|
||||
}
|
||||
|
||||
void SetPaddingWith(float vpSize, float itemSizeToUse)
|
||||
{
|
||||
var parameters = _IOSA.BaseParameters;
|
||||
float firstLastItemInsideAmount = itemSizeToUse * _FirstLastItemsInsidePercent;
|
||||
var pad = parameters.ContentPadding;
|
||||
int padStart = (int)(vpSize * _PaddingStartPercent - firstLastItemInsideAmount + .5f);
|
||||
int padEnd = (int)(vpSize * _PaddingEndPercent - firstLastItemInsideAmount + .5f);
|
||||
if (parameters.IsHorizontal)
|
||||
{
|
||||
pad.left = padStart;
|
||||
pad.right = padEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
pad.top = padStart;
|
||||
pad.bottom = padEnd;
|
||||
}
|
||||
|
||||
//_LastItemSize = itemSizeToUse;
|
||||
//_LastVPSize = vpSize;
|
||||
}
|
||||
|
||||
float GetSourceItemSize() { var itemRect = _ItemSizeCustomSource.rect; return _IsHorizontal ? itemRect.width : itemRect.height; }
|
||||
float GetVPSize() { var vpRect = _IOSA.BaseParameters.Viewport.rect; return _IsHorizontal ? vpRect.width : vpRect.height; }
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd01d781d1466a74c9900cbba5987cee
|
||||
timeCreated: 1549178429
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1135cb9e4f6819d479160f9733f571fe
|
||||
timeCreated: 1606644825
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1dd60ca44ca2acc4d9cedcc04484e754
|
||||
folderAsset: yes
|
||||
timeCreated: 1532022814
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Class representing the concept of a Views Holder, i.e. a class that references some views and the id of the data displayed by those views.
|
||||
/// Usually, the root and its child views, once created, don't change, but <see cref="ItemIndex"/> does, after which the views will change their data.
|
||||
/// </summary>
|
||||
public abstract class AbstractViewsHolder
|
||||
{
|
||||
/// <summary>The root of the view instance (which contains the actual views)</summary>
|
||||
public RectTransform root;
|
||||
|
||||
/// <summary> The index of the data model from which this viewsholder's views take their display information </summary>
|
||||
public virtual int ItemIndex { get; set; }
|
||||
|
||||
|
||||
/// <summary> Calls <see cref="Init(GameObject, RectTransform, int, bool, bool)"/> </summary>
|
||||
public void Init(RectTransform rootPrefab, RectTransform parent, int itemIndex, bool activateRootGameObject = true, bool callCollectViews = true)
|
||||
{ Init(rootPrefab.gameObject, parent, itemIndex, activateRootGameObject, callCollectViews); }
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates <paramref name="rootPrefabGO"/>, assigns it to root and sets its itemIndex to <paramref name="itemIndex"/>.
|
||||
/// Activates the new instance if <paramref name="activateRootGameObject"/> is true. Also calls CollectViews if <paramref name="callCollectViews"/> is true
|
||||
/// </summary>
|
||||
public void Init(GameObject rootPrefabGO, RectTransform parent, int itemIndex, bool activateRootGameObject = true, bool callCollectViews = true, bool worldPositionStays = false)
|
||||
{
|
||||
var go = GameObject.Instantiate(rootPrefabGO, parent, worldPositionStays);
|
||||
|
||||
root = go.transform as RectTransform;
|
||||
OnRootCreated(itemIndex, activateRootGameObject, callCollectViews);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialization alternative when you want to use a pre-instantiated object for the root, or an object from the scene.
|
||||
/// </summary>
|
||||
public void InitWithExistingRoot(RectTransform existingRoot, RectTransform parent, int itemIndex, bool activateRootGameObject = true, bool callCollectViews = true)
|
||||
{
|
||||
if (existingRoot.parent != parent)
|
||||
existingRoot.SetParent(parent, false);
|
||||
|
||||
root = existingRoot;
|
||||
OnRootCreated(itemIndex, activateRootGameObject, callCollectViews);
|
||||
}
|
||||
|
||||
/// <summary>If instead of calling <see cref="Init(GameObject, RectTransform, int, bool, bool)"/>, the initializaton is done manually, this should be called lastly as part of the initialization phase</summary>
|
||||
public virtual void CollectViews()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// The most common use case is when a Twin pass is to be executed. See <see cref="OSA{TParams, TItemViewsHolder}.ScheduleComputeVisibilityTwinPass(bool)"/> and its uses in the demos.
|
||||
/// Basically this prepares the root and any child layout elements and layout groups for a rebuild.
|
||||
/// Make sure to override this when you have children layouts (for example, a [Vertical/Horizontal/Grid]LayoutGroup) and call <see cref="LayoutRebuilder.MarkLayoutForRebuild(RectTransform)"/> for them. Base's implementation should still be called!
|
||||
/// </summary>
|
||||
public virtual void MarkForRebuild() { if (root) LayoutRebuilder.MarkLayoutForRebuild(root); }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MarkForRebuild"/> counterpart.
|
||||
/// <para>Called after the size information was retrieved from this views holder.</para>
|
||||
/// A very common use case is to disable a ContentSizeFitter which was previously enabled in <see cref="MarkForRebuild"/>
|
||||
/// </summary>
|
||||
public virtual void UnmarkForRebuild() { }
|
||||
|
||||
/// <summary>
|
||||
/// This is only called when an item is being shifted due to an <see cref="OSA{TParams, TItemViewsHolder}.InsertItems(int, int, bool, bool)"/> or
|
||||
/// <see cref="OSA{TParams, TItemViewsHolder}.RemoveItems(int, int, bool, bool)"/> call, but since its data remains the same (the models are shifted
|
||||
/// to make room for the others, but they don't change), there's no need to call <see cref="OSA{TParams, TItemViewsHolder}.UpdateViewsHolder(TItemViewsHolder)"/>
|
||||
/// <para>Don't forget to call the base implementation first if you override this method!</para>
|
||||
/// <para>Don't forget to call the base implementation first if you override this method!</para>
|
||||
/// </summary>
|
||||
/// <param name="shift"></param>
|
||||
/// <param name="modulo">
|
||||
/// This is the items count, but its purpose is to limit the new value of the itemIndex to be no greater than it.
|
||||
/// If it's greater, it should be rotated. This occurs in some cases when looping is enabled.
|
||||
/// You don't need to care about this as here it's the only place it's used</param>
|
||||
public virtual void ShiftIndex(int shift, int modulo)
|
||||
{
|
||||
ItemIndex = ShiftIntWithOverflowCheck(ItemIndex, shift, modulo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by OSA when it's decided that this Views Holder should be disabled (first) or recycled (second) by the current recycling policy.
|
||||
/// When fast-scrolling, a VH can be recycled without first being disabled (to save resources).
|
||||
/// <para>Most of the time, you'll be interested in this to cleanup any resources, such as pending image downloads that aren't needed anymore since this item goes out of view or will represent another model.</para>
|
||||
/// <para>See <see cref="OSA{TParams, TItemViewsHolder}.OnBeforeRecycleOrDisableViewsHolder(TItemViewsHolder, int)"/></para>
|
||||
/// </summary>
|
||||
public virtual void OnBeforeRecycleOrDisable(int newItemIndex)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by OSA when it's decided that this Views Holder should be destroyed by the current recycling policy.
|
||||
/// <para>See <see cref="OSA{TParams, TItemViewsHolder}.ShouldDestroyRecyclableItem(TItemViewsHolder, bool)"/></para>
|
||||
/// <para>See <see cref="OSA{TParams, TItemViewsHolder}.OnBeforeDestroyViewsHolder(TItemViewsHolder)"/></para>
|
||||
/// </summary>
|
||||
public virtual void OnBeforeDestroy()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnRootCreated(int itemIndex, bool activateRootGameObject = true, bool callCollectViews = true)
|
||||
{
|
||||
if (activateRootGameObject)
|
||||
root.gameObject.SetActive(true);
|
||||
this.ItemIndex = itemIndex;
|
||||
|
||||
if (callCollectViews)
|
||||
CollectViews();
|
||||
}
|
||||
|
||||
/// <summary>Internal utility for adding a <paramref name="shift"/> to <paramref name="value"/> and keeping it within range [0, <paramref name="modulo"/>), and also preventing integer overflow</summary>
|
||||
protected int ShiftIntWithOverflowCheck(int value, int shift, int modulo)
|
||||
{ return (int)(((long)value + shift + modulo) % modulo); }
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd48f5a30172f504c88bd48eb734ba81
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,31 @@
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Core
|
||||
{
|
||||
/// <summary>The minimal implementation of a Views Holder that can be used with <see cref="OSA{TParams, TItemViewsHolder}"/></summary>
|
||||
public class BaseItemViewsHolder : AbstractViewsHolder
|
||||
{
|
||||
/// <summary> Only used if the scroll rect is looping, otherwise it's the same as <see cref="AbstractViewsHolder.ItemIndex"/>; See <see cref="BaseParams.Effects.loopItems"/></summary>
|
||||
public int itemIndexInView;
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return itemIndexInView + "R"/*RealIdx*/ + ItemIndex;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual void ShiftIndexInView(int shift, int modulo)
|
||||
{
|
||||
int old = itemIndexInView;
|
||||
itemIndexInView += shift;
|
||||
|
||||
// IndexInView should not need rotating
|
||||
if (itemIndexInView >= modulo)
|
||||
throw new OSAException("BaseItemViewsHolder.ShiftIndex: (itemIndexInView=" + old + ")+(shift=" + shift + ") >= (modulo=" + modulo + ")");
|
||||
if (itemIndexInView < 0)
|
||||
throw new OSAException("BaseItemViewsHolder.ShiftIndex: (itemIndexInView=" + old + ")+(shift=" + shift + ") < 0");
|
||||
|
||||
//itemIndexInView = ShiftIntWithOverflowCheck(itemIndexInView, shift, modulo);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 647a4d2739c0ec14993eff7dc6ed4ea9
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,744 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Serialization;
|
||||
using frame8.Logic.Misc.Other.Extensions;
|
||||
using Com.ForbiddenByte.OSA.Core.SubComponents;
|
||||
using Com.ForbiddenByte.OSA.Core.Data;
|
||||
using Com.ForbiddenByte.OSA.Core.Data.Gallery;
|
||||
using Com.ForbiddenByte.OSA.Core.Data.Animations;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Input params to be passed to <see cref="OSA{TParams, TItemViewsHolder}.Init()"/></para>
|
||||
/// <para>This can be used Monobehaviour's field and exposed via inspector (most common case)</para>
|
||||
/// <para>Or can be manually constructed, depending on what's easier in your context</para>
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class BaseParams
|
||||
{
|
||||
#region Configuration
|
||||
|
||||
#region Core params
|
||||
[SerializeField]
|
||||
RectTransform _Content = null;
|
||||
public RectTransform Content { get { return _Content; } set { _Content = value; } }
|
||||
|
||||
[Tooltip("If null, the scrollRect is considered to be the viewport")]
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("viewport")]
|
||||
RectTransform _Viewport = null;
|
||||
/// <summary>If null, <see cref="ScrollViewRT"/> is considered to be the viewport</summary>
|
||||
public RectTransform Viewport { get { return _Viewport; } set { _Viewport = value; } }
|
||||
|
||||
[SerializeField]
|
||||
OrientationEnum _Orientation = OrientationEnum.VERTICAL;
|
||||
public OrientationEnum Orientation { get { return _Orientation; } set { _Orientation = value; } }
|
||||
|
||||
[SerializeField]
|
||||
Scrollbar _Scrollbar = null;
|
||||
public Scrollbar Scrollbar { get { return _Scrollbar; } set { _Scrollbar = value; } }
|
||||
|
||||
[Tooltip("The sensivity to the Mouse's scrolling wheel or similar input methods. " +
|
||||
"Not related to dragging or scrolling via scrollbar")]
|
||||
[SerializeField]
|
||||
float _ScrollSensivity = 100f;
|
||||
/// <summary>The sensivity to the Mouse's scrolling wheel or similar input methods. Not related to dragging or scrolling via scrollbar</summary>
|
||||
public float ScrollSensivity { get { return _ScrollSensivity; } set { _ScrollSensivity = value; } }
|
||||
|
||||
[Tooltip("The sensivity to the Mouse's horizontal scrolling wheel (where supported) or similar input methods that send scroll signals on the horizontal axis. " +
|
||||
"Not related to dragging or scrolling via scrollbar. \n" +
|
||||
"It's set to a positive value by default to comply with Unity's ScrollRect (which for some reason inverts the left and right directions). \n" +
|
||||
"If you'll nest OSA in a regular horizontal ScrollRect, set the ScrollRect's sensivity to a positive value and OSA's ScrollSensivityOnXAxis to a negative value to get an intuitive scroll")]
|
||||
[SerializeField]
|
||||
float _ScrollSensivityOnXAxis = 100f;
|
||||
/// <summary>The sensivity to the Mouse's left/right scrolling wheel (where supported) or similar input methods that send scroll signals on the horizontal axis. Not related to dragging or scrolling via scrollbar</summary>
|
||||
public float ScrollSensivityOnXAxis { get { return _ScrollSensivityOnXAxis; } set { _ScrollSensivityOnXAxis = value; } }
|
||||
|
||||
[SerializeField]
|
||||
//[HideInInspector]
|
||||
[Tooltip("Padding for the 4 edges of the content panel.\n"
|
||||
+ "Tip: if using a fixed, constant ItemTransversalSize, also set the paddings in the" +
|
||||
" transversal direction to -1 (left/right for vertical ScrollView and vice-versa)." +
|
||||
" This aligns the item in the center, transversally")]
|
||||
[FormerlySerializedAs("contentPadding")]
|
||||
RectOffset _ContentPadding = new RectOffset();
|
||||
/// <summary>
|
||||
/// Padding for the 4 edges of the content panel.
|
||||
/// <para>Tip: if using a fixed, constant <see cref="ItemTransversalSize"/>, also set the paddings in the
|
||||
/// transversal direction to -1 (left/right for vertical ScrollView and vice-versa). This aligns the item in the center, transversally</para>
|
||||
/// </summary>
|
||||
public RectOffset ContentPadding { get { return _ContentPadding; } set { _ContentPadding = value; } }
|
||||
|
||||
[SerializeField]
|
||||
//[HideInInspector]
|
||||
[FormerlySerializedAs("contentGravity")]
|
||||
ContentGravity _Gravity = ContentGravity.START;
|
||||
/// <summary>
|
||||
/// The effect of this property can only be seen when the content size is smaller than the viewport, case in which there are 3 possibilities:
|
||||
/// place the content at the start, middle or end. <see cref="ContentGravity.FROM_PIVOT"/> doesn't change the content's position (it'll be preserved from the way you aligned it in edit-mode)
|
||||
/// </summary>
|
||||
public ContentGravity Gravity { get { return _Gravity; } set { _Gravity = value; } }
|
||||
|
||||
[Tooltip("The space between items")]
|
||||
[SerializeField]
|
||||
//[HideInInspector]
|
||||
[FormerlySerializedAs("contentSpacing")]
|
||||
float _ContentSpacing = 0f;
|
||||
/// <summary>Spacing between items (horizontal if the ScrollView is horizontal. else, vertical)</summary>
|
||||
public float ContentSpacing { get { return _ContentSpacing; } set { _ContentSpacing = value; } }
|
||||
|
||||
[Tooltip("The size of all items for which the size is not specified in CollectItemSizes()")]
|
||||
[SerializeField]
|
||||
//[HideInInspector]
|
||||
float _DefaultItemSize = 60f;
|
||||
/// <summary>The size of all items for which the size is not specified</summary>
|
||||
public float DefaultItemSize { get { return _DefaultItemSize; } protected set { _DefaultItemSize = value; } }
|
||||
|
||||
[Tooltip("You'll probably need this if the scroll view is a child of another scroll view." +
|
||||
" If enabled, the first parent that implements all of IInitializePotentialDragHandler, IBeginDragHandler, IDragHandler and IEndDragHandler," +
|
||||
" as well as the first IScrollHandler found in parents (but it should be on the same game object as other handlers, IF they're found), " +
|
||||
" will receive these events when they occur on this scroll view. This works both with Unity's ScrollRect and OSA")]
|
||||
[SerializeField]
|
||||
bool _ForwardDragToParents = false;
|
||||
/// <summary>You'll probably need this if the scroll view is a child of another scroll view.
|
||||
/// If enabled, the first parent that implements all of IInitializePotentialDragHandler, IBeginDragHandler, IDragHandler and IEndDragHandler,
|
||||
/// as well as the first IScrollHandler found in parents (but it should be on the same game object as other handlers, IF they're found),
|
||||
/// will receive these events when they occur on this scroll view. This works both with Unity's ScrollRect and OSA</summary>
|
||||
public bool ForwardDragToParents { get { return _ForwardDragToParents; } protected set { _ForwardDragToParents = value; } }
|
||||
|
||||
[Tooltip("It forwards the drag/scroll in the same direction to the parent when the current scrolled position is at boundary, " +
|
||||
"thus allowing scrolling through nested Scroll Views that have the same scroll direction. \n" +
|
||||
"ForwardDragToParents also needs to be enabled for this to work.")]
|
||||
[SerializeField]
|
||||
bool _ForwardDragSameDirectionAtBoundary = false;
|
||||
/// <summary>It forwards the drag/scroll events in the same direction to the parent when the current scrolled position is at boundary,
|
||||
/// thus allowing scrolling through nested Scroll Views that have the same scroll direction.
|
||||
/// <para>ForwardDragToParents also needs to be enabled for this to work.</para>
|
||||
/// </summary>
|
||||
public bool ForwardDragSameDirectionAtBoundary { get { return _ForwardDragSameDirectionAtBoundary; } protected set { _ForwardDragSameDirectionAtBoundary = value; } }
|
||||
|
||||
[Tooltip("Allows you to click and drag the content directly (enabled by default). The property ForwardDragToParents is not affected by this")]
|
||||
[SerializeField]
|
||||
bool _DragEnabled = true;
|
||||
/// <summary>
|
||||
/// Allows you to click and drag the content directly (enabled by default).
|
||||
/// The <see cref="ForwardDragToParents"/> is not affected by this.
|
||||
/// </summary>
|
||||
public bool DragEnabled { get { return _DragEnabled; } set { _DragEnabled = value; } }
|
||||
|
||||
[Tooltip("Allows you to scroll by mouse wheel or other similar input devices (enabled by default). The property ForwardDragToParents is not affected by this")]
|
||||
[SerializeField]
|
||||
bool _ScrollEnabled = true;
|
||||
/// <summary>
|
||||
/// Allows you to scroll by mouse wheel or other similar input devices (enabled by default).
|
||||
/// The <see cref="ForwardDragToParents"/> is not affected by this.
|
||||
/// </summary>
|
||||
public bool ScrollEnabled { get { return _ScrollEnabled; } set { _ScrollEnabled = value; } }
|
||||
|
||||
[Tooltip("If enabled, will use Time.unscaledTime instead of Time.time, which means the animations, inertia etc. won't be affected by the Time.timeScale")]
|
||||
[SerializeField]
|
||||
bool _UseUnscaledTime = true;
|
||||
/// <summary>If enabled, will use <see cref="Time.unscaledTime"/> and <see cref="Time.unscaledDeltaTime"/> for animations, inertia etc. instead of <see cref="Time.time"/> and <see cref="Time.deltaTime"/></summary>
|
||||
public bool UseUnscaledTime { get { return _UseUnscaledTime; } set { _UseUnscaledTime = value; } }
|
||||
|
||||
[Tooltip(
|
||||
"The item size in the direction perpendicular to scrolling direction. Width for vertical ScrollViews, and vice-versa.\n" +
|
||||
"-1 = items won't have their widths (heights for horizontal ScrollViews) changed at all - you'll be responsible for them\n" +
|
||||
"0 = fill to available space, taking ContentPadding into account\n" +
|
||||
">0 = fixed size; in this case, it's better to also set transversal padding to -1 so the item will be centered\n")]
|
||||
[SerializeField]
|
||||
float _ItemTransversalSize = 0f;
|
||||
/// <summary>
|
||||
/// The item size in the direction perpendicular to scrolling direction. Width for vertical ScrollViews, and vice-versa
|
||||
/// <para>-1 = items won't have their widths (heights for horizontal ScrollViews) changed at all - you'll be responsible for them</para>
|
||||
/// <para>0 = fill to available space, taking <see cref="ContentPadding"/> into account</para>
|
||||
/// <para>any positive value = fixed size; in this case, it's better to also set transversal padding to -1 so the item will be centered</para>
|
||||
/// </summary>
|
||||
public float ItemTransversalSize { get { return _ItemTransversalSize; } set { _ItemTransversalSize = value; } }
|
||||
#endregion
|
||||
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("effects")]
|
||||
Effects _Effects = new Effects();
|
||||
public Effects effects { get { return _Effects; } }
|
||||
|
||||
[SerializeField]
|
||||
NavigationParams _Navigation = new NavigationParams();
|
||||
public NavigationParams Navigation { get { return _Navigation; } }
|
||||
|
||||
[SerializeField]
|
||||
AnimationParams _Animation = new AnimationParams();
|
||||
public AnimationParams Animation { get { return _Animation; } }
|
||||
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("optimization")]
|
||||
Optimization _Optimization = new Optimization();
|
||||
public Optimization optimization { get { return _Optimization; } }
|
||||
#endregion
|
||||
|
||||
|
||||
public bool IsHorizontal { get { return _Orientation == OrientationEnum.HORIZONTAL; } }
|
||||
public RectTransform ScrollViewRT { get { return _ScrollViewRT; } }
|
||||
public Snapper8 Snapper { get { return _Snapper; } }
|
||||
|
||||
RectTransform _ScrollViewRT;
|
||||
Snapper8 _Snapper;
|
||||
|
||||
|
||||
/// <summary>It's here just so the class can be serialized by Unity when used as a MonoBehaviour's field</summary>
|
||||
public BaseParams() { }
|
||||
|
||||
|
||||
public void PrepareForInit(bool firstTime)
|
||||
{
|
||||
if (!Content)
|
||||
throw new OSAException("Content cannot be null");
|
||||
Content.MatchParentSize(true);
|
||||
|
||||
if (firstTime)
|
||||
Canvas.ForceUpdateCanvases();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called internally in <see cref="OSA{TParams, TItemViewsHolder}.Init()"/> and every time the scrollview's size changes.
|
||||
/// This makes sure the content and viewport have valid values. It can also be overridden to initialize custom data
|
||||
/// </summary>
|
||||
public virtual void InitIfNeeded(IOSA iAdapter)
|
||||
{
|
||||
_ScrollViewRT = iAdapter.AsMonoBehaviour.transform as RectTransform;
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(ScrollViewRT);
|
||||
|
||||
AssertValidWidthHeight(ScrollViewRT);
|
||||
|
||||
var sr = ScrollViewRT.GetComponent<ScrollRect>();
|
||||
if (sr && sr.enabled)
|
||||
throw new OSAException("The ScrollRect is not needed anymore starting with v4.0. Remove or disable it!");
|
||||
|
||||
if (!Content)
|
||||
throw new OSAException("Content not set!");
|
||||
if (!Viewport)
|
||||
{
|
||||
Viewport = ScrollViewRT;
|
||||
if (Content.parent != ScrollViewRT)
|
||||
throw new OSAException("Content's parent should be the ScrollView itself if there's no viewport specified!");
|
||||
}
|
||||
if (!_Snapper)
|
||||
_Snapper = ScrollViewRT.GetComponent<Snapper8>();
|
||||
|
||||
if (ForwardDragSameDirectionAtBoundary && !ForwardDragToParents)
|
||||
Debug.Log("OSA: ForwardDragSameDirectionAtBoundary is true, but ForwardDragToParents is false. This will have no effect");
|
||||
|
||||
if ((ContentPadding.left == -1) != (ContentPadding.right == -1))
|
||||
{
|
||||
Debug.Log("OSA: ContentPadding.right and .left should either be both zero or positive or both -1. Setting both to 0...");
|
||||
ContentPadding.left = ContentPadding.right = 0;
|
||||
}
|
||||
|
||||
if ((ContentPadding.top == -1) != (ContentPadding.bottom == -1))
|
||||
{
|
||||
Debug.Log("OSA: ContentPadding.top and .bottom should either be both zero or positive or both -1. Setting both to 0...");
|
||||
ContentPadding.top = ContentPadding.bottom = 0;
|
||||
}
|
||||
|
||||
|
||||
effects.InitIfNeeded();
|
||||
|
||||
// There's no concept of content padding when looping. spacing should be used instead
|
||||
if (effects.LoopItems)
|
||||
{
|
||||
bool showLog = false;
|
||||
int ctSp = (int)ContentSpacing;
|
||||
if (IsHorizontal)
|
||||
{
|
||||
if (ContentPadding.left != ctSp)
|
||||
{
|
||||
showLog = true;
|
||||
ContentPadding.left = ctSp;
|
||||
}
|
||||
|
||||
if (ContentPadding.right != ctSp)
|
||||
{
|
||||
showLog = true;
|
||||
ContentPadding.right = ctSp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ContentPadding.top != ctSp)
|
||||
{
|
||||
showLog = true;
|
||||
ContentPadding.top = ctSp;
|
||||
}
|
||||
|
||||
if (ContentPadding.bottom != ctSp)
|
||||
{
|
||||
showLog = true;
|
||||
ContentPadding.bottom = ctSp;
|
||||
}
|
||||
}
|
||||
|
||||
if (showLog)
|
||||
Debug.Log("OSA: setting conteng padding to be the same as content spacing (" + ContentSpacing.ToString("#############.##") + "), because looping is enabled");
|
||||
}
|
||||
|
||||
Navigation.InitIfNeeded();
|
||||
|
||||
UpdateContentPivotFromGravityType();
|
||||
}
|
||||
|
||||
/// <summary>See <see cref="ContentGravity"/></summary>
|
||||
public void UpdateContentPivotFromGravityType()
|
||||
{
|
||||
if (Gravity != ContentGravity.FROM_PIVOT)
|
||||
{
|
||||
int v1_h0 = IsHorizontal ? 0 : 1;
|
||||
|
||||
var piv = Content.pivot;
|
||||
|
||||
// The transversal position is at the center
|
||||
piv[1 - v1_h0] = .5f;
|
||||
|
||||
int contentGravityAsInt = ((int)Gravity);
|
||||
float pivotInScrollingDirection_IfVerticalScrollView;
|
||||
if (contentGravityAsInt < 3)
|
||||
// 1 = TOP := 1f;
|
||||
// 2 = CENTER := .5f;
|
||||
pivotInScrollingDirection_IfVerticalScrollView = 1f / contentGravityAsInt;
|
||||
else
|
||||
// 3 = BOTTOM := 0f;
|
||||
pivotInScrollingDirection_IfVerticalScrollView = 0f;
|
||||
|
||||
piv[v1_h0] = pivotInScrollingDirection_IfVerticalScrollView;
|
||||
if (v1_h0 == 0) // i.e. if horizontal
|
||||
piv[v1_h0] = 1f - piv[v1_h0];
|
||||
|
||||
Content.pivot = piv;
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyScrollSensitivityTo(ref Vector2 vec)
|
||||
{
|
||||
vec.x *= OSAConst.SCROLL_DIR_X_MULTIPLIER * ScrollSensivityOnXAxis;
|
||||
vec.y *= OSAConst.SCROLL_DIR_Y_MULTIPLIER * ScrollSensivity;
|
||||
}
|
||||
|
||||
public void AssertValidWidthHeight(RectTransform rt)
|
||||
{
|
||||
var rectSize = rt.rect.size;
|
||||
string widthOfHeightErr = null;
|
||||
float sizErr;
|
||||
if ((sizErr = rectSize.x) < 1f)
|
||||
widthOfHeightErr = "width";
|
||||
else if ((sizErr = rectSize.y) < 1f)
|
||||
widthOfHeightErr = "height";
|
||||
if (widthOfHeightErr != null)
|
||||
throw new OSAException("OSA: '" + rt.name + "' reports a zero or negative " + widthOfHeightErr + "(" + sizErr + "). " +
|
||||
"\nThis can happen if you don't have a Canvas component in the OSA's parents or if you accidentally set an invalid size in editor. " +
|
||||
"\nIf '" + rt.name + "' is instantiated at runtime, make sure you use the version of Object.Instantiate(..) that also takes the parent " +
|
||||
"so it can be directly instantiated in it. The parent should be a Canvas or a descendant of a Canvas"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public enum OrientationEnum
|
||||
{
|
||||
VERTICAL,
|
||||
HORIZONTAL
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Represents how often or when the optimizer does his core loop: checking for any items that need to be created, destroyed, disabled, displayed, recycled</summary>
|
||||
public enum ContentGravity
|
||||
{
|
||||
/// <summary>you set it up manually</summary>
|
||||
FROM_PIVOT,
|
||||
|
||||
/// <summary>top if vertical scrollview, else left</summary>
|
||||
START,
|
||||
|
||||
/// <summary>top if vertical scrollview, else left</summary>
|
||||
CENTER,
|
||||
|
||||
/// <summary>bottom if vertical scrollview, else right</summary>
|
||||
END
|
||||
|
||||
}
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class Effects
|
||||
{
|
||||
public const float DEFAULT_MAX_SPEED = 10 * 1000f;
|
||||
public const float MAX_SPEED = DEFAULT_MAX_SPEED * 100;
|
||||
public const float MAX_SPEED_IF_LOOPING = DEFAULT_MAX_SPEED;
|
||||
|
||||
|
||||
[Tooltip("This RawImage will be scrolled together with the content. \n" +
|
||||
"The content is always stationary (this is the way the recycling process works), so the scrolling effect is faked by scrolling the texture's x/y.\n" +
|
||||
"Tip: use a seamless/looping background texture for best visual results")]
|
||||
[FormerlySerializedAs("contentVisual")]
|
||||
[SerializeField]
|
||||
RawImage _ContentVisual = null;
|
||||
[Obsolete("Use ContentVisual instead", true)]
|
||||
public RawImage contentVisual { get { return ContentVisual; } set { ContentVisual = value; } }
|
||||
public RawImage ContentVisual { get { return _ContentVisual; } set { _ContentVisual = value; } }
|
||||
|
||||
[FormerlySerializedAs("elasticMovement")]
|
||||
[SerializeField]
|
||||
bool _ElasticMovement = true;
|
||||
[Obsolete("Use ElasticMovement instead", true)]
|
||||
public bool elasticMovement { get { return ElasticMovement; } set { ElasticMovement = value; } }
|
||||
public bool ElasticMovement { get { return _ElasticMovement; } set { _ElasticMovement = value; } }
|
||||
|
||||
[FormerlySerializedAs("pullElasticity")]
|
||||
[SerializeField]
|
||||
float _PullElasticity = .3f;
|
||||
[Obsolete("Use PullElasticity instead", true)]
|
||||
public float pullElasticity { get { return PullElasticity; } set { PullElasticity = value; } }
|
||||
public float PullElasticity { get { return _PullElasticity; } set { _PullElasticity = value; } }
|
||||
|
||||
[FormerlySerializedAs("releaseTime")]
|
||||
[SerializeField]
|
||||
float _ReleaseTime = .1f;
|
||||
[Obsolete("Use ReleaseTime instead", true)]
|
||||
public float releaseTime { get { return ReleaseTime; } set { ReleaseTime = value; } }
|
||||
public float ReleaseTime { get { return _ReleaseTime; } set { _ReleaseTime = value; } }
|
||||
|
||||
[FormerlySerializedAs("inertia")]
|
||||
[SerializeField]
|
||||
bool _Inertia = true;
|
||||
[Obsolete("Use Inertia instead", true)]
|
||||
public bool inertia { get { return Inertia; } set { Inertia = value; } }
|
||||
public bool Inertia { get { return _Inertia; } set { _Inertia = value; } }
|
||||
|
||||
[Tooltip("What percent (0=0%, 1=100%) of the velociy will be lost per second after the drag ended. 1=all(immediate stop), 0=none(maitain constant scrolling speed indefinitely)")]
|
||||
[Range(0f, 1f)]
|
||||
[FormerlySerializedAs("inertiaDecelerationRate")]
|
||||
[SerializeField]
|
||||
float _InertiaDecelerationRate = 1f - .135f;
|
||||
[Obsolete("Use InertiaDecelerationRate instead", true)]
|
||||
public float inertiaDecelerationRate { get { return InertiaDecelerationRate; } set { InertiaDecelerationRate = value; } }
|
||||
/// <summary>What amount of the velociy will be lost per second after the drag ended</summary>
|
||||
// Fun fact: Unity's original ScrollRect mistakenly names "deceleration rate" the amount that should REMAIN,
|
||||
// not the one that will be REMOVED from the velocity. And its deault value is 0.135.
|
||||
// Here, we're setting the correct default value. A 0 deceleration rate should mean no deceleration
|
||||
public float InertiaDecelerationRate { get { return _InertiaDecelerationRate; } set { _InertiaDecelerationRate = value; } }
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Stop any movement from inertia or scrolling animations when a mouse click/touch begins")]
|
||||
bool _CutMovementOnPointerDown = true;
|
||||
/// <summary>
|
||||
/// Stop any movement from inertia or scrolling animations when a mouse click/touch begins
|
||||
/// </summary>
|
||||
public bool CutMovementOnPointerDown { get { return _CutMovementOnPointerDown; } set { _CutMovementOnPointerDown = value; } }
|
||||
|
||||
[FormerlySerializedAs("maxSpeed")]
|
||||
[SerializeField]
|
||||
float _MaxSpeed = DEFAULT_MAX_SPEED;
|
||||
[Obsolete("Use MaxSpeed instead", true)]
|
||||
public float maxSpeed { get { return MaxSpeed; } set { MaxSpeed = value; } }
|
||||
public float MaxSpeed { get { return _MaxSpeed; } set { _MaxSpeed = value; } }
|
||||
|
||||
[Tooltip("If enabled, multiple drags in the same direction will lead to greater speeds")]
|
||||
[SerializeField]
|
||||
bool _TransientSpeedBetweenDrags = true;
|
||||
/// <summary>If enabled, multiple drags in the same direction will lead to greater speeds</summary>
|
||||
public bool TransientSpeedBetweenDrags { get { return _TransientSpeedBetweenDrags; } protected set { _TransientSpeedBetweenDrags = value; } }
|
||||
|
||||
[Tooltip("If true: When the last item is reached, the first one appears after it, basically allowing you to scroll infinitely.\n" +
|
||||
" Initially intended for things like spinners, but it can be used for anything alike.\n" +
|
||||
" It may interfere with other functionalities in some very obscure/complex contexts/setups, so be sure to test the hell out of it.\n" +
|
||||
" Also please note that sometimes during dragging the content, the actual looping changes the Unity's internal PointerEventData for the current click/touch pointer id, so if you're also externally tracking the current click/touch, in this case only 'PointerEventData.pointerCurrentRaycast' and 'PointerEventData.position'(current position) are preserved, the other ones are reset to defaults to assure a smooth loop transition. Sorry for the long decription. Here's an ASCII potato: @")]
|
||||
[FormerlySerializedAs("loopItems")]
|
||||
[SerializeField]
|
||||
bool _LoopItems = false;
|
||||
[Obsolete("Use LoopItems instead", true)]
|
||||
public bool loopItems { get { return LoopItems; } set { LoopItems = value; } }
|
||||
/// <summary>
|
||||
/// <para>If true: When the last item is reached, the first one appears after it, basically allowing you to scroll infinitely.</para>
|
||||
/// <para>Initially intended for things like spinners, but it can be used for anything alike. It may interfere with other functionalities in some very obscure/complex contexts/setups, so be sure to test the hell out of it.</para>
|
||||
/// <para>Also please note that sometimes during dragging the content, the actual looping changes the Unity's internal PointerEventData for the current click/touch pointer id, </para>
|
||||
/// <para>so if you're also externally tracking the current click/touch, in this case only 'PointerEventData.pointerCurrentRaycast' and 'PointerEventData.position'(current position) are </para>
|
||||
/// <para>preserved, the other ones are reset to defaults to assure a smooth loop transition</para>
|
||||
/// </summary>
|
||||
public bool LoopItems { get { return _LoopItems; } set { _LoopItems = value; } }
|
||||
|
||||
[Tooltip("The contentVisual's additional drag factor. Examples:\n" +
|
||||
"-2: the contentVisual will move exactly by the same amount as the items, but in the opposite direction\n" +
|
||||
"-1: no movement\n" +
|
||||
" 0: same speed (together with the items)\n" +
|
||||
" 1: 2x faster in the same direction\n" +
|
||||
" 2: 3x faster etc.")]
|
||||
[Range(-5f, 5f)]
|
||||
[SerializeField]
|
||||
float _ContentVisualParallaxEffect = -.85f;
|
||||
public float ContentVisualParallaxEffect { get { return _ContentVisualParallaxEffect; } set { _ContentVisualParallaxEffect = value; } }
|
||||
|
||||
[SerializeField]
|
||||
GalleryEffectParams _Gallery = new GalleryEffectParams();
|
||||
public GalleryEffectParams Gallery { get { return _Gallery; } set { _Gallery = value; } }
|
||||
|
||||
[Range(0f, 1f)]
|
||||
[FormerlySerializedAs("galleryEffectAmount")]
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
float _GalleryEffectAmount = 0f;
|
||||
[Obsolete("Use GalleryEffectAmount instead", true)]
|
||||
public float galleryEffectAmount { get { return Gallery.OverallAmount; } set { Gallery.OverallAmount = value; } }
|
||||
[Obsolete("Use Gallery.OverallAmount instead")]
|
||||
public float GalleryEffectAmount { get { return Gallery.OverallAmount; } set { Gallery.OverallAmount = value; } }
|
||||
|
||||
[Range(0f, 1f)]
|
||||
[FormerlySerializedAs("galleryEffectViewportPivot")]
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
float _GalleryEffectViewportPivot = .5f;
|
||||
[Obsolete("Use GalleryEffectViewportPivot instead", true)]
|
||||
public float galleryEffectViewportPivot { get { return Gallery.Scale.ViewportPivot; } set { Gallery.Scale.ViewportPivot = value; } }
|
||||
[Obsolete("Use Gallery.Scale.ViewportPivot instead")]
|
||||
public float GalleryEffectViewportPivot { get { return Gallery.Scale.ViewportPivot; } set { Gallery.Scale.ViewportPivot = value; } }
|
||||
|
||||
public bool HasContentVisual { get { return _HasContentVisual; } }
|
||||
|
||||
bool _HasContentVisual;
|
||||
|
||||
|
||||
public void InitIfNeeded()
|
||||
{
|
||||
_HasContentVisual = ContentVisual != null;
|
||||
|
||||
float maxAllowed;
|
||||
string asString;
|
||||
if (LoopItems)
|
||||
{
|
||||
maxAllowed = MAX_SPEED_IF_LOOPING;
|
||||
asString = "MAX_SPEED_IF_LOOPING";
|
||||
}
|
||||
else
|
||||
{
|
||||
maxAllowed = MAX_SPEED;
|
||||
asString = "MAX_SPEED";
|
||||
}
|
||||
float maxSpeedClamped = Mathf.Clamp(MaxSpeed, 0f, maxAllowed);
|
||||
if (Math.Abs(maxSpeedClamped - MaxSpeed) > 1f)
|
||||
{
|
||||
Debug.Log("OSA: maxSpeed(" + MaxSpeed.ToString("#########.00") + ") value is negative or exceeded " + asString + "(" +
|
||||
maxAllowed.ToString("#########.00") +
|
||||
"). Clamped it to " + maxSpeedClamped.ToString("#########.00")
|
||||
);
|
||||
MaxSpeed = maxSpeedClamped;
|
||||
}
|
||||
|
||||
if (ElasticMovement && LoopItems)
|
||||
{
|
||||
ElasticMovement = false;
|
||||
Debug.Log("OSA: 'elasticMovement' was set to false, because 'loopItems' is true. Elasticity only makes sense when there is an end");
|
||||
}
|
||||
|
||||
if (HasContentVisual)
|
||||
ContentVisual.rectTransform.MatchParentSize(true);
|
||||
|
||||
InitGalleryEffectMigrations();
|
||||
}
|
||||
|
||||
|
||||
void InitGalleryEffectMigrations()
|
||||
{
|
||||
float defVal = 0f;
|
||||
if (_GalleryEffectAmount != defVal)
|
||||
{
|
||||
string warn = "OSA: Please go to BaseParams.cs, comment the [HideInInspector] attribute on _GalleryEffectAmount, then set this property to " + defVal + " (the default) in inspector, as this property will be removed in next versions." +
|
||||
" Use Gallery.OverallAmount instead to set the gallery effect amount. It's available through inspector." +
|
||||
" Will use _GalleryEffectAmount as the active one.";
|
||||
if (Gallery.OverallAmount != defVal)
|
||||
warn += ". Additional migration warning: Both _GalleryEffectAmount and Gallery.OverallAmount are non-default (non " + defVal + ").";
|
||||
Gallery.OverallAmount = _GalleryEffectAmount;
|
||||
Debug.Log(warn);
|
||||
}
|
||||
defVal = .5f;
|
||||
if (_GalleryEffectViewportPivot != defVal)
|
||||
{
|
||||
string warn = "OSA: Please go to BaseParams.cs, comment the [HideInInspector] attribute on _GalleryEffectViewportPivot, then set this property to " + defVal + " (the default) in inspector, as this property will be removed in next versions." +
|
||||
" Use Gallery.Scale.ViewportPivot instead to set the gallery effect pivot. It's available through inspector." +
|
||||
" Preserving the value of _GalleryEffectViewportPivot as the active one.";
|
||||
if (Gallery.Scale.ViewportPivot != defVal)
|
||||
warn += ". Additional migration warning: Both _GalleryEffectViewportPivot and Gallery.Scale.ViewportPivot are non-default (non " + defVal + ").";
|
||||
Gallery.Scale.ViewportPivot = _GalleryEffectViewportPivot;
|
||||
Debug.Log(warn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class NavigationParams
|
||||
{
|
||||
[Tooltip("Uses EventSystem.current (by default) to scroll to the currently selected item, if it's a ViewsHolder. Disabled by default for backward-compatibility.")]
|
||||
[SerializeField]
|
||||
bool _Enabled = false;
|
||||
/// <summary>
|
||||
/// Uses EventSystem.current (by default) to scroll to the currently selected item, if it's a ViewsHolder. Disabled by default for backward-compatibility.
|
||||
/// </summary>
|
||||
public bool Enabled { get { return _Enabled; } set { _Enabled = value; } }
|
||||
|
||||
[Tooltip(
|
||||
"Maximum depth up to which to search for a ViewsHolder in the parents of the currently selected GameObject (By default, EventSystem.current.currentSelectedGameObject). \n" +
|
||||
"A value of 0 means the selected GameObject itself should be the same as ViewsHolder.root. \n" +
|
||||
"If you have a Button that's selectable and it's a direct child of the ViewsHolder.root, the depth is 1. \n" +
|
||||
"Don't use a high value unnecessarily, as it affects performance. Default is 2.")]
|
||||
[SerializeField]
|
||||
int _MaxSearchDepthForViewsHolder = 2;
|
||||
/// <summary>
|
||||
/// <para>Maximum depth up to which to search for a ViewsHolder in the parents of the currently selected GameObject (By default, EventSystem.current.currentSelectedGameObject).</para>
|
||||
/// <para>A value of 0 means the selected GameObject itself should be the same as ViewsHolder.root.</para>
|
||||
/// <para>If you have a Button that's selectable and it's a direct child of the ViewsHolder.root, the depth is 1.</para>
|
||||
/// <para>Don't use a high value unnecessarily, as it affects performance. Default is 2.</para>
|
||||
/// </summary>
|
||||
public int MaxSearchDepthForViewsHolder { get { return _MaxSearchDepthForViewsHolder; } set { _MaxSearchDepthForViewsHolder = value; } }
|
||||
|
||||
[Tooltip(
|
||||
"Duration of scrolling to outside items when they're selected. Use 0 for no animation (immediate jump).\n" +
|
||||
"Clamped to (0, 1) and then again based on the input module's 'max actions per second'. Default is 0.1")]
|
||||
[SerializeField]
|
||||
float _ScrollDuration = .1f;
|
||||
/// <summary>
|
||||
/// <para>Duration of scrolling to outside items when they're selected. Use 0 for no animation (immediate jump).</para>
|
||||
/// <para>Clamped to (0, 1) and then again based on the input module's 'max actions per second'. Default is 0.1</para>
|
||||
/// </summary>
|
||||
public float ScrollDuration { get { return _ScrollDuration; } set { _ScrollDuration = value; } }
|
||||
|
||||
[Tooltip("If on, will center the selected item in the Viewport. Default is false")]
|
||||
[SerializeField]
|
||||
bool _Centered = false;
|
||||
/// <summary>
|
||||
/// <para>If on, will center the selected item in the Viewport. Default is false</para>
|
||||
/// </summary>
|
||||
public bool Centered { get { return _Centered; } set { _Centered = value; } }
|
||||
|
||||
[Tooltip(
|
||||
"Increase this to add more space between the focused (selected) item and the edge towards which you navigate. " +
|
||||
"This is useful for scenarios like when you have some items that aren't selectable, but still want to see the ones after them (and thus, select them).\n" +
|
||||
"Has no effect if Centered=true")]
|
||||
[SerializeField]
|
||||
float _AdditionalSpacingTowardsEdge = 0f;
|
||||
/// <summary>
|
||||
/// <para>Increase this to add more space between the focused (selected) item and the edge towards which you navigate.</para>
|
||||
/// <para>This is useful for scenarios like when you have some items that aren't selectable, but still want to see the ones after them (and thus, select them).</para>
|
||||
/// <para>Has no effect if <see cref="Centered"/> is true<.</para>
|
||||
/// </summary>
|
||||
public float AdditionalSpacingTowardsEdge { get { return _AdditionalSpacingTowardsEdge; } set { _AdditionalSpacingTowardsEdge = value; } }
|
||||
|
||||
|
||||
public void InitIfNeeded()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class Optimization
|
||||
{
|
||||
[Tooltip("How many objects besides the visible ones to keep in memory at max. \n" +
|
||||
"By default, no more than the heuristically found \"ideal\" number of items will be held in memory.\n" +
|
||||
"Set to a positive integer to limit it. In this case, you'll either use more RAM than needed or more CPU than needed. " +
|
||||
"One advantage is that you can get a predictable usage of the resources (for example, by specifying a constant bin size, no item will be destroyed if the actual visible items count won't exceed that).\n" +
|
||||
"Note that this doesn't include the 'buffered' items, which by design can't be directly destroyed")]
|
||||
[FormerlySerializedAs("recycleBinCapacity")]
|
||||
[SerializeField]
|
||||
int _RecycleBinCapacity = -1;
|
||||
[Obsolete("Use RecycleBinCapacity instead", true)]
|
||||
public int recycleBinCapacity { get { return RecycleBinCapacity; } set { RecycleBinCapacity = value; } }
|
||||
/// <summary>
|
||||
/// <para>How many objects besides the visible ones to keep in memory at max, besides the visible ones</para>
|
||||
/// <para>By default, no more than the heuristically found "ideal" number of items will be held in memory</para>
|
||||
/// <para>Set to a positive integer to limit it - Not recommended, unless you're OK with more GC calls (i.e. occasional FPS hiccups) in favor of using less RAM</para>
|
||||
/// </summary>
|
||||
public int RecycleBinCapacity { get { return _RecycleBinCapacity; } set { _RecycleBinCapacity = value; } }
|
||||
|
||||
[FormerlySerializedAs("scaleToZeroInsteadOfDisable")]
|
||||
[SerializeField]
|
||||
bool _ScaleToZeroInsteadOfDisable = false;
|
||||
[Obsolete("Use ScaleToZeroInsteadOfDisable instead", true)]
|
||||
public bool scaleToZeroInsteadOfDisable { get { return ScaleToZeroInsteadOfDisable; } set { ScaleToZeroInsteadOfDisable = value; } }
|
||||
/// <summary>
|
||||
/// Enables ability to scale out-of-view objects to zero instead of de-activating them,
|
||||
/// since GameObject.SetActive is slightly more expensive to call each frame (especially when scrolling via the scrollbar).
|
||||
/// This is not a major speed improvement, but rather a slight memory improvement.
|
||||
/// It's recommended to use this option if your game/business logic doesn't require the game objects to be de-activated.
|
||||
/// </summary>
|
||||
public bool ScaleToZeroInsteadOfDisable { get { return _ScaleToZeroInsteadOfDisable; } set { _ScaleToZeroInsteadOfDisable = value; } }
|
||||
|
||||
// WIP
|
||||
///// <summary>
|
||||
///// <para>The bigger, the more items will be active past the minimum needed to fill the viewport - with a performance cost, of course</para>
|
||||
///// <para>1f = generally, the number of visible items + 1 will always be active</para>
|
||||
///// <para>2f = twice the number of visible items + 1 will be always active</para>
|
||||
///// <para>2.5f = 2.5 * (the number of visible items) + 1 will be always active</para>
|
||||
///// </summary>
|
||||
//[Range(1f, 5f)]
|
||||
//public float recyclingToleranceFactor = 1f;
|
||||
|
||||
[FormerlySerializedAs("forceLayoutRebuildOnBeginSmoothScroll")]
|
||||
[SerializeField]
|
||||
bool _ForceLayoutRebuildOnBeginSmoothScroll = true;
|
||||
[Obsolete("Use ForceLayoutRebuildOnBeginSmoothScroll instead", true)]
|
||||
public bool forceLayoutRebuildOnBeginSmoothScroll { get { return ForceLayoutRebuildOnBeginSmoothScroll; } set { ForceLayoutRebuildOnBeginSmoothScroll = value; } }
|
||||
/// <summary>Disable only if you see FPS drops when calling <see cref="OSA{TParams, TItemViewsHolder}.SmoothScrollTo(int, float, float, float, Func{float, bool}, Action, bool)"/></summary>
|
||||
public bool ForceLayoutRebuildOnBeginSmoothScroll { get { return _ForceLayoutRebuildOnBeginSmoothScroll; } set { _ForceLayoutRebuildOnBeginSmoothScroll = value; } }
|
||||
|
||||
[FormerlySerializedAs("forceLayoutRebuildOnDrag")]
|
||||
[SerializeField]
|
||||
bool _ForceLayoutRebuildOnDrag = false;
|
||||
[Obsolete("Use ForceLayoutRebuildOnDrag instead", true)]
|
||||
public bool forceLayoutRebuildOnDrag { get { return ForceLayoutRebuildOnDrag; } set { ForceLayoutRebuildOnDrag = value; } }
|
||||
/// <summary>
|
||||
/// Enable only if you experience issues with misaligned items. If OSA is correctly implemented, this shouldn't happen (please report if you find otherwise).
|
||||
/// However, we still provide this property if you want a quick fix
|
||||
/// </summary>
|
||||
public bool ForceLayoutRebuildOnDrag { get { return _ForceLayoutRebuildOnDrag; } set { _ForceLayoutRebuildOnDrag = value; } }
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Whether to sort the actual GameObjects representing the items under the Content. Only use if needed, as it slightly affects performance. Off by default")]
|
||||
bool _KeepItemsSortedInHierarchy = false;
|
||||
/// <summary>
|
||||
/// Whether to sort the actual GameObjects representing the items under the Content. Only use if needed, as it slightly affects performance. Off by default
|
||||
/// </summary>
|
||||
public bool KeepItemsSortedInHierarchy { get { return _KeepItemsSortedInHierarchy; } set { _KeepItemsSortedInHierarchy = value; } }
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("When the list becomes empty, should the currently cached item views be kept (True) or destroyed in order to start with a fresh state (False)? False by default")]
|
||||
bool _KeepItemsPoolOnEmptyList = false;
|
||||
/// <summary>When the list becomes empty, should the currently cached item views be kept (True) or destroyed in order to start with a fresh state (False)? False by default</summary>
|
||||
public bool KeepItemsPoolOnEmptyList { get { return _KeepItemsPoolOnEmptyList; } set { _KeepItemsPoolOnEmptyList = value; } }
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("When the ScrollView is rebuilt (as when its size changes), should the currently cached item views be kept (True) or destroyed in order to start with a fresh state (False)? False by default")]
|
||||
bool _KeepItemsPoolOnLayoutRebuild = false;
|
||||
/// <summary>When the ScrollView is rebuilt (as when its size changes), should the currently cached item views be kept (True) or destroyed in order to start with a fresh state (False)? False by default</summary>
|
||||
public bool KeepItemsPoolOnLayoutRebuild { get { return _KeepItemsPoolOnLayoutRebuild; } set { _KeepItemsPoolOnLayoutRebuild = value; } }
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("When the ScrollView is rebuilt (as when its size changes), should the currently cached item sizes views be kept (True)? False by default")]
|
||||
bool _KeepItemsSizesOnLayoutRebuild = false;
|
||||
/// <summary>When the ScrollView is rebuilt (as when its size changes), should the currently cached item sizes views be kept (True)? False by default</summary>
|
||||
public bool KeepItemsSizesOnLayoutRebuild { get { return _KeepItemsSizesOnLayoutRebuild; } set { _KeepItemsSizesOnLayoutRebuild = value; } }
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip(
|
||||
"When the ScrollView changes its size (as when the orientation changes), should we try (best-effort) to preserve the exact position of all visible items and OSA's velocity?\n" +
|
||||
"Of course you usually want this, and at least the position of all items is already preserved by default, but in some cases, such as when you're changing items' sizes on the " +
|
||||
"fly or applying CSF patterns, the scroll position jumps a few times to accommodate those dynamic changes\n" +
|
||||
"This property handles that. And it's off by default for backwards-compatibility, but also because of a small performance hit")]
|
||||
bool _ResponsiveOnScrollViewSizeChange = false;
|
||||
/// <summary>
|
||||
/// <para>When the ScrollView changes its size (as when the orientation changes), should we try (best-effort) to preserve the exact position of all visible items and OSA's velocity?</para>
|
||||
/// <para>Of course you usually want this, and at least the position of all items is already preserved by default, but in some cases, such as when you're changing items' sizes on the fly or applying CSF patterns, the scroll position jumps a few times to accommodate those dynamic changes</para>
|
||||
/// <para>This property handles that. And it's off by default for backwards-compatibility, but also because of a small performance hit</para>
|
||||
/// </summary>
|
||||
public bool ResponsiveOnScrollViewSizeChange { get { return _ResponsiveOnScrollViewSizeChange; } set { _ResponsiveOnScrollViewSizeChange = value; } }
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09e9165bf6b8b0a489a277761c5e0d83
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e03335a3112b26a4e8b36f509b1b5787
|
||||
folderAsset: yes
|
||||
timeCreated: 1562749645
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a883c623f6081545a247b9417505ccf
|
||||
folderAsset: yes
|
||||
timeCreated: 1580308561
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Core.Data.Animations
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters for cancelling certain animations on certain events
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AnimationCancelling
|
||||
{
|
||||
[SerializeField]
|
||||
[Tooltip("This decides whether or not to stop an existing SmoothScrollTo animation on certain events")]
|
||||
SmoothScrollCancellingEvents _SmoothScroll = new SmoothScrollCancellingEvents();
|
||||
/// <summary>
|
||||
/// This decides whether or not to stop an existing <see cref="OSA{TParams, TItemViewsHolder}.SmoothScrollTo(int, float, float, float, Func{float, bool}, Action, bool)"/> animation on certain events
|
||||
/// </summary>
|
||||
public SmoothScrollCancellingEvents SmoothScroll { get { return _SmoothScroll; } set { _SmoothScroll = value; } }
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Custom animations you may have. This decides whether or not to call CancelUserAnimations() on certain events, which you can override to comply")]
|
||||
UserAnimationsCancellingEvents _UserAnimations = new UserAnimationsCancellingEvents();
|
||||
/// <summary>
|
||||
/// Custom animations you may have. This decides whether or not to call <see cref="OSA{TParams, TItemViewsHolder}.CancelUserAnimations"/>, which you can override to comply
|
||||
/// </summary>
|
||||
public UserAnimationsCancellingEvents UserAnimations { get { return _UserAnimations; } set { _UserAnimations = value; } }
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16189e0639555c743a98aabe94b31bc9
|
||||
timeCreated: 1580308561
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Core.Data.Animations
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class AnimationCancellingEvents
|
||||
{
|
||||
[SerializeField]
|
||||
[Tooltip("Whether to cancel on any count change event: Insert/Remove/Reset")]
|
||||
bool _OnCountChanges = true;
|
||||
/// <summary>Whether to cancel on any count change event: Insert/Remove/Reset</summary>
|
||||
public bool OnCountChanges { get { return _OnCountChanges; } set { _OnCountChanges = value; } }
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Whether to cancel on any event that changes sizes of the items or content")]
|
||||
bool _OnSizeChanges = true;
|
||||
/// <summary>Whether to cancel on any event that changes sizes of the items or content</summary>
|
||||
public bool OnSizeChanges { get { return _OnSizeChanges; } set { _OnSizeChanges = value; } }
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Whether to cancel on OSA.ScrollTo")]
|
||||
bool _OnScrollTo = true;
|
||||
/// <summary>Whether to cancel on <see cref="OSA{TParams, TItemViewsHolder}.ScrollTo(int, float, float)"/></summary>
|
||||
public bool OnScrollTo { get { return _OnScrollTo; } set { _OnScrollTo = value; } }
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e145c3ff65c3ecf4dae1159b0079abe6
|
||||
timeCreated: 1580308561
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Core.Data.Animations
|
||||
{
|
||||
[Serializable]
|
||||
public enum AnimationFunctionType
|
||||
{
|
||||
SLOW_OUT,
|
||||
FAST_IN_SLOW_OUT,
|
||||
SLOW_IN_OUT,
|
||||
LINEAR
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d309f7028e135ef4bad911afa1c2d72b
|
||||
timeCreated: 1580310809
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.Core.Data.Animations
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters for animations in general
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AnimationParams
|
||||
{
|
||||
[SerializeField]
|
||||
AnimationFunctionType _SmoothScrollType = AnimationFunctionType.SLOW_OUT;
|
||||
public AnimationFunctionType SmoothScrollType { get { return _SmoothScrollType; } set { _SmoothScrollType = value; } }
|
||||
|
||||
[SerializeField]
|
||||
AnimationCancelling _Cancel = new AnimationCancelling();
|
||||
public AnimationCancelling Cancel { get { return _Cancel; } set { _Cancel = value; } }
|
||||
|
||||
public bool CallDoneOnScrollCancel { get { return _OnDoneWhenCancelled; } set { _OnDoneWhenCancelled = value; } }
|
||||
|
||||
[SerializeField]
|
||||
bool _OnDoneWhenCancelled;
|
||||
}
|
||||
}
|