유닛 크기 = 머리(눈 간격) 기준 통일 · 기마 = 탄 사람이 보병 크기 · 위군 그림 5종 폐기(#1104 · PD 2026-11-09)
- PD 「영웅 리스트 캐릭터 크기 동일 · 말 탄 유닛도 보병·창병과 비슷한 비율」: 원인 = 그림마다 몸 키(bodyHeightPx)를 같은 높이로 맞춰 와서, 말까지 한 그림에 든 기마는 탄 사람이 절반 크기(눈 간격/키 0.09~0.12 vs 보병 0.14~0.20) - 크기 표 Assets/Resources/Units/art_size.csv(SOT) = 눈 간격 자동 측정(Tools/unit_art_size.py · 얼굴 피부 안 어두운 구멍 2개) ÷ 말 안 탄 14종 중앙값 0.1687 → size_px(머리 크기가 표준인 유닛의 키) · mounted 열만 수동(장비 · 조운 · 여포 = 1) - 게임: FrameAnimator 배율 = size_px 기준(기마 x1.38~1.82) · TopHeight = 실제 머리 끝 → Unit.ArtHeight(HP 바 · 머리 위 표시) - 영웅 목록 카드: 같은 px 배율 → UnitPx 450 / size_px(머리 크기 같음 · 머리 끝 위치 그대로) - PD 「화풍이 전혀 다른 유닛 폐기」 = Resources/Units/wei_* 5종 삭제(사마의 영웅 · 위군 = 도형 대체 · heroes.csv art id 유지) - 테스트 118/118(+1 UnitArt_SizeTable_SameHeadSize_MountedRiderLikeFoot) · console error 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d16d354873
commit
747b3968a8
|
|
@ -0,0 +1,21 @@
|
||||||
|
art,mounted,eye_px,body_px,size_px,note
|
||||||
|
cc_archer,0,125.1,744,741.6,
|
||||||
|
cc_boss_caocao,0,135.0,808,800.3,
|
||||||
|
cc_cavalry,1,91.9,849,544.8,
|
||||||
|
cc_infantry,0,125.3,765,742.8,
|
||||||
|
cc_spear,0,124.1,785,735.7,
|
||||||
|
dz_archer,0,123.3,745,730.9,
|
||||||
|
dz_boss_lvbu,1,75.8,819,449.3,
|
||||||
|
dz_cavalry,1,96.2,873,570.3,
|
||||||
|
dz_infantry,0,139.1,844,824.6,
|
||||||
|
dz_spear,0,117.2,818,694.8,
|
||||||
|
guanyu,0,122.7,725,727.4,
|
||||||
|
hgj_archer,0,154.7,833,917.0,
|
||||||
|
hgj_boss_zhangjiao,0,147.8,854,876.1,
|
||||||
|
hgj_cavalry,1,107.4,879,636.7,
|
||||||
|
hgj_infantry,0,161.5,850,957.4,
|
||||||
|
hgj_spear,0,168.5,862,998.9,
|
||||||
|
huangzhong,0,148.8,797,882.1,
|
||||||
|
liubei,0,142.2,752,843.0,
|
||||||
|
zhangfei,1,108.2,917,641.4,
|
||||||
|
zhaoyun,1,100.4,926,595.2,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 6c52ae5244a4c1d47999b26723feb8d6
|
guid: 7f92b435a2912a24cb826a5b40683511
|
||||||
TextScriptImporter:
|
TextScriptImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
userData:
|
userData:
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: c8fe4e3059806cd4198d7544e2061771
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 44bb65b9a5cf86848ab36c47523fe2a2
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 524 KiB |
|
|
@ -1,168 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 154714b72b6b71a439a066069edd217a
|
|
||||||
TextureImporter:
|
|
||||||
internalIDToNameTable:
|
|
||||||
- first:
|
|
||||||
213: -166343660977832731
|
|
||||||
second: f000_0
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 13
|
|
||||||
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: 1
|
|
||||||
nPOTScale: 0
|
|
||||||
lightmap: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
spriteMode: 1
|
|
||||||
spriteExtrude: 1
|
|
||||||
spriteMeshType: 0
|
|
||||||
alignment: 9
|
|
||||||
spritePivot: {x: 0.5, y: 0.02101}
|
|
||||||
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: 4
|
|
||||||
buildTarget: DefaultTexturePlatform
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 4
|
|
||||||
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: 4
|
|
||||||
buildTarget: Android
|
|
||||||
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: 4
|
|
||||||
buildTarget: WebGL
|
|
||||||
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:
|
|
||||||
- serializedVersion: 2
|
|
||||||
name: f000_0
|
|
||||||
rect:
|
|
||||||
serializedVersion: 2
|
|
||||||
x: 19
|
|
||||||
y: 19
|
|
||||||
width: 578
|
|
||||||
height: 914
|
|
||||||
alignment: 0
|
|
||||||
pivot: {x: 0, y: 0}
|
|
||||||
border: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
customData:
|
|
||||||
outline: []
|
|
||||||
physicsShape: []
|
|
||||||
tessellationDetail: -1
|
|
||||||
bones: []
|
|
||||||
spriteID: 5ec37c8525701bdf0800000000000000
|
|
||||||
internalID: -166343660977832731
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
outline: []
|
|
||||||
customData:
|
|
||||||
physicsShape: []
|
|
||||||
bones: []
|
|
||||||
spriteID: 5e97eb03825dee720800000000000000
|
|
||||||
internalID: 0
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
secondaryTextures: []
|
|
||||||
spriteCustomMetadata:
|
|
||||||
entries: []
|
|
||||||
nameFileIdTable: {}
|
|
||||||
mipmapLimitGroupName:
|
|
||||||
pSDRemoveMatte: 0
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
{
|
|
||||||
"fps": 1,
|
|
||||||
"ppu": 100,
|
|
||||||
"frame": [
|
|
||||||
616,
|
|
||||||
952
|
|
||||||
],
|
|
||||||
"pivot": [
|
|
||||||
0.5,
|
|
||||||
0.02101
|
|
||||||
],
|
|
||||||
"charHeightPx": 912,
|
|
||||||
"bodyHeightPx": 842,
|
|
||||||
"clips": [
|
|
||||||
{
|
|
||||||
"name": "front_idle",
|
|
||||||
"frames": 1,
|
|
||||||
"loop": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 357942899e8b8504792baf9a75f4795f
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 321a9b9e1c1291640bb97fc92b2924c9
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: f2de55fd9322ded4e8e550631eb53734
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 465 KiB |
|
|
@ -1,168 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: a5abb9cd3db4e694891b52a867a1707a
|
|
||||||
TextureImporter:
|
|
||||||
internalIDToNameTable:
|
|
||||||
- first:
|
|
||||||
213: -166343660977832731
|
|
||||||
second: f000_0
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 13
|
|
||||||
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: 1
|
|
||||||
nPOTScale: 0
|
|
||||||
lightmap: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
spriteMode: 1
|
|
||||||
spriteExtrude: 1
|
|
||||||
spriteMeshType: 0
|
|
||||||
alignment: 9
|
|
||||||
spritePivot: {x: 0.5, y: 0.02037}
|
|
||||||
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: 4
|
|
||||||
buildTarget: DefaultTexturePlatform
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 4
|
|
||||||
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: 4
|
|
||||||
buildTarget: Android
|
|
||||||
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: 4
|
|
||||||
buildTarget: WebGL
|
|
||||||
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:
|
|
||||||
- serializedVersion: 2
|
|
||||||
name: f000_0
|
|
||||||
rect:
|
|
||||||
serializedVersion: 2
|
|
||||||
x: 19
|
|
||||||
y: 19
|
|
||||||
width: 532
|
|
||||||
height: 944
|
|
||||||
alignment: 0
|
|
||||||
pivot: {x: 0, y: 0}
|
|
||||||
border: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
customData:
|
|
||||||
outline: []
|
|
||||||
physicsShape: []
|
|
||||||
tessellationDetail: -1
|
|
||||||
bones: []
|
|
||||||
spriteID: 5ec37c8525701bdf0800000000000000
|
|
||||||
internalID: -166343660977832731
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
outline: []
|
|
||||||
customData:
|
|
||||||
physicsShape: []
|
|
||||||
bones: []
|
|
||||||
spriteID: 5e97eb03825dee720800000000000000
|
|
||||||
internalID: 0
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
secondaryTextures: []
|
|
||||||
spriteCustomMetadata:
|
|
||||||
entries: []
|
|
||||||
nameFileIdTable: {}
|
|
||||||
mipmapLimitGroupName:
|
|
||||||
pSDRemoveMatte: 0
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
{
|
|
||||||
"fps": 1,
|
|
||||||
"ppu": 100,
|
|
||||||
"frame": [
|
|
||||||
570,
|
|
||||||
982
|
|
||||||
],
|
|
||||||
"pivot": [
|
|
||||||
0.5,
|
|
||||||
0.02037
|
|
||||||
],
|
|
||||||
"charHeightPx": 942,
|
|
||||||
"bodyHeightPx": 799,
|
|
||||||
"clips": [
|
|
||||||
{
|
|
||||||
"name": "front_idle",
|
|
||||||
"frames": 1,
|
|
||||||
"loop": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 48fa1fa1606e6d44e857c4e315d8ba96
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 0d68a9e892581594e939bb8bb78a3ac1
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 513 KiB |
|
|
@ -1,168 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 1900b449bbfb58b4393d5665f5129b0c
|
|
||||||
TextureImporter:
|
|
||||||
internalIDToNameTable:
|
|
||||||
- first:
|
|
||||||
213: -166343660977832731
|
|
||||||
second: f000_0
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 13
|
|
||||||
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: 1
|
|
||||||
nPOTScale: 0
|
|
||||||
lightmap: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
spriteMode: 1
|
|
||||||
spriteExtrude: 1
|
|
||||||
spriteMeshType: 0
|
|
||||||
alignment: 9
|
|
||||||
spritePivot: {x: 0.5, y: 0.02045}
|
|
||||||
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: 4
|
|
||||||
buildTarget: DefaultTexturePlatform
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 4
|
|
||||||
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: 4
|
|
||||||
buildTarget: Android
|
|
||||||
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: 4
|
|
||||||
buildTarget: WebGL
|
|
||||||
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:
|
|
||||||
- serializedVersion: 2
|
|
||||||
name: f000_0
|
|
||||||
rect:
|
|
||||||
serializedVersion: 2
|
|
||||||
x: 19
|
|
||||||
y: 19
|
|
||||||
width: 694
|
|
||||||
height: 940
|
|
||||||
alignment: 0
|
|
||||||
pivot: {x: 0, y: 0}
|
|
||||||
border: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
customData:
|
|
||||||
outline: []
|
|
||||||
physicsShape: []
|
|
||||||
tessellationDetail: -1
|
|
||||||
bones: []
|
|
||||||
spriteID: 5ec37c8525701bdf0800000000000000
|
|
||||||
internalID: -166343660977832731
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
outline: []
|
|
||||||
customData:
|
|
||||||
physicsShape: []
|
|
||||||
bones: []
|
|
||||||
spriteID: 5e97eb03825dee720800000000000000
|
|
||||||
internalID: 0
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
secondaryTextures: []
|
|
||||||
spriteCustomMetadata:
|
|
||||||
entries: []
|
|
||||||
nameFileIdTable: {}
|
|
||||||
mipmapLimitGroupName:
|
|
||||||
pSDRemoveMatte: 0
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
{
|
|
||||||
"fps": 1,
|
|
||||||
"ppu": 100,
|
|
||||||
"frame": [
|
|
||||||
732,
|
|
||||||
978
|
|
||||||
],
|
|
||||||
"pivot": [
|
|
||||||
0.5,
|
|
||||||
0.02045
|
|
||||||
],
|
|
||||||
"charHeightPx": 938,
|
|
||||||
"bodyHeightPx": 877,
|
|
||||||
"clips": [
|
|
||||||
{
|
|
||||||
"name": "front_idle",
|
|
||||||
"frames": 1,
|
|
||||||
"loop": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: e2e0e727ef2627e4e95edf3bee7fc76b
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: ab5e1fb35f54c734f9849c8cea6396b2
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 2182604a7db43d840b09344b749496d4
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 466 KiB |
|
|
@ -1,168 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: cc7eaa04bc7977848bc4717a47ff8f4b
|
|
||||||
TextureImporter:
|
|
||||||
internalIDToNameTable:
|
|
||||||
- first:
|
|
||||||
213: -166343660977832731
|
|
||||||
second: f000_0
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 13
|
|
||||||
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: 1
|
|
||||||
nPOTScale: 0
|
|
||||||
lightmap: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
spriteMode: 1
|
|
||||||
spriteExtrude: 1
|
|
||||||
spriteMeshType: 0
|
|
||||||
alignment: 9
|
|
||||||
spritePivot: {x: 0.5, y: 0.02075}
|
|
||||||
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: 4
|
|
||||||
buildTarget: DefaultTexturePlatform
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 4
|
|
||||||
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: 4
|
|
||||||
buildTarget: Android
|
|
||||||
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: 4
|
|
||||||
buildTarget: WebGL
|
|
||||||
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:
|
|
||||||
- serializedVersion: 2
|
|
||||||
name: f000_0
|
|
||||||
rect:
|
|
||||||
serializedVersion: 2
|
|
||||||
x: 19
|
|
||||||
y: 19
|
|
||||||
width: 525
|
|
||||||
height: 926
|
|
||||||
alignment: 0
|
|
||||||
pivot: {x: 0, y: 0}
|
|
||||||
border: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
customData:
|
|
||||||
outline: []
|
|
||||||
physicsShape: []
|
|
||||||
tessellationDetail: -1
|
|
||||||
bones: []
|
|
||||||
spriteID: 5ec37c8525701bdf0800000000000000
|
|
||||||
internalID: -166343660977832731
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
outline: []
|
|
||||||
customData:
|
|
||||||
physicsShape: []
|
|
||||||
bones: []
|
|
||||||
spriteID: 5e97eb03825dee720800000000000000
|
|
||||||
internalID: 0
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
secondaryTextures: []
|
|
||||||
spriteCustomMetadata:
|
|
||||||
entries: []
|
|
||||||
nameFileIdTable: {}
|
|
||||||
mipmapLimitGroupName:
|
|
||||||
pSDRemoveMatte: 0
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
{
|
|
||||||
"fps": 1,
|
|
||||||
"ppu": 100,
|
|
||||||
"frame": [
|
|
||||||
563,
|
|
||||||
964
|
|
||||||
],
|
|
||||||
"pivot": [
|
|
||||||
0.5,
|
|
||||||
0.02075
|
|
||||||
],
|
|
||||||
"charHeightPx": 924,
|
|
||||||
"bodyHeightPx": 850,
|
|
||||||
"clips": [
|
|
||||||
{
|
|
||||||
"name": "front_idle",
|
|
||||||
"frames": 1,
|
|
||||||
"loop": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: a91577d55a26cf145bdb48cae6068b51
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: daf601eef2501824cba4fcf78852bed7
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 70d931937e5258447851f43e7fc4429b
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 444 KiB |
|
|
@ -1,168 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 8671e3ec0807b3340b1921dc2ed4a333
|
|
||||||
TextureImporter:
|
|
||||||
internalIDToNameTable:
|
|
||||||
- first:
|
|
||||||
213: -166343660977832731
|
|
||||||
second: f000_0
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 13
|
|
||||||
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: 1
|
|
||||||
nPOTScale: 0
|
|
||||||
lightmap: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
spriteMode: 1
|
|
||||||
spriteExtrude: 1
|
|
||||||
spriteMeshType: 0
|
|
||||||
alignment: 9
|
|
||||||
spritePivot: {x: 0.5, y: 0.02121}
|
|
||||||
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: 4
|
|
||||||
buildTarget: DefaultTexturePlatform
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 4
|
|
||||||
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: 4
|
|
||||||
buildTarget: Android
|
|
||||||
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: 4
|
|
||||||
buildTarget: WebGL
|
|
||||||
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:
|
|
||||||
- serializedVersion: 2
|
|
||||||
name: f000_0
|
|
||||||
rect:
|
|
||||||
serializedVersion: 2
|
|
||||||
x: 19
|
|
||||||
y: 19
|
|
||||||
width: 474
|
|
||||||
height: 905
|
|
||||||
alignment: 0
|
|
||||||
pivot: {x: 0, y: 0}
|
|
||||||
border: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
customData:
|
|
||||||
outline: []
|
|
||||||
physicsShape: []
|
|
||||||
tessellationDetail: -1
|
|
||||||
bones: []
|
|
||||||
spriteID: 5ec37c8525701bdf0800000000000000
|
|
||||||
internalID: -166343660977832731
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
outline: []
|
|
||||||
customData:
|
|
||||||
physicsShape: []
|
|
||||||
bones: []
|
|
||||||
spriteID: 5e97eb03825dee720800000000000000
|
|
||||||
internalID: 0
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
secondaryTextures: []
|
|
||||||
spriteCustomMetadata:
|
|
||||||
entries: []
|
|
||||||
nameFileIdTable: {}
|
|
||||||
mipmapLimitGroupName:
|
|
||||||
pSDRemoveMatte: 0
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
{
|
|
||||||
"fps": 1,
|
|
||||||
"ppu": 100,
|
|
||||||
"frame": [
|
|
||||||
512,
|
|
||||||
943
|
|
||||||
],
|
|
||||||
"pivot": [
|
|
||||||
0.5,
|
|
||||||
0.02121
|
|
||||||
],
|
|
||||||
"charHeightPx": 903,
|
|
||||||
"bodyHeightPx": 860,
|
|
||||||
"clips": [
|
|
||||||
{
|
|
||||||
"name": "front_idle",
|
|
||||||
"frames": 1,
|
|
||||||
"loop": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: c3f282f7fd7dedf4a9d91436db8ca357
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -84,8 +84,8 @@ namespace TKS.OutGame
|
||||||
{
|
{
|
||||||
public static readonly Vector2 CellSize = new Vector2(320f, 431f);
|
public static readonly Vector2 CellSize = new Vector2(320f, 431f);
|
||||||
public static readonly Vector2 Spacing = new Vector2(22f, 20f);
|
public static readonly Vector2 Spacing = new Vector2(22f, 20f);
|
||||||
/// <summary>일러 배율(원본 px → 화면 px · 전 유닛 공통) · 머리 끝 위치(카드 위에서 px).</summary>
|
/// <summary>크기 표 size_px(머리 크기 기준 표준 키)가 카드에서 차지할 px — 배율 = UnitPx ÷ size_px(모든 유닛 머리 크기 같음) · 머리 끝 위치(카드 위에서 px).</summary>
|
||||||
const float ArtScale = 0.56f;
|
const float UnitPx = 450f;
|
||||||
const float HeadTop = 50f;
|
const float HeadTop = 50f;
|
||||||
|
|
||||||
public static Image Card(Transform content, OutGameSession s, HeroDb.Hero h, bool deployed, System.Action onTap)
|
public static Image Card(Transform content, OutGameSession s, HeroDb.Hero h, bool deployed, System.Action onTap)
|
||||||
|
|
@ -107,17 +107,18 @@ namespace TKS.OutGame
|
||||||
var sp = UiKit.ArtSprite(h.art);
|
var sp = UiKit.ArtSprite(h.art);
|
||||||
if (sp != null)
|
if (sp != null)
|
||||||
{
|
{
|
||||||
// 모든 유닛 같은 배율(PD 2026-11-09 「유닛 크기를 동일한 비율로」) = 원본 px × ArtScale · 머리 끝(발 + bodyHeightPx · 무기 제외)을 카드 위 HeadTop 에 맞춤
|
// 머리 크기 통일(PD 2026-11-09 「캐릭터 크기가 동일하게 보이도록」) = 배율 UnitPx ÷ 크기 표 size_px(눈 간격 기준 · 말 탄 유닛은 탄 사람 기준) ·
|
||||||
// → 머리 크기가 같고 다리·말은 아래 띠 뒤로 잘림(레퍼런스 흉상 느낌) · 메타가 없으면 칸 맞춤
|
// 머리 끝(발 + bodyHeightPx · 무기 제외)을 카드 위 HeadTop 에 맞춤 → 다리·말은 아래 띠 뒤로 잘림(레퍼런스 흉상 느낌) · 메타가 없으면 칸 맞춤
|
||||||
var a = UnitArt.Load(h.art);
|
var a = UnitArt.Load(h.art);
|
||||||
var m = a != null ? a.Meta : null;
|
var m = a != null ? a.Meta : null;
|
||||||
float body = m != null ? (m.bodyHeightPx > 0.5f ? m.bodyHeightPx : m.charHeightPx) : 0f;
|
float body = a != null ? a.BodyPx : 0f;
|
||||||
|
float size = a != null && a.SizePx > 0.5f ? a.SizePx : body;
|
||||||
Image art;
|
Image art;
|
||||||
if (body > 0.5f && m.pivot != null && m.pivot.Length > 1)
|
if (body > 0.5f && m.pivot != null && m.pivot.Length > 1)
|
||||||
{
|
{
|
||||||
float hgt = sp.rect.height;
|
float hgt = sp.rect.height;
|
||||||
float headY = Mathf.Clamp01((m.pivot[1] * hgt + body) / hgt); // 머리 끝 = 프레임 아래에서의 비율
|
float headY = Mathf.Clamp01((m.pivot[1] * hgt + body) / hgt); // 머리 끝 = 프레임 아래에서의 비율
|
||||||
art = UiKit.Rect("Character", b, new Vector2(0.5f, 1f), new Vector2(0.5f, headY), new Vector2(0f, -HeadTop), sp.rect.size * ArtScale).gameObject.AddComponent<Image>();
|
art = UiKit.Rect("Character", b, new Vector2(0.5f, 1f), new Vector2(0.5f, headY), new Vector2(0f, -HeadTop), sp.rect.size * (UnitPx / size)).gameObject.AddComponent<Image>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace TKS
|
||||||
public float ArcherMoveAllow;
|
public float ArcherMoveAllow;
|
||||||
/// <summary>Resources/Units/<ArtId>/ 아트 폴더 · 비면 도형.</summary>
|
/// <summary>Resources/Units/<ArtId>/ 아트 폴더 · 비면 도형.</summary>
|
||||||
public string ArtId = "";
|
public string ArtId = "";
|
||||||
/// <summary>아트 세로 크기(월드) = unitArtHeight × 반지름 배율.</summary>
|
/// <summary>아트 머리 끝 높이(월드) — Init = 표준 키(unitArtHeight × 반지름 배율) · 아트가 있으면 UnitView 가 크기 표 배율 뒤 실제 머리 끝으로 바꾼다.</summary>
|
||||||
public float ArtHeight;
|
public float ArtHeight;
|
||||||
|
|
||||||
/// <summary>이번 아군 턴에 행동을 마쳤는가.</summary>
|
/// <summary>이번 아군 턴에 행동을 마쳤는가.</summary>
|
||||||
|
|
|
||||||
|
|
@ -37,15 +37,25 @@ namespace TKS
|
||||||
public UnitArtMeta Meta;
|
public UnitArtMeta Meta;
|
||||||
public readonly Dictionary<string, Sprite[]> Clips = new Dictionary<string, Sprite[]>();
|
public readonly Dictionary<string, Sprite[]> Clips = new Dictionary<string, Sprite[]>();
|
||||||
public readonly Dictionary<string, bool> Loop = new Dictionary<string, bool>();
|
public readonly Dictionary<string, bool> Loop = new Dictionary<string, bool>();
|
||||||
|
/// <summary>
|
||||||
|
/// 크기 기준 px = Resources/Units/art_size.csv 의 size_px(눈 간격 ÷ 기준 비율 = 머리 크기가 표준인 유닛의 키로 환산 · Tools/unit_art_size.py) ·
|
||||||
|
/// 0 = 표에 없음 → BodyPx. PD 2026-11-09 「캐릭터 크기 동일 · 말 탄 유닛도 보병·창병과 비슷한 비율」.
|
||||||
|
/// </summary>
|
||||||
|
public float SizePx;
|
||||||
|
|
||||||
/// <summary>캐릭터 몸 세로 크기(월드) — 임포터 PPU = meta.ppu 전제 · bodyHeightPx(무기 제외) 우선, 없으면 charHeightPx.</summary>
|
/// <summary>그림 속 몸(머리 끝~발) 세로 px — bodyHeightPx(무기 제외) 우선, 없으면 charHeightPx.</summary>
|
||||||
|
public float BodyPx
|
||||||
|
{
|
||||||
|
get { return Meta.bodyHeightPx > 0.5f ? Meta.bodyHeightPx : Meta.charHeightPx; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>배율 기준 세로 크기(월드) — 임포터 PPU = meta.ppu 전제 · 크기 표 size_px 우선(모든 유닛의 머리 크기가 같아짐), 없으면 BodyPx.</summary>
|
||||||
public float CharHeightWorld
|
public float CharHeightWorld
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Meta.ppu <= 0.01f) return 1f;
|
if (Meta.ppu <= 0.01f) return 1f;
|
||||||
float px = Meta.bodyHeightPx > 0.5f ? Meta.bodyHeightPx : Meta.charHeightPx;
|
return (SizePx > 0.5f ? SizePx : BodyPx) / Meta.ppu;
|
||||||
return px / Meta.ppu;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +64,41 @@ namespace TKS
|
||||||
public static class UnitArt
|
public static class UnitArt
|
||||||
{
|
{
|
||||||
public const string Root = "Units/";
|
public const string Root = "Units/";
|
||||||
|
/// <summary>크기 표(TextAsset · utf-8-sig CSV · 열 art · size_px) = Resources/Units/art_size.csv.</summary>
|
||||||
|
public const string SizeTable = "art_size";
|
||||||
static readonly Dictionary<string, UnitArtData> cache = new Dictionary<string, UnitArtData>();
|
static readonly Dictionary<string, UnitArtData> cache = new Dictionary<string, UnitArtData>();
|
||||||
|
static Dictionary<string, float> sizes;
|
||||||
|
|
||||||
|
/// <summary>크기 표의 size_px(없으면 0).</summary>
|
||||||
|
public static float SizeOf(string id)
|
||||||
|
{
|
||||||
|
if (sizes == null) sizes = ParseSizes(Resources.Load<TextAsset>(Root + SizeTable));
|
||||||
|
float v;
|
||||||
|
return id != null && sizes.TryGetValue(id, out v) ? v : 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Dictionary<string, float> ParseSizes(TextAsset ta)
|
||||||
|
{
|
||||||
|
var d = new Dictionary<string, float>();
|
||||||
|
if (ta == null) return d;
|
||||||
|
var lines = ta.text.TrimStart('').Split('\n');
|
||||||
|
if (lines.Length == 0) return d;
|
||||||
|
var head = new List<string>(lines[0].Trim().Split(','));
|
||||||
|
int ia = head.IndexOf("art"), isz = head.IndexOf("size_px");
|
||||||
|
if (ia < 0 || isz < 0)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("[TKS] 유닛 크기 표 열(art · size_px) 없음");
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
for (int i = 1; i < lines.Length; i++)
|
||||||
|
{
|
||||||
|
var c = lines[i].Trim().Split(',');
|
||||||
|
float v;
|
||||||
|
if (c.Length > Mathf.Max(ia, isz) && float.TryParse(c[isz], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out v) && v > 0f)
|
||||||
|
d[c[ia]] = v;
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
public static UnitArtData Load(string id)
|
public static UnitArtData Load(string id)
|
||||||
{
|
{
|
||||||
|
|
@ -69,6 +113,7 @@ namespace TKS
|
||||||
public static void ClearCache()
|
public static void ClearCache()
|
||||||
{
|
{
|
||||||
cache.Clear();
|
cache.Clear();
|
||||||
|
sizes = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UnitArtData LoadUncached(string id)
|
static UnitArtData LoadUncached(string id)
|
||||||
|
|
@ -87,7 +132,7 @@ namespace TKS
|
||||||
}
|
}
|
||||||
if (meta == null || meta.clips == null) return null;
|
if (meta == null || meta.clips == null) return null;
|
||||||
|
|
||||||
var d = new UnitArtData { Id = id, Meta = meta };
|
var d = new UnitArtData { Id = id, Meta = meta, SizePx = SizeOf(id) };
|
||||||
foreach (var c in meta.clips)
|
foreach (var c in meta.clips)
|
||||||
{
|
{
|
||||||
if (c == null || string.IsNullOrEmpty(c.name)) continue;
|
if (c == null || string.IsNullOrEmpty(c.name)) continue;
|
||||||
|
|
@ -134,6 +179,10 @@ namespace TKS
|
||||||
get { return data; }
|
get { return data; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>그려진 머리 끝 높이(월드 · 발 기준) = BodyPx × 배율 — 크기 표로 커진 기마 유닛은 표준 키보다 높다.</summary>
|
||||||
|
public float TopHeight { get; private set; }
|
||||||
|
|
||||||
|
/// <param name="worldHeight">표준 키(월드) — 크기 표 size_px 가 이 높이가 되도록 배율(= 머리 크기 통일).</param>
|
||||||
public void Setup(UnitArtData d, float worldHeight, int sortingOrder)
|
public void Setup(UnitArtData d, float worldHeight, int sortingOrder)
|
||||||
{
|
{
|
||||||
data = d;
|
data = d;
|
||||||
|
|
@ -143,6 +192,7 @@ namespace TKS
|
||||||
float h = d.CharHeightWorld;
|
float h = d.CharHeightWorld;
|
||||||
float s = h > 0.001f ? worldHeight / h : 1f;
|
float s = h > 0.001f ? worldHeight / h : 1f;
|
||||||
transform.localScale = new Vector3(s, s, 1f);
|
transform.localScale = new Vector3(s, s, 1f);
|
||||||
|
TopHeight = d.Meta.ppu > 0.01f ? d.BodyPx / d.Meta.ppu * s : worldHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Has(string clip)
|
public bool Has(string clip)
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,7 @@ namespace TKS
|
||||||
ago.transform.localPosition = new Vector3(0f, -u.Radius * 0.55f, 0f);
|
ago.transform.localPosition = new Vector3(0f, -u.Radius * 0.55f, 0f);
|
||||||
anim = ago.AddComponent<FrameAnimator>();
|
anim = ago.AddComponent<FrameAnimator>();
|
||||||
anim.Setup(art, u.ArtHeight, 0);
|
anim.Setup(art, u.ArtHeight, 0);
|
||||||
|
u.ArtHeight = anim.TopHeight; // 크기 표 배율 뒤 실제 머리 끝(HP 바 · 머리 위 표시 기준)
|
||||||
anim.Renderer.flipX = facingLeft;
|
anim.Renderer.flipX = facingLeft;
|
||||||
anim.SetIdle(ClipName("idle"));
|
anim.SetIdle(ClipName("idle"));
|
||||||
anim.PlayIdle();
|
anim.PlayIdle();
|
||||||
|
|
|
||||||
|
|
@ -975,6 +975,49 @@ namespace TKS.Tests
|
||||||
Assert.IsTrue(u.View.Anim.Renderer.flipX, "왼쪽 = 좌우 반전");
|
Assert.IsTrue(u.View.Anim.Renderer.flipX, "왼쪽 = 좌우 반전");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator UnitArt_SizeTable_SameHeadSize_MountedRiderLikeFoot()
|
||||||
|
{
|
||||||
|
// PD 2026-11-09 「캐릭터 크기 동일 · 말 탄 유닛도 보병·창병과 비슷한 비율」 — 크기 표(art_size.csv · 눈 간격 기준)로 배율을 정하면
|
||||||
|
// 게임 안 눈 간격(월드)이 모든 유닛에서 같다 · 기마 유닛은 표준 키보다 커진다(탄 사람 = 보병 크기)
|
||||||
|
var ta = Resources.Load<TextAsset>(UnitArt.Root + UnitArt.SizeTable);
|
||||||
|
Assert.IsNotNull(ta, "크기 표 Resources/Units/art_size.csv");
|
||||||
|
var lines = ta.text.TrimStart('').Split('\n');
|
||||||
|
var head = new List<string>(lines[0].Trim().Split(','));
|
||||||
|
int ia = head.IndexOf("art"), im = head.IndexOf("mounted"), ie = head.IndexOf("eye_px");
|
||||||
|
var eyes = new List<float>();
|
||||||
|
int mounted = 0;
|
||||||
|
var go = new GameObject("SizeProbe");
|
||||||
|
var fa = go.AddComponent<FrameAnimator>();
|
||||||
|
for (int i = 1; i < lines.Length; i++)
|
||||||
|
{
|
||||||
|
var c = lines[i].Trim().Split(',');
|
||||||
|
if (c.Length <= ie) continue;
|
||||||
|
var a = UnitArt.Load(c[ia]);
|
||||||
|
Assert.IsNotNull(a, "표의 아트 " + c[ia]);
|
||||||
|
Assert.Greater(a.SizePx, 0f, c[ia] + " size_px");
|
||||||
|
fa.Setup(a, cfg.unitArtHeight, 0);
|
||||||
|
eyes.Add(float.Parse(c[ie], System.Globalization.CultureInfo.InvariantCulture) / a.Meta.ppu * go.transform.localScale.x);
|
||||||
|
if (c[im] == "1")
|
||||||
|
{
|
||||||
|
mounted++;
|
||||||
|
Assert.Greater(fa.TopHeight, cfg.unitArtHeight * 1.2f, c[ia] + " 기마 = 탄 사람이 보병 크기가 되도록 커짐");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Object.Destroy(go);
|
||||||
|
Assert.GreaterOrEqual(eyes.Count, 15, "표 행 수");
|
||||||
|
Assert.GreaterOrEqual(mounted, 5, "기마 행 수");
|
||||||
|
eyes.Sort();
|
||||||
|
Assert.Less(eyes[eyes.Count - 1] / eyes[0], 1.01f, "모든 유닛 눈 간격(월드) 같음");
|
||||||
|
|
||||||
|
// 배치된 기마 영웅 = HP 바 기준(ArtHeight)이 실제 머리 끝
|
||||||
|
yield return Fresh();
|
||||||
|
var u = bm.SpawnUnit(UnitType.Cavalry, Faction.Player, new Vector2(0f, -4f), "조운", 1f, 1f, false, "zhaoyun");
|
||||||
|
yield return null;
|
||||||
|
Assert.AreEqual(u.View.Anim.TopHeight, u.ArtHeight, 1e-4f, "ArtHeight = 그려진 머리 끝");
|
||||||
|
Assert.Greater(u.ArtHeight, cfg.unitArtHeight, "기마 = 표준 키보다 높음");
|
||||||
|
}
|
||||||
|
|
||||||
// ---------- 스테이지 표(Assets/Data/Stages/*.csv · 145 스테이지 · 2026-11-05 #1086) ----------
|
// ---------- 스테이지 표(Assets/Data/Stages/*.csv · 145 스테이지 · 2026-11-05 #1086) ----------
|
||||||
|
|
||||||
static StageTable.Tables ReadStageTable()
|
static StageTable.Tables ReadStageTable()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""유닛 아트 크기 표 생성(PD 2026-11-09 「영웅 목록 캐릭터 크기 동일 · 말 탄 유닛도 보병·창병과 비슷한 비율」).
|
||||||
|
|
||||||
|
기준 = 눈 간격(머리 크기) — 투구·수염·말과 상관없이 같은 화풍이면 머리 크기에 비례한다.
|
||||||
|
eye_px = 대기 첫 프레임(front_idle/f000.png)의 두 눈 중심 사이 가로 px(얼굴 피부 덩어리 안 어두운 구멍 2개)
|
||||||
|
ref = 말을 타지 않은 유닛(mounted=0)의 eye_px / body_px 중앙값
|
||||||
|
size_px = eye_px / ref = 「머리 크기가 표준인 유닛의 키」로 환산한 세로 px
|
||||||
|
게임(FrameAnimator)·영웅 목록은 bodyHeightPx 대신 size_px 로 배율을 정한다 → 모든 유닛의 머리 크기가 같아지고,
|
||||||
|
말 탄 유닛은 탄 사람이 보병과 같은 크기가 되도록 커진다.
|
||||||
|
|
||||||
|
표 = Assets/Resources/Units/art_size.csv(utf-8-sig · SOT) · mounted 열만 사람이 고친다(새 아트 = 이름에 cavalry 면 1).
|
||||||
|
눈을 못 찾으면 size_px 를 비워 둔다(게임은 bodyHeightPx 로 대체) · 실행 결과를 --sheet 시트로 눈 위치를 확인할 것.
|
||||||
|
|
||||||
|
사용: python -I -B -X utf8 Tools/unit_art_size.py <프로젝트 루트> [--sheet out.png]
|
||||||
|
"""
|
||||||
|
import csv
|
||||||
|
import glob
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
from scipy import ndimage
|
||||||
|
|
||||||
|
TABLE = 'Assets/Resources/Units/art_size.csv'
|
||||||
|
FIELDS = ['art', 'mounted', 'eye_px', 'body_px', 'size_px', 'note']
|
||||||
|
|
||||||
|
|
||||||
|
def skin_mask(a, red):
|
||||||
|
r, g, b, al = a[..., 0], a[..., 1], a[..., 2], a[..., 3]
|
||||||
|
mx = np.maximum(np.maximum(r, g), b)
|
||||||
|
mn = np.minimum(np.minimum(r, g), b)
|
||||||
|
sat = np.where(mx > 0, (mx - mn) / np.maximum(mx, 1e-6), 0)
|
||||||
|
if red: # 붉은 얼굴(관우)
|
||||||
|
sk = (al > 0.9) & (r > 0.8) & (g > 0.3) & (g < 0.6) & (b > 0.25) & (b < 0.55)
|
||||||
|
else:
|
||||||
|
sk = (al > 0.9) & (r >= g) & (g >= b - 0.02) & (mx > 0.78) & (sat > 0.06) & (sat < 0.45) & ((r - b) > 0.06)
|
||||||
|
return sk, mx
|
||||||
|
|
||||||
|
|
||||||
|
def find_eyes(img):
|
||||||
|
"""두 눈 (왼쪽, 오른쪽) = (면적, x, y) · 못 찾으면 None."""
|
||||||
|
a = np.asarray(img.convert('RGBA')).astype(np.float32) / 255.0
|
||||||
|
for red in (False, True):
|
||||||
|
sk, val = skin_mask(a, red)
|
||||||
|
lab, n = ndimage.label(sk)
|
||||||
|
if not n:
|
||||||
|
continue
|
||||||
|
sizes = ndimage.sum(sk, lab, range(1, n + 1))
|
||||||
|
for k in list(np.argsort(sizes)[::-1][:6] + 1):
|
||||||
|
face = lab == k
|
||||||
|
ys, xs = np.where(face)
|
||||||
|
if len(ys) < 3000:
|
||||||
|
continue
|
||||||
|
fh = ys.max() - ys.min() + 1
|
||||||
|
holes = ndimage.binary_fill_holes(face) & ~face
|
||||||
|
hl, hn = ndimage.label(holes)
|
||||||
|
cand = []
|
||||||
|
for j in range(1, hn + 1):
|
||||||
|
yy, xx = np.where(hl == j)
|
||||||
|
if len(yy) < 150 or val[yy, xx].mean() > 0.4:
|
||||||
|
continue
|
||||||
|
if (xx.max() - xx.min() + 1) > 2.2 * (yy.max() - yy.min() + 1):
|
||||||
|
continue # 가로로 긴 구멍 = 수염·입
|
||||||
|
cand.append((len(yy), xx.mean(), yy.mean()))
|
||||||
|
best = None
|
||||||
|
for l in cand:
|
||||||
|
for r in cand:
|
||||||
|
if l[1] >= r[1] or abs(l[2] - r[2]) > 0.12 * fh:
|
||||||
|
continue
|
||||||
|
if min(l[0], r[0]) < 0.45 * max(l[0], r[0]):
|
||||||
|
continue
|
||||||
|
score = min(l[0], r[0]) * (r[1] - l[1])
|
||||||
|
if best is None or score > best[0]:
|
||||||
|
best = (score, l, r)
|
||||||
|
if best:
|
||||||
|
return best[1], best[2]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
root = sys.argv[1]
|
||||||
|
sheet_path = sys.argv[sys.argv.index('--sheet') + 1] if '--sheet' in sys.argv else None
|
||||||
|
table = os.path.join(root, TABLE)
|
||||||
|
old = {}
|
||||||
|
if os.path.exists(table):
|
||||||
|
with open(table, encoding='utf-8-sig', newline='') as f:
|
||||||
|
old = {r['art']: r for r in csv.DictReader(f)}
|
||||||
|
|
||||||
|
rows, shots = [], []
|
||||||
|
for meta_path in sorted(glob.glob(os.path.join(root, 'Assets/Resources/Units/*/meta.json'))):
|
||||||
|
folder = os.path.dirname(meta_path)
|
||||||
|
art = os.path.basename(folder)
|
||||||
|
meta = json.load(open(meta_path, encoding='utf-8'))
|
||||||
|
body = meta.get('bodyHeightPx') or meta.get('charHeightPx') or 0
|
||||||
|
frame = os.path.join(folder, 'front_idle', 'f000.png')
|
||||||
|
if not os.path.exists(frame):
|
||||||
|
frame = sorted(glob.glob(os.path.join(folder, '*', 'f000.png')))[0]
|
||||||
|
img = Image.open(frame).convert('RGBA')
|
||||||
|
eyes = find_eyes(img)
|
||||||
|
prev = old.get(art, {})
|
||||||
|
mounted = prev.get('mounted', '1' if 'cavalry' in art else '0')
|
||||||
|
eye = round(eyes[1][1] - eyes[0][1], 1) if eyes else 0
|
||||||
|
rows.append({'art': art, 'mounted': mounted, 'eye_px': eye, 'body_px': body, 'size_px': '', 'note': prev.get('note', '')})
|
||||||
|
shots.append((art, meta, img, eyes))
|
||||||
|
|
||||||
|
foot = sorted(r['eye_px'] / r['body_px'] for r in rows if r['mounted'] == '0' and r['eye_px'] and r['body_px'])
|
||||||
|
if not foot:
|
||||||
|
sys.exit('말을 타지 않은 유닛의 눈 간격을 하나도 못 찾음')
|
||||||
|
mid = len(foot) // 2
|
||||||
|
ref = foot[mid] if len(foot) % 2 else (foot[mid - 1] + foot[mid]) / 2
|
||||||
|
for r in rows:
|
||||||
|
r['size_px'] = round(r['eye_px'] / ref, 1) if r['eye_px'] else ''
|
||||||
|
|
||||||
|
with open(table, 'w', encoding='utf-8-sig', newline='') as f:
|
||||||
|
w = csv.DictWriter(f, fieldnames=FIELDS, lineterminator='\n')
|
||||||
|
w.writeheader()
|
||||||
|
w.writerows(rows)
|
||||||
|
print('ref(눈 간격 / 키 · 말 안 탄 %d종 중앙값) = %.4f' % (len(foot), ref))
|
||||||
|
for r in rows:
|
||||||
|
s = (r['size_px'] / r['body_px']) if r['size_px'] else 0
|
||||||
|
print('%-22s mounted %s eye %6s body %5s size %7s 배율 x%.2f%s' % (
|
||||||
|
r['art'], r['mounted'], r['eye_px'], r['body_px'], r['size_px'], 1 / s if s else 0, '' if r['eye_px'] else ' ← 눈 못 찾음(bodyHeightPx 대체)'))
|
||||||
|
|
||||||
|
if sheet_path: # 확인 시트: 표 배율로 그린 대기 그림 + 눈 표시(머리 크기가 같아 보여야 함)
|
||||||
|
unit = 160.0 # 표준 키 = 시트 160 px
|
||||||
|
cols, cw, ch = 9, 220, 330
|
||||||
|
sheet = Image.new('RGB', (cw * cols, ch * ((len(shots) + cols - 1) // cols)), (40, 44, 60))
|
||||||
|
dr = ImageDraw.Draw(sheet)
|
||||||
|
font = ImageFont.truetype('C:/Windows/Fonts/malgun.ttf', 13)
|
||||||
|
for i, ((art, meta, img, eyes), r) in enumerate(zip(shots, rows)):
|
||||||
|
size = r['size_px'] or r['body_px']
|
||||||
|
sc = unit / size
|
||||||
|
x0, y0 = (i % cols) * cw, (i // cols) * ch
|
||||||
|
t = img.resize((max(1, int(img.width * sc)), max(1, int(img.height * sc))), Image.LANCZOS)
|
||||||
|
base = y0 + ch - 22
|
||||||
|
ox, oy = x0 + cw // 2 - t.width // 2, int(base - (1 - meta['pivot'][1]) * img.height * sc)
|
||||||
|
sheet.paste(t, (ox, oy), t)
|
||||||
|
for e in eyes or ():
|
||||||
|
ex, ey = ox + e[1] * sc, oy + e[2] * sc
|
||||||
|
dr.ellipse([ex - 3, ey - 3, ex + 3, ey + 3], outline=(0, 255, 0), width=2)
|
||||||
|
dr.text((x0 + 3, base + 3), '%s%s' % (art, ' (말)' if r['mounted'] == '1' else ''), fill=(255, 255, 255), font=font)
|
||||||
|
sheet.save(sheet_path)
|
||||||
|
print('sheet', sheet_path)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Loading…
Reference in New Issue