yuhonglei
8 months ago
77 changed files with 9666 additions and 81 deletions
After Width: | Height: | Size: 757 B |
@ -0,0 +1,127 @@
|
||||
fileFormatVersion: 2 |
||||
guid: f25f8b04febb28c439258ea0bd1b1f38 |
||||
TextureImporter: |
||||
internalIDToNameTable: [] |
||||
externalObjects: {} |
||||
serializedVersion: 12 |
||||
mipmaps: |
||||
mipMapMode: 0 |
||||
enableMipMap: 0 |
||||
sRGBTexture: 1 |
||||
linearTexture: 0 |
||||
fadeOut: 0 |
||||
borderMipMap: 0 |
||||
mipMapsPreserveCoverage: 0 |
||||
alphaTestReferenceValue: 0.5 |
||||
mipMapFadeDistanceStart: 1 |
||||
mipMapFadeDistanceEnd: 3 |
||||
bumpmap: |
||||
convertToNormalMap: 0 |
||||
externalNormalMap: 0 |
||||
heightScale: 0.25 |
||||
normalMapFilter: 0 |
||||
flipGreenChannel: 0 |
||||
isReadable: 0 |
||||
streamingMipmaps: 0 |
||||
streamingMipmapsPriority: 0 |
||||
vTOnly: 0 |
||||
ignoreMipmapLimit: 0 |
||||
grayScaleToAlpha: 0 |
||||
generateCubemap: 6 |
||||
cubemapConvolution: 0 |
||||
seamlessCubemap: 0 |
||||
textureFormat: 1 |
||||
maxTextureSize: 2048 |
||||
textureSettings: |
||||
serializedVersion: 2 |
||||
filterMode: 1 |
||||
aniso: 1 |
||||
mipBias: 0 |
||||
wrapU: 1 |
||||
wrapV: 1 |
||||
wrapW: 0 |
||||
nPOTScale: 0 |
||||
lightmap: 0 |
||||
compressionQuality: 50 |
||||
spriteMode: 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 |
||||
flipbookRows: 1 |
||||
flipbookColumns: 1 |
||||
maxTextureSizeSet: 0 |
||||
compressionQualitySet: 0 |
||||
textureFormatSet: 0 |
||||
ignorePngGamma: 0 |
||||
applyGammaDecoding: 0 |
||||
swizzle: 50462976 |
||||
cookieLightType: 0 |
||||
platformSettings: |
||||
- serializedVersion: 3 |
||||
buildTarget: DefaultTexturePlatform |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
ignorePlatformSupport: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
- serializedVersion: 3 |
||||
buildTarget: Standalone |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
ignorePlatformSupport: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
- serializedVersion: 3 |
||||
buildTarget: Server |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
ignorePlatformSupport: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
spriteSheet: |
||||
serializedVersion: 2 |
||||
sprites: [] |
||||
outline: [] |
||||
physicsShape: [] |
||||
bones: [] |
||||
spriteID: 5e97eb03825dee720800000000000000 |
||||
internalID: 0 |
||||
vertices: [] |
||||
indices: |
||||
edges: [] |
||||
weights: [] |
||||
secondaryTextures: [] |
||||
nameFileIdTable: {} |
||||
mipmapLimitGroupName: |
||||
pSDRemoveMatte: 0 |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,116 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 193eab39bf9605049854af8db158d842 |
||||
TextureImporter: |
||||
internalIDToNameTable: [] |
||||
externalObjects: {} |
||||
serializedVersion: 11 |
||||
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: 0 |
||||
wrapU: 1 |
||||
wrapV: 1 |
||||
wrapW: 0 |
||||
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 |
||||
applyGammaDecoding: 0 |
||||
platformSettings: |
||||
- serializedVersion: 3 |
||||
buildTarget: DefaultTexturePlatform |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
- serializedVersion: 3 |
||||
buildTarget: Standalone |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
- serializedVersion: 3 |
||||
buildTarget: WebGL |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
spriteSheet: |
||||
serializedVersion: 2 |
||||
sprites: [] |
||||
outline: [] |
||||
physicsShape: [] |
||||
bones: [] |
||||
spriteID: 5e97eb03825dee720800000000000000 |
||||
internalID: 0 |
||||
vertices: [] |
||||
indices: |
||||
edges: [] |
||||
weights: [] |
||||
secondaryTextures: [] |
||||
spritePackingTag: |
||||
pSDRemoveMatte: 0 |
||||
pSDShowRemoveMatteOption: 0 |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
After Width: | Height: | Size: 359 B |
@ -0,0 +1,127 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 92c5eca69f57f6f44b3275c04a78d6cd |
||||
TextureImporter: |
||||
internalIDToNameTable: [] |
||||
externalObjects: {} |
||||
serializedVersion: 12 |
||||
mipmaps: |
||||
mipMapMode: 0 |
||||
enableMipMap: 0 |
||||
sRGBTexture: 1 |
||||
linearTexture: 0 |
||||
fadeOut: 0 |
||||
borderMipMap: 0 |
||||
mipMapsPreserveCoverage: 0 |
||||
alphaTestReferenceValue: 0.5 |
||||
mipMapFadeDistanceStart: 1 |
||||
mipMapFadeDistanceEnd: 3 |
||||
bumpmap: |
||||
convertToNormalMap: 0 |
||||
externalNormalMap: 0 |
||||
heightScale: 0.25 |
||||
normalMapFilter: 0 |
||||
flipGreenChannel: 0 |
||||
isReadable: 0 |
||||
streamingMipmaps: 0 |
||||
streamingMipmapsPriority: 0 |
||||
vTOnly: 0 |
||||
ignoreMipmapLimit: 0 |
||||
grayScaleToAlpha: 0 |
||||
generateCubemap: 6 |
||||
cubemapConvolution: 0 |
||||
seamlessCubemap: 0 |
||||
textureFormat: 1 |
||||
maxTextureSize: 2048 |
||||
textureSettings: |
||||
serializedVersion: 2 |
||||
filterMode: 1 |
||||
aniso: 1 |
||||
mipBias: 0 |
||||
wrapU: 1 |
||||
wrapV: 1 |
||||
wrapW: 0 |
||||
nPOTScale: 0 |
||||
lightmap: 0 |
||||
compressionQuality: 50 |
||||
spriteMode: 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 |
||||
flipbookRows: 1 |
||||
flipbookColumns: 1 |
||||
maxTextureSizeSet: 0 |
||||
compressionQualitySet: 0 |
||||
textureFormatSet: 0 |
||||
ignorePngGamma: 0 |
||||
applyGammaDecoding: 0 |
||||
swizzle: 50462976 |
||||
cookieLightType: 0 |
||||
platformSettings: |
||||
- serializedVersion: 3 |
||||
buildTarget: DefaultTexturePlatform |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
ignorePlatformSupport: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
- serializedVersion: 3 |
||||
buildTarget: Standalone |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
ignorePlatformSupport: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
- serializedVersion: 3 |
||||
buildTarget: Server |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
ignorePlatformSupport: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
spriteSheet: |
||||
serializedVersion: 2 |
||||
sprites: [] |
||||
outline: [] |
||||
physicsShape: [] |
||||
bones: [] |
||||
spriteID: 5e97eb03825dee720800000000000000 |
||||
internalID: 0 |
||||
vertices: [] |
||||
indices: |
||||
edges: [] |
||||
weights: [] |
||||
secondaryTextures: [] |
||||
nameFileIdTable: {} |
||||
mipmapLimitGroupName: |
||||
pSDRemoveMatte: 0 |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
After Width: | Height: | Size: 693 B |
@ -0,0 +1,116 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 25c4f82fa6d52c144830118665c3610e |
||||
TextureImporter: |
||||
internalIDToNameTable: [] |
||||
externalObjects: {} |
||||
serializedVersion: 11 |
||||
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: 0 |
||||
wrapU: 1 |
||||
wrapV: 1 |
||||
wrapW: 0 |
||||
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 |
||||
applyGammaDecoding: 0 |
||||
platformSettings: |
||||
- serializedVersion: 3 |
||||
buildTarget: DefaultTexturePlatform |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
- serializedVersion: 3 |
||||
buildTarget: Standalone |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
- serializedVersion: 3 |
||||
buildTarget: WebGL |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
spriteSheet: |
||||
serializedVersion: 2 |
||||
sprites: [] |
||||
outline: [] |
||||
physicsShape: [] |
||||
bones: [] |
||||
spriteID: 5e97eb03825dee720800000000000000 |
||||
internalID: 0 |
||||
vertices: [] |
||||
indices: |
||||
edges: [] |
||||
weights: [] |
||||
secondaryTextures: [] |
||||
spritePackingTag: |
||||
pSDRemoveMatte: 0 |
||||
pSDShowRemoveMatteOption: 0 |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,127 @@
|
||||
fileFormatVersion: 2 |
||||
guid: aadc30f65c04aef4281f896eabbb3153 |
||||
TextureImporter: |
||||
internalIDToNameTable: [] |
||||
externalObjects: {} |
||||
serializedVersion: 12 |
||||
mipmaps: |
||||
mipMapMode: 0 |
||||
enableMipMap: 0 |
||||
sRGBTexture: 1 |
||||
linearTexture: 0 |
||||
fadeOut: 0 |
||||
borderMipMap: 0 |
||||
mipMapsPreserveCoverage: 0 |
||||
alphaTestReferenceValue: 0.5 |
||||
mipMapFadeDistanceStart: 1 |
||||
mipMapFadeDistanceEnd: 3 |
||||
bumpmap: |
||||
convertToNormalMap: 0 |
||||
externalNormalMap: 0 |
||||
heightScale: 0.25 |
||||
normalMapFilter: 0 |
||||
flipGreenChannel: 0 |
||||
isReadable: 0 |
||||
streamingMipmaps: 0 |
||||
streamingMipmapsPriority: 0 |
||||
vTOnly: 0 |
||||
ignoreMipmapLimit: 0 |
||||
grayScaleToAlpha: 0 |
||||
generateCubemap: 6 |
||||
cubemapConvolution: 0 |
||||
seamlessCubemap: 0 |
||||
textureFormat: 1 |
||||
maxTextureSize: 2048 |
||||
textureSettings: |
||||
serializedVersion: 2 |
||||
filterMode: 1 |
||||
aniso: 1 |
||||
mipBias: 0 |
||||
wrapU: 1 |
||||
wrapV: 1 |
||||
wrapW: 0 |
||||
nPOTScale: 0 |
||||
lightmap: 0 |
||||
compressionQuality: 50 |
||||
spriteMode: 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 |
||||
flipbookRows: 1 |
||||
flipbookColumns: 1 |
||||
maxTextureSizeSet: 0 |
||||
compressionQualitySet: 0 |
||||
textureFormatSet: 0 |
||||
ignorePngGamma: 0 |
||||
applyGammaDecoding: 0 |
||||
swizzle: 50462976 |
||||
cookieLightType: 0 |
||||
platformSettings: |
||||
- serializedVersion: 3 |
||||
buildTarget: DefaultTexturePlatform |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
ignorePlatformSupport: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
- serializedVersion: 3 |
||||
buildTarget: Standalone |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
ignorePlatformSupport: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
- serializedVersion: 3 |
||||
buildTarget: Server |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
ignorePlatformSupport: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
spriteSheet: |
||||
serializedVersion: 2 |
||||
sprites: [] |
||||
outline: [] |
||||
physicsShape: [] |
||||
bones: [] |
||||
spriteID: 5e97eb03825dee720800000000000000 |
||||
internalID: 0 |
||||
vertices: [] |
||||
indices: |
||||
edges: [] |
||||
weights: [] |
||||
secondaryTextures: [] |
||||
nameFileIdTable: {} |
||||
mipmapLimitGroupName: |
||||
pSDRemoveMatte: 0 |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,116 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 5a105fe12e6c52d4db49fa5a196556eb |
||||
TextureImporter: |
||||
internalIDToNameTable: [] |
||||
externalObjects: {} |
||||
serializedVersion: 11 |
||||
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: 0 |
||||
wrapU: 1 |
||||
wrapV: 1 |
||||
wrapW: 0 |
||||
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 |
||||
applyGammaDecoding: 0 |
||||
platformSettings: |
||||
- serializedVersion: 3 |
||||
buildTarget: DefaultTexturePlatform |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
- serializedVersion: 3 |
||||
buildTarget: Standalone |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
- serializedVersion: 3 |
||||
buildTarget: WebGL |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
spriteSheet: |
||||
serializedVersion: 2 |
||||
sprites: [] |
||||
outline: [] |
||||
physicsShape: [] |
||||
bones: [] |
||||
spriteID: 5e97eb03825dee720800000000000000 |
||||
internalID: 0 |
||||
vertices: [] |
||||
indices: |
||||
edges: [] |
||||
weights: [] |
||||
secondaryTextures: [] |
||||
spritePackingTag: |
||||
pSDRemoveMatte: 0 |
||||
pSDShowRemoveMatteOption: 0 |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: e96fff2b1589a0445b2df862ac2f4c05 |
||||
PrefabImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: ddb36a4a3676f9242ab086cc480029b4 |
||||
PrefabImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 185e6a65fe0cb544ea452d704c39bc99 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a9d8e1e977396b94a855e275832e45f2 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 8ffb7de350b44394782adf7d65ed903c |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,79 @@
|
||||
using System; |
||||
using UnityEngine; |
||||
|
||||
public class EventManager : MonoBehaviour |
||||
{ |
||||
//清除轨迹事件 |
||||
public event Action OnClearTrack; |
||||
//隐藏轨迹 |
||||
public event Action OnHideTrack; |
||||
//显示轨迹 |
||||
public event Action OnShowTrack; |
||||
//拉近 |
||||
public event Action<long> OnZoomIn; |
||||
//停止定位 |
||||
public event Action OnStopLocation; |
||||
//显示轨迹 |
||||
public event Action<bool> OnShowTrajectories; |
||||
|
||||
public event Action OnMainCameraActive; |
||||
public event Action OnFollowCameraActive; |
||||
//人员列表Toggle |
||||
public event Action<bool> OnEmployeeItemActive; |
||||
public event Action<long,bool> OnEmployeeActive; |
||||
|
||||
public void EmployeeActive(long targetNo,bool isOn) |
||||
{ |
||||
OnEmployeeActive?.Invoke(targetNo,isOn); |
||||
} |
||||
|
||||
public void EmployeeItemActive(bool isOn) |
||||
{ |
||||
OnEmployeeItemActive?.Invoke(isOn); |
||||
} |
||||
public void MainCameraActive() |
||||
{ |
||||
OnMainCameraActive?.Invoke(); |
||||
} |
||||
|
||||
public void FollowCameraActive() |
||||
{ |
||||
OnFollowCameraActive?.Invoke(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 清除轨迹 |
||||
/// </summary> |
||||
public void ClearTrack() |
||||
{ |
||||
OnClearTrack?.Invoke(); |
||||
} |
||||
|
||||
public void HideTrack() |
||||
{ |
||||
OnHideTrack?.Invoke(); |
||||
} |
||||
|
||||
public void ShowTrack() |
||||
{ |
||||
OnShowTrack?.Invoke(); |
||||
} |
||||
|
||||
public void ZoomIn(long targetNo) |
||||
{ |
||||
OnZoomIn?.Invoke(targetNo); |
||||
} |
||||
|
||||
public void StopLocation() |
||||
{ |
||||
OnStopLocation?.Invoke(); |
||||
} |
||||
|
||||
public void ShowTrajectories(bool isOn) |
||||
{ |
||||
OnShowTrajectories?.Invoke(isOn); |
||||
} |
||||
|
||||
|
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 888db11086d6dff48be7aec5e47e0432 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 2714ec107d98f8047a9b25a33a0f645c |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,249 @@
|
||||
using DG.Tweening; |
||||
using System; |
||||
using UnityEngine; |
||||
using UnityEngine.AI; |
||||
using UnityEngine.UI; |
||||
|
||||
public class AgentController : MonoBehaviour |
||||
{ |
||||
public long targetNo; |
||||
private NavMeshAgent agent; |
||||
private float speed = 0f; |
||||
private Animator animator; |
||||
private Canvas canvas; |
||||
private const float daTingY = -0.01f; |
||||
private const float f1Y = -4.344f; |
||||
private const float f2Y = 0f; |
||||
|
||||
void Awake() |
||||
{ |
||||
animator = GetComponent<Animator>(); |
||||
agent = GetComponent<NavMeshAgent>(); |
||||
agent.stoppingDistance = 0f; |
||||
agent.autoBraking = false; |
||||
canvas = transform.Find("Canvas").GetComponent<Canvas>(); |
||||
canvas.worldCamera = Camera.main; |
||||
} |
||||
|
||||
private void Start() |
||||
{ |
||||
//Main.Event.OnMainCameraActive += OnMainCameraActive; |
||||
//Main.Event.OnFollowCameraActive += OnFollowCameraActive; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 当第一人称摄影机被激活后,Canvas的摄影机切为第一人称 |
||||
/// </summary> |
||||
private void OnFollowCameraActive() |
||||
{ |
||||
//canvas.worldCamera = CameraManager.FollowCamera.GetComponent<Camera>(); |
||||
} |
||||
/// <summary> |
||||
/// 当上帝视角被激活后,Canvas的摄影机切为全局相机 |
||||
/// </summary> |
||||
private void OnMainCameraActive() |
||||
{ |
||||
//canvas.worldCamera = CameraManager.MainCamera.GetComponent<Camera>(); |
||||
} |
||||
|
||||
private void Update() |
||||
{ |
||||
canvas.transform.LookAt(Camera.main.transform); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 更新位置 |
||||
/// </summary> |
||||
/// <param name="data"></param> |
||||
public void UpdatePosition(LocationData data) |
||||
{ |
||||
var pos =Main.LocationSimulator.ConversionTransform(data); |
||||
if (data.targetNo == 10774520) |
||||
{ |
||||
var info = $"卡号:{data.targetNo} - 定位基站:{data.stations} - 位置{pos}"; |
||||
Debug.Log(info); |
||||
} |
||||
|
||||
if (Vector3.Distance(transform.position, pos) < Config.Range) |
||||
return; |
||||
OnMoveTo(pos); |
||||
ShowStatus(data.createdTime, targetNo); |
||||
|
||||
|
||||
} |
||||
/// <summary> |
||||
/// 移动 |
||||
/// </summary> |
||||
/// <param name="pos"></param> |
||||
/// <param name="data"></param> |
||||
private void Movement(Vector3 pos, LocationData data) |
||||
{ |
||||
int currentFloor = DetermineFloor(agent.transform.position); |
||||
int targetFloor = DetermineFloor(pos); |
||||
if(data.targetNo.ToString()== "10777826") |
||||
{ |
||||
var info = $"卡号:{data.targetNo} - 当前楼层:{currentFloor} - 目标楼层:{targetFloor} - 定位基站:{data.stations} - 位置{pos}"; |
||||
Debug.Log(info); |
||||
//Debug.Log(pos); |
||||
} |
||||
|
||||
//上行 |
||||
if (currentFloor < targetFloor) |
||||
{ |
||||
if(data.stations.Contains("1020")&& data.stations.Contains("1040")) |
||||
{ |
||||
agent.isStopped = true; |
||||
} |
||||
else if(data.stations.Contains("1040")&& data.stations.Contains("1150")) |
||||
{ |
||||
if (pos.x < 11f) |
||||
{ |
||||
ByStair(pos); |
||||
} |
||||
else |
||||
{ |
||||
ByElevator(pos, true); |
||||
} |
||||
|
||||
} |
||||
else |
||||
{ |
||||
OnMoveTo(pos); |
||||
} |
||||
} |
||||
//下行 |
||||
else if (currentFloor > targetFloor) |
||||
{ |
||||
if (data.stations.Contains("1150") && data.stations.Contains("1040")) |
||||
{ |
||||
agent.isStopped = true; |
||||
} |
||||
else if (data.stations.Contains("1040") && data.stations.Contains("1020")) |
||||
{ |
||||
if (pos.x < 11f) |
||||
{ |
||||
ByStair(pos); |
||||
} |
||||
else |
||||
{ |
||||
ByElevator(pos, false); |
||||
|
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
// 在同一楼层移动 |
||||
OnMoveTo(pos); |
||||
} |
||||
ShowStatus(data.createdTime, targetNo); |
||||
} |
||||
/// <summary> |
||||
/// Wrap到寻路网格 |
||||
/// </summary> |
||||
/// <param name="targetPos"></param> |
||||
public void SetToNvMesh(Vector3 targetPos) |
||||
{ |
||||
if (!agent.isOnNavMesh) |
||||
agent.Warp(targetPos); |
||||
} |
||||
/// <summary> |
||||
/// 动画 |
||||
/// </summary> |
||||
private void OnAnimatorMove() |
||||
{ |
||||
speed = agent.velocity.magnitude; |
||||
animator.SetFloat("speed", speed); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 显示信息 |
||||
/// </summary> |
||||
/// <param name="createdTime"></param> |
||||
/// <param name="targetNo"></param> |
||||
public void ShowStatus(long createdTime, long targetNo) |
||||
{ |
||||
// UI显示目标数据 |
||||
canvas.transform.Find("Info/CardNumber").GetComponent<Text>().text = "卡号:" + targetNo; |
||||
canvas.transform.Find("Info/CurrentTime").GetComponent<Text>().text = "时间:" + DateTimeOffset.FromUnixTimeMilliseconds(createdTime).LocalDateTime; |
||||
} |
||||
/// <summary> |
||||
/// 检测楼层 |
||||
/// </summary> |
||||
/// <param name="pos"></param> |
||||
/// <returns></returns> |
||||
private int DetermineFloor(Vector3 pos) |
||||
{ |
||||
if (pos.y>= daTingY) |
||||
return 2; |
||||
else |
||||
return 1; |
||||
//else if (pos.y <= floor1Y) |
||||
// return 1; |
||||
//else return 2; |
||||
} |
||||
/// <summary> |
||||
/// 寻路 |
||||
/// </summary> |
||||
/// <param name="destination"></param> |
||||
private void OnMoveTo(Vector3 destination) |
||||
{ |
||||
if (agent.isOnNavMesh) |
||||
{ |
||||
if (agent.isStopped == true) |
||||
agent.isStopped = false; |
||||
agent.SetDestination(destination); |
||||
} |
||||
else |
||||
agent.Warp(destination); |
||||
} |
||||
/// <summary> |
||||
/// 使用楼梯 |
||||
/// </summary> |
||||
/// <param name="destination"></param> |
||||
private void ByStair(Vector3 destination) |
||||
{ |
||||
OnMoveTo(destination); |
||||
} |
||||
/// <summary> |
||||
/// 使用电梯 |
||||
/// </summary> |
||||
/// <param name="destination"></param> |
||||
/// <param name="isUp"></param> |
||||
private void ByElevator(Vector3 destination, bool isUp) |
||||
{ |
||||
StopAgentAndMoveToElevator(isUp ? f1Y : f2Y); |
||||
MoveElevatorAndContinue(destination, isUp ? f2Y : f1Y); |
||||
} |
||||
/// <summary> |
||||
/// 停止寻路并移动到电梯内 |
||||
/// </summary> |
||||
/// <param name="elevatorY"></param> |
||||
private void StopAgentAndMoveToElevator(float elevatorY) |
||||
{ |
||||
agent.isStopped = true; |
||||
transform.position = new Vector3(17.399f, elevatorY, 7.402f); |
||||
} |
||||
/// <summary> |
||||
/// 出电梯并继续寻路 |
||||
/// </summary> |
||||
/// <param name="destination"></param> |
||||
/// <param name="targetY"></param> |
||||
private void MoveElevatorAndContinue(Vector3 destination, float targetY) |
||||
{ |
||||
transform.DOMove(new Vector3(17.399f, targetY, 7.402f), 2f).OnComplete(() => |
||||
{ |
||||
agent.Warp(destination); |
||||
agent.isStopped = false; |
||||
}); |
||||
} |
||||
|
||||
private void OnDestroy() |
||||
{ |
||||
//if (Main.Event == null) |
||||
// return; |
||||
//Main.Event.OnMainCameraActive -= OnMainCameraActive; |
||||
//Main.Event.OnFollowCameraActive -= OnFollowCameraActive; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 872b1eb133011f84dbaf6b010a9a1e0a |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,164 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using UnityEngine; |
||||
[Serializable] |
||||
public class AlarmData : MonoBehaviour |
||||
{ |
||||
public int ErrorCode { get; set; } |
||||
public List<Alarm> List { get; set; } |
||||
} |
||||
[Serializable] |
||||
public class Alarm |
||||
{ |
||||
/// <summary> |
||||
/// 告警唯一ID |
||||
/// </summary> |
||||
public long Id { get; set; } |
||||
/// <summary> |
||||
/// 详情 |
||||
/// </summary> |
||||
public string Description { get; set; } |
||||
/// <summary> |
||||
/// 激活器ID |
||||
/// </summary> |
||||
public int DeviceId { get; set; } |
||||
/// <summary> |
||||
/// 激活器编号 |
||||
/// </summary> |
||||
public int DeviceNo { get; set; } |
||||
/// <summary> |
||||
/// 人员ID |
||||
/// </summary> |
||||
public int GoodsId { get; set; } |
||||
/// <summary> |
||||
/// 具体位置说明 |
||||
/// </summary> |
||||
public string Location { get; set; } |
||||
/// <summary> |
||||
/// 人员名称 |
||||
/// </summary> |
||||
public string Name { get; set; } |
||||
/// <summary> |
||||
/// 房间ID |
||||
/// </summary> |
||||
public int RoomId { get; set; } |
||||
/// <summary> |
||||
/// 房间名称 |
||||
/// </summary> |
||||
public string RoomName { get; set; } |
||||
/// <summary> |
||||
/// 标签ID |
||||
/// </summary> |
||||
public int TargetId { get; set; } |
||||
/// <summary> |
||||
/// 标签类型 |
||||
/// </summary> |
||||
public int TargetType { get; set; } |
||||
/// <summary> |
||||
/// 地图ID |
||||
/// </summary> |
||||
public int TilesId { get; set; } |
||||
/// <summary> |
||||
/// 坐标X |
||||
/// </summary> |
||||
public double X { get; set; } |
||||
/// <summary> |
||||
/// 坐标Y |
||||
/// </summary> |
||||
public double Y { get; set; } |
||||
/// <summary> |
||||
/// 坐标Z |
||||
/// </summary> |
||||
public double Z { get; set; } |
||||
/// <summary> |
||||
/// 告警说明 |
||||
/// </summary> |
||||
public string AlarmDesc { get; set; } |
||||
/// <summary> |
||||
/// 告警名称 |
||||
/// </summary> |
||||
public string AlarmName { get; set; } |
||||
/// <summary> |
||||
/// 告警时间 |
||||
/// </summary> |
||||
public long AlarmTime { get; set; } |
||||
/// <summary> |
||||
/// 告警类型 |
||||
/// </summary> |
||||
public int AlarmType { get; set; } |
||||
/// <summary> |
||||
/// 是否处理 |
||||
/// </summary> |
||||
public int IsRead { get; set; } |
||||
/// <summary> |
||||
/// “alarmType=13”时才会有personList这个对象,其他告警类型没有, |
||||
/// </summary> |
||||
public List<Person> PersonList { get; set; } |
||||
} |
||||
[Serializable] |
||||
public class Person |
||||
{ |
||||
/// <summary> |
||||
/// ID |
||||
/// </summary> |
||||
public long Id { get; set; } |
||||
/// <summary> |
||||
/// 添加日期 |
||||
/// </summary> |
||||
public long AddDate { get; set; } |
||||
/// <summary> |
||||
/// 地址 |
||||
/// </summary> |
||||
public string Address { get; set; } |
||||
/// <summary> |
||||
/// 证件号码 |
||||
/// </summary> |
||||
public string CertificateNo { get; set; } |
||||
/// <summary> |
||||
/// 证件类型 |
||||
/// </summary> |
||||
public long CertificateTypeId { get; set; } |
||||
/// <summary> |
||||
/// 标签ID |
||||
/// </summary> |
||||
public long DwbqId { get; set; } |
||||
/// <summary> |
||||
/// 标签编号 |
||||
/// </summary> |
||||
public string DwbqNo { get; set; } |
||||
/// <summary> |
||||
/// 电话 |
||||
/// </summary> |
||||
public string Mobile { get; set; } |
||||
/// <summary> |
||||
/// 名称 |
||||
/// </summary> |
||||
public string Name { get; set; } |
||||
/// <summary> |
||||
/// 人员类型 |
||||
/// </summary> |
||||
public long PersonType { get; set; } |
||||
/// <summary> |
||||
/// 人员类型名称 |
||||
/// </summary> |
||||
public string PersonTypeName { get; set; } |
||||
/// <summary> |
||||
/// 性别 |
||||
/// </summary> |
||||
public long Sex { get; set; } |
||||
/// <summary> |
||||
/// 性别名称 |
||||
/// </summary> |
||||
public string SexName { get; set; } |
||||
/// <summary> |
||||
/// 工作地址 |
||||
/// </summary> |
||||
public string WorkAddress { get; set; } |
||||
/// <summary> |
||||
/// 照片地址 |
||||
/// </summary> |
||||
public string PhotoUrl { get; set; } |
||||
|
||||
|
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 7ad67d1e3ef41ed4ead3ee2212732580 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,39 @@
|
||||
using AX.MessageSystem; |
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
|
||||
public class EmployeeItem : MonoBehaviour |
||||
{ |
||||
public Toggle show; |
||||
public Toggle track; |
||||
public long targetNo; |
||||
|
||||
private void Awake() |
||||
{ |
||||
Main.Event.OnEmployeeItemActive += OnEmployeeItemActive; |
||||
} |
||||
|
||||
private void Start() |
||||
{ |
||||
MessageDispatcher.AddListener("TRACKPLAYBACK", OnTrackPlayback, targetNo.ToString()); |
||||
} |
||||
|
||||
private void OnTrackPlayback(IMessage message) |
||||
{ |
||||
var value = (bool)message.Data; |
||||
track.isOn = value; |
||||
} |
||||
|
||||
private void OnEmployeeItemActive(bool isOn) |
||||
{ |
||||
show.isOn = isOn; |
||||
} |
||||
|
||||
private void OnDestroy() |
||||
{ |
||||
if (Main.Event != null) |
||||
Main.Event.OnEmployeeItemActive -= OnEmployeeItemActive; |
||||
MessageDispatcher.RemoveListener("TRACKPLAYBACK", OnTrackPlayback, targetNo.ToString()); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 497edb61565620a40ad131e14f9abb1f |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,333 @@
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using UnityEngine; |
||||
|
||||
public class LocationSimulator : MonoBehaviour |
||||
{ |
||||
//定位人员 |
||||
private Dictionary<long, AgentController> agentControllers = new Dictionary<long, AgentController>(); |
||||
//历史数据 |
||||
private List<PositionData> historyData = new List<PositionData>(); |
||||
//是否保存历史数据 |
||||
public bool isSaveHistory; |
||||
//轨迹回放人员 |
||||
private GameObject trackAgent; |
||||
//轨迹回放数据 |
||||
private List<LocationData> trackLocationData; |
||||
//轨迹回放Coroutines |
||||
private List<Coroutine> trackCoroutines = new List<Coroutine>(); |
||||
public LayerMask layerMask = -1; |
||||
private const string HistoryDataFilePath = "HistortData.json"; |
||||
private int characterCount = 0; |
||||
|
||||
/// <summary> |
||||
/// 开启定位 |
||||
/// </summary> |
||||
public void StartLocation() |
||||
{ |
||||
StartCoroutine(GetRealTimeData()); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 停止定位 |
||||
/// </summary> |
||||
public void StopLocation() |
||||
{ |
||||
StopAllCoroutines(); |
||||
agentControllers.Clear(); |
||||
historyData.Clear(); |
||||
} |
||||
|
||||
#region 轨迹回放 |
||||
|
||||
/// <summary> |
||||
/// 保存历史数据 |
||||
/// </summary> |
||||
public void SaveHistoryData() |
||||
{ |
||||
if (isSaveHistory) |
||||
{ |
||||
//var url = $"{Application.streamingAssetsPath}/{HistoryDataFilePath}"; |
||||
//QuickSaveRaw.Save(url, historyData); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 轨迹回放 |
||||
/// </summary> |
||||
/// <param name="targetNo"></param> |
||||
public void GetTrackPlaybackData(bool isOn, long targetNo) |
||||
{ |
||||
|
||||
if (isOn) |
||||
{ |
||||
trackLocationData = LoadTrackData(targetNo); |
||||
if (trackLocationData.Count > 0) |
||||
{ |
||||
StartTrackPlayback(); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
ClearTrackPlayback(); |
||||
} |
||||
} |
||||
/// <summary> |
||||
/// 加载轨迹回放数据 |
||||
/// </summary> |
||||
/// <param name="targetNo"></param> |
||||
/// <returns></returns> |
||||
private List<LocationData> LoadTrackData(long targetNo) |
||||
{ |
||||
//string url = $"{Application.streamingAssetsPath}/{HistoryDataFilePath}"; |
||||
//var tempData = QuickSaveRaw.Load<List<PositionData>>(url); |
||||
var loadedData = new List<LocationData>(); |
||||
|
||||
//foreach (var item in tempData) |
||||
//{ |
||||
// var data = item.list.Find(d => d.targetNo == targetNo); |
||||
// if (data != null) |
||||
// { |
||||
// if (trackAgent == null) |
||||
// { |
||||
// InitializeTrackAgent(data); |
||||
// } |
||||
// loadedData.Add(data); |
||||
// } |
||||
//} |
||||
return loadedData; |
||||
} |
||||
/// <summary> |
||||
/// 根据数据初始化定位人员 |
||||
/// </summary> |
||||
/// <param name="data"></param> |
||||
private void InitializeTrackAgent(LocationData data) |
||||
{ |
||||
//trackAgent = Instantiate(characterTrack); |
||||
trackAgent = Instantiate(Resources.Load("Characters/YBot")) as GameObject; |
||||
trackAgent.name = "YBotAgent"; |
||||
Vector3 pos = ConversionTransform(data); |
||||
trackAgent.transform.position = pos; |
||||
var agentController = trackAgent.AddComponent<AgentController>(); |
||||
agentController.targetNo = data.targetNo; |
||||
} |
||||
/// <summary> |
||||
/// 开始轨迹回放 |
||||
/// </summary> |
||||
private void StartTrackPlayback() |
||||
{ |
||||
Coroutine co = StartCoroutine(TrackPlayback()); |
||||
trackCoroutines.Add(co); |
||||
} |
||||
|
||||
private void ClearTrackPlayback() |
||||
{ |
||||
trackLocationData.Clear(); |
||||
Destroy(trackAgent); |
||||
StopTrackCoroutine(); |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// 停止轨迹回放协程 |
||||
/// </summary> |
||||
private void StopTrackCoroutine() |
||||
{ |
||||
foreach (var item in trackCoroutines) |
||||
{ |
||||
if (item != null) |
||||
StopCoroutine(item); |
||||
} |
||||
trackCoroutines.Clear(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 轨迹回放模拟 |
||||
/// </summary> |
||||
/// <param name="data"></param> |
||||
/// <returns></returns> |
||||
private IEnumerator TrackPlayback() |
||||
{ |
||||
if (trackLocationData.Count > 1) |
||||
{ |
||||
for (int i = 0; i < trackLocationData.Count - 1; i++) |
||||
{ |
||||
var currentLocation = trackLocationData[i]; |
||||
var nextLocation = trackLocationData[i + 1]; |
||||
long timestamp1 = currentLocation.createdTime; |
||||
long timestamp2 = nextLocation.createdTime; |
||||
TimeSpan timeDifference = TimeSpan.FromMilliseconds(timestamp2 - timestamp1); |
||||
// 获取时间差的毫秒数 |
||||
var timespan = (float)timeDifference.TotalMilliseconds / 1000; |
||||
if (trackAgent != null) |
||||
{ |
||||
// 设置位置 |
||||
//var position = new Vector3(-(float)currentLocation.xAxis, 0f, -(float)currentLocation.yAxis); |
||||
//position.y = SetY(trackAgent.transform.position); |
||||
//trackAgent.GetComponent<AgentController>().MoveTo(position, currentLocation.createdTime, currentLocation.targetNo); |
||||
trackAgent.GetComponent<AgentController>().UpdatePosition(trackLocationData[i]); |
||||
} |
||||
|
||||
// 等待间隔时间 |
||||
yield return new WaitForSecondsRealtime(timespan); |
||||
|
||||
} |
||||
} |
||||
} |
||||
#endregion |
||||
/// <summary> |
||||
/// 实时数据 |
||||
/// </summary> |
||||
/// <returns></returns> |
||||
private IEnumerator GetRealTimeData() |
||||
{ |
||||
while (true) |
||||
{ |
||||
var url = $"{Config.LocationServer}/le/uwbofferdata/getPositionDataByMapId/12"; |
||||
HttpManager.Instance.Get<PositionData>(url, tempData => |
||||
{ |
||||
if (tempData.errorCode != 1) |
||||
return; |
||||
if (tempData.list.Count > 0) |
||||
{ |
||||
|
||||
foreach (var data in tempData.list) |
||||
{ |
||||
// 将时间戳转换为本地的DateTime对象 |
||||
DateTime timestampDate = DateTimeOffset.FromUnixTimeMilliseconds(data.createdTime).LocalDateTime; |
||||
// 获取当前时间 |
||||
DateTime currentDate = DateTime.Now; |
||||
// 计算时间差 |
||||
TimeSpan timeDifference = currentDate - timestampDate; |
||||
|
||||
if (timeDifference.TotalSeconds <= 10) |
||||
{ |
||||
|
||||
if (agentControllers.ContainsKey(data.targetNo)) |
||||
{ |
||||
agentControllers[data.targetNo].UpdatePosition(data); |
||||
} |
||||
else |
||||
{ |
||||
var agent = CreateAgent(data); |
||||
agentControllers.Add(data.targetNo, agent); |
||||
} |
||||
|
||||
} |
||||
else |
||||
{ |
||||
if (data.targetNo == 10774520) |
||||
Debug.Log("时间戳与当前时间不匹配" + "-定位卡号:" + data.targetNo + "时间:" + timestampDate + "-基站" + data.stations); |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (isSaveHistory) |
||||
historyData.Add(tempData); |
||||
|
||||
}); |
||||
|
||||
//刷新数据 |
||||
yield return new WaitForSeconds(Config.Interval); |
||||
} |
||||
} |
||||
|
||||
|
||||
/// <summary> |
||||
/// 确保角色始终在地面上 |
||||
/// </summary> |
||||
/// <param name="position"></param> |
||||
/// <returns></returns> |
||||
public float SetY(Vector3 position) |
||||
{ |
||||
RaycastHit hit; |
||||
if (Physics.Raycast(position, Vector3.down, out hit, Mathf.Infinity, layerMask)) |
||||
{ |
||||
// 如果射线击中地面,设置Y轴为地面高度 |
||||
return hit.point.y; |
||||
} |
||||
return 0f; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 创建agent对象 |
||||
/// </summary> |
||||
/// <param name="targetNo"></param> |
||||
/// <param name="position"></param> |
||||
/// <returns></returns> |
||||
private AgentController CreateAgent(LocationData data) |
||||
{ |
||||
if (characterCount > 5) |
||||
characterCount = 0; |
||||
//var obj = Instantiate(character); |
||||
characterCount++; |
||||
var obj = Instantiate(Resources.Load($"Characters/Character{characterCount}")) as GameObject; |
||||
var pos = ConversionTransform(data); |
||||
obj.transform.position = pos; |
||||
obj.name = $"Agent {data.targetNo}"; |
||||
// 添加控制器脚本 |
||||
obj.AddComponent<AgentController>(); |
||||
var controller = obj.GetComponent<AgentController>(); |
||||
controller.targetNo = data.targetNo; |
||||
controller.ShowStatus(data.createdTime, data.targetNo); |
||||
controller.SetToNvMesh(pos); |
||||
SetActive(obj,data); |
||||
return controller; |
||||
|
||||
} |
||||
/// <summary> |
||||
/// 实例化后判断是否显示 |
||||
/// </summary> |
||||
/// <param name="agent"></param> |
||||
/// <param name="data"></param> |
||||
private void SetActive(GameObject agent, LocationData data) |
||||
{ |
||||
//var panel = UIManager.Instance.GetView<EmployeeFilePanel>(); |
||||
//var item = panel.items.Find(go => go.name == data.targetNo.ToString()); |
||||
//if(item != null) |
||||
//{ |
||||
// agent.SetChildrenActive(item.show.isOn); |
||||
//} |
||||
} |
||||
/// <summary> |
||||
/// 根据数据转换到Unity坐标 |
||||
/// </summary> |
||||
/// <param name="data"></param> |
||||
/// <returns></returns> |
||||
public Vector3 ConversionTransform(LocationData data) |
||||
{ |
||||
var y = 0f; |
||||
if(data.stations.Contains("1020")) |
||||
y = -0.5f; |
||||
else |
||||
y = 0.5f; |
||||
|
||||
var pos = new Vector3(-(float)data.xAxis, y, -(float)data.yAxis/1.057f); |
||||
pos.y = SetY(pos); |
||||
|
||||
if(data.stations.Contains("1040,1150")) |
||||
{ |
||||
pos.z = 6.25f; |
||||
if (pos.x < 7.5f) |
||||
pos.x = 7.5f; |
||||
if(pos.x>15) |
||||
pos.x = 15; |
||||
} |
||||
|
||||
if (data.stations.Contains("1040,1020")) |
||||
{ |
||||
pos.z = 8.15f; |
||||
if (pos.x < 7.5f) |
||||
pos.x = 7.5f; |
||||
if (pos.x > 14.5f) |
||||
pos.x = 14.5f; |
||||
} |
||||
|
||||
if (data.stations.Contains("1160")) |
||||
pos.z = 4.65f; |
||||
|
||||
return pos; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: b5b8b2c8e74ce544f878df610467aa59 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,29 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
[Serializable] |
||||
public class PositionData |
||||
{ |
||||
public int errorCode; |
||||
public List<LocationData> list; |
||||
} |
||||
[Serializable] |
||||
public class LocationData |
||||
{ |
||||
public string algorithm; |
||||
public string group; |
||||
//地图编号 |
||||
public int mapId; |
||||
//X坐标 |
||||
public double xAxis; |
||||
//Y坐标 |
||||
public double yAxis; |
||||
//Z坐标 |
||||
public double zAxis; |
||||
//收到数据时间 |
||||
public long createdTime; |
||||
//标签编号 |
||||
public long targetNo; |
||||
public string stations; |
||||
} |
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: dc0c270cc052d9f42ac5b8ec3acec05e |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,29 @@
|
||||
using AX.MessageSystem; |
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
|
||||
public class TrackPlayback : MonoBehaviour |
||||
{ |
||||
public long targetNo; |
||||
|
||||
private void Start() |
||||
{ |
||||
MessageDispatcher.AddListener("TRACKPLAYBACK",OnTrackPlayback,targetNo.ToString()); |
||||
GetComponent<Toggle>().onValueChanged.AddListener(v => |
||||
{ |
||||
Main.LocationSimulator.GetTrackPlaybackData(v, targetNo); |
||||
}); |
||||
} |
||||
|
||||
private void OnTrackPlayback(IMessage message) |
||||
{ |
||||
var value = (bool)message.Data; |
||||
|
||||
GetComponent<Toggle>().isOn = value; |
||||
} |
||||
|
||||
private void OnDestroy() |
||||
{ |
||||
MessageDispatcher.RemoveListener("TRACKPLAYBACK", OnTrackPlayback, targetNo.ToString()); |
||||
} |
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 80ab6927a90600a49b1d7d9278df89e6 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,19 @@
|
||||
using UnityEngine; |
||||
|
||||
public class Main : MonoBehaviour |
||||
{ |
||||
public static LocationSimulator LocationSimulator { get; private set; } |
||||
public static EventManager Event { get; set; } |
||||
|
||||
private void Awake() |
||||
{ |
||||
DontDestroyOnLoad(this); |
||||
LocationSimulator = GetComponentInChildren<LocationSimulator>(); |
||||
Event = GetComponentInChildren<EventManager>(); |
||||
} |
||||
private void OnDestroy() |
||||
{ |
||||
Event = null; |
||||
LocationSimulator = null; |
||||
} |
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 81619809ed7401c42a993dcd042e4967 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,137 @@
|
||||
%YAML 1.1 |
||||
%TAG !u! tag:unity3d.com,2011: |
||||
--- !u!1 &9058738664880783783 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
serializedVersion: 6 |
||||
m_Component: |
||||
- component: {fileID: 9058738664880783780} |
||||
- component: {fileID: 9058738664880783781} |
||||
m_Layer: 0 |
||||
m_Name: EventManager |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!4 &9058738664880783780 |
||||
Transform: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 9058738664880783783} |
||||
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: 9058738665975546261} |
||||
m_RootOrder: 1 |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
--- !u!114 &9058738664880783781 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 9058738664880783783} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: 888db11086d6dff48be7aec5e47e0432, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
--- !u!1 &9058738665440617401 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
serializedVersion: 6 |
||||
m_Component: |
||||
- component: {fileID: 9058738665440617406} |
||||
- component: {fileID: 9058738665440617407} |
||||
m_Layer: 0 |
||||
m_Name: LocationSimulator |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!4 &9058738665440617406 |
||||
Transform: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 9058738665440617401} |
||||
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: 9058738665975546261} |
||||
m_RootOrder: 0 |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
--- !u!114 &9058738665440617407 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 9058738665440617401} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: b5b8b2c8e74ce544f878df610467aa59, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
isSaveHistory: 0 |
||||
layerMask: |
||||
serializedVersion: 2 |
||||
m_Bits: 4294967295 |
||||
--- !u!1 &9058738665975546263 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
serializedVersion: 6 |
||||
m_Component: |
||||
- component: {fileID: 9058738665975546261} |
||||
- component: {fileID: 9058738665975546260} |
||||
m_Layer: 0 |
||||
m_Name: Main |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!4 &9058738665975546261 |
||||
Transform: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 9058738665975546263} |
||||
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: 9058738665440617406} |
||||
- {fileID: 9058738664880783780} |
||||
m_Father: {fileID: 0} |
||||
m_RootOrder: 0 |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
--- !u!114 &9058738665975546260 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 9058738665975546263} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: 81619809ed7401c42a993dcd042e4967, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 4824139d1e71d7345b9314892b98184e |
||||
PrefabImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 3b4abe4362d385b438ed673b2dba7f29 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9ac31e2a6a87d42428fc128181c54790 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,18 @@
|
||||
{ |
||||
"name": "AillieoUtils.UnityDynamicScrollView.Editor", |
||||
"rootNamespace": "", |
||||
"references": [ |
||||
"AillieoUtils.UnityDynamicScrollView" |
||||
], |
||||
"includePlatforms": [ |
||||
"Editor" |
||||
], |
||||
"excludePlatforms": [], |
||||
"allowUnsafeCode": false, |
||||
"overrideReferences": false, |
||||
"precompiledReferences": [], |
||||
"autoReferenced": true, |
||||
"defineConstraints": [], |
||||
"versionDefines": [], |
||||
"noEngineReferences": false |
||||
} |
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 8254afa3a0c1ae84cb4f46c31dba3655 |
||||
AssemblyDefinitionImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,267 @@
|
||||
// ----------------------------------------------------------------------- |
||||
// <copyright file="ScrollViewEditor.cs" company="AillieoTech"> |
||||
// Copyright (c) AillieoTech. All rights reserved. |
||||
// </copyright> |
||||
// ----------------------------------------------------------------------- |
||||
|
||||
namespace AillieoUtils |
||||
{ |
||||
using System; |
||||
using System.Linq; |
||||
using System.Reflection; |
||||
using UnityEditor; |
||||
using UnityEditor.UI; |
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
|
||||
[CustomEditor(typeof(ScrollView))] |
||||
public class ScrollViewEditor : ScrollRectEditor |
||||
{ |
||||
private const string bgPath = "UI/Skin/Background.psd"; |
||||
private const string spritePath = "UI/Skin/UISprite.psd"; |
||||
private const string maskPath = "UI/Skin/UIMask.psd"; |
||||
private static Color panelColor = new Color(1f, 1f, 1f, 0.392f); |
||||
private static Color defaultSelectableColor = new Color(1f, 1f, 1f, 1f); |
||||
private static Vector2 thinElementSize = new Vector2(160f, 20f); |
||||
private static Action<GameObject, MenuCommand> PlaceUIElementRoot; |
||||
|
||||
private SerializedProperty itemTemplate; |
||||
private SerializedProperty poolSize; |
||||
private SerializedProperty defaultItemSize; |
||||
private SerializedProperty layoutType; |
||||
|
||||
private GUIStyle cachedCaption; |
||||
|
||||
private GUIStyle caption |
||||
{ |
||||
get |
||||
{ |
||||
if (this.cachedCaption == null) |
||||
{ |
||||
this.cachedCaption = new GUIStyle { richText = true, alignment = TextAnchor.MiddleCenter }; |
||||
} |
||||
|
||||
return this.cachedCaption; |
||||
} |
||||
} |
||||
|
||||
public override void OnInspectorGUI() |
||||
{ |
||||
this.serializedObject.Update(); |
||||
|
||||
EditorGUILayout.BeginVertical("box"); |
||||
EditorGUILayout.LabelField("<b>Additional configs</b>", this.caption); |
||||
EditorGUILayout.Space(5); |
||||
this.DrawConfigInfo(); |
||||
this.serializedObject.ApplyModifiedProperties(); |
||||
EditorGUILayout.EndVertical(); |
||||
|
||||
EditorGUILayout.BeginVertical("box"); |
||||
EditorGUILayout.LabelField("<b>For original ScrollRect</b>", this.caption); |
||||
EditorGUILayout.Space(5); |
||||
base.OnInspectorGUI(); |
||||
EditorGUILayout.EndVertical(); |
||||
} |
||||
|
||||
protected static void InternalAddScrollView<T>(MenuCommand menuCommand) |
||||
where T : ScrollView |
||||
{ |
||||
GetPrivateMethodByReflection(); |
||||
|
||||
GameObject root = CreateUIElementRoot(typeof(T).Name, new Vector2(200, 200)); |
||||
PlaceUIElementRoot?.Invoke(root, menuCommand); |
||||
|
||||
GameObject viewport = CreateUIObject("Viewport", root); |
||||
GameObject content = CreateUIObject("Content", viewport); |
||||
|
||||
var parent = menuCommand.context as GameObject; |
||||
if (parent != null) |
||||
{ |
||||
root.transform.SetParent(parent.transform, false); |
||||
} |
||||
|
||||
Selection.activeGameObject = root; |
||||
|
||||
GameObject hScrollbar = CreateScrollbar(); |
||||
hScrollbar.name = "Scrollbar Horizontal"; |
||||
hScrollbar.transform.SetParent(root.transform, false); |
||||
RectTransform hScrollbarRT = hScrollbar.GetComponent<RectTransform>(); |
||||
hScrollbarRT.anchorMin = Vector2.zero; |
||||
hScrollbarRT.anchorMax = Vector2.right; |
||||
hScrollbarRT.pivot = Vector2.zero; |
||||
hScrollbarRT.sizeDelta = new Vector2(0, hScrollbarRT.sizeDelta.y); |
||||
|
||||
GameObject vScrollbar = CreateScrollbar(); |
||||
vScrollbar.name = "Scrollbar Vertical"; |
||||
vScrollbar.transform.SetParent(root.transform, false); |
||||
vScrollbar.GetComponent<Scrollbar>().SetDirection(Scrollbar.Direction.BottomToTop, true); |
||||
RectTransform vScrollbarRT = vScrollbar.GetComponent<RectTransform>(); |
||||
vScrollbarRT.anchorMin = Vector2.right; |
||||
vScrollbarRT.anchorMax = Vector2.one; |
||||
vScrollbarRT.pivot = Vector2.one; |
||||
vScrollbarRT.sizeDelta = new Vector2(vScrollbarRT.sizeDelta.x, 0); |
||||
|
||||
RectTransform viewportRect = viewport.GetComponent<RectTransform>(); |
||||
viewportRect.anchorMin = Vector2.zero; |
||||
viewportRect.anchorMax = Vector2.one; |
||||
viewportRect.sizeDelta = Vector2.zero; |
||||
viewportRect.pivot = Vector2.up; |
||||
|
||||
RectTransform contentRect = content.GetComponent<RectTransform>(); |
||||
contentRect.anchorMin = Vector2.up; |
||||
contentRect.anchorMax = Vector2.one; |
||||
contentRect.sizeDelta = new Vector2(0, 300); |
||||
contentRect.pivot = Vector2.up; |
||||
|
||||
ScrollView scrollRect = root.AddComponent<T>(); |
||||
scrollRect.content = contentRect; |
||||
scrollRect.viewport = viewportRect; |
||||
scrollRect.horizontalScrollbar = hScrollbar.GetComponent<Scrollbar>(); |
||||
scrollRect.verticalScrollbar = vScrollbar.GetComponent<Scrollbar>(); |
||||
scrollRect.horizontalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport; |
||||
scrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport; |
||||
scrollRect.horizontalScrollbarSpacing = -3; |
||||
scrollRect.verticalScrollbarSpacing = -3; |
||||
|
||||
Image rootImage = root.AddComponent<Image>(); |
||||
rootImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(bgPath); |
||||
rootImage.type = Image.Type.Sliced; |
||||
rootImage.color = panelColor; |
||||
|
||||
Mask viewportMask = viewport.AddComponent<Mask>(); |
||||
viewportMask.showMaskGraphic = false; |
||||
|
||||
Image viewportImage = viewport.AddComponent<Image>(); |
||||
viewportImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(maskPath); |
||||
viewportImage.type = Image.Type.Sliced; |
||||
} |
||||
|
||||
protected override void OnEnable() |
||||
{ |
||||
base.OnEnable(); |
||||
|
||||
this.itemTemplate = this.serializedObject.FindProperty("itemTemplate"); |
||||
this.poolSize = this.serializedObject.FindProperty("poolSize"); |
||||
this.defaultItemSize = this.serializedObject.FindProperty("defaultItemSize"); |
||||
this.layoutType = this.serializedObject.FindProperty("layoutType"); |
||||
} |
||||
|
||||
protected virtual void DrawConfigInfo() |
||||
{ |
||||
EditorGUILayout.PropertyField(this.itemTemplate); |
||||
EditorGUILayout.PropertyField(this.poolSize); |
||||
EditorGUILayout.PropertyField(this.defaultItemSize); |
||||
this.layoutType.intValue = (int)(ScrollView.ItemLayoutType)EditorGUILayout.EnumPopup("layoutType", (ScrollView.ItemLayoutType)this.layoutType.intValue); |
||||
} |
||||
|
||||
[MenuItem("GameObject/UI/DynamicScrollView", false, 90)] |
||||
private static void AddScrollView(MenuCommand menuCommand) |
||||
{ |
||||
InternalAddScrollView<ScrollView>(menuCommand); |
||||
} |
||||
|
||||
private static GameObject CreateScrollbar() |
||||
{ |
||||
// Create GOs Hierarchy |
||||
GameObject scrollbarRoot = CreateUIElementRoot("Scrollbar", thinElementSize); |
||||
GameObject sliderArea = CreateUIObject("Sliding Area", scrollbarRoot); |
||||
GameObject handle = CreateUIObject("Handle", sliderArea); |
||||
|
||||
Image bgImage = scrollbarRoot.AddComponent<Image>(); |
||||
bgImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(bgPath); |
||||
bgImage.type = Image.Type.Sliced; |
||||
bgImage.color = defaultSelectableColor; |
||||
|
||||
Image handleImage = handle.AddComponent<Image>(); |
||||
handleImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(spritePath); |
||||
handleImage.type = Image.Type.Sliced; |
||||
handleImage.color = defaultSelectableColor; |
||||
|
||||
RectTransform sliderAreaRect = sliderArea.GetComponent<RectTransform>(); |
||||
sliderAreaRect.sizeDelta = new Vector2(-20, -20); |
||||
sliderAreaRect.anchorMin = Vector2.zero; |
||||
sliderAreaRect.anchorMax = Vector2.one; |
||||
|
||||
RectTransform handleRect = handle.GetComponent<RectTransform>(); |
||||
handleRect.sizeDelta = new Vector2(20, 20); |
||||
|
||||
Scrollbar scrollbar = scrollbarRoot.AddComponent<Scrollbar>(); |
||||
scrollbar.handleRect = handleRect; |
||||
scrollbar.targetGraphic = handleImage; |
||||
SetDefaultColorTransitionValues(scrollbar); |
||||
|
||||
return scrollbarRoot; |
||||
} |
||||
|
||||
private static GameObject CreateUIElementRoot(string name, Vector2 size) |
||||
{ |
||||
var child = new GameObject(name); |
||||
RectTransform rectTransform = child.AddComponent<RectTransform>(); |
||||
rectTransform.sizeDelta = size; |
||||
return child; |
||||
} |
||||
|
||||
private static GameObject CreateUIObject(string name, GameObject parent) |
||||
{ |
||||
var go = new GameObject(name); |
||||
go.AddComponent<RectTransform>(); |
||||
SetParentAndAlign(go, parent); |
||||
return go; |
||||
} |
||||
|
||||
private static void SetParentAndAlign(GameObject child, GameObject parent) |
||||
{ |
||||
if (parent == null) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
child.transform.SetParent(parent.transform, false); |
||||
SetLayerRecursively(child, parent.layer); |
||||
} |
||||
|
||||
private static void SetLayerRecursively(GameObject go, int layer) |
||||
{ |
||||
go.layer = layer; |
||||
Transform t = go.transform; |
||||
for (var i = 0; i < t.childCount; i++) |
||||
{ |
||||
SetLayerRecursively(t.GetChild(i).gameObject, layer); |
||||
} |
||||
} |
||||
|
||||
private static void SetDefaultColorTransitionValues(Selectable slider) |
||||
{ |
||||
ColorBlock colors = slider.colors; |
||||
colors.highlightedColor = new Color(0.882f, 0.882f, 0.882f); |
||||
colors.pressedColor = new Color(0.698f, 0.698f, 0.698f); |
||||
colors.disabledColor = new Color(0.521f, 0.521f, 0.521f); |
||||
} |
||||
|
||||
private static void GetPrivateMethodByReflection() |
||||
{ |
||||
if (PlaceUIElementRoot == null) |
||||
{ |
||||
Assembly uiEditorAssembly = AppDomain.CurrentDomain.GetAssemblies() |
||||
.FirstOrDefault(asm => asm.GetName().Name == "UnityEditor.UI"); |
||||
if (uiEditorAssembly != null) |
||||
{ |
||||
Type menuOptionType = uiEditorAssembly.GetType("UnityEditor.UI.MenuOptions"); |
||||
if (menuOptionType != null) |
||||
{ |
||||
MethodInfo miPlaceUIElementRoot = menuOptionType.GetMethod( |
||||
"PlaceUIElementRoot", |
||||
BindingFlags.NonPublic | BindingFlags.Static); |
||||
if (miPlaceUIElementRoot != null) |
||||
{ |
||||
PlaceUIElementRoot = Delegate.CreateDelegate( |
||||
typeof(Action<GameObject, MenuCommand>), |
||||
miPlaceUIElementRoot) |
||||
as Action<GameObject, MenuCommand>; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 8518bb829bc508049a52f0606b4f43a5 |
||||
timeCreated: 1533042733 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,34 @@
|
||||
// ----------------------------------------------------------------------- |
||||
// <copyright file="ScrollViewExEditor.cs" company="AillieoTech"> |
||||
// Copyright (c) AillieoTech. All rights reserved. |
||||
// </copyright> |
||||
// ----------------------------------------------------------------------- |
||||
|
||||
namespace AillieoUtils |
||||
{ |
||||
using UnityEditor; |
||||
|
||||
[CustomEditor(typeof(ScrollViewEx))] |
||||
public class ScrollViewExEditor : ScrollViewEditor |
||||
{ |
||||
private SerializedProperty pageSize; |
||||
|
||||
protected override void OnEnable() |
||||
{ |
||||
base.OnEnable(); |
||||
this.pageSize = this.serializedObject.FindProperty("pageSize"); |
||||
} |
||||
|
||||
protected override void DrawConfigInfo() |
||||
{ |
||||
base.DrawConfigInfo(); |
||||
EditorGUILayout.PropertyField(this.pageSize); |
||||
} |
||||
|
||||
[MenuItem("GameObject/UI/DynamicScrollViewEx", false, 90)] |
||||
private static void AddScrollViewEx(MenuCommand menuCommand) |
||||
{ |
||||
InternalAddScrollView<ScrollViewEx>(menuCommand); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 12cd1055a4162f842842a60918857100 |
||||
timeCreated: 1533042733 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 934f7beec05a7044cad47dc2487d1b24 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,490 @@
|
||||
%YAML 1.1 |
||||
%TAG !u! tag:unity3d.com,2011: |
||||
--- !u!1 &3709271829403358370 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
serializedVersion: 6 |
||||
m_Component: |
||||
- component: {fileID: 3709271829403358373} |
||||
- component: {fileID: 3709271829403358375} |
||||
- component: {fileID: 3709271829403358372} |
||||
m_Layer: 5 |
||||
m_Name: Handle |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!224 &3709271829403358373 |
||||
RectTransform: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271829403358370} |
||||
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_ConstrainProportionsScale: 0 |
||||
m_Children: [] |
||||
m_Father: {fileID: 3709271829717700148} |
||||
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: 8, y: 20} |
||||
m_Pivot: {x: 0.5, y: 0.5} |
||||
--- !u!222 &3709271829403358375 |
||||
CanvasRenderer: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271829403358370} |
||||
m_CullTransparentMesh: 0 |
||||
--- !u!114 &3709271829403358372 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271829403358370} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Material: {fileID: 0} |
||||
m_Color: {r: 0.21568628, g: 0.94509804, b: 1, a: 0.3254902} |
||||
m_RaycastTarget: 1 |
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} |
||||
m_Maskable: 1 |
||||
m_OnCullStateChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
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 |
||||
m_UseSpriteMesh: 0 |
||||
m_PixelsPerUnitMultiplier: 1 |
||||
--- !u!1 &3709271829717700149 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
serializedVersion: 6 |
||||
m_Component: |
||||
- component: {fileID: 3709271829717700148} |
||||
m_Layer: 5 |
||||
m_Name: Sliding Area |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!224 &3709271829717700148 |
||||
RectTransform: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271829717700149} |
||||
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_ConstrainProportionsScale: 0 |
||||
m_Children: |
||||
- {fileID: 3709271829403358373} |
||||
m_Father: {fileID: 3709271830637054744} |
||||
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: -8, y: -20} |
||||
m_Pivot: {x: 0.5, y: 0.5} |
||||
--- !u!1 &3709271830102431829 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
serializedVersion: 6 |
||||
m_Component: |
||||
- component: {fileID: 3709271830102431828} |
||||
- component: {fileID: 3679557676129440665} |
||||
m_Layer: 5 |
||||
m_Name: Content |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!224 &3709271830102431828 |
||||
RectTransform: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830102431829} |
||||
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_ConstrainProportionsScale: 0 |
||||
m_Children: [] |
||||
m_Father: {fileID: 3709271830862119990} |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
m_AnchorMin: {x: 0, y: 1} |
||||
m_AnchorMax: {x: 1, y: 1} |
||||
m_AnchoredPosition: {x: 0, y: 25.00384} |
||||
m_SizeDelta: {x: 0, y: 745} |
||||
m_Pivot: {x: 0, y: 1} |
||||
--- !u!114 &3679557676129440665 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830102431829} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: 2fafe2cfe61f6974895a912c3755e8f1, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_AllowSwitchOff: 1 |
||||
--- !u!1 &3709271830637054745 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
serializedVersion: 6 |
||||
m_Component: |
||||
- component: {fileID: 3709271830637054744} |
||||
- component: {fileID: 3709271830637054749} |
||||
- component: {fileID: 3709271830637054746} |
||||
- component: {fileID: 3709271830637054747} |
||||
m_Layer: 5 |
||||
m_Name: Scrollbar Vertical |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!224 &3709271830637054744 |
||||
RectTransform: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830637054745} |
||||
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_ConstrainProportionsScale: 0 |
||||
m_Children: |
||||
- {fileID: 3709271829717700148} |
||||
m_Father: {fileID: 3709271830742558232} |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
m_AnchorMin: {x: 1, y: 0} |
||||
m_AnchorMax: {x: 1, y: 1} |
||||
m_AnchoredPosition: {x: 10, y: 0} |
||||
m_SizeDelta: {x: 8, y: 0} |
||||
m_Pivot: {x: 1, y: 1} |
||||
--- !u!222 &3709271830637054749 |
||||
CanvasRenderer: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830637054745} |
||||
m_CullTransparentMesh: 0 |
||||
--- !u!114 &3709271830637054746 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830637054745} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Material: {fileID: 0} |
||||
m_Color: {r: 1, g: 1, b: 1, a: 0} |
||||
m_RaycastTarget: 1 |
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} |
||||
m_Maskable: 1 |
||||
m_OnCullStateChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} |
||||
m_Type: 1 |
||||
m_PreserveAspect: 0 |
||||
m_FillCenter: 1 |
||||
m_FillMethod: 4 |
||||
m_FillAmount: 1 |
||||
m_FillClockwise: 1 |
||||
m_FillOrigin: 0 |
||||
m_UseSpriteMesh: 0 |
||||
m_PixelsPerUnitMultiplier: 1 |
||||
--- !u!114 &3709271830637054747 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830637054745} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Navigation: |
||||
m_Mode: 3 |
||||
m_WrapAround: 0 |
||||
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_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, 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_SelectedSprite: {fileID: 0} |
||||
m_DisabledSprite: {fileID: 0} |
||||
m_AnimationTriggers: |
||||
m_NormalTrigger: Normal |
||||
m_HighlightedTrigger: Highlighted |
||||
m_PressedTrigger: Pressed |
||||
m_SelectedTrigger: Selected |
||||
m_DisabledTrigger: Disabled |
||||
m_Interactable: 1 |
||||
m_TargetGraphic: {fileID: 3709271829403358372} |
||||
m_HandleRect: {fileID: 3709271829403358373} |
||||
m_Direction: 2 |
||||
m_Value: -0.00015380859 |
||||
m_Size: 0.96257234 |
||||
m_NumberOfSteps: 0 |
||||
m_OnValueChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
--- !u!1 &3709271830742558233 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
serializedVersion: 6 |
||||
m_Component: |
||||
- component: {fileID: 3709271830742558232} |
||||
- component: {fileID: 3709271830742558236} |
||||
- component: {fileID: 3709271830742558237} |
||||
- component: {fileID: 8808391433916102189} |
||||
m_Layer: 5 |
||||
m_Name: VerticalScrollView |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!224 &3709271830742558232 |
||||
RectTransform: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830742558233} |
||||
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_ConstrainProportionsScale: 0 |
||||
m_Children: |
||||
- {fileID: 3709271830862119990} |
||||
- {fileID: 3709271830637054744} |
||||
m_Father: {fileID: 0} |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
m_AnchorMin: {x: 0.5, y: 0} |
||||
m_AnchorMax: {x: 0.5, y: 1} |
||||
m_AnchoredPosition: {x: 0, y: -12.5} |
||||
m_SizeDelta: {x: 390, y: -105} |
||||
m_Pivot: {x: 0.5, y: 0.5} |
||||
--- !u!222 &3709271830742558236 |
||||
CanvasRenderer: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830742558233} |
||||
m_CullTransparentMesh: 0 |
||||
--- !u!114 &3709271830742558237 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830742558233} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Material: {fileID: 0} |
||||
m_Color: {r: 1, g: 1, b: 1, a: 0} |
||||
m_RaycastTarget: 1 |
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} |
||||
m_Maskable: 1 |
||||
m_OnCullStateChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} |
||||
m_Type: 1 |
||||
m_PreserveAspect: 0 |
||||
m_FillCenter: 1 |
||||
m_FillMethod: 4 |
||||
m_FillAmount: 1 |
||||
m_FillClockwise: 1 |
||||
m_FillOrigin: 0 |
||||
m_UseSpriteMesh: 0 |
||||
m_PixelsPerUnitMultiplier: 1 |
||||
--- !u!114 &8808391433916102189 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830742558233} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: 2d355eec575560046ba27246695b84ad, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Content: {fileID: 3709271830102431828} |
||||
m_Horizontal: 0 |
||||
m_Vertical: 1 |
||||
m_MovementType: 1 |
||||
m_Elasticity: 0.1 |
||||
m_Inertia: 1 |
||||
m_DecelerationRate: 0.135 |
||||
m_ScrollSensitivity: 1 |
||||
m_Viewport: {fileID: 3709271830862119990} |
||||
m_HorizontalScrollbar: {fileID: 0} |
||||
m_VerticalScrollbar: {fileID: 3709271830637054747} |
||||
m_HorizontalScrollbarVisibility: 0 |
||||
m_VerticalScrollbarVisibility: 2 |
||||
m_HorizontalScrollbarSpacing: 0 |
||||
m_VerticalScrollbarSpacing: -3 |
||||
m_OnValueChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
defaultItemSize: {x: 390, y: 35} |
||||
itemTemplate: {fileID: 0} |
||||
layoutType: 1 |
||||
poolSize: 200 |
||||
--- !u!1 &3709271830862119991 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
serializedVersion: 6 |
||||
m_Component: |
||||
- component: {fileID: 3709271830862119990} |
||||
- component: {fileID: 3709271830862119947} |
||||
- component: {fileID: 3709271830862119944} |
||||
- component: {fileID: 3709271830862119945} |
||||
m_Layer: 5 |
||||
m_Name: Viewport |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!224 &3709271830862119990 |
||||
RectTransform: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830862119991} |
||||
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_ConstrainProportionsScale: 0 |
||||
m_Children: |
||||
- {fileID: 3709271830102431828} |
||||
m_Father: {fileID: 3709271830742558232} |
||||
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, y: 1} |
||||
--- !u!222 &3709271830862119947 |
||||
CanvasRenderer: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830862119991} |
||||
m_CullTransparentMesh: 0 |
||||
--- !u!114 &3709271830862119944 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830862119991} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Material: {fileID: 0} |
||||
m_Color: {r: 1, g: 1, b: 1, a: 1} |
||||
m_RaycastTarget: 1 |
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} |
||||
m_Maskable: 1 |
||||
m_OnCullStateChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
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 |
||||
m_UseSpriteMesh: 0 |
||||
m_PixelsPerUnitMultiplier: 1 |
||||
--- !u!114 &3709271830862119945 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 0 |
||||
m_CorrespondingSourceObject: {fileID: 0} |
||||
m_PrefabInstance: {fileID: 0} |
||||
m_PrefabAsset: {fileID: 0} |
||||
m_GameObject: {fileID: 3709271830862119991} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_ShowMaskGraphic: 0 |
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a3c05a63b89cee44294ee69c283ebaa2 |
||||
PrefabImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 6d059c374f38f1a4d8e4adb7f375e9e8 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,13 @@
|
||||
{ |
||||
"name": "AillieoUtils.UnityDynamicScrollView", |
||||
"references": [], |
||||
"includePlatforms": [], |
||||
"excludePlatforms": [], |
||||
"allowUnsafeCode": false, |
||||
"overrideReferences": false, |
||||
"precompiledReferences": [], |
||||
"autoReferenced": true, |
||||
"defineConstraints": [], |
||||
"versionDefines": [], |
||||
"noEngineReferences": false |
||||
} |
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9bff4ab8c2b0f4d2780540e2780db4ce |
||||
AssemblyDefinitionImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: f0676fa1c0082e2408572d35067b7caa |
||||
folderAsset: yes |
||||
timeCreated: 1533284978 |
||||
licenseType: Free |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,92 @@
|
||||
// ----------------------------------------------------------------------- |
||||
// <copyright file="SimpleObjPool.cs" company="AillieoTech"> |
||||
// Copyright (c) AillieoTech. All rights reserved. |
||||
// </copyright> |
||||
// ----------------------------------------------------------------------- |
||||
|
||||
namespace AillieoUtils |
||||
{ |
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
public class SimpleObjPool<T> |
||||
{ |
||||
private readonly Stack<T> stack; |
||||
private readonly Func<T> ctor; |
||||
private readonly Action<T> onRecycle; |
||||
private readonly Action<T> dtor; |
||||
private int size; |
||||
private int usedCount; |
||||
|
||||
public SimpleObjPool(int max = 5, Action<T> onRecycle = null, Func<T> ctor = null, Action<T> dtor = null) |
||||
{ |
||||
this.stack = new Stack<T>(max); |
||||
this.size = max; |
||||
this.onRecycle = onRecycle; |
||||
this.ctor = ctor; |
||||
this.dtor = dtor; |
||||
} |
||||
|
||||
public T Get() |
||||
{ |
||||
T item; |
||||
if (this.stack.Count == 0) |
||||
{ |
||||
if (this.ctor != null) |
||||
{ |
||||
item = this.ctor(); |
||||
} |
||||
else |
||||
{ |
||||
item = Activator.CreateInstance<T>(); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
item = this.stack.Pop(); |
||||
} |
||||
|
||||
this.usedCount++; |
||||
return item; |
||||
} |
||||
|
||||
public void Recycle(T item) |
||||
{ |
||||
if (this.onRecycle != null) |
||||
{ |
||||
this.onRecycle.Invoke(item); |
||||
} |
||||
|
||||
if (this.stack.Count < this.size) |
||||
{ |
||||
this.stack.Push(item); |
||||
} |
||||
else |
||||
{ |
||||
if (this.dtor != null) |
||||
{ |
||||
this.dtor.Invoke(item); |
||||
} |
||||
} |
||||
|
||||
this.usedCount--; |
||||
} |
||||
|
||||
public void Purge() |
||||
{ |
||||
while (this.stack.Count > 0) |
||||
{ |
||||
var item = this.stack.Pop(); |
||||
if (this.dtor != null) |
||||
{ |
||||
this.dtor.Invoke(item); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return $"SimpleObjPool: item=[{typeof(T)}], inUse=[{this.usedCount}], restInPool=[{this.stack.Count}/{this.size}] "; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 779a3e961157c3f468ebe1db83df1e8d |
||||
timeCreated: 1533284979 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 94da82d2b551d1e4da1543a8beb76371 |
||||
folderAsset: yes |
||||
timeCreated: 1533284978 |
||||
licenseType: Free |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,871 @@
|
||||
// ----------------------------------------------------------------------- |
||||
// <copyright file="ScrollView.cs" company="AillieoTech"> |
||||
// Copyright (c) AillieoTech. All rights reserved. |
||||
// </copyright> |
||||
// ----------------------------------------------------------------------- |
||||
|
||||
namespace AillieoUtils |
||||
{ |
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using UnityEngine; |
||||
using UnityEngine.Serialization; |
||||
using UnityEngine.UI; |
||||
|
||||
[RequireComponent(typeof(RectTransform))] |
||||
[DisallowMultipleComponent] |
||||
public class ScrollView : ScrollRect |
||||
{ |
||||
public Action<int> selectedChanged; |
||||
[Tooltip("默认item尺寸")] |
||||
public Vector2 defaultItemSize; |
||||
|
||||
[Tooltip("item的模板")] |
||||
public RectTransform itemTemplate; |
||||
|
||||
// 0001 |
||||
protected const int flagScrollDirection = 1; |
||||
|
||||
[SerializeField] |
||||
[FormerlySerializedAs("m_layoutType")] |
||||
protected ItemLayoutType layoutType = ItemLayoutType.Vertical; |
||||
|
||||
// 只保存4个临界index |
||||
protected int[] criticalItemIndex = new int[4]; |
||||
|
||||
// callbacks for items |
||||
protected Action<int, RectTransform> updateFunc; |
||||
protected Func<int, Vector2> itemSizeFunc; |
||||
protected Func<int> itemCountFunc; |
||||
protected Func<int, RectTransform> itemGetFunc; |
||||
protected Action<RectTransform> itemRecycleFunc; |
||||
|
||||
private readonly List<ScrollItemWithRect> managedItems = new List<ScrollItemWithRect>(); |
||||
|
||||
private Rect refRect; |
||||
|
||||
// resource management |
||||
private SimpleObjPool<RectTransform> itemPool = null; |
||||
|
||||
private int dataCount = 0; |
||||
|
||||
[Tooltip("初始化时池内item数量")] |
||||
[SerializeField] |
||||
private int poolSize; |
||||
|
||||
// status |
||||
private bool initialized = false; |
||||
private int willUpdateData = 0; |
||||
|
||||
private Vector3[] viewWorldConers = new Vector3[4]; |
||||
private Vector3[] rectCorners = new Vector3[2]; |
||||
|
||||
private bool applicationIsQuitting; |
||||
|
||||
// for hide and show |
||||
public enum ItemLayoutType |
||||
{ |
||||
// 最后一位表示滚动方向 |
||||
Vertical = 0b0001, // 0001 |
||||
Horizontal = 0b0010, // 0010 |
||||
VerticalThenHorizontal = 0b0100, // 0100 |
||||
HorizontalThenVertical = 0b0101, // 0101 |
||||
} |
||||
|
||||
public virtual void SetUpdateFunc(Action<int, RectTransform> func) |
||||
{ |
||||
this.updateFunc = func; |
||||
} |
||||
|
||||
public virtual void SetItemSizeFunc(Func<int, Vector2> func) |
||||
{ |
||||
this.itemSizeFunc = func; |
||||
} |
||||
|
||||
public virtual void SetItemCountFunc(Func<int> func) |
||||
{ |
||||
this.itemCountFunc = func; |
||||
} |
||||
|
||||
public void SetItemGetAndRecycleFunc(Func<int, RectTransform> getFunc, Action<RectTransform> recycleFunc) |
||||
{ |
||||
if (getFunc != null && recycleFunc != null) |
||||
{ |
||||
this.itemGetFunc = getFunc; |
||||
this.itemRecycleFunc = recycleFunc; |
||||
} |
||||
else |
||||
{ |
||||
this.itemGetFunc = null; |
||||
this.itemRecycleFunc = null; |
||||
} |
||||
} |
||||
|
||||
public void ResetAllDelegates() |
||||
{ |
||||
this.SetUpdateFunc(null); |
||||
this.SetItemSizeFunc(null); |
||||
this.SetItemCountFunc(null); |
||||
this.SetItemGetAndRecycleFunc(null, null); |
||||
} |
||||
|
||||
public void UpdateData(bool immediately = true) |
||||
{ |
||||
if (immediately) |
||||
{ |
||||
this.willUpdateData |= 3; // 0011 |
||||
this.InternalUpdateData(); |
||||
} |
||||
else |
||||
{ |
||||
if (this.willUpdateData == 0 && this.IsActive()) |
||||
{ |
||||
this.StartCoroutine(this.DelayUpdateData()); |
||||
} |
||||
|
||||
this.willUpdateData |= 3; |
||||
} |
||||
} |
||||
|
||||
public void UpdateDataIncrementally(bool immediately = true) |
||||
{ |
||||
if (immediately) |
||||
{ |
||||
this.willUpdateData |= 1; // 0001 |
||||
this.InternalUpdateData(); |
||||
} |
||||
else |
||||
{ |
||||
if (this.willUpdateData == 0) |
||||
{ |
||||
this.StartCoroutine(this.DelayUpdateData()); |
||||
} |
||||
|
||||
this.willUpdateData |= 1; |
||||
} |
||||
} |
||||
|
||||
public void ScrollTo(int index) |
||||
{ |
||||
this.InternalScrollTo(index); |
||||
} |
||||
public void OnSelection(int index) |
||||
{ |
||||
this.InternalScrollTo(index); |
||||
selectedChanged?.Invoke(index); |
||||
} |
||||
|
||||
|
||||
protected override void OnEnable() |
||||
{ |
||||
base.OnEnable(); |
||||
if (this.willUpdateData != 0) |
||||
{ |
||||
this.StartCoroutine(this.DelayUpdateData()); |
||||
} |
||||
} |
||||
|
||||
protected override void OnDisable() |
||||
{ |
||||
this.initialized = false; |
||||
base.OnDisable(); |
||||
} |
||||
|
||||
protected virtual void InternalScrollTo(int index) |
||||
{ |
||||
index = Mathf.Clamp(index, 0, this.dataCount - 1); |
||||
this.EnsureItemRect(index); |
||||
Rect r = this.managedItems[index].rect; |
||||
var dir = (int)this.layoutType & flagScrollDirection; |
||||
if (dir == 1) |
||||
{ |
||||
// vertical |
||||
var value = 1 - (-r.yMax / (this.content.sizeDelta.y - this.refRect.height)); |
||||
value = Mathf.Clamp01(value); |
||||
this.SetNormalizedPosition(value, 1); |
||||
} |
||||
else |
||||
{ |
||||
// horizontal |
||||
var value = r.xMin / (this.content.sizeDelta.x - this.refRect.width); |
||||
value = Mathf.Clamp01(value); |
||||
this.SetNormalizedPosition(value, 0); |
||||
} |
||||
} |
||||
|
||||
protected override void SetContentAnchoredPosition(Vector2 position) |
||||
{ |
||||
base.SetContentAnchoredPosition(position); |
||||
|
||||
if (this.willUpdateData != 0) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
this.UpdateCriticalItems(); |
||||
} |
||||
|
||||
protected override void SetNormalizedPosition(float value, int axis) |
||||
{ |
||||
base.SetNormalizedPosition(value, axis); |
||||
|
||||
if (this.willUpdateData != 0) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
this.ResetCriticalItems(); |
||||
} |
||||
|
||||
protected void EnsureItemRect(int index) |
||||
{ |
||||
if (!this.managedItems[index].rectDirty) |
||||
{ |
||||
// 已经是干净的了 |
||||
return; |
||||
} |
||||
|
||||
ScrollItemWithRect firstItem = this.managedItems[0]; |
||||
if (firstItem.rectDirty) |
||||
{ |
||||
Vector2 firstSize = this.GetItemSize(0); |
||||
firstItem.rect = CreateWithLeftTopAndSize(Vector2.zero, firstSize); |
||||
firstItem.rectDirty = false; |
||||
} |
||||
|
||||
// 当前item之前的最近的已更新的rect |
||||
var nearestClean = 0; |
||||
for (var i = index; i >= 0; --i) |
||||
{ |
||||
if (!this.managedItems[i].rectDirty) |
||||
{ |
||||
nearestClean = i; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
// 需要更新 从 nearestClean 到 index 的尺寸 |
||||
Rect nearestCleanRect = this.managedItems[nearestClean].rect; |
||||
Vector2 curPos = GetLeftTop(nearestCleanRect); |
||||
Vector2 size = nearestCleanRect.size; |
||||
this.MovePos(ref curPos, size); |
||||
|
||||
for (var i = nearestClean + 1; i <= index; i++) |
||||
{ |
||||
size = this.GetItemSize(i); |
||||
this.managedItems[i].rect = CreateWithLeftTopAndSize(curPos, size); |
||||
this.managedItems[i].rectDirty = false; |
||||
this.MovePos(ref curPos, size); |
||||
} |
||||
|
||||
var range = new Vector2(Mathf.Abs(curPos.x), Mathf.Abs(curPos.y)); |
||||
switch (this.layoutType) |
||||
{ |
||||
case ItemLayoutType.VerticalThenHorizontal: |
||||
range.x += size.x; |
||||
range.y = this.refRect.height; |
||||
break; |
||||
case ItemLayoutType.HorizontalThenVertical: |
||||
range.x = this.refRect.width; |
||||
if (curPos.x != 0) |
||||
{ |
||||
range.y += size.y; |
||||
} |
||||
|
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
this.content.sizeDelta = range; |
||||
} |
||||
|
||||
protected override void OnDestroy() |
||||
{ |
||||
if (this.itemPool != null) |
||||
{ |
||||
this.itemPool.Purge(); |
||||
} |
||||
} |
||||
|
||||
protected Rect GetItemLocalRect(int index) |
||||
{ |
||||
if (index >= 0 && index < this.dataCount) |
||||
{ |
||||
this.EnsureItemRect(index); |
||||
return this.managedItems[index].rect; |
||||
} |
||||
|
||||
return (Rect)default; |
||||
} |
||||
|
||||
#if UNITY_EDITOR |
||||
protected override void OnValidate() |
||||
{ |
||||
var dir = (int)this.layoutType & flagScrollDirection; |
||||
if (dir == 1) |
||||
{ |
||||
// vertical |
||||
if (this.horizontalScrollbar != null) |
||||
{ |
||||
this.horizontalScrollbar.gameObject.SetActive(false); |
||||
this.horizontalScrollbar = null; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
// horizontal |
||||
if (this.verticalScrollbar != null) |
||||
{ |
||||
this.verticalScrollbar.gameObject.SetActive(false); |
||||
this.verticalScrollbar = null; |
||||
} |
||||
} |
||||
|
||||
base.OnValidate(); |
||||
} |
||||
#endif |
||||
|
||||
private static Vector2 GetLeftTop(Rect rect) |
||||
{ |
||||
Vector2 ret = rect.position; |
||||
ret.y += rect.size.y; |
||||
return ret; |
||||
} |
||||
|
||||
private static Rect CreateWithLeftTopAndSize(Vector2 leftTop, Vector2 size) |
||||
{ |
||||
Vector2 leftBottom = leftTop - new Vector2(0, size.y); |
||||
return new Rect(leftBottom, size); |
||||
} |
||||
|
||||
private IEnumerator DelayUpdateData() |
||||
{ |
||||
yield return new WaitForEndOfFrame(); |
||||
|
||||
this.InternalUpdateData(); |
||||
} |
||||
|
||||
private void InternalUpdateData() |
||||
{ |
||||
if (!this.IsActive()) |
||||
{ |
||||
this.willUpdateData |= 3; |
||||
return; |
||||
} |
||||
|
||||
if (!this.initialized) |
||||
{ |
||||
this.InitScrollView(); |
||||
} |
||||
|
||||
this.CheckDataCountChange(); |
||||
|
||||
this.ResetCriticalItems(); |
||||
|
||||
this.willUpdateData = 0; |
||||
} |
||||
|
||||
protected virtual void CheckDataCountChange() |
||||
{ |
||||
var newDataCount = 0; |
||||
|
||||
if (this.itemCountFunc != null) |
||||
{ |
||||
newDataCount = this.itemCountFunc(); |
||||
} |
||||
|
||||
var keepOldItems = (this.willUpdateData & 2) == 0; |
||||
|
||||
if (newDataCount != this.managedItems.Count) |
||||
{ |
||||
if (this.managedItems.Count < newDataCount) |
||||
{ |
||||
// 增加 |
||||
if (!keepOldItems) |
||||
{ |
||||
foreach (var itemWithRect in this.managedItems) |
||||
{ |
||||
// 重置所有rect |
||||
itemWithRect.rectDirty = true; |
||||
} |
||||
} |
||||
|
||||
while (this.managedItems.Count < newDataCount) |
||||
{ |
||||
this.managedItems.Add(new ScrollItemWithRect()); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
// 减少 保留空位 避免GC |
||||
for (int i = 0, count = this.managedItems.Count; i < count; ++i) |
||||
{ |
||||
if (i < newDataCount) |
||||
{ |
||||
// 重置所有rect |
||||
if (!keepOldItems) |
||||
{ |
||||
this.managedItems[i].rectDirty = true; |
||||
} |
||||
|
||||
if (i == newDataCount - 1) |
||||
{ |
||||
this.managedItems[i].rectDirty = true; |
||||
} |
||||
} |
||||
|
||||
// 超出部分 清理回收item |
||||
if (i >= newDataCount) |
||||
{ |
||||
this.managedItems[i].rectDirty = true; |
||||
if (this.managedItems[i].item != null) |
||||
{ |
||||
this.RecycleOldItem(this.managedItems[i].item); |
||||
this.managedItems[i].item = null; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if (!keepOldItems) |
||||
{ |
||||
for (int i = 0, count = this.managedItems.Count; i < count; ++i) |
||||
{ |
||||
// 重置所有rect |
||||
this.managedItems[i].rectDirty = true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
this.dataCount = newDataCount; |
||||
} |
||||
|
||||
private void ResetCriticalItems() |
||||
{ |
||||
bool hasItem, shouldShow; |
||||
int firstIndex = -1, lastIndex = -1; |
||||
|
||||
for (var i = 0; i < this.dataCount; i++) |
||||
{ |
||||
hasItem = this.managedItems[i].item != null; |
||||
shouldShow = this.ShouldItemSeenAtIndex(i); |
||||
|
||||
if (shouldShow) |
||||
{ |
||||
if (firstIndex == -1) |
||||
{ |
||||
firstIndex = i; |
||||
} |
||||
|
||||
lastIndex = i; |
||||
} |
||||
|
||||
if (hasItem && shouldShow) |
||||
{ |
||||
// 应显示且已显示 |
||||
this.SetDataForItemAtIndex(this.managedItems[i].item, i); |
||||
continue; |
||||
} |
||||
|
||||
if (hasItem == shouldShow) |
||||
{ |
||||
// 不应显示且未显示 |
||||
// if (firstIndex != -1) |
||||
// { |
||||
// // 已经遍历完所有要显示的了 后边的先跳过 |
||||
// break; |
||||
// } |
||||
continue; |
||||
} |
||||
|
||||
if (hasItem && !shouldShow) |
||||
{ |
||||
// 不该显示 但是有 |
||||
this.RecycleOldItem(this.managedItems[i].item); |
||||
this.managedItems[i].item = null; |
||||
continue; |
||||
} |
||||
|
||||
if (shouldShow && !hasItem) |
||||
{ |
||||
// 需要显示 但是没有 |
||||
RectTransform item = this.GetNewItem(i); |
||||
this.OnGetItemForDataIndex(item, i); |
||||
this.managedItems[i].item = item; |
||||
continue; |
||||
} |
||||
} |
||||
|
||||
// content.localPosition = Vector2.zero; |
||||
this.criticalItemIndex[CriticalItemType.UpToHide] = firstIndex; |
||||
this.criticalItemIndex[CriticalItemType.DownToHide] = lastIndex; |
||||
this.criticalItemIndex[CriticalItemType.UpToShow] = Mathf.Max(firstIndex - 1, 0); |
||||
this.criticalItemIndex[CriticalItemType.DownToShow] = Mathf.Min(lastIndex + 1, this.dataCount - 1); |
||||
} |
||||
|
||||
private RectTransform GetCriticalItem(int type) |
||||
{ |
||||
var index = this.criticalItemIndex[type]; |
||||
if (index >= 0 && index < this.dataCount) |
||||
{ |
||||
return this.managedItems[index].item; |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
private void UpdateCriticalItems() |
||||
{ |
||||
var dirty = true; |
||||
|
||||
while (dirty) |
||||
{ |
||||
dirty = false; |
||||
|
||||
for (int i = CriticalItemType.UpToHide; i <= CriticalItemType.DownToShow; i++) |
||||
{ |
||||
if (i <= CriticalItemType.DownToHide) |
||||
{ |
||||
// 隐藏离开可见区域的item |
||||
dirty = dirty || this.CheckAndHideItem(i); |
||||
} |
||||
else |
||||
{ |
||||
// 显示进入可见区域的item |
||||
dirty = dirty || this.CheckAndShowItem(i); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private bool CheckAndHideItem(int criticalItemType) |
||||
{ |
||||
RectTransform item = this.GetCriticalItem(criticalItemType); |
||||
var criticalIndex = this.criticalItemIndex[criticalItemType]; |
||||
if (item != null && !this.ShouldItemSeenAtIndex(criticalIndex)) |
||||
{ |
||||
this.RecycleOldItem(item); |
||||
this.managedItems[criticalIndex].item = null; |
||||
|
||||
if (criticalItemType == CriticalItemType.UpToHide) |
||||
{ |
||||
// 最上隐藏了一个 |
||||
this.criticalItemIndex[criticalItemType + 2] = Mathf.Max(criticalIndex, this.criticalItemIndex[criticalItemType + 2]); |
||||
this.criticalItemIndex[criticalItemType]++; |
||||
} |
||||
else |
||||
{ |
||||
// 最下隐藏了一个 |
||||
this.criticalItemIndex[criticalItemType + 2] = Mathf.Min(criticalIndex, this.criticalItemIndex[criticalItemType + 2]); |
||||
this.criticalItemIndex[criticalItemType]--; |
||||
} |
||||
|
||||
this.criticalItemIndex[criticalItemType] = Mathf.Clamp(this.criticalItemIndex[criticalItemType], 0, this.dataCount - 1); |
||||
|
||||
if (this.criticalItemIndex[CriticalItemType.UpToHide] > this.criticalItemIndex[CriticalItemType.DownToHide]) |
||||
{ |
||||
// 偶然的情况 拖拽超出一屏 |
||||
this.ResetCriticalItems(); |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
private bool CheckAndShowItem(int criticalItemType) |
||||
{ |
||||
RectTransform item = this.GetCriticalItem(criticalItemType); |
||||
var criticalIndex = this.criticalItemIndex[criticalItemType]; |
||||
|
||||
if (item == null && this.ShouldItemSeenAtIndex(criticalIndex)) |
||||
{ |
||||
RectTransform newItem = this.GetNewItem(criticalIndex); |
||||
this.OnGetItemForDataIndex(newItem, criticalIndex); |
||||
this.managedItems[criticalIndex].item = newItem; |
||||
|
||||
if (criticalItemType == CriticalItemType.UpToShow) |
||||
{ |
||||
// 最上显示了一个 |
||||
this.criticalItemIndex[criticalItemType - 2] = Mathf.Min(criticalIndex, this.criticalItemIndex[criticalItemType - 2]); |
||||
this.criticalItemIndex[criticalItemType]--; |
||||
} |
||||
else |
||||
{ |
||||
// 最下显示了一个 |
||||
this.criticalItemIndex[criticalItemType - 2] = Mathf.Max(criticalIndex, this.criticalItemIndex[criticalItemType - 2]); |
||||
this.criticalItemIndex[criticalItemType]++; |
||||
} |
||||
|
||||
this.criticalItemIndex[criticalItemType] = Mathf.Clamp(this.criticalItemIndex[criticalItemType], 0, this.dataCount - 1); |
||||
|
||||
if (this.criticalItemIndex[CriticalItemType.UpToShow] >= this.criticalItemIndex[CriticalItemType.DownToShow]) |
||||
{ |
||||
// 偶然的情况 拖拽超出一屏 |
||||
this.ResetCriticalItems(); |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
private bool ShouldItemSeenAtIndex(int index) |
||||
{ |
||||
if (index < 0 || index >= this.dataCount) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
this.EnsureItemRect(index); |
||||
return new Rect(this.refRect.position - this.content.anchoredPosition, this.refRect.size).Overlaps(this.managedItems[index].rect); |
||||
} |
||||
|
||||
private bool ShouldItemFullySeenAtIndex(int index) |
||||
{ |
||||
if (index < 0 || index >= this.dataCount) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
this.EnsureItemRect(index); |
||||
return this.IsRectContains(new Rect(this.refRect.position - this.content.anchoredPosition, this.refRect.size), this.managedItems[index].rect); |
||||
} |
||||
|
||||
private bool IsRectContains(Rect outRect, Rect inRect, bool bothDimensions = false) |
||||
{ |
||||
if (bothDimensions) |
||||
{ |
||||
var xContains = (outRect.xMax >= inRect.xMax) && (outRect.xMin <= inRect.xMin); |
||||
var yContains = (outRect.yMax >= inRect.yMax) && (outRect.yMin <= inRect.yMin); |
||||
return xContains && yContains; |
||||
} |
||||
else |
||||
{ |
||||
var dir = (int)this.layoutType & flagScrollDirection; |
||||
if (dir == 1) |
||||
{ |
||||
// 垂直滚动 只计算y向 |
||||
return (outRect.yMax >= inRect.yMax) && (outRect.yMin <= inRect.yMin); |
||||
} |
||||
else |
||||
{ |
||||
// = 0 |
||||
// 水平滚动 只计算x向 |
||||
return (outRect.xMax >= inRect.xMax) && (outRect.xMin <= inRect.xMin); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void InitPool() |
||||
{ |
||||
var poolNode = new GameObject("POOL"); |
||||
poolNode.SetActive(false); |
||||
poolNode.transform.SetParent(this.transform, false); |
||||
this.itemPool = new SimpleObjPool<RectTransform>( |
||||
this.poolSize, |
||||
(RectTransform item) => |
||||
{ |
||||
item.transform.SetParent(poolNode.transform, false); |
||||
}, |
||||
() => |
||||
{ |
||||
GameObject itemObj = Instantiate(this.itemTemplate.gameObject); |
||||
RectTransform item = itemObj.GetComponent<RectTransform>(); |
||||
itemObj.transform.SetParent(poolNode.transform, false); |
||||
|
||||
item.anchorMin = Vector2.up; |
||||
item.anchorMax = Vector2.up; |
||||
item.pivot = Vector2.zero; |
||||
|
||||
itemObj.SetActive(true); |
||||
return item; |
||||
}, |
||||
(RectTransform item) => |
||||
{ |
||||
if (!applicationIsQuitting) |
||||
{ |
||||
item.transform.SetParent(null, false); |
||||
Destroy(item.gameObject); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private void OnGetItemForDataIndex(RectTransform item, int index) |
||||
{ |
||||
this.SetDataForItemAtIndex(item, index); |
||||
item.transform.SetParent(this.content, false); |
||||
} |
||||
|
||||
private void SetDataForItemAtIndex(RectTransform item, int index) |
||||
{ |
||||
if (this.updateFunc != null) |
||||
{ |
||||
this.updateFunc(index, item); |
||||
} |
||||
|
||||
this.SetPosForItemAtIndex(item, index); |
||||
} |
||||
|
||||
private void SetPosForItemAtIndex(RectTransform item, int index) |
||||
{ |
||||
this.EnsureItemRect(index); |
||||
Rect r = this.managedItems[index].rect; |
||||
item.localPosition = r.position; |
||||
item.sizeDelta = r.size; |
||||
} |
||||
|
||||
private Vector2 GetItemSize(int index) |
||||
{ |
||||
if (index >= 0 && index <= this.dataCount) |
||||
{ |
||||
if (this.itemSizeFunc != null) |
||||
{ |
||||
return this.itemSizeFunc(index); |
||||
} |
||||
} |
||||
|
||||
return this.defaultItemSize; |
||||
} |
||||
|
||||
private RectTransform GetNewItem(int index) |
||||
{ |
||||
RectTransform item; |
||||
if (this.itemGetFunc != null) |
||||
{ |
||||
item = this.itemGetFunc(index); |
||||
} |
||||
else |
||||
{ |
||||
item = this.itemPool.Get(); |
||||
} |
||||
|
||||
return item; |
||||
} |
||||
|
||||
private void RecycleOldItem(RectTransform item) |
||||
{ |
||||
if (this.itemRecycleFunc != null) |
||||
{ |
||||
this.itemRecycleFunc(item); |
||||
} |
||||
else |
||||
{ |
||||
this.itemPool.Recycle(item); |
||||
} |
||||
} |
||||
|
||||
private void InitScrollView() |
||||
{ |
||||
this.initialized = true; |
||||
|
||||
// 根据设置来控制原ScrollRect的滚动方向 |
||||
var dir = (int)this.layoutType & flagScrollDirection; |
||||
this.vertical = dir == 1; |
||||
this.horizontal = dir == 0; |
||||
|
||||
this.content.pivot = Vector2.up; |
||||
this.content.anchorMin = Vector2.up; |
||||
this.content.anchorMax = Vector2.up; |
||||
this.content.anchoredPosition = Vector2.zero; |
||||
|
||||
this.InitPool(); |
||||
this.UpdateRefRect(); |
||||
} |
||||
|
||||
// refRect是在Content节点下的 viewport的 rect |
||||
private void UpdateRefRect() |
||||
{ |
||||
/* |
||||
* WorldCorners |
||||
* |
||||
* 1 ------- 2 |
||||
* | | |
||||
* | | |
||||
* 0 ------- 3 |
||||
* |
||||
*/ |
||||
|
||||
if (!CanvasUpdateRegistry.IsRebuildingLayout()) |
||||
{ |
||||
Canvas.ForceUpdateCanvases(); |
||||
} |
||||
|
||||
this.viewRect.GetWorldCorners(this.viewWorldConers); |
||||
this.rectCorners[0] = this.content.transform.InverseTransformPoint(this.viewWorldConers[0]); |
||||
this.rectCorners[1] = this.content.transform.InverseTransformPoint(this.viewWorldConers[2]); |
||||
this.refRect = new Rect((Vector2)this.rectCorners[0] - this.content.anchoredPosition, this.rectCorners[1] - this.rectCorners[0]); |
||||
} |
||||
|
||||
private void MovePos(ref Vector2 pos, Vector2 size) |
||||
{ |
||||
// 注意 所有的rect都是左下角为基准 |
||||
switch (this.layoutType) |
||||
{ |
||||
case ItemLayoutType.Vertical: |
||||
// 垂直方向 向下移动 |
||||
pos.y -= size.y; |
||||
break; |
||||
case ItemLayoutType.Horizontal: |
||||
// 水平方向 向右移动 |
||||
pos.x += size.x; |
||||
break; |
||||
case ItemLayoutType.VerticalThenHorizontal: |
||||
pos.y -= size.y; |
||||
if (pos.y - size.y < -this.refRect.height) |
||||
{ |
||||
pos.y = 0; |
||||
pos.x += size.x; |
||||
} |
||||
|
||||
break; |
||||
case ItemLayoutType.HorizontalThenVertical: |
||||
|
||||
pos.x += size.x; |
||||
if (pos.x + size.x > this.refRect.width) |
||||
{ |
||||
pos.x = 0; |
||||
pos.y -= size.y; |
||||
} |
||||
|
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
} |
||||
|
||||
private void OnApplicationQuit() |
||||
{ |
||||
applicationIsQuitting = true; |
||||
} |
||||
|
||||
// const int 代替 enum 减少 (int)和(CriticalItemType)转换 |
||||
protected static class CriticalItemType |
||||
{ |
||||
public static byte UpToHide = 0; |
||||
public static byte DownToHide = 1; |
||||
public static byte UpToShow = 2; |
||||
public static byte DownToShow = 3; |
||||
} |
||||
|
||||
private class ScrollItemWithRect |
||||
{ |
||||
// scroll item 身上的 RectTransform组件 |
||||
public RectTransform item; |
||||
|
||||
// scroll item 在scrollview中的位置 |
||||
public Rect rect; |
||||
|
||||
// rect 是否需要更新 |
||||
public bool rectDirty = true; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 2d355eec575560046ba27246695b84ad |
||||
timeCreated: 1533042733 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,265 @@
|
||||
// ----------------------------------------------------------------------- |
||||
// <copyright file="ScrollViewEx.cs" company="AillieoTech"> |
||||
// Copyright (c) AillieoTech. All rights reserved. |
||||
// </copyright> |
||||
// ----------------------------------------------------------------------- |
||||
|
||||
namespace AillieoUtils |
||||
{ |
||||
using System; |
||||
using UnityEngine; |
||||
using UnityEngine.EventSystems; |
||||
using UnityEngine.Serialization; |
||||
|
||||
[RequireComponent(typeof(RectTransform))] |
||||
[DisallowMultipleComponent] |
||||
public class ScrollViewEx : ScrollView |
||||
{ |
||||
[SerializeField] |
||||
[FormerlySerializedAs("m_pageSize")] |
||||
private int pageSize = 50; |
||||
|
||||
private int startOffset = 0; |
||||
|
||||
private Func<int> realItemCountFunc; |
||||
|
||||
private Vector2 lastPosition; |
||||
|
||||
private bool reloadFlag = false; |
||||
|
||||
private int realDataCount = 0; |
||||
|
||||
public override void SetUpdateFunc(Action<int, RectTransform> func) |
||||
{ |
||||
if (func != null) |
||||
{ |
||||
var f = func; |
||||
func = (index, rect) => |
||||
{ |
||||
f(index + this.startOffset, rect); |
||||
}; |
||||
} |
||||
|
||||
base.SetUpdateFunc(func); |
||||
} |
||||
|
||||
public override void SetItemSizeFunc(Func<int, Vector2> func) |
||||
{ |
||||
if (func != null) |
||||
{ |
||||
var f = func; |
||||
func = (index) => |
||||
{ |
||||
return f(index + this.startOffset); |
||||
}; |
||||
} |
||||
|
||||
base.SetItemSizeFunc(func); |
||||
} |
||||
|
||||
public override void SetItemCountFunc(Func<int> func) |
||||
{ |
||||
this.realItemCountFunc = func; |
||||
if (func != null) |
||||
{ |
||||
var f = func; |
||||
func = () => Mathf.Min(f(), this.pageSize); |
||||
} |
||||
|
||||
base.SetItemCountFunc(func); |
||||
} |
||||
|
||||
public override void OnDrag(PointerEventData eventData) |
||||
{ |
||||
if (this.reloadFlag) |
||||
{ |
||||
this.reloadFlag = false; |
||||
this.OnEndDrag(eventData); |
||||
this.OnBeginDrag(eventData); |
||||
|
||||
return; |
||||
} |
||||
|
||||
base.OnDrag(eventData); |
||||
} |
||||
|
||||
protected override void Awake() |
||||
{ |
||||
base.Awake(); |
||||
|
||||
this.lastPosition = Vector2.up; |
||||
this.onValueChanged.AddListener(this.OnValueChanged); |
||||
} |
||||
|
||||
protected override void InternalScrollTo(int index) |
||||
{ |
||||
var count = 0; |
||||
if (this.realItemCountFunc != null) |
||||
{ |
||||
count = this.realItemCountFunc(); |
||||
} |
||||
|
||||
index = Mathf.Clamp(index, 0, count - 1); |
||||
this.startOffset = Mathf.Clamp(index - (this.pageSize / 2), 0, count - this.itemCountFunc()); |
||||
this.UpdateData(true); |
||||
base.InternalScrollTo(index - this.startOffset); |
||||
} |
||||
|
||||
protected override void CheckDataCountChange() |
||||
{ |
||||
base.CheckDataCountChange(); |
||||
|
||||
var newDataCount = 0; |
||||
if (this.realItemCountFunc != null) |
||||
{ |
||||
newDataCount = this.realItemCountFunc(); |
||||
} |
||||
|
||||
if (newDataCount < this.realDataCount) |
||||
{ |
||||
this.startOffset = Mathf.Clamp(this.startOffset, 0, Mathf.Max(this.realItemCountFunc() - this.pageSize, 0)); |
||||
} |
||||
|
||||
this.realDataCount = newDataCount; |
||||
} |
||||
|
||||
private void OnValueChanged(Vector2 position) |
||||
{ |
||||
int toShow; |
||||
int critical; |
||||
bool downward; |
||||
int pin; |
||||
|
||||
Vector2 delta = position - this.lastPosition; |
||||
this.lastPosition = position; |
||||
|
||||
this.reloadFlag = false; |
||||
|
||||
if (((int)this.layoutType & flagScrollDirection) == 1) |
||||
{ |
||||
// 垂直滚动 只计算y向 |
||||
if (delta.y < 0) |
||||
{ |
||||
// 向上 |
||||
toShow = this.criticalItemIndex[CriticalItemType.DownToShow]; |
||||
critical = this.pageSize - 1; |
||||
if (toShow < critical) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
pin = critical - 1; |
||||
downward = false; |
||||
} |
||||
else if (delta.y > 0) |
||||
{ |
||||
// 向下 |
||||
toShow = this.criticalItemIndex[CriticalItemType.UpToShow]; |
||||
critical = 0; |
||||
if (toShow > critical) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
pin = critical + 1; |
||||
downward = true; |
||||
} |
||||
else |
||||
{ |
||||
return; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
// = 0 |
||||
// 水平滚动 只计算x向 |
||||
if (delta.x > 0) |
||||
{ |
||||
// 向右 |
||||
toShow = this.criticalItemIndex[CriticalItemType.UpToShow]; |
||||
critical = 0; |
||||
if (toShow > critical) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
pin = critical + 1; |
||||
downward = true; |
||||
} |
||||
else if (delta.x < 0) |
||||
{ |
||||
// 向左 |
||||
toShow = this.criticalItemIndex[CriticalItemType.DownToShow]; |
||||
critical = this.pageSize - 1; |
||||
if (toShow < critical) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
pin = critical - 1; |
||||
downward = false; |
||||
} |
||||
else |
||||
{ |
||||
return; |
||||
} |
||||
} |
||||
|
||||
// 该翻页了 翻半页吧 |
||||
var old = this.startOffset; |
||||
if (downward) |
||||
{ |
||||
this.startOffset -= this.pageSize / 2; |
||||
} |
||||
else |
||||
{ |
||||
this.startOffset += this.pageSize / 2; |
||||
} |
||||
|
||||
var realDataCount = 0; |
||||
if (this.realItemCountFunc != null) |
||||
{ |
||||
realDataCount = this.realItemCountFunc(); |
||||
} |
||||
|
||||
this.startOffset = Mathf.Clamp(this.startOffset, 0, Mathf.Max(realDataCount - this.pageSize, 0)); |
||||
|
||||
if (old != this.startOffset) |
||||
{ |
||||
this.reloadFlag = true; |
||||
|
||||
// 记录 原先的速度 |
||||
Vector2 oldVelocity = this.velocity; |
||||
|
||||
// 计算 pin元素的世界坐标 |
||||
Rect rect = this.GetItemLocalRect(pin); |
||||
|
||||
Vector2 oldWorld = this.content.TransformPoint(rect.position); |
||||
var dataCount = 0; |
||||
if (this.itemCountFunc != null) |
||||
{ |
||||
dataCount = this.itemCountFunc(); |
||||
} |
||||
|
||||
if (dataCount > 0) |
||||
{ |
||||
this.EnsureItemRect(0); |
||||
if (dataCount > 1) |
||||
{ |
||||
this.EnsureItemRect(dataCount - 1); |
||||
} |
||||
} |
||||
|
||||
// 根据 pin元素的世界坐标 计算出content的position |
||||
var pin2 = pin + old - this.startOffset; |
||||
Rect rect2 = this.GetItemLocalRect(pin2); |
||||
Vector2 newWorld = this.content.TransformPoint(rect2.position); |
||||
Vector2 deltaWorld = newWorld - oldWorld; |
||||
Vector2 deltaLocal = this.content.InverseTransformVector(deltaWorld); |
||||
this.SetContentAnchoredPosition(this.content.anchoredPosition - deltaLocal); |
||||
this.UpdateData(true); |
||||
this.velocity = oldVelocity; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: d8f3e076f25860743a2d5212b2c285ac |
||||
timeCreated: 1533042733 |
||||
licenseType: Free |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
|
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using UnityEngine; |
||||
|
||||
public class PersonnelLocationMenuPanel : UIView |
||||
{ |
||||
|
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: afa9dde832c9cb946b7252bf2efa5bfb |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,44 @@
|
||||
using AillieoUtils; |
||||
using System.Collections.Generic; |
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
/// <summary> |
||||
/// 人员定位面板 |
||||
/// </summary> |
||||
public class PersonnelLocationPanel : UIView |
||||
{ |
||||
public ScrollView alarmScrollView; |
||||
public ScrollView employeeScrollView; |
||||
public List<GameObject> locationCards = new List<GameObject>(); |
||||
public List<EmployeeItem> items = new List<EmployeeItem>(); |
||||
public Toggle showAll; |
||||
|
||||
public override void Awake() |
||||
{ |
||||
base.Awake(); |
||||
showAll.onValueChanged.AddListener(v => Main.Event.EmployeeItemActive(v)); |
||||
LoadTags(Config.Tags); |
||||
} |
||||
|
||||
|
||||
|
||||
private void LoadTags(List<string> tags) |
||||
{ |
||||
employeeScrollView.SetUpdateFunc((index, item) => |
||||
{ |
||||
string info = tags[index]; |
||||
item.gameObject.SetActive(true); |
||||
item.name = info; |
||||
item.GetComponent<EmployeeItem>().targetNo=long.Parse(info); |
||||
item.transform.Find("CardNumber").GetComponent<Text>().text=info; |
||||
locationCards.Add(item.gameObject); |
||||
items.Add(item.GetComponent<EmployeeItem>()); |
||||
item.Find("Show").GetComponent<Toggle>().onValueChanged.AddListener(v => Main.Event.EmployeeActive(long.Parse(info), v)); |
||||
item.Find("Track").GetComponent<Toggle>().onValueChanged.AddListener(v => Main.LocationSimulator.GetTrackPlaybackData(v, long.Parse(info))); |
||||
|
||||
}); |
||||
|
||||
employeeScrollView.SetItemCountFunc(() => tags.Count); |
||||
employeeScrollView.UpdateData(false); |
||||
} |
||||
} |
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 4aabee8c336d5f14a9c9f6f896358ff8 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Loading…
Reference in new issue