Compare commits
2 Commits
9e5c383a49
...
02ee7fc72e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02ee7fc72e | ||
|
|
810d019619 |
@@ -213,7 +213,7 @@ Material:
|
||||
- _Dst: 10
|
||||
- _DstBlend: 0
|
||||
- _DstBlendAlpha: 0
|
||||
- _EdgeValue: 0.92061317
|
||||
- _EdgeValue: 0.4454634
|
||||
- _EnvironmentReflections: 1
|
||||
- _FNLfanxiangkaiguan: 0
|
||||
- _Face: 1
|
||||
@@ -258,7 +258,7 @@ Material:
|
||||
- _Mask_scale: 1
|
||||
- _Metallic: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Opacity: 0.07938683
|
||||
- _Opacity: 0.5545366
|
||||
- _Parallax: 0.005
|
||||
- _Pass: 0
|
||||
- _QueueOffset: 0
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e00e6f90ab8233e46a41c5e33917c642
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9da5530d5ebfab24c8ecad68795e720f
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa102d640b98b5d4781710a3a3dd6983
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a0bb33169d95ec499136d59cb25918b
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 641c955d37d2fac4f87e00ac5c9d9bd8
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2690f45490c175045bbdc63395bf6278
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fbd1fd9b3a70fad429d1eaaa5799c2a5
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3579d9cf4b75c564faa8fffc58a9f3f6
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0023a0858ba124646a55dfcb7231ed46
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1c0b77896049554fa4b635531caf741
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0a0a980c9ba86345bc15411db88d34f
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2edbf4a9b9544774bbef617e92429664
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13ab599a7bda4e54fba3e92a13c9580a
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6f268949ccf3f34fa4d18e92501ed82
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69bc3229216b1504ea3e28b5820bbb0d
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f665a06c5a2aa5499fa1c79ac058999
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a87ed432fe2d97498c0de5fae312e35
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c3bfbbeb9427b94099254e2e2768ad4
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5303861611f41c438a30be552da5de4
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9d68dd8913f05d4d9ce75e7b40c6044
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2243c8b4e1ab6914995699133f67ab5a
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a5e61a8b3421b944863d0946e32da0a
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89f0b84148d149d4d96b838d7ef60e92
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19939ee2cdb76e0489b1b8cd4bed7f3d
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70777e8ce9f3c8d4a8182ca2f965cdb2
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba281a1a00c8ac54c914e0763299f637
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6fc8948257acee42b666d0bfe1d782c
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b5cb8698f2d9c14fadf8e2383441d37
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b460b52e6c1feae45b70b7ddc2c45bd6
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57fcea0ed8b5eb347923c4c21fa31b57
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e9da72e7e3196146bf7d27450013734
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0904cdf24ddcd5042b024326476220d5
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 929783250050f8a448821b6ca1f2c578
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fcc4d2eb0af82e546ae75506872cf092
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd0a0171c5157b748afe763b89f71211
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4990f6ace6142c4bbbf41cdd80b0bd3
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1782b72cd0e99a54fac09382c482e3db
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49d5bcbbd4cbd754b98cf3200197b0f1
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eefe45a405f061045be947217e30ed10
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e995dfe11e22d34d92432383d15c067
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec984c51d4ae2504184eeb292734c672
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e447b3d7d913d694ca35f74e30581840
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6584a66582083a1459dcf5e4e87f6d62
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0190b8bde50f12943926613d9a63c89a
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae2ce8ad295486349839288636aed1ed
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d69745226619e3241a8e04ce86aee6a6
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37e6a9374416bc946a55779c58d0d984
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/FR2_Cache.asset
LFS
BIN
Assets/FR2_Cache.asset
LFS
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e45363610a59a4543a9793b3bf2be4aa
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de41a70ead12af544a4e99a925b269d2
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f597f19f656ba56eae4f6a3a7cc528f4
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48e08dc33330d11e9d4a1b246c52e4f6
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed09910c0094cb27be8f3ca264680da3
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc355dd4cf1e6173beaeb22c2858cbe1
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -17,7 +17,7 @@ GameObject:
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
m_IsActive: 0
|
||||
--- !u!224 &4551339722402108901
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -376,20 +376,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 00000000
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -710,20 +713,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 00000000
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -920,20 +926,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 00000000
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -968,7 +977,7 @@ GameObject:
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
m_IsActive: 0
|
||||
--- !u!224 &3053449365611135054
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -1129,20 +1138,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 00000000
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -1339,20 +1351,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 00000000
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -1473,20 +1488,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 00000000
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -1773,20 +1791,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 00000000
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -1947,20 +1968,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -2082,20 +2106,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -2333,20 +2360,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -2468,20 +2498,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -2603,20 +2636,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 00000000
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -3019,20 +3055,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -3327,20 +3366,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 00000000
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -4045,20 +4087,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -4145,6 +4190,7 @@ MonoBehaviour:
|
||||
enterSongSelectionButton: {fileID: 5935354699868473682}
|
||||
connectedChapter: {fileID: 0}
|
||||
chapterName:
|
||||
isLocked: 0
|
||||
isExpanded: 0
|
||||
isDuringAnimation: 0
|
||||
bottomTip: {fileID: 3369054462927452463}
|
||||
@@ -4477,20 +4523,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 00000000
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -4694,20 +4743,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 00000000
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
@@ -5137,20 +5189,23 @@ MonoBehaviour:
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_enableWordWrapping: 1
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 00000000
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
|
||||
@@ -101,7 +101,7 @@ MonoBehaviour:
|
||||
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_DisabledColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
|
||||
@@ -101,7 +101,7 @@ MonoBehaviour:
|
||||
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_DisabledColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
@@ -116,7 +116,7 @@ MonoBehaviour:
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 1269722336407503250}
|
||||
m_TargetGraphic: {fileID: 0}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
|
||||
@@ -101,7 +101,7 @@ MonoBehaviour:
|
||||
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_DisabledColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
|
||||
@@ -11,6 +11,7 @@ GameObject:
|
||||
- component: {fileID: 7895181244729415272}
|
||||
- component: {fileID: 5622993008979475129}
|
||||
- component: {fileID: 7873337981602853883}
|
||||
- component: {fileID: 3155030838568361280}
|
||||
m_Layer: 5
|
||||
m_Name: Text (TMP) (1)
|
||||
m_TagString: Untagged
|
||||
@@ -138,6 +139,18 @@ MonoBehaviour:
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!225 &3155030838568361280
|
||||
CanvasGroup:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1266875872687906005}
|
||||
m_Enabled: 1
|
||||
m_Alpha: 1
|
||||
m_Interactable: 1
|
||||
m_BlocksRaycasts: 0
|
||||
m_IgnoreParentGroups: 0
|
||||
--- !u!1 &2549272938280010857
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -182,126 +195,6 @@ CanvasRenderer:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2549272938280010857}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!1 &2947357181438598616
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 808855937929311006}
|
||||
- component: {fileID: 3938143345111524688}
|
||||
- component: {fileID: 1269722336407503250}
|
||||
- component: {fileID: 3931523710101296998}
|
||||
m_Layer: 5
|
||||
m_Name: Image
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 0
|
||||
--- !u!224 &808855937929311006
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2947357181438598616}
|
||||
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: 5350638854831129010}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3938143345111524688
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2947357181438598616}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &1269722336407503250
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2947357181438598616}
|
||||
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: 21300000, guid: ba2e784cfa5cc0549bf66051f872367c, type: 3}
|
||||
m_Type: 0
|
||||
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 &3931523710101296998
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2947357181438598616}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, 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: 1269722336407503250}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &5694744930588099522
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -357,6 +250,7 @@ GameObject:
|
||||
- component: {fileID: 9095470796084918386}
|
||||
- component: {fileID: 606259940963463531}
|
||||
- component: {fileID: 8391808794720387191}
|
||||
- component: {fileID: 8456607026273325819}
|
||||
m_Layer: 5
|
||||
m_Name: Text (TMP)
|
||||
m_TagString: Untagged
|
||||
@@ -484,6 +378,18 @@ MonoBehaviour:
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!225 &8456607026273325819
|
||||
CanvasGroup:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7991069327751894070}
|
||||
m_Enabled: 1
|
||||
m_Alpha: 1
|
||||
m_Interactable: 1
|
||||
m_BlocksRaycasts: 0
|
||||
m_IgnoreParentGroups: 0
|
||||
--- !u!1 &8279096577214194803
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -514,7 +420,6 @@ RectTransform:
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 808855937929311006}
|
||||
- {fileID: 9095470796084918386}
|
||||
- {fileID: 7895181244729415272}
|
||||
- {fileID: 5784757909052703056}
|
||||
@@ -638,6 +543,6 @@ MonoBehaviour:
|
||||
blockRect: {fileID: 5350638854831129010}
|
||||
inPort: {fileID: 5784757909052703056}
|
||||
outPort: {fileID: 4937946904652960982}
|
||||
button: {fileID: 3931523710101296998}
|
||||
button: {fileID: 0}
|
||||
storyIdText: {fileID: 8391808794720387191}
|
||||
titleText: {fileID: 8391808794720387191}
|
||||
|
||||
@@ -101,7 +101,7 @@ MonoBehaviour:
|
||||
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_DisabledColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
|
||||
@@ -101,7 +101,7 @@ MonoBehaviour:
|
||||
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_DisabledColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
@@ -116,7 +116,7 @@ MonoBehaviour:
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 1269722336407503250}
|
||||
m_TargetGraphic: {fileID: 0}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
|
||||
@@ -101,7 +101,7 @@ MonoBehaviour:
|
||||
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_DisabledColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
|
||||
@@ -221,7 +221,7 @@ MonoBehaviour:
|
||||
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_DisabledColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
|
||||
@@ -101,7 +101,7 @@ MonoBehaviour:
|
||||
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_DisabledColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
|
||||
@@ -150,126 +150,6 @@ MonoBehaviour:
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!1 &2947357181438598616
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 808855937929311006}
|
||||
- component: {fileID: 464408401004507889}
|
||||
- component: {fileID: 5684991247721594449}
|
||||
- component: {fileID: 3931523710101296998}
|
||||
m_Layer: 5
|
||||
m_Name: Button
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &808855937929311006
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2947357181438598616}
|
||||
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: 5350638854831129010}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &464408401004507889
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2947357181438598616}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &5684991247721594449
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2947357181438598616}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
|
||||
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: 0}
|
||||
m_Type: 0
|
||||
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 &3931523710101296998
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2947357181438598616}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, 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: 5684991247721594449}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &3472041800732464321
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -281,6 +161,7 @@ GameObject:
|
||||
- component: {fileID: 6776097071409445873}
|
||||
- component: {fileID: 5860881451225714455}
|
||||
- component: {fileID: 4081607830298877796}
|
||||
- component: {fileID: 5567213864031973997}
|
||||
m_Layer: 5
|
||||
m_Name: TitleText
|
||||
m_TagString: Untagged
|
||||
@@ -408,6 +289,18 @@ MonoBehaviour:
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!225 &5567213864031973997
|
||||
CanvasGroup:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3472041800732464321}
|
||||
m_Enabled: 1
|
||||
m_Alpha: 1
|
||||
m_Interactable: 1
|
||||
m_BlocksRaycasts: 0
|
||||
m_IgnoreParentGroups: 0
|
||||
--- !u!1 &7991069327751894070
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -419,6 +312,7 @@ GameObject:
|
||||
- component: {fileID: 9095470796084918386}
|
||||
- component: {fileID: 606259940963463531}
|
||||
- component: {fileID: 8391808794720387191}
|
||||
- component: {fileID: 7157907970610375421}
|
||||
m_Layer: 5
|
||||
m_Name: StoryIdText
|
||||
m_TagString: Untagged
|
||||
@@ -546,6 +440,18 @@ MonoBehaviour:
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!225 &7157907970610375421
|
||||
CanvasGroup:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7991069327751894070}
|
||||
m_Enabled: 1
|
||||
m_Alpha: 1
|
||||
m_Interactable: 1
|
||||
m_BlocksRaycasts: 0
|
||||
m_IgnoreParentGroups: 0
|
||||
--- !u!1 &8279096577214194803
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -580,7 +486,6 @@ RectTransform:
|
||||
- {fileID: 6776097071409445873}
|
||||
- {fileID: 8088187650405042001}
|
||||
- {fileID: 5120337310990590007}
|
||||
- {fileID: 808855937929311006}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
@@ -687,6 +592,6 @@ MonoBehaviour:
|
||||
blockRect: {fileID: 5350638854831129010}
|
||||
inPort: {fileID: 8088187650405042001}
|
||||
outPort: {fileID: 5120337310990590007}
|
||||
button: {fileID: 3931523710101296998}
|
||||
button: {fileID: 0}
|
||||
storyIdText: {fileID: 8391808794720387191}
|
||||
titleText: {fileID: 4081607830298877796}
|
||||
|
||||
@@ -1,94 +1,5 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &629758055316317495
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5620483555661743440}
|
||||
- component: {fileID: 808211794615970900}
|
||||
- component: {fileID: 1717850242396468755}
|
||||
m_Layer: 5
|
||||
m_Name: Button
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5620483555661743440
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 629758055316317495}
|
||||
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: 5350638854831129010}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 2.75, y: -1}
|
||||
m_SizeDelta: {x: -25.5, y: -22}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &808211794615970900
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 629758055316317495}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &1717850242396468755
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 629758055316317495}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, 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: 0
|
||||
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: 0}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &847642077185086423
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -257,6 +168,7 @@ GameObject:
|
||||
- component: {fileID: 1824825661128247125}
|
||||
- component: {fileID: 6839066121088903434}
|
||||
- component: {fileID: 4619121194727073750}
|
||||
- component: {fileID: 6000241608163664205}
|
||||
m_Layer: 5
|
||||
m_Name: Mask
|
||||
m_TagString: Untagged
|
||||
@@ -335,6 +247,50 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Mask
|
||||
m_ShowMaskGraphic: 0
|
||||
--- !u!114 &6000241608163664205
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2685032725291833036}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Button
|
||||
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: 5963302735353550978}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &2947357181438598616
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -1053,7 +1009,6 @@ RectTransform:
|
||||
- {fileID: 530893922272850372}
|
||||
- {fileID: 5732796955640118753}
|
||||
- {fileID: 4908100188787544557}
|
||||
- {fileID: 5620483555661743440}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
@@ -1095,7 +1050,7 @@ MonoBehaviour:
|
||||
blockRect: {fileID: 5350638854831129010}
|
||||
inPort: {fileID: 5732796955640118753}
|
||||
outPort: {fileID: 4908100188787544557}
|
||||
button: {fileID: 1717850242396468755}
|
||||
button: {fileID: 6000241608163664205}
|
||||
illustrationImage: {fileID: 5963302735353550978}
|
||||
illustrationRect: {fileID: 4492029902276622460}
|
||||
songNameText: {fileID: 8391808794720387191}
|
||||
|
||||
@@ -55,6 +55,7 @@ GameObject:
|
||||
- component: {fileID: 808855937929311006}
|
||||
- component: {fileID: 3938143345111524688}
|
||||
- component: {fileID: 1269722336407503250}
|
||||
- component: {fileID: 2589979841992238672}
|
||||
m_Layer: 5
|
||||
m_Name: Image
|
||||
m_TagString: Untagged
|
||||
@@ -119,63 +120,18 @@ MonoBehaviour:
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!1 &2971854550119419744
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6723909345398867291}
|
||||
- component: {fileID: 1883720140888459607}
|
||||
- component: {fileID: 1506827284251123157}
|
||||
m_Layer: 5
|
||||
m_Name: Button
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &6723909345398867291
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2971854550119419744}
|
||||
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: 5350638854831129010}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0.5, y: -7.5}
|
||||
m_SizeDelta: {x: -31, y: -29}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &1883720140888459607
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2971854550119419744}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &1506827284251123157
|
||||
--- !u!114 &2589979841992238672
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2971854550119419744}
|
||||
m_GameObject: {fileID: 2947357181438598616}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Button
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_WrapAround: 0
|
||||
@@ -183,7 +139,7 @@ MonoBehaviour:
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 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}
|
||||
@@ -204,7 +160,7 @@ MonoBehaviour:
|
||||
m_SelectedTrigger: Selected
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 0}
|
||||
m_TargetGraphic: {fileID: 1269722336407503250}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
@@ -263,6 +219,7 @@ GameObject:
|
||||
- component: {fileID: 9095470796084918386}
|
||||
- component: {fileID: 606259940963463531}
|
||||
- component: {fileID: 8391808794720387191}
|
||||
- component: {fileID: 2409804111795149599}
|
||||
m_Layer: 5
|
||||
m_Name: Text (TMP)
|
||||
m_TagString: Untagged
|
||||
@@ -390,6 +347,18 @@ MonoBehaviour:
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!225 &2409804111795149599
|
||||
CanvasGroup:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7991069327751894070}
|
||||
m_Enabled: 1
|
||||
m_Alpha: 1
|
||||
m_Interactable: 1
|
||||
m_BlocksRaycasts: 0
|
||||
m_IgnoreParentGroups: 0
|
||||
--- !u!1 &8279096577214194803
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -424,7 +393,6 @@ RectTransform:
|
||||
- {fileID: 9095470796084918386}
|
||||
- {fileID: 5784757909052703056}
|
||||
- {fileID: 4937946904652960982}
|
||||
- {fileID: 6723909345398867291}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0.5}
|
||||
@@ -466,5 +434,5 @@ MonoBehaviour:
|
||||
blockRect: {fileID: 5350638854831129010}
|
||||
inPort: {fileID: 5784757909052703056}
|
||||
outPort: {fileID: 4937946904652960982}
|
||||
button: {fileID: 1506827284251123157}
|
||||
button: {fileID: 2589979841992238672}
|
||||
tutorialNameText: {fileID: 8391808794720387191}
|
||||
|
||||
407
Assets/Prefabs/Story/Dialog/HistoryText.prefab
Normal file
407
Assets/Prefabs/Story/Dialog/HistoryText.prefab
Normal file
@@ -0,0 +1,407 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &65537282130585173
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1643897006236830438}
|
||||
- component: {fileID: 6202551277621388703}
|
||||
- component: {fileID: 6295076540922261237}
|
||||
m_Layer: 5
|
||||
m_Name: Speaker
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1643897006236830438
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 65537282130585173}
|
||||
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: 5159032239856795640}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0.5}
|
||||
m_AnchorMax: {x: 0, y: 0.5}
|
||||
m_AnchoredPosition: {x: 225, y: 0}
|
||||
m_SizeDelta: {x: 250, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6202551277621388703
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 65537282130585173}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &6295076540922261237
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 65537282130585173}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
|
||||
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_text: "Speaker: \n"
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 87c1b020037c81841b3d98dd497cbdeb, type: 2}
|
||||
m_sharedMaterial: {fileID: -5812992765432063453, guid: 87c1b020037c81841b3d98dd497cbdeb,
|
||||
type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_enableVertexGradient: 0
|
||||
m_colorMode: 3
|
||||
m_fontColorGradient:
|
||||
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_fontColorGradientPreset: {fileID: 0}
|
||||
m_spriteAsset: {fileID: 0}
|
||||
m_tintAllSprites: 0
|
||||
m_StyleSheet: {fileID: 0}
|
||||
m_TextStyleHashCode: -1183493901
|
||||
m_overrideHtmlColors: 0
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 42
|
||||
m_fontSizeBase: 42
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_fontStyle: 0
|
||||
m_HorizontalAlignment: 1
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 0
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
m_horizontalMapping: 0
|
||||
m_verticalMapping: 0
|
||||
m_uvLineOffset: 0
|
||||
m_geometrySortingOrder: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_VertexBufferAutoSizeReduction: 0
|
||||
m_useMaxVisibleDescender: 1
|
||||
m_pageToDisplay: 1
|
||||
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_isUsingLegacyAnimationComponent: 0
|
||||
m_isVolumetricText: 0
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!1 &1609519350888832602
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4891349041236814278}
|
||||
- component: {fileID: 4388088537228770510}
|
||||
- component: {fileID: 5176135775194928437}
|
||||
m_Layer: 5
|
||||
m_Name: Content
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &4891349041236814278
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1609519350888832602}
|
||||
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: 5159032239856795640}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0.5}
|
||||
m_AnchorMax: {x: 1, y: 0.5}
|
||||
m_AnchoredPosition: {x: 175.00002, y: 0}
|
||||
m_SizeDelta: {x: -349.99997, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4388088537228770510
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1609519350888832602}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &5176135775194928437
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1609519350888832602}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshProUGUI
|
||||
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_text: Content
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 87c1b020037c81841b3d98dd497cbdeb, type: 2}
|
||||
m_sharedMaterial: {fileID: -5812992765432063453, guid: 87c1b020037c81841b3d98dd497cbdeb,
|
||||
type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_enableVertexGradient: 0
|
||||
m_colorMode: 3
|
||||
m_fontColorGradient:
|
||||
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_fontColorGradientPreset: {fileID: 0}
|
||||
m_spriteAsset: {fileID: 0}
|
||||
m_tintAllSprites: 0
|
||||
m_StyleSheet: {fileID: 0}
|
||||
m_TextStyleHashCode: -1183493901
|
||||
m_overrideHtmlColors: 0
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 42
|
||||
m_fontSizeBase: 42
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_fontStyle: 0
|
||||
m_HorizontalAlignment: 1
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 0
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
m_horizontalMapping: 0
|
||||
m_verticalMapping: 0
|
||||
m_uvLineOffset: 0
|
||||
m_geometrySortingOrder: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_VertexBufferAutoSizeReduction: 0
|
||||
m_useMaxVisibleDescender: 1
|
||||
m_pageToDisplay: 1
|
||||
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_isUsingLegacyAnimationComponent: 0
|
||||
m_isVolumetricText: 0
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!1 &3327801269455335983
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5159032239856795640}
|
||||
- component: {fileID: 5965612576668694196}
|
||||
m_Layer: 5
|
||||
m_Name: HistoryText
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5159032239856795640
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3327801269455335983}
|
||||
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: 1643897006236830438}
|
||||
- {fileID: 4891349041236814278}
|
||||
- {fileID: 572619156665643296}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 2560, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &5965612576668694196
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3327801269455335983}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: eaf151163c994d31bfabde12ede0fa98, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Ichni.Story.UI.DialogueHistoryEntryView
|
||||
speakerText: {fileID: 6295076540922261237}
|
||||
contentText: {fileID: 5176135775194928437}
|
||||
choiceIndicator: {fileID: 4440795975948891807}
|
||||
--- !u!1 &4440795975948891807
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 572619156665643296}
|
||||
- component: {fileID: 7654607494418361635}
|
||||
- component: {fileID: 4823002412552371432}
|
||||
m_Layer: 5
|
||||
m_Name: ChoiceIndicator
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &572619156665643296
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4440795975948891807}
|
||||
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: 5159032239856795640}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0.5}
|
||||
m_AnchorMax: {x: 0, y: 0.5}
|
||||
m_AnchoredPosition: {x: 50, y: 0}
|
||||
m_SizeDelta: {x: 25, y: 25}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7654607494418361635
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4440795975948891807}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &4823002412552371432
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4440795975948891807}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
|
||||
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: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
7
Assets/Prefabs/Story/Dialog/HistoryText.prefab.meta
Normal file
7
Assets/Prefabs/Story/Dialog/HistoryText.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75e7242449b105748a3d9a0864ce1391
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
387
Assets/Prefabs/Story/HelperTalk.prefab
Normal file
387
Assets/Prefabs/Story/HelperTalk.prefab
Normal file
@@ -0,0 +1,387 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &1508090727333609782
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4686535100579303134}
|
||||
- component: {fileID: 287764825431730093}
|
||||
- component: {fileID: 604884221485964818}
|
||||
- component: {fileID: -2678516924990041575}
|
||||
- component: {fileID: 4403268097300063903}
|
||||
m_Layer: 5
|
||||
m_Name: HelperTalk
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &4686535100579303134
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1508090727333609782}
|
||||
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: 7502641187092686647}
|
||||
- {fileID: 3218827982254574115}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 700, y: 270}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &287764825431730093
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1508090727333609782}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &604884221485964818
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1508090727333609782}
|
||||
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: 21300000, guid: 8746c977baa2dfb42a2e1acd589d3c5b, type: 3}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 1
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!225 &-2678516924990041575
|
||||
CanvasGroup:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1508090727333609782}
|
||||
m_Enabled: 1
|
||||
m_Alpha: 1
|
||||
m_Interactable: 1
|
||||
m_BlocksRaycasts: 1
|
||||
m_IgnoreParentGroups: 0
|
||||
--- !u!114 &4403268097300063903
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1508090727333609782}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e8bca20cc0f14b97944b95bdcf47d506, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Ichni.Story.StoryHelperTalk
|
||||
speakerText: {fileID: 966082263634710134}
|
||||
contentText: {fileID: 5450284912810547205}
|
||||
showDuration: 0.18
|
||||
visibleDuration: 4.5
|
||||
hideDuration: 0.16
|
||||
initialScaleMultiplier: 0.92
|
||||
--- !u!1 &3587908678025149924
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3218827982254574115}
|
||||
- component: {fileID: 904411096527340721}
|
||||
- component: {fileID: 5450284912810547205}
|
||||
m_Layer: 5
|
||||
m_Name: HelperText
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3218827982254574115
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3587908678025149924}
|
||||
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: 4686535100579303134}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 17.5, y: -7.5}
|
||||
m_SizeDelta: {x: -85, y: -165}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &904411096527340721
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3587908678025149924}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &5450284912810547205
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3587908678025149924}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, 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_text: "\u95F9\u9EBB\u4E86"
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 73f9a9bb620a2b040ab7347b390452fe, type: 2}
|
||||
m_sharedMaterial: {fileID: 1291443754377433884, guid: 73f9a9bb620a2b040ab7347b390452fe,
|
||||
type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_enableVertexGradient: 0
|
||||
m_colorMode: 3
|
||||
m_fontColorGradient:
|
||||
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_fontColorGradientPreset: {fileID: 0}
|
||||
m_spriteAsset: {fileID: 0}
|
||||
m_tintAllSprites: 0
|
||||
m_StyleSheet: {fileID: 0}
|
||||
m_TextStyleHashCode: -1183493901
|
||||
m_overrideHtmlColors: 0
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 32
|
||||
m_fontSizeBase: 32
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 1
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 32
|
||||
m_fontStyle: 0
|
||||
m_HorizontalAlignment: 1
|
||||
m_VerticalAlignment: 256
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
m_horizontalMapping: 0
|
||||
m_verticalMapping: 0
|
||||
m_uvLineOffset: 0
|
||||
m_geometrySortingOrder: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_VertexBufferAutoSizeReduction: 0
|
||||
m_useMaxVisibleDescender: 1
|
||||
m_pageToDisplay: 1
|
||||
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_isUsingLegacyAnimationComponent: 0
|
||||
m_isVolumetricText: 0
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!1 &7936195258843532652
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7502641187092686647}
|
||||
- component: {fileID: 5167521932169979174}
|
||||
- component: {fileID: 966082263634710134}
|
||||
m_Layer: 5
|
||||
m_Name: HelperName
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &7502641187092686647
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7936195258843532652}
|
||||
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: 4686535100579303134}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 200, y: -55}
|
||||
m_SizeDelta: {x: 300, y: 45}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5167521932169979174
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7936195258843532652}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &966082263634710134
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7936195258843532652}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, 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_text: "\u95F9\u9EBB\u4E86"
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 73f9a9bb620a2b040ab7347b390452fe, type: 2}
|
||||
m_sharedMaterial: {fileID: 1291443754377433884, guid: 73f9a9bb620a2b040ab7347b390452fe,
|
||||
type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_enableVertexGradient: 0
|
||||
m_colorMode: 3
|
||||
m_fontColorGradient:
|
||||
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_fontColorGradientPreset: {fileID: 0}
|
||||
m_spriteAsset: {fileID: 0}
|
||||
m_tintAllSprites: 0
|
||||
m_StyleSheet: {fileID: 0}
|
||||
m_TextStyleHashCode: -1183493901
|
||||
m_overrideHtmlColors: 0
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 37.2
|
||||
m_fontSizeBase: 32
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 1
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 42
|
||||
m_fontStyle: 0
|
||||
m_HorizontalAlignment: 1
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
m_horizontalMapping: 0
|
||||
m_verticalMapping: 0
|
||||
m_uvLineOffset: 0
|
||||
m_geometrySortingOrder: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_VertexBufferAutoSizeReduction: 0
|
||||
m_useMaxVisibleDescender: 1
|
||||
m_pageToDisplay: 1
|
||||
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_isUsingLegacyAnimationComponent: 0
|
||||
m_isVolumetricText: 0
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
7
Assets/Prefabs/Story/HelperTalk.prefab.meta
Normal file
7
Assets/Prefabs/Story/HelperTalk.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40df11d39d80e2f4785e492c3b1d1a10
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -10,6 +10,7 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 4290474858249249208}
|
||||
- component: {fileID: 483471027588563956}
|
||||
- component: {fileID: 6009244213662721001}
|
||||
m_Layer: 5
|
||||
m_Name: StoryTimelineMarker
|
||||
m_TagString: Untagged
|
||||
@@ -48,10 +49,55 @@ MonoBehaviour:
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5fa49b969e984456985eec86f0275d7d, type: 3}
|
||||
m_Name:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Ichni.Story.UI.StoryTimelineMarkerView
|
||||
markerRect: {fileID: 4290474858249249208}
|
||||
labelText: {fileID: 3350283590570236064}
|
||||
button: {fileID: 6009244213662721001}
|
||||
--- !u!114 &6009244213662721001
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1574009245387883632}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
||||
m_Name: ""
|
||||
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Button
|
||||
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: 0
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_PressedColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_SelectedColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_DisabledColor: {r: 1, g: 1, b: 1, a: 0.5}
|
||||
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: 940605879243566513}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &4209846266689669036
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using AK.Wwise;
|
||||
using Ichni.Menu;
|
||||
using Ichni.Story;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
@@ -28,6 +29,12 @@ namespace Ichni
|
||||
/// </summary>
|
||||
public MenuReturnDestination menuReturnDestination;
|
||||
|
||||
/// <summary>
|
||||
/// 由剧情 SongBlock 发起的单次选曲上下文。它是运行时路由数据,不属于玩家存档;
|
||||
/// 仅用于校验目标歌曲、决定返回页面并还原剧情树浏览位置。
|
||||
/// </summary>
|
||||
[System.NonSerialized] public StorySongEntryContext storySongEntryContext = new StorySongEntryContext();
|
||||
|
||||
public ChapterSelectionUnit chapter;
|
||||
public SongItemData song;
|
||||
public DifficultyData difficulty;
|
||||
@@ -57,7 +64,12 @@ namespace Ichni
|
||||
{
|
||||
// 保留旧入口,供现有选曲流程在播放过场前预先写入歌曲信息。
|
||||
// 真正进入 GameScene 时,MenuManager.EnterGame 会补充 SongSelection 返回目标。
|
||||
PrepareGameLaunch(chapter, song, difficulty, MenuReturnDestination.None);
|
||||
if (PrepareGameLaunch(chapter, song, difficulty, MenuReturnDestination.None))
|
||||
{
|
||||
// 只有玩家真正确认“进入游戏”且命中剧情目标歌曲时,才完成对应 SongBlock。
|
||||
// 单纯从剧情打开选曲、浏览其它歌曲或返回菜单都不会写入剧情进度。
|
||||
StoryManager.instance?.HandleSongSelectionConfirmed(chapter, song);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -79,6 +91,10 @@ namespace Ichni
|
||||
chapterSwitch = chapter.chapterSwitch;
|
||||
songSwitch = song.songSwitch;
|
||||
menuReturnDestination = returnDestination;
|
||||
|
||||
// “确认进入游戏”是歌曲尝试的统一边界。无论入口来自普通选曲、Story SongBlock 或教程,
|
||||
// 都由 SongSaves 记录这一次尝试;StoryTree 会在构建/返回时据此同步 SongBlock 完成状态。
|
||||
GameSaveManager.instance?.SongSaveModule?.MarkSongTried(song.songName);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ namespace Ichni
|
||||
// 不能依赖旧场景中残留的 Block 实例。
|
||||
StoryManager.instance?.OpenChapter(ChapterSelectionManager.instance.currentChapter.chapterIndex);
|
||||
storyUIPage.FadeIn();
|
||||
StoryManager.instance?.RestoreStoryAfterGameReturn();
|
||||
}
|
||||
|
||||
// 返回目标是一次性运行态信息。无论是否能恢复页面,都不能让它在下次重进菜单时重复生效。
|
||||
@@ -96,7 +97,14 @@ namespace Ichni
|
||||
{
|
||||
public void EnterGame()
|
||||
{
|
||||
EnterGame(MenuReturnDestination.SongSelection);
|
||||
// 剧情 SongBlock 仅在玩家确认进入指定目标歌曲后才要求返回剧情;
|
||||
// 普通选曲与从剧情入口改选其它歌曲都继续返回选曲页。
|
||||
StorySongEntryContext context = InformationTransistor.instance?.storySongEntryContext;
|
||||
MenuReturnDestination destination = context != null && context.isActive &&
|
||||
context.returnToStoryAfterGame
|
||||
? MenuReturnDestination.Story
|
||||
: MenuReturnDestination.SongSelection;
|
||||
EnterGame(destination);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -40,14 +40,14 @@ namespace Ichni.Story
|
||||
[LabelText("Emotion Sprites")]
|
||||
[ShowIf("portraitStyle", PortraitStyle.Sprite)]
|
||||
[DictionaryDrawerSettings(KeyLabel = "Emotion Name", ValueLabel = "Sprite")]
|
||||
[InfoBox("Key 为情绪名(如 normal / happy / angry),Value 为对应 Sprite 资产。")]
|
||||
[Tooltip("Key 为情绪名(如 normal / happy / angry),Value 为对应 Sprite 资产。")]
|
||||
public Dictionary<string, Sprite> emotionSprites = new Dictionary<string, Sprite>();
|
||||
|
||||
// ── Dynamic (Live2D / Spine) ─────────────────────────────────────────────
|
||||
|
||||
[LabelText("Dynamic Portrait Prefab")]
|
||||
[ShowIf("IsDynamicPortrait")]
|
||||
[InfoBox("Live2D / Spine 立绘预制体,需挂载实现 IPortraitRenderer 接口的组件(阶段 3 制作)。")]
|
||||
[Tooltip("Live2D / Spine 立绘预制体,需挂载实现 IPortraitRenderer 接口的组件。")]
|
||||
public GameObject dynamicPortraitPrefab;
|
||||
|
||||
private bool IsDynamicPortrait => portraitStyle == PortraitStyle.Live2D || portraitStyle == PortraitStyle.Spine;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Ichni.Story
|
||||
{
|
||||
[LabelText("Characters")]
|
||||
[ListDrawerSettings(ShowFoldout = true, DraggableItems = true)]
|
||||
[InfoBox("将所有角色的 CharacterData 资产拖入此列表,系统运行时会自动按 characterId 建立索引。")]
|
||||
[Tooltip("将所有角色的 CharacterData 资产拖入此列表,系统运行时会自动按 characterId 建立索引。")]
|
||||
public List<CharacterData> characters = new List<CharacterData>();
|
||||
|
||||
// 运行时缓存,首次 TryGet 时延迟构建
|
||||
|
||||
@@ -26,6 +26,25 @@ namespace Ichni.Story
|
||||
Tutorial
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 一个 Block 如何自动处理指向它的直接连接线。
|
||||
/// <para>连接线表达基础流程关系,因此默认要求所有直接前置 Block 都已完成;该结果会与
|
||||
/// <see cref="StoryBlockDefinition.unlockCondition"/> 按 AND 合并。</para>
|
||||
/// <para>路线汇合时应使用 <see cref="RequireAnyDirectPredecessor"/>;仅用于视觉连线、
|
||||
/// 不应影响可用性的连接则使用 <see cref="IgnoreConnections"/>。</para>
|
||||
/// </summary>
|
||||
public enum ConnectedBlockUnlockRule
|
||||
{
|
||||
/// <summary>默认值:全部直接前置 Block 都必须完成。</summary>
|
||||
RequireAllDirectPredecessors = 0,
|
||||
|
||||
/// <summary>至少一个直接前置 Block 完成即可,适用于互斥分支的汇合节点。</summary>
|
||||
RequireAnyDirectPredecessor = 1,
|
||||
|
||||
/// <summary>忽略连接线,只按手写 Unlock Condition 判断。</summary>
|
||||
IgnoreConnections = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TextBlock 的叙事层级。层级只决定剧情树中的视觉样式和 checkpoint 候选资格,
|
||||
/// 不会自行改变 Block 的解锁条件或 Yarn 执行逻辑。
|
||||
@@ -53,34 +72,59 @@ namespace Ichni.Story
|
||||
/// 故事树中单个 block 的完整数据定义,由 <see cref="StoryData"/> 持有。
|
||||
/// </summary>
|
||||
[InlineProperty]
|
||||
[HideReferenceObjectPicker]
|
||||
[Serializable]
|
||||
public class StoryBlockDefinition
|
||||
{
|
||||
[FoldoutGroup("$blockId", false)]
|
||||
[LabelText("Block ID")]
|
||||
// 仅用于 Odin Inspector 的动态折叠标题,不参与序列化或运行时状态推导。
|
||||
// 在列表中即可识别 Block 的身份、类型与布局位置,减少频繁展开确认的需要。
|
||||
private string EditorHeader => string.IsNullOrWhiteSpace(blockId)
|
||||
? "New Block"
|
||||
: $"{blockId} · {blockType} · C{gridColumn:0.##} / R{gridRow:0.##}";
|
||||
|
||||
[FoldoutGroup("$EditorHeader", false)]
|
||||
[HorizontalGroup("$EditorHeader/Identity", 0.58f)]
|
||||
[LabelText("ID")]
|
||||
[Tooltip("Block 的稳定唯一 ID。连接、条件、Timeline Marker 与存档均依赖该值;建议使用英文、数字和下划线。")]
|
||||
public string blockId;
|
||||
|
||||
[FoldoutGroup("$blockId")]
|
||||
[FoldoutGroup("$EditorHeader")]
|
||||
[HorizontalGroup("$EditorHeader/Identity")]
|
||||
[LabelText("Type")]
|
||||
[Tooltip("决定该 Block 的运行时入口与下方显示的专属配置。")]
|
||||
public StoryBlockType blockType;
|
||||
|
||||
[FoldoutGroup("$blockId")]
|
||||
[LabelText("Grid Column")]
|
||||
[FoldoutGroup("$EditorHeader")]
|
||||
[HorizontalGroup("$EditorHeader/Layout")]
|
||||
[LabelText("Column")]
|
||||
[Tooltip("故事树网格中的列:向右为正,(0,0) 位于容器左侧中部。可为负数与小数(用于微调)。")]
|
||||
public float gridColumn;
|
||||
|
||||
[FoldoutGroup("$blockId")]
|
||||
[LabelText("Grid Row")]
|
||||
[FoldoutGroup("$EditorHeader")]
|
||||
[HorizontalGroup("$EditorHeader/Layout")]
|
||||
[LabelText("Row")]
|
||||
[Tooltip("故事树网格中的行:向下为正、向上为负,0 对应垂直中线。可为小数(用于微调)。")]
|
||||
public float gridRow;
|
||||
|
||||
[FoldoutGroup("$blockId")]
|
||||
[LabelText("Next Block IDs")]
|
||||
[FoldoutGroup("$EditorHeader/Flow", false)]
|
||||
[LabelText("Next Blocks")]
|
||||
[Tooltip("从本 Block 指向的后续 Block ID。该列表既决定连接线,也会成为后续 Block 的自动前置条件来源。")]
|
||||
[ListDrawerSettings(ShowFoldout = true, DefaultExpandedState = false, ShowItemCount = true)]
|
||||
public List<string> nextBlockIds = new List<string>();
|
||||
|
||||
[FoldoutGroup("$blockId")]
|
||||
[LabelText("Unlock Condition")]
|
||||
[InfoBox("留空表示无条件解锁(章节起始即可用)。")]
|
||||
/// <summary>
|
||||
/// 自动把所有指向本 Block 的直接连接线转化为基础解锁条件。
|
||||
/// 没有前置连接线的章节起始 Block 不受此字段限制;默认“全部前置完成”再与手写条件按 AND 合并。
|
||||
/// </summary>
|
||||
[FoldoutGroup("$EditorHeader/Flow")]
|
||||
[LabelText("Connected Rule")]
|
||||
[Tooltip("默认 Require All:所有直接前置 Block 完成后才可用。互斥路线汇合使用 Require Any;纯视觉连接使用 Ignore。")]
|
||||
public ConnectedBlockUnlockRule connectedBlockUnlockRule =
|
||||
ConnectedBlockUnlockRule.RequireAllDirectPredecessors;
|
||||
|
||||
[FoldoutGroup("$EditorHeader/Rules", false)]
|
||||
[LabelText("Unlock")]
|
||||
[Tooltip("可选的额外可用条件;它与 Connected Rule 按 AND 合并。没有前置连接的起始 Block 通常留空即可。")]
|
||||
public StoryCondition unlockCondition = new StoryCondition();
|
||||
|
||||
/// <summary>
|
||||
@@ -88,38 +132,41 @@ namespace Ichni.Story
|
||||
/// 因而可直接使用剧情变量、Block 完成状态及 AND / OR / NOT 组合。
|
||||
/// 条件满足时,该 Block 的状态固定为 Forbidden,且优先于 Completed / Current / Locked。
|
||||
/// </summary>
|
||||
[FoldoutGroup("$blockId")]
|
||||
[LabelText("Forbidden Condition")]
|
||||
[InfoBox("可选。留空表示此 Block 不会被条件禁用;满足时显示为 Forbidden 且不可点击。")]
|
||||
[FoldoutGroup("$EditorHeader/Rules")]
|
||||
[LabelText("Forbidden")]
|
||||
[Tooltip("可选。满足时该 Block 固定显示为 Forbidden 且不可点击;留空表示不会被条件禁用。")]
|
||||
public StoryCondition forbiddenCondition = new StoryCondition();
|
||||
|
||||
// ── Text Block ──────────────────────────────────────────────────────────
|
||||
|
||||
[FoldoutGroup("$blockId")]
|
||||
[FoldoutGroup("$EditorHeader/Text Content", false)]
|
||||
[ShowIf("blockType", StoryBlockType.Text)]
|
||||
[LabelText("Yarn Node Name")]
|
||||
[LabelText("Yarn Node")]
|
||||
[Tooltip("点击 TextBlock 后由 Yarn Spinner 开始执行的节点名。")]
|
||||
public string yarnNodeName;
|
||||
|
||||
[FoldoutGroup("$blockId")]
|
||||
[FoldoutGroup("$EditorHeader/Text Content")]
|
||||
[ShowIf("blockType", StoryBlockType.Text)]
|
||||
[LabelText("Title Key (Localization)")]
|
||||
[LabelText("Title Key")]
|
||||
[Tooltip("该 TextBlock 标题使用的 Unity Localization Entry Key;留空时视觉层可使用 Block ID 作为开发阶段回退。")]
|
||||
public string titleKey;
|
||||
|
||||
/// <summary>
|
||||
/// TextBlock 的视觉和叙事层级。Important 用于主线转折与后续 checkpoint;
|
||||
/// Secondary 用于支线或补充剧情。默认 Important,以保持现有 TextBlock 的呈现语义。
|
||||
/// </summary>
|
||||
[FoldoutGroup("$blockId")]
|
||||
[FoldoutGroup("$EditorHeader/Text Content")]
|
||||
[ShowIf("blockType", StoryBlockType.Text)]
|
||||
[LabelText("Text Importance")]
|
||||
[LabelText("Importance")]
|
||||
[Tooltip("Important 用于主线转折与后续 Checkpoint;Secondary 用于支线或补充剧情,并决定对应的 Block Prefab。")]
|
||||
public TextBlockImportance textImportance = TextBlockImportance.Important;
|
||||
|
||||
// ── Song Block ──────────────────────────────────────────────────────────
|
||||
|
||||
[FoldoutGroup("$blockId")]
|
||||
[FoldoutGroup("$EditorHeader/Song Content", false)]
|
||||
[ShowIf("blockType", StoryBlockType.Song)]
|
||||
[LabelText("Song Name (Stable ID)")]
|
||||
[InfoBox("对应 ChapterSelectionUnit 中 SongItemData.songName 的稳定歌曲标识。它用于查找歌曲资料与进入选曲,不能填写 displaySongName、翻译文本或作曲者名称。")]
|
||||
[LabelText("Song ID")]
|
||||
[Tooltip("对应 ChapterSelectionUnit 中 SongItemData.songName 的稳定歌曲标识。不能填写 displaySongName、翻译文本或作曲者名称。")]
|
||||
public string songName;
|
||||
|
||||
/// <summary>
|
||||
@@ -127,18 +174,19 @@ namespace Ichni.Story
|
||||
/// Mask 可视区域固定为当前 Prefab 的尺寸;在不露出上下空白的前提下,安全范围为 -74.25 到 74.25。
|
||||
/// 该值是最终坐标而非偏移量:0 表示居中,负值向下移动,正值向上移动。
|
||||
/// </summary>
|
||||
[FoldoutGroup("$blockId")]
|
||||
[FoldoutGroup("$EditorHeader/Song Content")]
|
||||
[ShowIf("blockType", StoryBlockType.Song)]
|
||||
[LabelText("Illustration Local Y")]
|
||||
[LabelText("Illustration Y")]
|
||||
[Range(-74.25f, 74.25f)]
|
||||
[InfoBox("用于微调 16:9 插画在 SongBlock Mask 中的纵向裁切。请保持 SongBlockUI 的 Illustration 尺寸为 400 x 225。")]
|
||||
[Tooltip("微调 16:9 插画在 SongBlock Mask 中的纵向裁切。SongBlockUI 的 Illustration 尺寸应保持为 400 × 225。")]
|
||||
public float illustrationLocalY;
|
||||
|
||||
// ── Tutorial Block ──────────────────────────────────────────────────────
|
||||
|
||||
[FoldoutGroup("$blockId")]
|
||||
[FoldoutGroup("$EditorHeader/Tutorial Content", false)]
|
||||
[ShowIf("blockType", StoryBlockType.Tutorial)]
|
||||
[LabelText("Tutorial Name")]
|
||||
[LabelText("Display Name")]
|
||||
[Tooltip("仅用于 StoryBlock 的显示与编辑识别,不参与教程查找。")]
|
||||
public string tutorialName;
|
||||
|
||||
/// <summary>
|
||||
@@ -146,29 +194,32 @@ namespace Ichni.Story
|
||||
/// 只用于运行时查找,不使用展示名称或章节名称作为逻辑匹配条件。
|
||||
/// 命名统一使用小写英文、数字和下划线,例如 <c>chapter0_intro</c>。
|
||||
/// </summary>
|
||||
[FoldoutGroup("$blockId")]
|
||||
[FoldoutGroup("$EditorHeader/Tutorial Content")]
|
||||
[ShowIf("blockType", StoryBlockType.Tutorial)]
|
||||
[LabelText("Tutorial Key")]
|
||||
[Tooltip("TutorialCollection 中的稳定 Key。使用小写英文、数字和下划线,例如 chapter0_intro。")]
|
||||
public string tutorialKey;
|
||||
|
||||
/// <summary>
|
||||
/// 教程被玩家选择“游玩”或“跳过”后写入的全局剧情变量。
|
||||
/// 教程被玩家选择“游玩”或“跳过”后写入的当前章节剧情变量。
|
||||
/// 后续 Block 应通过 <see cref="VariableCondition"/> 检查该变量是否等于 1 来解锁。
|
||||
/// 命名统一使用小写英文、数字和下划线,例如
|
||||
/// <c>story_tutorial_chapter0_intro_resolved</c>。
|
||||
/// </summary>
|
||||
[FoldoutGroup("$blockId")]
|
||||
[FoldoutGroup("$EditorHeader/Tutorial Content")]
|
||||
[ShowIf("blockType", StoryBlockType.Tutorial)]
|
||||
[LabelText("Progress Variable")]
|
||||
[Tooltip("玩家选择游玩或跳过教程后写入 true 的章节剧情变量;后续 Block 可通过条件检查它。")]
|
||||
public string tutorialProgressVariable;
|
||||
|
||||
/// <summary>
|
||||
/// 要启动的教程难度的稳定存档 ID,对应 <see cref="Ichni.Menu.DifficultyData.saveDifficultyId"/>。
|
||||
/// 不使用难度列表下标,避免调整难度排列后教程进入错误谱面。
|
||||
/// </summary>
|
||||
[FoldoutGroup("$blockId")]
|
||||
[FoldoutGroup("$EditorHeader/Tutorial Content")]
|
||||
[ShowIf("blockType", StoryBlockType.Tutorial)]
|
||||
[LabelText("Tutorial Difficulty Save ID")]
|
||||
[LabelText("Difficulty Save ID")]
|
||||
[Tooltip("要启动教程谱面的 DifficultyData.saveDifficultyId。不要使用难度列表下标,以免排序变化后指向错误谱面。")]
|
||||
public int tutorialDifficultySaveId = -1;
|
||||
|
||||
/// <summary>
|
||||
@@ -196,12 +247,13 @@ namespace Ichni.Story
|
||||
/// 例如 unlockCondition 留空即允许,而 forbiddenCondition 留空即不禁用。</para>
|
||||
/// </summary>
|
||||
[InlineProperty]
|
||||
[HideReferenceObjectPicker]
|
||||
[Serializable]
|
||||
public class StoryCondition
|
||||
{
|
||||
[HideLabel]
|
||||
[SerializeReference]
|
||||
[InfoBox("留空表示未配置条件。可选择 All Of(AND) / Any Of(OR) / Not 复合节点进行任意嵌套。")]
|
||||
[Tooltip("留空表示未配置条件。可选择 All Of(AND) / Any Of(OR) / Not 复合节点进行任意嵌套。")]
|
||||
public StoryConditionNode root;
|
||||
|
||||
/// <summary>
|
||||
@@ -219,5 +271,15 @@ namespace Ichni.Story
|
||||
{
|
||||
return root != null && root.Evaluate(getVariable, isBlockCompleted);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Odin 条件 Drawer 使用的只读摘要;不参与运行时求值和序列化。
|
||||
/// </summary>
|
||||
public string GetEditorSummary()
|
||||
{
|
||||
return root == null ? "None" : root.GetEditorSummary();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,13 @@ namespace Ichni.Story
|
||||
/// <param name="getVariable">按变量名返回其整型值的委托。</param>
|
||||
/// <param name="isBlockCompleted">按 blockId 判断该 Block 是否已完成的委托。</param>
|
||||
public abstract bool Evaluate(Func<string, int> getVariable, Func<string, bool> isBlockCompleted);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// 返回 Inspector 中使用的紧凑摘要。条件编辑器只读取该文本,不影响运行时求值逻辑。
|
||||
/// </summary>
|
||||
public virtual string GetEditorSummary() => GetType().Name;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -43,6 +50,10 @@ namespace Ichni.Story
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public override string GetEditorSummary() => $"All Of ({conditions?.Count ?? 0})";
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -70,6 +81,10 @@ namespace Ichni.Story
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public override string GetEditorSummary() => $"Any Of ({conditions?.Count ?? 0})";
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -87,6 +102,10 @@ namespace Ichni.Story
|
||||
{
|
||||
return condition == null || !condition.Evaluate(getVariable, isBlockCompleted);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public override string GetEditorSummary() => $"Not ({condition?.GetEditorSummary() ?? "None"})";
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -97,12 +116,20 @@ namespace Ichni.Story
|
||||
public class BlockCompletedCondition : StoryConditionNode
|
||||
{
|
||||
[LabelText("Block ID")]
|
||||
[LabelWidth(50)]
|
||||
[Tooltip("必须已完成的 StoryBlock ID。可用于表达显式前置条件;通常连接关系已由 Connected Rule 自动处理。")]
|
||||
public string blockId;
|
||||
|
||||
public override bool Evaluate(Func<string, int> getVariable, Func<string, bool> isBlockCompleted)
|
||||
{
|
||||
return !string.IsNullOrEmpty(blockId) && isBlockCompleted(blockId);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public override string GetEditorSummary() => string.IsNullOrWhiteSpace(blockId)
|
||||
? "Block Completed: <missing ID>"
|
||||
: $"Block Completed: {blockId}";
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -113,13 +140,22 @@ namespace Ichni.Story
|
||||
[LabelText("Variable Compare")]
|
||||
public class VariableCondition : StoryConditionNode
|
||||
{
|
||||
[LabelText("Variable Name")]
|
||||
[HorizontalGroup("VariableComparison", 0.50f)]
|
||||
[LabelText("Var")]
|
||||
[LabelWidth(24)]
|
||||
[Tooltip("章节剧情变量名。使用小写英文、数字和下划线;可由 Yarn 的 set_* 指令写入。")]
|
||||
public string variableName;
|
||||
|
||||
[LabelText("Comparison")]
|
||||
[HorizontalGroup("VariableComparison", 0.22f)]
|
||||
[LabelText("Op")]
|
||||
[LabelWidth(20)]
|
||||
[Tooltip("变量值与目标值之间的比较方式。")]
|
||||
public VariableComparison comparison;
|
||||
|
||||
[HorizontalGroup("VariableComparison")]
|
||||
[LabelText("Value")]
|
||||
[LabelWidth(35)]
|
||||
[Tooltip("用于比较的整数目标值。Bool 条件使用 0 / 1。")]
|
||||
public int value;
|
||||
|
||||
public override bool Evaluate(Func<string, int> getVariable, Func<string, bool> isBlockCompleted)
|
||||
@@ -136,5 +172,67 @@ namespace Ichni.Story
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public override string GetEditorSummary()
|
||||
{
|
||||
string variable = string.IsNullOrWhiteSpace(variableName) ? "<missing variable>" : variableName;
|
||||
string operation = comparison switch
|
||||
{
|
||||
VariableComparison.Equal => "==",
|
||||
VariableComparison.NotEqual => "!=",
|
||||
VariableComparison.Greater => ">",
|
||||
VariableComparison.GreaterOrEqual => ">=",
|
||||
VariableComparison.Less => "<",
|
||||
VariableComparison.LessOrEqual => "<=",
|
||||
_ => "?"
|
||||
};
|
||||
return $"{variable} {operation} {value}";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace Ichni.Story.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 通用 StoryCondition 的 Odin Inspector Drawer。
|
||||
/// <para>Unlock、Forbidden 与 Helper Availability 共用同一条件模型;此 Drawer 只改变编辑器中的
|
||||
/// 折叠呈现方式,不修改条件树的序列化结构或运行时求值结果。</para>
|
||||
/// <para>默认仅显示可读摘要。需要调整条件时再展开,避免 SerializeReference 条件树长期占据 Block 的编辑空间。</para>
|
||||
/// </summary>
|
||||
public class StoryConditionDrawer : Sirenix.OdinInspector.Editor.OdinValueDrawer<StoryCondition>
|
||||
{
|
||||
private bool _isExpanded;
|
||||
|
||||
protected override void DrawPropertyLayout(UnityEngine.GUIContent label)
|
||||
{
|
||||
StoryCondition condition = ValueEntry.SmartValue;
|
||||
string summary = condition == null ? "None" : condition.GetEditorSummary();
|
||||
|
||||
// 父属性若保留了简短标签(例如 Helper 的 Availability),则与摘要合并显示;
|
||||
// StoryBlock 中使用 HideLabel 时只保留摘要,避免重复占用左侧标签列。
|
||||
string prefix = label == null || string.IsNullOrWhiteSpace(label.text)
|
||||
? string.Empty
|
||||
: $"{label.text}: ";
|
||||
|
||||
UnityEngine.GUIContent foldoutLabel = new UnityEngine.GUIContent(
|
||||
prefix + summary,
|
||||
"留空表示未配置条件。展开后可选择 All Of (AND)、Any Of (OR)、Not、Block Completed 或 Variable Compare。"
|
||||
);
|
||||
|
||||
_isExpanded = UnityEditor.EditorGUILayout.Foldout(_isExpanded, foldoutLabel, true);
|
||||
if (!_isExpanded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UnityEditor.EditorGUI.indentLevel++;
|
||||
// 继续调用 Odin 的默认 SerializeReference 绘制链,使类型选择、嵌套条件和 Undo 行为保持原样。
|
||||
CallNextDrawer(UnityEngine.GUIContent.none);
|
||||
UnityEditor.EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
780
Assets/Scripts/NewStorySystem/Data/StoryData.Editor.cs
Normal file
780
Assets/Scripts/NewStorySystem/Data/StoryData.Editor.cs
Normal file
@@ -0,0 +1,780 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.Story
|
||||
{
|
||||
/// <summary>
|
||||
/// StoryData 的编辑器扩展:集中存放只读 Validation 与故事树 Preview。
|
||||
/// 与运行时数据查询拆分后,修改剧情结构时无需在同一文件中穿过大量 Inspector 绘制代码。
|
||||
/// </summary>
|
||||
public partial class StoryData
|
||||
{
|
||||
private enum StoryPreviewMode { Detailed, Simple }
|
||||
|
||||
// 编辑器 UI 临时状态(不参与序列化)
|
||||
[System.NonSerialized] private StoryPreviewMode _previewMode = StoryPreviewMode.Detailed;
|
||||
[System.NonSerialized] private Vector2 _previewPan;
|
||||
[System.NonSerialized] private bool _isPanningPreview;
|
||||
[System.NonSerialized] private bool _isPreviewExpanded;
|
||||
[System.NonSerialized] private bool _requestPreviewFit;
|
||||
|
||||
private const float PreviewViewportHeight = 380f;
|
||||
private const float PreviewPaddingLeft = 24f;
|
||||
|
||||
// 预览与运行时共用同一套“列 / 行代表 Block 中心点”的布局语义。
|
||||
// 这里的尺寸直接对应当前四种 Block Prefab 的设计尺寸;若未来修改 Prefab 尺寸,必须同步更新本组常量。
|
||||
private const float ImportantBlockWidth = 600f;
|
||||
private const float ImportantBlockHeight = 375f;
|
||||
private const float SecondaryBlockWidth = 400f;
|
||||
private const float SecondaryBlockHeight = 200f;
|
||||
private const float SongBlockWidth = 400f;
|
||||
private const float SongBlockHeight = 100f;
|
||||
private const float TutorialBlockWidth = 400f;
|
||||
private const float TutorialBlockHeight = 100f;
|
||||
|
||||
// 与 StoryTreeController 默认 columnStep / rowStep 保持比例一致,
|
||||
// 因而预览中的相邻列、行间距也能反映运行时的实际布局关系。
|
||||
private const float RuntimeColumnStep = 720f;
|
||||
private const float RuntimeRowStep = 525f;
|
||||
private const float DetailedPreviewScale = 0.25f;
|
||||
private const float SimplePreviewScale = 0.10f;
|
||||
|
||||
[PropertyOrder(-9)]
|
||||
[Button("Validate Story Data", ButtonSizes.Medium)]
|
||||
[Tooltip("只读检查当前 StoryData 的引用、ID 与必要字段,不会自动修改资产,也不会检查歌曲/谱面的导入内容。")]
|
||||
private void ValidateStoryData()
|
||||
{
|
||||
List<string> issues = new List<string>();
|
||||
HashSet<string> blockIds = new HashSet<string>();
|
||||
HashSet<string> variableKeys = new HashSet<string>();
|
||||
HashSet<string> markerIds = new HashSet<string>();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(chapterIndex))
|
||||
{
|
||||
issues.Add("[Error] Chapter Index 为空。");
|
||||
}
|
||||
|
||||
if (yarnProject == null)
|
||||
{
|
||||
issues.Add("[Warning] Yarn Project 未配置;TextBlock 无法开始对应的 Yarn 节点。");
|
||||
}
|
||||
|
||||
foreach (StoryVariableDefinition variable in initialVariables)
|
||||
{
|
||||
if (variable == null)
|
||||
{
|
||||
issues.Add("[Warning] Initial Variables 中存在空项。");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsValidStableKey(variable.key))
|
||||
{
|
||||
issues.Add($"[Warning] Initial Variable Key '{variable.key}' 为空或不符合小写英文、数字、下划线的命名规则。");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!variableKeys.Add(variable.key))
|
||||
{
|
||||
issues.Add($"[Error] Initial Variable Key '{variable.key}' 重复。");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (StoryBlockDefinition block in blocks)
|
||||
{
|
||||
if (block == null)
|
||||
{
|
||||
issues.Add("[Warning] Blocks 中存在空项。");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(block.blockId))
|
||||
{
|
||||
issues.Add("[Error] 存在未填写 Block ID 的 Block。");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!blockIds.Add(block.blockId))
|
||||
{
|
||||
issues.Add($"[Error] Block ID '{block.blockId}' 重复。");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (StoryBlockDefinition block in blocks)
|
||||
{
|
||||
if (block == null || string.IsNullOrWhiteSpace(block.blockId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ValidateBlock(block, blockIds, issues);
|
||||
ValidateCondition(block.unlockCondition, $"Block '{block.blockId}' Unlock Condition", blockIds, issues);
|
||||
ValidateCondition(block.forbiddenCondition, $"Block '{block.blockId}' Forbidden Condition", blockIds, issues);
|
||||
}
|
||||
|
||||
ValidateTextBlockYarnNodes(issues);
|
||||
HashSet<string> reachableBlockIds = ValidateStoryGraph(blockIds, issues);
|
||||
|
||||
foreach (StoryTimelineMarkerDefinition marker in timelineMarkers)
|
||||
{
|
||||
if (marker == null)
|
||||
{
|
||||
issues.Add("[Warning] Timeline Markers 中存在空项。");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsValidStableKey(marker.markerId))
|
||||
{
|
||||
issues.Add($"[Error] Timeline Marker ID '{marker.markerId}' 为空或不符合命名规则。");
|
||||
}
|
||||
else if (!markerIds.Add(marker.markerId))
|
||||
{
|
||||
issues.Add($"[Error] Timeline Marker ID '{marker.markerId}' 重复。");
|
||||
}
|
||||
|
||||
StoryBlockDefinition anchor = GetBlock(marker.anchorBlockId);
|
||||
if (anchor == null)
|
||||
{
|
||||
issues.Add($"[Error] Timeline Marker '{marker.markerId}' 指向不存在的 Anchor Block '{marker.anchorBlockId}'。");
|
||||
}
|
||||
else if (anchor.blockType != StoryBlockType.Text)
|
||||
{
|
||||
issues.Add($"[Error] Timeline Marker '{marker.markerId}' 的 Anchor Block '{marker.anchorBlockId}' 不是 TextBlock。");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(marker.labelKey))
|
||||
{
|
||||
issues.Add($"[Warning] Timeline Marker '{marker.markerId}' 未配置 Label Key。");
|
||||
}
|
||||
}
|
||||
|
||||
ValidateTimelineMarkerAnchors(reachableBlockIds, issues);
|
||||
ValidateExclusiveRouteGroups(blockIds, issues);
|
||||
ValidateLegacyYarnSyntax(issues);
|
||||
|
||||
if (issues.Count == 0)
|
||||
{
|
||||
Debug.Log($"[StoryData] '{name}' validation passed.", this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unity Console 的折叠列表不会为单条日志中的换行自动增加行高,
|
||||
// 把整份报告拼成多行字符串会导致文本重叠。摘要与每个问题分别输出,
|
||||
// 既保持 Console 可读,也能让使用者逐条双击定位所属 StoryData。
|
||||
Debug.LogWarning($"[StoryData] '{name}' validation found {issues.Count} issue(s). See the following entries.", this);
|
||||
for (int index = 0; index < issues.Count; index++)
|
||||
{
|
||||
string issue = issues[index];
|
||||
string message = $"[StoryData] '{name}' [{index + 1}/{issues.Count}] {issue}";
|
||||
if (issue.StartsWith("[Error]"))
|
||||
Debug.LogError(message, this);
|
||||
else
|
||||
Debug.LogWarning(message, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查单个 Block 的必要配置。该方法只报告明确会导致运行时入口失效的字段,
|
||||
/// 不检查歌曲或谱面导入结果,以免把内容制作流程变成阻断式校验。
|
||||
/// </summary>
|
||||
private static void ValidateBlock(StoryBlockDefinition block, HashSet<string> blockIds, List<string> issues)
|
||||
{
|
||||
HashSet<string> nextIds = new HashSet<string>();
|
||||
foreach (string nextId in block.nextBlockIds)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(nextId))
|
||||
{
|
||||
issues.Add($"[Warning] Block '{block.blockId}' 的 Next Blocks 中存在空 ID。");
|
||||
}
|
||||
else if (!blockIds.Contains(nextId))
|
||||
{
|
||||
issues.Add($"[Error] Block '{block.blockId}' 指向不存在的 Next Block '{nextId}'。");
|
||||
}
|
||||
else if (!nextIds.Add(nextId))
|
||||
{
|
||||
issues.Add($"[Warning] Block '{block.blockId}' 重复指向 Next Block '{nextId}'。");
|
||||
}
|
||||
}
|
||||
|
||||
switch (block.blockType)
|
||||
{
|
||||
case StoryBlockType.Text when string.IsNullOrWhiteSpace(block.yarnNodeName):
|
||||
issues.Add($"[Warning] TextBlock '{block.blockId}' 未配置 Yarn Node。");
|
||||
break;
|
||||
case StoryBlockType.Song when string.IsNullOrWhiteSpace(block.songName):
|
||||
issues.Add($"[Warning] SongBlock '{block.blockId}' 未配置 Song ID。");
|
||||
break;
|
||||
case StoryBlockType.Tutorial:
|
||||
if (string.IsNullOrWhiteSpace(block.tutorialKey))
|
||||
issues.Add($"[Warning] TutorialBlock '{block.blockId}' 未配置 Tutorial Key。");
|
||||
if (string.IsNullOrWhiteSpace(block.tutorialProgressVariable))
|
||||
issues.Add($"[Warning] TutorialBlock '{block.blockId}' 未配置 Progress Variable。");
|
||||
if (block.tutorialDifficultySaveId < 0)
|
||||
issues.Add($"[Warning] TutorialBlock '{block.blockId}' 未配置有效的 Difficulty Save ID。");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验 TextBlock 的 Yarn 节点是否真实存在于已编译的 YarnProject,及是否被多个 Block 共用。
|
||||
/// 后者并非必然错误,但通常意味着复制 Block 后忘记替换 Node,因此仅报告 Warning。
|
||||
/// </summary>
|
||||
private void ValidateTextBlockYarnNodes(List<string> issues)
|
||||
{
|
||||
if (yarnProject?.Program == null)
|
||||
return;
|
||||
|
||||
Dictionary<string, List<string>> blockIdsByNode = new Dictionary<string, List<string>>();
|
||||
foreach (StoryBlockDefinition block in blocks)
|
||||
{
|
||||
if (block == null || block.blockType != StoryBlockType.Text || string.IsNullOrWhiteSpace(block.yarnNodeName))
|
||||
continue;
|
||||
|
||||
if (!yarnProject.Program.Nodes.ContainsKey(block.yarnNodeName))
|
||||
issues.Add($"[Error] TextBlock '{block.blockId}' 指向的 Yarn Node '{block.yarnNodeName}' 不存在于当前 Yarn Project。" );
|
||||
|
||||
if (!blockIdsByNode.TryGetValue(block.yarnNodeName, out List<string> referencedBlocks))
|
||||
{
|
||||
referencedBlocks = new List<string>();
|
||||
blockIdsByNode[block.yarnNodeName] = referencedBlocks;
|
||||
}
|
||||
|
||||
referencedBlocks.Add(block.blockId);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, List<string>> pair in blockIdsByNode)
|
||||
{
|
||||
if (pair.Value.Count > 1)
|
||||
issues.Add($"[Warning] Yarn Node '{pair.Key}' 被多个 TextBlock 共用:{string.Join(", ", pair.Value)}。确认这是有意复用,而非遗漏修改 Node。" );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对 StoryData 的连接图做只读的结构检查:入口、不可达 Block、环路、非向前连接与终点。
|
||||
/// 这些检查不评价具体剧情质量,只定位最容易造成“永远无法游玩”或“无法结束章节”的配置问题。
|
||||
/// </summary>
|
||||
private HashSet<string> ValidateStoryGraph(HashSet<string> blockIds, List<string> issues)
|
||||
{
|
||||
Dictionary<string, List<string>> adjacency = new Dictionary<string, List<string>>();
|
||||
Dictionary<string, int> indegree = new Dictionary<string, int>();
|
||||
foreach (string id in blockIds)
|
||||
{
|
||||
adjacency[id] = new List<string>();
|
||||
indegree[id] = 0;
|
||||
}
|
||||
|
||||
foreach (StoryBlockDefinition block in blocks)
|
||||
{
|
||||
if (block == null || !blockIds.Contains(block.blockId))
|
||||
continue;
|
||||
|
||||
foreach (string nextId in block.nextBlockIds.Where(id => !string.IsNullOrWhiteSpace(id) && blockIds.Contains(id)).Distinct())
|
||||
{
|
||||
adjacency[block.blockId].Add(nextId);
|
||||
indegree[nextId]++;
|
||||
|
||||
StoryBlockDefinition next = GetBlock(nextId);
|
||||
if (next != null && next.gridColumn <= block.gridColumn)
|
||||
issues.Add($"[Warning] Block '{block.blockId}' -> '{nextId}' 没有指向更靠后的 Column;请确认这不是意外的回退连接或循环。" );
|
||||
}
|
||||
}
|
||||
|
||||
List<string> entries = indegree.Where(pair => pair.Value == 0).Select(pair => pair.Key).ToList();
|
||||
if (entries.Count == 0 && blockIds.Count > 0)
|
||||
issues.Add("[Error] 剧情连接图没有入口 Block(所有 Block 都存在前置连接)。");
|
||||
else if (entries.Count > 1)
|
||||
issues.Add($"[Warning] 剧情连接图存在 {entries.Count} 个入口 Block:{string.Join(", ", entries)}。确认它们均由条件或设计意图控制。" );
|
||||
|
||||
HashSet<string> reachable = new HashSet<string>();
|
||||
Stack<string> pending = new Stack<string>(entries);
|
||||
while (pending.Count > 0)
|
||||
{
|
||||
string current = pending.Pop();
|
||||
if (!reachable.Add(current))
|
||||
continue;
|
||||
|
||||
foreach (string next in adjacency[current])
|
||||
pending.Push(next);
|
||||
}
|
||||
|
||||
foreach (string id in blockIds.Where(id => !reachable.Contains(id)))
|
||||
issues.Add($"[Warning] Block '{id}' 从任何入口都不可达;若依赖纯变量条件进入,请确认存在外部入口。" );
|
||||
|
||||
List<string> terminalBlocks = adjacency.Where(pair => pair.Value.Count == 0).Select(pair => pair.Key).ToList();
|
||||
if (blockIds.Count > 0 && terminalBlocks.Count == 0)
|
||||
issues.Add("[Warning] 剧情连接图不存在终点 Block;请确认循环路线可以按预期结束。" );
|
||||
|
||||
HashSet<string> visiting = new HashSet<string>();
|
||||
HashSet<string> visited = new HashSet<string>();
|
||||
foreach (string entry in entries)
|
||||
DetectCycle(entry, adjacency, visiting, visited, issues);
|
||||
|
||||
return reachable;
|
||||
}
|
||||
|
||||
private static void DetectCycle(string blockId, Dictionary<string, List<string>> adjacency,
|
||||
HashSet<string> visiting, HashSet<string> visited, List<string> issues)
|
||||
{
|
||||
if (visited.Contains(blockId))
|
||||
return;
|
||||
|
||||
if (!visiting.Add(blockId))
|
||||
{
|
||||
issues.Add($"[Warning] 剧情连接图检测到包含 Block '{blockId}' 的循环。请确认该循环有明确的变量出口。" );
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string next in adjacency[blockId])
|
||||
DetectCycle(next, adjacency, visiting, visited, issues);
|
||||
|
||||
visiting.Remove(blockId);
|
||||
visited.Add(blockId);
|
||||
}
|
||||
|
||||
/// <summary>检查多个 Marker 是否锚定到同一 Block;通常表示重复配置,不阻止特殊的多标签时间点。</summary>
|
||||
private void ValidateTimelineMarkerAnchors(HashSet<string> reachableBlockIds, List<string> issues)
|
||||
{
|
||||
foreach (IGrouping<string, StoryTimelineMarkerDefinition> group in timelineMarkers
|
||||
.Where(marker => marker != null && !string.IsNullOrWhiteSpace(marker.anchorBlockId))
|
||||
.GroupBy(marker => marker.anchorBlockId))
|
||||
{
|
||||
if (group.Count() > 1)
|
||||
issues.Add($"[Warning] 多个 Timeline Marker 锚定到 Block '{group.Key}':{string.Join(", ", group.Select(marker => marker.markerId))}。确认这是有意的多标签时间点。" );
|
||||
|
||||
if (!reachableBlockIds.Contains(group.Key))
|
||||
issues.Add($"[Warning] Timeline Marker 锚定的 Block '{group.Key}' 从任何入口都不可达,Marker 将永远不会按正常流程显示。" );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查互斥结局的编辑期声明。由于 Forbidden Condition 可以是任意变量表达式,
|
||||
/// 自检无法数学证明条件完全互斥;它只检查显式分组、引用、终点形态和最基本的禁用条件覆盖。
|
||||
/// </summary>
|
||||
private void ValidateExclusiveRouteGroups(HashSet<string> blockIds, List<string> issues)
|
||||
{
|
||||
HashSet<string> groupIds = new HashSet<string>();
|
||||
foreach (StoryRouteValidationGroup group in exclusiveRouteGroups)
|
||||
{
|
||||
if (group == null)
|
||||
{
|
||||
issues.Add("[Warning] Exclusive Route Groups 中存在空项。");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsValidStableKey(group.groupId))
|
||||
issues.Add($"[Error] Exclusive Route Group ID '{group.groupId}' 为空或不符合命名规则。" );
|
||||
else if (!groupIds.Add(group.groupId))
|
||||
issues.Add($"[Error] Exclusive Route Group ID '{group.groupId}' 重复。" );
|
||||
|
||||
if (group.terminalBlockIds == null || group.terminalBlockIds.Count < 2)
|
||||
{
|
||||
issues.Add($"[Warning] Exclusive Route Group '{group.groupId}' 至少应包含两个互斥终点 Block。" );
|
||||
continue;
|
||||
}
|
||||
|
||||
HashSet<string> seenTerminalIds = new HashSet<string>();
|
||||
foreach (string terminalId in group.terminalBlockIds)
|
||||
{
|
||||
if (!seenTerminalIds.Add(terminalId))
|
||||
{
|
||||
issues.Add($"[Warning] Exclusive Route Group '{group.groupId}' 重复包含 Block '{terminalId}'。" );
|
||||
continue;
|
||||
}
|
||||
|
||||
StoryBlockDefinition terminal = GetBlock(terminalId);
|
||||
if (terminal == null || !blockIds.Contains(terminalId))
|
||||
{
|
||||
issues.Add($"[Error] Exclusive Route Group '{group.groupId}' 引用了不存在的 Block '{terminalId}'。" );
|
||||
continue;
|
||||
}
|
||||
|
||||
if (terminal.nextBlockIds.Any(id => !string.IsNullOrWhiteSpace(id)))
|
||||
issues.Add($"[Warning] Exclusive Route Group '{group.groupId}' 的终点 Block '{terminalId}' 仍配置了 Next Block。" );
|
||||
|
||||
if (terminal.forbiddenCondition == null || !terminal.forbiddenCondition.IsConfigured)
|
||||
issues.Add($"[Warning] 互斥终点 Block '{terminalId}' 未配置 Forbidden Condition;请人工确认其它路线完成后会禁用它。" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 侦测已废弃的 Yarn 临时变量语法。新台本应只使用项目提供的 set_* / get_* 永久变量命令;
|
||||
/// C0 旧台本仍可能保留历史语法,故当前只输出 Warning,不自动修改任何文本资产。
|
||||
/// </summary>
|
||||
private void ValidateLegacyYarnSyntax(List<string> issues)
|
||||
{
|
||||
if (yarnProject == null)
|
||||
return;
|
||||
|
||||
string projectPath = AssetDatabase.GetAssetPath(yarnProject);
|
||||
foreach (string path in AssetDatabase.GetDependencies(projectPath, true).Where(path => path.EndsWith(".yarn")))
|
||||
{
|
||||
TextAsset yarnSource = AssetDatabase.LoadAssetAtPath<TextAsset>(path);
|
||||
if (yarnSource == null)
|
||||
continue;
|
||||
|
||||
string[] lines = yarnSource.text.Split('\n');
|
||||
for (int index = 0; index < lines.Length; index++)
|
||||
{
|
||||
string line = lines[index].TrimStart();
|
||||
if (line.StartsWith("<<declare ") || line.StartsWith("<<set $"))
|
||||
issues.Add($"[Warning] {path}:{index + 1} 使用了已废弃的 Yarn 临时变量语法 '{line}'。请改用 set_* / get_* 永久变量接口。" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 遍历通用条件树,检查会造成条件无法按预期求值的空引用或不存在 Block 引用。
|
||||
/// VariableCondition 只检查变量名是否为空:未在 Initial Variables 声明的变量允许由 Yarn 在运行时首次写入。
|
||||
/// </summary>
|
||||
private static void ValidateCondition(StoryCondition condition, string owner, HashSet<string> blockIds, List<string> issues)
|
||||
{
|
||||
if (condition?.root != null)
|
||||
{
|
||||
ValidateConditionNode(condition.root, owner, blockIds, issues);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ValidateConditionNode(StoryConditionNode node, string owner, HashSet<string> blockIds, List<string> issues)
|
||||
{
|
||||
switch (node)
|
||||
{
|
||||
case AllOfCondition allOf:
|
||||
if (allOf.conditions == null || allOf.conditions.Count == 0)
|
||||
issues.Add($"[Warning] {owner} 的 All Of 没有子条件,会恒为 true。");
|
||||
else
|
||||
ValidateConditionChildren(allOf.conditions, owner, blockIds, issues);
|
||||
break;
|
||||
case AnyOfCondition anyOf:
|
||||
if (anyOf.conditions == null || anyOf.conditions.Count == 0)
|
||||
issues.Add($"[Warning] {owner} 的 Any Of 没有子条件,会恒为 false。");
|
||||
else
|
||||
ValidateConditionChildren(anyOf.conditions, owner, blockIds, issues);
|
||||
break;
|
||||
case NotCondition not:
|
||||
if (not.condition == null)
|
||||
issues.Add($"[Warning] {owner} 的 Not 没有子条件,会恒为 true。");
|
||||
else
|
||||
ValidateConditionNode(not.condition, owner, blockIds, issues);
|
||||
break;
|
||||
case BlockCompletedCondition blockCompleted:
|
||||
if (string.IsNullOrWhiteSpace(blockCompleted.blockId) || !blockIds.Contains(blockCompleted.blockId))
|
||||
issues.Add($"[Error] {owner} 引用了不存在的 Block Completed ID '{blockCompleted.blockId}'。");
|
||||
break;
|
||||
case VariableCondition variable when string.IsNullOrWhiteSpace(variable.variableName):
|
||||
issues.Add($"[Error] {owner} 存在未填写 Variable Name 的 Variable Compare。");
|
||||
break;
|
||||
case null:
|
||||
issues.Add($"[Warning] {owner} 包含空条件节点。");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ValidateConditionChildren(List<StoryConditionNode> children, string owner, HashSet<string> blockIds, List<string> issues)
|
||||
{
|
||||
foreach (StoryConditionNode child in children)
|
||||
{
|
||||
ValidateConditionNode(child, owner, blockIds, issues);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsValidStableKey(string value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (char character in value)
|
||||
{
|
||||
if (!(character is >= 'a' and <= 'z') &&
|
||||
!(character is >= '0' and <= '9') &&
|
||||
character != '_')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在 Inspector 顶部绘制只读的故事树结构预览(流程图样式,连线左右相连)。
|
||||
/// 提供"详细 / 简略"两种可拖拽平移的视图;按 (gridColumn, gridRow) 摆放 block。
|
||||
/// 每个 Block 使用其运行时 Prefab 尺寸按统一比例缩放后的矩形,且列坐标始终代表 Block 的中心点,
|
||||
/// 从而让 Important / Secondary / Song / Tutorial 的体积与连线端点关系尽量接近游戏内画面。
|
||||
/// </summary>
|
||||
[PropertyOrder(-10)]
|
||||
[OnInspectorGUI]
|
||||
private void DrawStoryPreview()
|
||||
{
|
||||
_isPreviewExpanded = EditorGUILayout.Foldout(
|
||||
_isPreviewExpanded,
|
||||
new GUIContent(
|
||||
"Story Tree Preview",
|
||||
"只读预览:按 StoryData 的 Column / Row、连接关系和当前 Block 尺寸约定绘制。展开后可拖动平移视图。"
|
||||
),
|
||||
true
|
||||
);
|
||||
if (!_isPreviewExpanded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (blocks == null || blocks.Count == 0)
|
||||
{
|
||||
EditorGUILayout.HelpBox("尚未定义任何 block。", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
// 顶部工具条:模式切换 + 复位视图
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
_previewMode = (StoryPreviewMode)GUILayout.Toolbar(
|
||||
(int)_previewMode, new[] { "Detailed", "Simple" }, GUILayout.Height(20f));
|
||||
if (GUILayout.Button("Fit View", GUILayout.Width(80f), GUILayout.Height(20f)))
|
||||
_requestPreviewFit = true;
|
||||
if (GUILayout.Button("Reset", GUILayout.Width(60f), GUILayout.Height(20f)))
|
||||
_previewPan = Vector2.zero;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
bool simple = _previewMode == StoryPreviewMode.Simple;
|
||||
float previewScale = simple ? SimplePreviewScale : DetailedPreviewScale;
|
||||
float stepX = RuntimeColumnStep * previewScale;
|
||||
float stepY = RuntimeRowStep * previewScale;
|
||||
|
||||
Rect area = GUILayoutUtility.GetRect(0f, PreviewViewportHeight, GUILayout.ExpandWidth(true));
|
||||
// 工具栏按钮在取得最终 Preview 区域后才可执行精确 Fit;用当前 Event 的热键标记延迟到这里处理。
|
||||
if (_requestPreviewFit)
|
||||
{
|
||||
FitPreviewView(area, previewScale);
|
||||
_requestPreviewFit = false;
|
||||
}
|
||||
EditorGUI.DrawRect(area, new Color(0.12f, 0.12f, 0.14f, 1f));
|
||||
|
||||
HandlePreviewPanning(area);
|
||||
|
||||
// 裁剪到预览区,超出部分(平移后)不外溢到其它 Inspector 元素
|
||||
GUI.BeginClip(area);
|
||||
{
|
||||
// (0,0) 是 Block 的逻辑中心点。为避免第一列 Important Block 被左侧裁掉,
|
||||
// 初始视图预留半个最大 Block 宽度;这不改变 StoryData 的坐标语义。
|
||||
float originX = PreviewPaddingLeft + ImportantBlockWidth * previewScale * 0.5f + _previewPan.x;
|
||||
float originY = area.height * 0.5f + _previewPan.y;
|
||||
|
||||
// 计算各 Block 的实际比例矩形。运行时同样以中心 Pivot 放置,因此 gridColumn / gridRow
|
||||
// 在预览中也对应矩形中心,而不是左边缘。
|
||||
Dictionary<string, Rect> cellRects = new Dictionary<string, Rect>();
|
||||
foreach (StoryBlockDefinition block in blocks)
|
||||
{
|
||||
if (!HasPreviewableBlockId(block)) continue;
|
||||
|
||||
Vector2 blockSize = GetPreviewBlockSize(block, previewScale);
|
||||
float px = originX + block.gridColumn * stepX; // 列向右为正(可负、可小数)
|
||||
float py = originY + block.gridRow * stepY; // 行向下为正、向上为负
|
||||
cellRects[block.blockId] = new Rect(
|
||||
px - blockSize.x * 0.5f,
|
||||
py - blockSize.y * 0.5f,
|
||||
blockSize.x,
|
||||
blockSize.y);
|
||||
}
|
||||
|
||||
// 先画连线:与 BlockConnectorView 相同,起点右中 → 以两个 Block 中心的中点列折线 → 终点左中。
|
||||
// 不使用端口中点作为转折列,避免不同宽度 Block 在同一列时出现不一致的转折位置。
|
||||
Handles.BeginGUI();
|
||||
foreach (StoryBlockDefinition block in blocks)
|
||||
{
|
||||
if (!HasPreviewableBlockId(block) || !cellRects.TryGetValue(block.blockId, out Rect fromRect)) continue;
|
||||
|
||||
foreach (string nextId in block.nextBlockIds)
|
||||
{
|
||||
if (string.IsNullOrEmpty(nextId) || !cellRects.TryGetValue(nextId, out Rect toRect)) continue;
|
||||
|
||||
Vector3 start = new Vector3(fromRect.xMax, fromRect.center.y, 0f);
|
||||
Vector3 end = new Vector3(toRect.xMin, toRect.center.y, 0f);
|
||||
float midX = (fromRect.center.x + toRect.center.x) * 0.5f;
|
||||
Vector3 mid1 = new Vector3(midX, start.y, 0f);
|
||||
Vector3 mid2 = new Vector3(midX, end.y, 0f);
|
||||
|
||||
Handles.color = new Color(0.82f, 0.82f, 0.88f, 1f);
|
||||
Handles.DrawAAPolyLine(simple ? 2f : 3f, start, mid1, mid2, end);
|
||||
}
|
||||
}
|
||||
Handles.EndGUI();
|
||||
|
||||
// 再画 block 方块
|
||||
GUIStyle labelStyle = new GUIStyle(EditorStyles.boldLabel)
|
||||
{
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
wordWrap = true,
|
||||
richText = false,
|
||||
fontSize = simple ? 9 : 11,
|
||||
normal = { textColor = Color.white }
|
||||
};
|
||||
|
||||
foreach (StoryBlockDefinition block in blocks)
|
||||
{
|
||||
if (!HasPreviewableBlockId(block) || !cellRects.TryGetValue(block.blockId, out Rect rect)) continue;
|
||||
|
||||
EditorGUI.DrawRect(rect, GetTypeColor(block.blockType));
|
||||
string label = GetPreviewLabel(block, simple, rect.height);
|
||||
GUI.Label(rect, label, labelStyle);
|
||||
}
|
||||
}
|
||||
GUI.EndClip();
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回一个 Block 在 Inspector 预览中的尺寸。所有类型使用同一缩放比例,
|
||||
/// 因而宽高比及不同 Block 之间的体积关系与运行时 Prefab 保持一致。
|
||||
/// </summary>
|
||||
private static Vector2 GetPreviewBlockSize(StoryBlockDefinition block, float previewScale)
|
||||
{
|
||||
Vector2 runtimeSize = block.blockType switch
|
||||
{
|
||||
StoryBlockType.Text when block.textImportance == TextBlockImportance.Important =>
|
||||
new Vector2(ImportantBlockWidth, ImportantBlockHeight),
|
||||
StoryBlockType.Text => new Vector2(SecondaryBlockWidth, SecondaryBlockHeight),
|
||||
StoryBlockType.Song => new Vector2(SongBlockWidth, SongBlockHeight),
|
||||
StoryBlockType.Tutorial => new Vector2(TutorialBlockWidth, TutorialBlockHeight),
|
||||
_ => Vector2.zero
|
||||
};
|
||||
|
||||
return runtimeSize * previewScale;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将当前 StoryData 的真实预览边界居中到可视区域。
|
||||
/// 只修改 Inspector 的临时平移量,不会修改任何 Block 的 gridColumn / gridRow。
|
||||
/// </summary>
|
||||
private void FitPreviewView(Rect area, float previewScale)
|
||||
{
|
||||
if (blocks == null || blocks.Count == 0)
|
||||
{
|
||||
_previewPan = Vector2.zero;
|
||||
return;
|
||||
}
|
||||
|
||||
float stepX = RuntimeColumnStep * previewScale;
|
||||
float stepY = RuntimeRowStep * previewScale;
|
||||
float minX = float.PositiveInfinity;
|
||||
float maxX = float.NegativeInfinity;
|
||||
float minY = float.PositiveInfinity;
|
||||
float maxY = float.NegativeInfinity;
|
||||
|
||||
foreach (StoryBlockDefinition block in blocks)
|
||||
{
|
||||
if (!HasPreviewableBlockId(block))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector2 size = GetPreviewBlockSize(block, previewScale);
|
||||
float centerX = block.gridColumn * stepX;
|
||||
float centerY = block.gridRow * stepY;
|
||||
minX = Mathf.Min(minX, centerX - size.x * 0.5f);
|
||||
maxX = Mathf.Max(maxX, centerX + size.x * 0.5f);
|
||||
minY = Mathf.Min(minY, centerY - size.y * 0.5f);
|
||||
maxY = Mathf.Max(maxY, centerY + size.y * 0.5f);
|
||||
}
|
||||
|
||||
if (float.IsPositiveInfinity(minX))
|
||||
{
|
||||
_previewPan = Vector2.zero;
|
||||
return;
|
||||
}
|
||||
|
||||
// DrawStoryPreview 的初始原点位于左侧 Padding + 半个最大 Block 宽度;
|
||||
// 此处只补偿该基础原点与内容包围盒中心之间的差值。
|
||||
float baseOriginX = PreviewPaddingLeft + ImportantBlockWidth * previewScale * 0.5f;
|
||||
_previewPan = new Vector2(
|
||||
area.width * 0.5f - baseOriginX - (minX + maxX) * 0.5f,
|
||||
-(minY + maxY) * 0.5f
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据可用高度选择预览标签密度。Song / Tutorial 的真实比例高度较小,
|
||||
/// 因此只显示 Block ID,避免文字撑破矩形而掩盖实际体积关系。
|
||||
/// </summary>
|
||||
private static string GetPreviewLabel(StoryBlockDefinition block, bool simple, float blockHeight)
|
||||
{
|
||||
if (simple || blockHeight < 32f)
|
||||
{
|
||||
return block.blockId;
|
||||
}
|
||||
|
||||
if (blockHeight < 60f)
|
||||
{
|
||||
return $"{block.blockId}\n[{block.blockType}]";
|
||||
}
|
||||
|
||||
return $"{block.blockId}\n[{block.blockType}]\n{block.GetDisplayTitle()}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理预览区内的鼠标拖拽平移。
|
||||
/// </summary>
|
||||
private void HandlePreviewPanning(Rect area)
|
||||
{
|
||||
Event e = Event.current;
|
||||
switch (e.type)
|
||||
{
|
||||
case EventType.MouseDown:
|
||||
if (area.Contains(e.mousePosition))
|
||||
{
|
||||
_isPanningPreview = true;
|
||||
e.Use();
|
||||
}
|
||||
break;
|
||||
case EventType.MouseDrag:
|
||||
if (_isPanningPreview)
|
||||
{
|
||||
_previewPan += e.delta;
|
||||
GUI.changed = true;
|
||||
e.Use();
|
||||
}
|
||||
break;
|
||||
case EventType.MouseUp:
|
||||
if (_isPanningPreview)
|
||||
{
|
||||
_isPanningPreview = false;
|
||||
e.Use();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断 Block 能否参与 Inspector 中的故事树预览。
|
||||
/// 新增 Block 时,Odin 会先创建一个尚未填写 blockId 的临时数据项;它还不能作为
|
||||
/// Dictionary 的 Key,也不应在预览中显示或连接。统一在三个预览阶段过滤,避免后续
|
||||
/// Draw / TryGetValue 阶段再次把空引用传入 Dictionary。
|
||||
/// </summary>
|
||||
private static bool HasPreviewableBlockId(StoryBlockDefinition block)
|
||||
{
|
||||
return block != null && !string.IsNullOrWhiteSpace(block.blockId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 预览中不同 block 类型的填充色。
|
||||
/// </summary>
|
||||
private static Color GetTypeColor(StoryBlockType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
StoryBlockType.Text => new Color(0.20f, 0.42f, 0.72f, 1f), // 蓝
|
||||
StoryBlockType.Song => new Color(0.62f, 0.30f, 0.66f, 1f), // 紫
|
||||
StoryBlockType.Tutorial => new Color(0.28f, 0.56f, 0.36f, 1f), // 绿
|
||||
_ => new Color(0.4f, 0.4f, 0.4f, 1f)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93a8de9ae74f4e8784af656377c443be
|
||||
@@ -2,10 +2,6 @@ using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using Yarn.Unity;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using Sirenix.Utilities.Editor;
|
||||
#endif
|
||||
|
||||
namespace Ichni.Story
|
||||
{
|
||||
@@ -14,17 +10,30 @@ namespace Ichni.Story
|
||||
/// 布局完全由每个 block 的 (gridColumn, gridRow) 静态决定,运行时全量展示。
|
||||
/// </summary>
|
||||
[CreateAssetMenu(fileName = "StoryData", menuName = "Ichni/Story/New/StoryData")]
|
||||
public class StoryData : SerializedScriptableObject
|
||||
public partial class StoryData : SerializedScriptableObject
|
||||
{
|
||||
[TitleGroup("Chapter Settings", Alignment = TitleAlignments.Centered)]
|
||||
[LabelText("Chapter Index")]
|
||||
[Tooltip("章节的稳定索引。StorySave、StoryManager 与 ChapterSelection 都以该值定位当前章节。")]
|
||||
public string chapterIndex;
|
||||
|
||||
[TitleGroup("Chapter Settings")]
|
||||
[LabelText("Yarn Project")]
|
||||
[InfoBox("该章节对应的 YarnProject 编译资产,阶段 2 接线。")]
|
||||
[Tooltip("该章节对应的 YarnProject 编译资产。TextBlock 会在运行时从此项目中执行配置的 Yarn Node。")]
|
||||
public YarnProject yarnProject;
|
||||
|
||||
/// <summary>
|
||||
/// 本章节永久剧情变量的默认值。它们只属于本章节,且不会直接写入存档;
|
||||
/// 玩家第一次通过 Yarn 或其它剧情入口写入同名变量后,存档值才会覆盖这里的默认值。
|
||||
/// </summary>
|
||||
[LabelText("Initial Variables")]
|
||||
[ListDrawerSettings(ShowFoldout = true, DefaultExpandedState = false, DraggableItems = true, ShowItemCount = true)]
|
||||
[Tooltip("变量 Key 使用小写英文、数字和下划线。Yarn 请通过 <<set_*>> 与 get_*() 访问,不使用 <<declare>>、<<set>> 或 $variable。")]
|
||||
public List<StoryVariableDefinition> initialVariables = new List<StoryVariableDefinition>();
|
||||
|
||||
[LabelText("Blocks")]
|
||||
[ListDrawerSettings(ShowFoldout = true, DefaultExpandedState = false, DraggableItems = true, ShowItemCount = true)]
|
||||
[Tooltip("章节的完整剧情树定义。列表排序不决定运行时流程;连接关系、条件与网格坐标才是唯一依据。")]
|
||||
public List<StoryBlockDefinition> blocks = new List<StoryBlockDefinition>();
|
||||
|
||||
/// <summary>
|
||||
@@ -34,9 +43,18 @@ namespace Ichni.Story
|
||||
/// </summary>
|
||||
[LabelText("Timeline Markers")]
|
||||
[ListDrawerSettings(ShowFoldout = true, DefaultExpandedState = false, DraggableItems = true, ShowItemCount = true)]
|
||||
[InfoBox("每个标记锚定到一个 TextBlock;运行时使用该 Block 的 Grid Column 对齐 Timeline。TextBlock 为 Current / Completed 时显示,Locked / Forbidden 时隐藏。未配置标记时,现有章节行为不变。")]
|
||||
[Tooltip("每个标记锚定到一个 TextBlock;运行时使用该 Block 的 Grid Column 对齐 Timeline。TextBlock 为 Current / Completed 时显示,Locked / Forbidden 时隐藏。")]
|
||||
public List<StoryTimelineMarkerDefinition> timelineMarkers = new List<StoryTimelineMarkerDefinition>();
|
||||
|
||||
/// <summary>
|
||||
/// 仅供编辑器自检使用的互斥结局分组,不参与运行时的解锁、禁用或存档逻辑。
|
||||
/// 实际路线禁用仍完全通过各 Block 的 Forbidden Condition 表达,以保留剧情变量组合的灵活性。
|
||||
/// </summary>
|
||||
[LabelText("Exclusive Route Groups")]
|
||||
[ListDrawerSettings(ShowFoldout = true, DefaultExpandedState = false, DraggableItems = true, ShowItemCount = true)]
|
||||
[Tooltip("把同一章节中只能同时达成一个的结局 Block 放入同一组。Validate Story Data 会检查引用、终点形态与 Forbidden Condition 配置;不会改变运行时逻辑。")]
|
||||
public List<StoryRouteValidationGroup> exclusiveRouteGroups = new List<StoryRouteValidationGroup>();
|
||||
|
||||
// ── Queries ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
@@ -46,13 +64,35 @@ namespace Ichni.Story
|
||||
{
|
||||
foreach (StoryBlockDefinition block in blocks)
|
||||
{
|
||||
if (block.blockId == blockId)
|
||||
if (block != null && block.blockId == blockId)
|
||||
return block;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取一个章节变量的静态默认定义。重复 Key 取列表中第一项,
|
||||
/// 因此配置时应保持 Key 唯一,以免在 Inspector 中产生歧义。
|
||||
/// </summary>
|
||||
public bool TryGetInitialVariable(string key, out StoryVariableDefinition definition)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(key) && initialVariables != null)
|
||||
{
|
||||
foreach (StoryVariableDefinition item in initialVariables)
|
||||
{
|
||||
if (item != null && item.key == key)
|
||||
{
|
||||
definition = item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
definition = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定 blockId 的所有直接后继 block 定义。
|
||||
/// </summary>
|
||||
@@ -61,6 +101,9 @@ namespace Ichni.Story
|
||||
StoryBlockDefinition source = GetBlock(blockId);
|
||||
if (source == null) yield break;
|
||||
|
||||
if (source.nextBlockIds == null)
|
||||
yield break;
|
||||
|
||||
foreach (string nextId in source.nextBlockIds)
|
||||
{
|
||||
StoryBlockDefinition next = GetBlock(nextId);
|
||||
@@ -69,241 +112,5 @@ namespace Ichni.Story
|
||||
}
|
||||
}
|
||||
|
||||
// ── Editor Preview ────────────────────────────────────────────────────────
|
||||
#if UNITY_EDITOR
|
||||
private enum StoryPreviewMode { Detailed, Simple }
|
||||
|
||||
// 编辑器 UI 临时状态(不参与序列化)
|
||||
[System.NonSerialized] private StoryPreviewMode _previewMode = StoryPreviewMode.Detailed;
|
||||
[System.NonSerialized] private Vector2 _previewPan;
|
||||
[System.NonSerialized] private bool _isPanningPreview;
|
||||
|
||||
private const float PreviewViewportHeight = 380f;
|
||||
private const float PreviewPaddingLeft = 24f;
|
||||
|
||||
// 预览与运行时共用同一套“列 / 行代表 Block 中心点”的布局语义。
|
||||
// 这里的尺寸直接对应当前四种 Block Prefab 的设计尺寸;若未来修改 Prefab 尺寸,必须同步更新本组常量。
|
||||
private const float ImportantBlockWidth = 600f;
|
||||
private const float ImportantBlockHeight = 375f;
|
||||
private const float SecondaryBlockWidth = 400f;
|
||||
private const float SecondaryBlockHeight = 200f;
|
||||
private const float SongBlockWidth = 400f;
|
||||
private const float SongBlockHeight = 100f;
|
||||
private const float TutorialBlockWidth = 400f;
|
||||
private const float TutorialBlockHeight = 100f;
|
||||
|
||||
// 与 StoryTreeController 默认 columnStep / rowStep 保持比例一致,
|
||||
// 因而预览中的相邻列、行间距也能反映运行时的实际布局关系。
|
||||
private const float RuntimeColumnStep = 720f;
|
||||
private const float RuntimeRowStep = 525f;
|
||||
private const float DetailedPreviewScale = 0.25f;
|
||||
private const float SimplePreviewScale = 0.10f;
|
||||
|
||||
/// <summary>
|
||||
/// 在 Inspector 顶部绘制只读的故事树结构预览(流程图样式,连线左右相连)。
|
||||
/// 提供"详细 / 简略"两种可拖拽平移的视图;按 (gridColumn, gridRow) 摆放 block。
|
||||
/// 每个 Block 使用其运行时 Prefab 尺寸按统一比例缩放后的矩形,且列坐标始终代表 Block 的中心点,
|
||||
/// 从而让 Important / Secondary / Song / Tutorial 的体积与连线端点关系尽量接近游戏内画面。
|
||||
/// </summary>
|
||||
[PropertyOrder(-10)]
|
||||
[OnInspectorGUI]
|
||||
private void DrawStoryPreview()
|
||||
{
|
||||
SirenixEditorGUI.Title("Story Tree Preview", null, TextAlignment.Left, true);
|
||||
|
||||
if (blocks == null || blocks.Count == 0)
|
||||
{
|
||||
EditorGUILayout.HelpBox("尚未定义任何 block。", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
// 顶部工具条:模式切换 + 复位视图
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
_previewMode = (StoryPreviewMode)GUILayout.Toolbar(
|
||||
(int)_previewMode, new[] { "Detailed", "Simple" }, GUILayout.Height(20f));
|
||||
if (GUILayout.Button("Reset View", GUILayout.Width(90f), GUILayout.Height(20f)))
|
||||
_previewPan = Vector2.zero;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
bool simple = _previewMode == StoryPreviewMode.Simple;
|
||||
float previewScale = simple ? SimplePreviewScale : DetailedPreviewScale;
|
||||
float stepX = RuntimeColumnStep * previewScale;
|
||||
float stepY = RuntimeRowStep * previewScale;
|
||||
|
||||
Rect area = GUILayoutUtility.GetRect(0f, PreviewViewportHeight, GUILayout.ExpandWidth(true));
|
||||
EditorGUI.DrawRect(area, new Color(0.12f, 0.12f, 0.14f, 1f));
|
||||
|
||||
HandlePreviewPanning(area);
|
||||
|
||||
// 裁剪到预览区,超出部分(平移后)不外溢到其它 Inspector 元素
|
||||
GUI.BeginClip(area);
|
||||
{
|
||||
// (0,0) 是 Block 的逻辑中心点。为避免第一列 Important Block 被左侧裁掉,
|
||||
// 初始视图预留半个最大 Block 宽度;这不改变 StoryData 的坐标语义。
|
||||
float originX = PreviewPaddingLeft + ImportantBlockWidth * previewScale * 0.5f + _previewPan.x;
|
||||
float originY = area.height * 0.5f + _previewPan.y;
|
||||
|
||||
// 计算各 Block 的实际比例矩形。运行时同样以中心 Pivot 放置,因此 gridColumn / gridRow
|
||||
// 在预览中也对应矩形中心,而不是左边缘。
|
||||
Dictionary<string, Rect> cellRects = new Dictionary<string, Rect>();
|
||||
foreach (StoryBlockDefinition block in blocks)
|
||||
{
|
||||
if (!HasPreviewableBlockId(block)) continue;
|
||||
|
||||
Vector2 blockSize = GetPreviewBlockSize(block, previewScale);
|
||||
float px = originX + block.gridColumn * stepX; // 列向右为正(可负、可小数)
|
||||
float py = originY + block.gridRow * stepY; // 行向下为正、向上为负
|
||||
cellRects[block.blockId] = new Rect(
|
||||
px - blockSize.x * 0.5f,
|
||||
py - blockSize.y * 0.5f,
|
||||
blockSize.x,
|
||||
blockSize.y);
|
||||
}
|
||||
|
||||
// 先画连线:与 BlockConnectorView 相同,起点右中 → 以两个 Block 中心的中点列折线 → 终点左中。
|
||||
// 不使用端口中点作为转折列,避免不同宽度 Block 在同一列时出现不一致的转折位置。
|
||||
Handles.BeginGUI();
|
||||
foreach (StoryBlockDefinition block in blocks)
|
||||
{
|
||||
if (!HasPreviewableBlockId(block) || !cellRects.TryGetValue(block.blockId, out Rect fromRect)) continue;
|
||||
|
||||
foreach (string nextId in block.nextBlockIds)
|
||||
{
|
||||
if (string.IsNullOrEmpty(nextId) || !cellRects.TryGetValue(nextId, out Rect toRect)) continue;
|
||||
|
||||
Vector3 start = new Vector3(fromRect.xMax, fromRect.center.y, 0f);
|
||||
Vector3 end = new Vector3(toRect.xMin, toRect.center.y, 0f);
|
||||
float midX = (fromRect.center.x + toRect.center.x) * 0.5f;
|
||||
Vector3 mid1 = new Vector3(midX, start.y, 0f);
|
||||
Vector3 mid2 = new Vector3(midX, end.y, 0f);
|
||||
|
||||
Handles.color = new Color(0.82f, 0.82f, 0.88f, 1f);
|
||||
Handles.DrawAAPolyLine(simple ? 2f : 3f, start, mid1, mid2, end);
|
||||
}
|
||||
}
|
||||
Handles.EndGUI();
|
||||
|
||||
// 再画 block 方块
|
||||
GUIStyle labelStyle = new GUIStyle(EditorStyles.boldLabel)
|
||||
{
|
||||
alignment = TextAnchor.MiddleCenter,
|
||||
wordWrap = true,
|
||||
richText = false,
|
||||
fontSize = simple ? 9 : 11,
|
||||
normal = { textColor = Color.white }
|
||||
};
|
||||
|
||||
foreach (StoryBlockDefinition block in blocks)
|
||||
{
|
||||
if (!HasPreviewableBlockId(block) || !cellRects.TryGetValue(block.blockId, out Rect rect)) continue;
|
||||
|
||||
EditorGUI.DrawRect(rect, GetTypeColor(block.blockType));
|
||||
string label = GetPreviewLabel(block, simple, rect.height);
|
||||
GUI.Label(rect, label, labelStyle);
|
||||
}
|
||||
}
|
||||
GUI.EndClip();
|
||||
|
||||
EditorGUILayout.HelpBox(
|
||||
"在预览区内拖拽可平移视图。列 = 水平(右为正),行 = 垂直(下为正、上为负);坐标代表 Block 中心点。预览按当前 Prefab 尺寸比例绘制:Important 600×375、Secondary 400×200、Song / Tutorial 400×100。",
|
||||
MessageType.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回一个 Block 在 Inspector 预览中的尺寸。所有类型使用同一缩放比例,
|
||||
/// 因而宽高比及不同 Block 之间的体积关系与运行时 Prefab 保持一致。
|
||||
/// </summary>
|
||||
private static Vector2 GetPreviewBlockSize(StoryBlockDefinition block, float previewScale)
|
||||
{
|
||||
Vector2 runtimeSize = block.blockType switch
|
||||
{
|
||||
StoryBlockType.Text when block.textImportance == TextBlockImportance.Important =>
|
||||
new Vector2(ImportantBlockWidth, ImportantBlockHeight),
|
||||
StoryBlockType.Text => new Vector2(SecondaryBlockWidth, SecondaryBlockHeight),
|
||||
StoryBlockType.Song => new Vector2(SongBlockWidth, SongBlockHeight),
|
||||
StoryBlockType.Tutorial => new Vector2(TutorialBlockWidth, TutorialBlockHeight),
|
||||
_ => Vector2.zero
|
||||
};
|
||||
|
||||
return runtimeSize * previewScale;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据可用高度选择预览标签密度。Song / Tutorial 的真实比例高度较小,
|
||||
/// 因此只显示 Block ID,避免文字撑破矩形而掩盖实际体积关系。
|
||||
/// </summary>
|
||||
private static string GetPreviewLabel(StoryBlockDefinition block, bool simple, float blockHeight)
|
||||
{
|
||||
if (simple || blockHeight < 32f)
|
||||
{
|
||||
return block.blockId;
|
||||
}
|
||||
|
||||
if (blockHeight < 60f)
|
||||
{
|
||||
return $"{block.blockId}\n[{block.blockType}]";
|
||||
}
|
||||
|
||||
return $"{block.blockId}\n[{block.blockType}]\n{block.GetDisplayTitle()}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理预览区内的鼠标拖拽平移。
|
||||
/// </summary>
|
||||
private void HandlePreviewPanning(Rect area)
|
||||
{
|
||||
Event e = Event.current;
|
||||
switch (e.type)
|
||||
{
|
||||
case EventType.MouseDown:
|
||||
if (area.Contains(e.mousePosition))
|
||||
{
|
||||
_isPanningPreview = true;
|
||||
e.Use();
|
||||
}
|
||||
break;
|
||||
case EventType.MouseDrag:
|
||||
if (_isPanningPreview)
|
||||
{
|
||||
_previewPan += e.delta;
|
||||
GUI.changed = true;
|
||||
e.Use();
|
||||
}
|
||||
break;
|
||||
case EventType.MouseUp:
|
||||
if (_isPanningPreview)
|
||||
{
|
||||
_isPanningPreview = false;
|
||||
e.Use();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断 Block 能否参与 Inspector 中的故事树预览。
|
||||
/// 新增 Block 时,Odin 会先创建一个尚未填写 blockId 的临时数据项;它还不能作为
|
||||
/// Dictionary 的 Key,也不应在预览中显示或连接。统一在三个预览阶段过滤,避免后续
|
||||
/// Draw / TryGetValue 阶段再次把空引用传入 Dictionary。
|
||||
/// </summary>
|
||||
private static bool HasPreviewableBlockId(StoryBlockDefinition block)
|
||||
{
|
||||
return block != null && !string.IsNullOrWhiteSpace(block.blockId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 预览中不同 block 类型的填充色。
|
||||
/// </summary>
|
||||
private static Color GetTypeColor(StoryBlockType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
StoryBlockType.Text => new Color(0.20f, 0.42f, 0.72f, 1f), // 蓝
|
||||
StoryBlockType.Song => new Color(0.62f, 0.30f, 0.66f, 1f), // 紫
|
||||
StoryBlockType.Tutorial => new Color(0.28f, 0.56f, 0.36f, 1f), // 绿
|
||||
_ => new Color(0.4f, 0.4f, 0.4f, 1f)
|
||||
};
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Localization;
|
||||
using UnityEngine.Localization.Tables;
|
||||
|
||||
namespace Ichni.Story
|
||||
{
|
||||
@@ -10,21 +12,47 @@ namespace Ichni.Story
|
||||
/// <para>该资产不隶属于任何 StoryData,由 <see cref="StoryManager.helperData"/> 统一引用,
|
||||
/// 因而所有章节都共用同一个 Helper 角色、名称和候选对话池。</para>
|
||||
/// <para>运行时会在满足条件的候选中按权重抽取,并在候选数量允许时避免与上次对话重复;
|
||||
/// 具体抽取和 UI 展示逻辑将在 Helper 功能实现阶段接入。</para>
|
||||
/// 具体抽取和 UI 展示由 <see cref="StoryHelperController"/> 负责。</para>
|
||||
/// </summary>
|
||||
[CreateAssetMenu(fileName = "StoryHelperData", menuName = "Ichni/Story/New/Story Helper Data")]
|
||||
public class StoryHelperData : SerializedScriptableObject
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper 的稳定身份标识。当前阶段只有一个 Helper,但后续的更换界面、存档和统计
|
||||
/// 都应使用该 ID,而非依赖可变的资源名称或显示名称。
|
||||
/// </summary>
|
||||
[LabelText("Helper ID")]
|
||||
[Tooltip("使用小写英文、数字和下划线,例如 chapter0_helper。未来切换与持久化 Helper 时使用此稳定 ID。")]
|
||||
public string helperId;
|
||||
|
||||
/// <summary>
|
||||
/// 当前静态版本使用的立绘。留空时,静态 Presenter 会保留场景中原本配置的 Image,
|
||||
/// 因而可以在不立即迁移全部美术引用的情况下逐步接入本数据资产。
|
||||
/// </summary>
|
||||
[PreviewField(75, ObjectFieldAlignment.Left)]
|
||||
[LabelText("Portrait Sprite")]
|
||||
[Tooltip("当前静态 Helper 立绘。未来改用 Spine 或 Live2D 时,可由对应 Presenter 忽略该字段。")]
|
||||
public Sprite portraitSprite;
|
||||
|
||||
/// <summary>
|
||||
/// Helper 名称与对话文本所使用的 Unity Localization String Table。
|
||||
/// </summary>
|
||||
[LabelText("Localization Table")]
|
||||
[Tooltip("Display Name Key、Fallback Dialogue Key 与 Dialogue Pool 的 Text Key 均在此 String Table 中查找。")]
|
||||
public TableReference localizationTable;
|
||||
|
||||
/// <summary>
|
||||
/// Helper 显示名称的 Unity Localization Entry Key。
|
||||
/// </summary>
|
||||
[LabelText("Display Name Key (Localization)")]
|
||||
[Tooltip("Helper 显示名称使用的 Unity Localization Entry Key。")]
|
||||
public string displayNameKey;
|
||||
|
||||
/// <summary>
|
||||
/// 当所有候选对话均不满足条件时显示的兜底对话 Entry Key。
|
||||
/// </summary>
|
||||
[LabelText("Fallback Dialogue Key (Localization)")]
|
||||
[Tooltip("没有候选对话满足条件时显示的 Unity Localization Entry Key。")]
|
||||
public string fallbackDialogueKey;
|
||||
|
||||
/// <summary>
|
||||
@@ -32,6 +60,7 @@ namespace Ichni.Story
|
||||
/// </summary>
|
||||
[LabelText("Dialogue Pool")]
|
||||
[ListDrawerSettings(ShowFoldout = true, DefaultExpandedState = false, DraggableItems = true, ShowItemCount = true)]
|
||||
[Tooltip("全章节共用的候选 Helper 对话。条件留空时该项始终可参与按权重抽取。")]
|
||||
public List<StoryHelperDialogueDefinition> dialoguePool = new List<StoryHelperDialogueDefinition>();
|
||||
}
|
||||
|
||||
@@ -42,25 +71,33 @@ namespace Ichni.Story
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[InlineProperty]
|
||||
[HideReferenceObjectPicker]
|
||||
public class StoryHelperDialogueDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// 候选对话的稳定 ID,仅用于调试、去重和未来数据追踪。
|
||||
/// 命名使用小写英文、数字和下划线,例如 <c>general_greeting_01</c>。
|
||||
/// </summary>
|
||||
[LabelText("Dialogue ID")]
|
||||
[HorizontalGroup("Identity", 0.38f)]
|
||||
[LabelText("ID")]
|
||||
[LabelWidth(20)]
|
||||
[Tooltip("候选对话的稳定 ID,仅用于调试、去重和未来数据追踪。")]
|
||||
public string dialogueId;
|
||||
|
||||
/// <summary>
|
||||
/// 实际显示内容的 Unity Localization Entry Key。
|
||||
/// </summary>
|
||||
[LabelText("Dialogue Key (Localization)")]
|
||||
[HorizontalGroup("Identity")]
|
||||
[LabelText("Text Key")]
|
||||
[LabelWidth(52)]
|
||||
[Tooltip("实际显示文本的 Unity Localization Entry Key。")]
|
||||
public string dialogueKey;
|
||||
|
||||
/// <summary>
|
||||
/// 此对话可被抽取的条件;留空表示始终可用。
|
||||
/// </summary>
|
||||
[LabelText("Availability Condition")]
|
||||
[LabelText("Availability")]
|
||||
[Tooltip("此候选对话可参与抽取的条件;留空表示始终可用。")]
|
||||
public StoryCondition availabilityCondition = new StoryCondition();
|
||||
|
||||
/// <summary>
|
||||
@@ -69,6 +106,7 @@ namespace Ichni.Story
|
||||
/// </summary>
|
||||
[LabelText("Weight")]
|
||||
[MinValue(1)]
|
||||
[Tooltip("在满足条件的候选中使用的相对抽取权重,最小为 1。")]
|
||||
public int weight = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.Story
|
||||
{
|
||||
/// <summary>
|
||||
/// StoryData 编辑期的互斥路线声明。
|
||||
/// <para>本类不会参与运行时条件求值:路线的开放与禁用仍只由 StoryBlockDefinition 中的
|
||||
/// Unlock Condition / Forbidden Condition 控制。它的唯一职责是让 Validate Story Data 能够
|
||||
/// 对“多个结局只能完成一个”的人工配置意图进行可定位检查。</para>
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[InlineProperty]
|
||||
[HideReferenceObjectPicker]
|
||||
public class StoryRouteValidationGroup
|
||||
{
|
||||
[HorizontalGroup("Identity", 0.34f)]
|
||||
[LabelText("Group ID")]
|
||||
[LabelWidth(58)]
|
||||
[Tooltip("仅用于编辑器验证与日志定位的稳定 ID。使用小写英文、数字和下划线,例如 chapter0_ending。")]
|
||||
public string groupId;
|
||||
|
||||
[HorizontalGroup("Identity")]
|
||||
[LabelText("Terminal Blocks")]
|
||||
[Tooltip("同一互斥结局组中的终点 Block ID。Validate Story Data 会检查它们是否存在、是否重复、是否为图终点,以及是否配置 Forbidden Condition。")]
|
||||
public List<string> terminalBlockIds = new List<string>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c6fe8ac7f9f4efba5df1c7a7c52b3e1
|
||||
@@ -13,40 +13,56 @@ namespace Ichni.Story
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[InlineProperty]
|
||||
[HideReferenceObjectPicker]
|
||||
public class StoryTimelineMarkerDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// 标记的稳定唯一 ID,仅用于配置、调试和未来持久化引用。
|
||||
/// 命名使用小写英文、数字和下划线,例如 <c>chapter0_day_01</c>。
|
||||
/// </summary>
|
||||
[HorizontalGroup("Identity", 0.34f)]
|
||||
[LabelText("Marker ID")]
|
||||
[LabelWidth(62)]
|
||||
[Tooltip("Marker 的稳定唯一 ID。回滚快照会使用它作为索引;建议使用小写英文、数字和下划线。")]
|
||||
public string markerId;
|
||||
|
||||
/// <summary>
|
||||
/// 被此标记锚定的 TextBlock ID。该 Block 的 gridColumn 是标记的唯一位置来源;
|
||||
/// 当它处于 Current 或 Completed 时,标记显示;Locked 或 Forbidden 时,标记隐藏。
|
||||
/// </summary>
|
||||
[LabelText("Anchor Block ID")]
|
||||
[HorizontalGroup("Identity", 0.33f)]
|
||||
[LabelText("Anchor")]
|
||||
[LabelWidth(42)]
|
||||
[Tooltip("被此 Marker 锚定的 TextBlock ID。该 Block 的列位置决定 Marker 的横坐标。")]
|
||||
public string anchorBlockId;
|
||||
|
||||
/// <summary>
|
||||
/// Timeline 上显示的本地化文本 Key。通常用于时间描述,也可用于特殊叙事文本。
|
||||
/// </summary>
|
||||
[LabelText("Label Key (Localization)")]
|
||||
[HorizontalGroup("Identity")]
|
||||
[LabelText("Label Key")]
|
||||
[LabelWidth(54)]
|
||||
[Tooltip("Timeline 上显示的 Unity Localization Entry Key,通常用于时间或特殊叙事文本。")]
|
||||
public string labelKey;
|
||||
|
||||
/// <summary>
|
||||
/// 是否参与章节主线进度百分比计算。支线或纯装饰性时间标记应关闭此项。
|
||||
/// </summary>
|
||||
[LabelText("Contributes To Main Progress")]
|
||||
[HorizontalGroup("Progress", 0.42f)]
|
||||
[LabelText("Main Progress")]
|
||||
[Tooltip("开启后,此 Marker 完成时会参与章节主线进度百分比的最大值计算。")]
|
||||
public bool contributesToMainProgress = true;
|
||||
|
||||
/// <summary>
|
||||
/// 锚定 Block 完成后可贡献的主线进度,范围为 0 到 1。
|
||||
/// 同一章节的不同结局都应配置为 1;运行时取所有有效完成标记中的最大值。
|
||||
/// </summary>
|
||||
[LabelText("Progress Value")]
|
||||
[HorizontalGroup("Progress")]
|
||||
[LabelText("Value")]
|
||||
[LabelWidth(35)]
|
||||
[ShowIf(nameof(contributesToMainProgress))]
|
||||
[Range(0f, 1f)]
|
||||
[Tooltip("完成该锚定 Block 后贡献的主线进度,范围为 0 到 1。互斥结局通常都设为 1。")]
|
||||
public float progressValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.Story
|
||||
{
|
||||
/// <summary>
|
||||
/// StoryData 中声明的章节变量默认值类型。
|
||||
/// 数值变量会保存为 float;Int 仅决定 Inspector 和读取接口的语义。
|
||||
/// </summary>
|
||||
public enum StoryVariableType
|
||||
{
|
||||
Bool,
|
||||
Int,
|
||||
Float,
|
||||
String
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 一个章节变量的静态默认定义。
|
||||
/// 默认值不写入玩家存档:当存档中没有同名覆盖值时,StoryVariables 才返回此处的配置。
|
||||
/// 因此“重开章节”只要清空章节变量容器,便会自然回到该定义的初始状态。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[InlineProperty]
|
||||
[HideReferenceObjectPicker]
|
||||
public class StoryVariableDefinition
|
||||
{
|
||||
[HorizontalGroup("Variable", 0.55f)]
|
||||
[LabelText("Key")]
|
||||
[LabelWidth(28)]
|
||||
[Tooltip("变量 Key:使用小写英文、数字和下划线,例如 c0_route_choice。不要使用 Yarn 的 $variable 语法。")]
|
||||
public string key;
|
||||
|
||||
[HorizontalGroup("Variable", 0.18f)]
|
||||
[LabelText("Type")]
|
||||
[LabelWidth(32)]
|
||||
[Tooltip("变量的默认值类型。运行时可由 Yarn 的 set_* 指令写入同名永久章节变量。")]
|
||||
public StoryVariableType type;
|
||||
|
||||
[HorizontalGroup("Variable")]
|
||||
[LabelText("Default")]
|
||||
[LabelWidth(48)]
|
||||
[ShowIf(nameof(IsBool))]
|
||||
[Tooltip("变量尚未被玩家存档覆盖时使用的默认 Bool 值。")]
|
||||
public bool boolValue;
|
||||
|
||||
[HorizontalGroup("Variable")]
|
||||
[LabelText("Default")]
|
||||
[LabelWidth(48)]
|
||||
[ShowIf(nameof(IsInt))]
|
||||
[Tooltip("变量尚未被玩家存档覆盖时使用的默认 Int 值。")]
|
||||
public int intValue;
|
||||
|
||||
[HorizontalGroup("Variable")]
|
||||
[LabelText("Default")]
|
||||
[LabelWidth(48)]
|
||||
[ShowIf(nameof(IsFloat))]
|
||||
[Tooltip("变量尚未被玩家存档覆盖时使用的默认 Float 值。")]
|
||||
public float floatValue;
|
||||
|
||||
[HorizontalGroup("Variable")]
|
||||
[LabelText("Default")]
|
||||
[LabelWidth(48)]
|
||||
[ShowIf(nameof(IsString))]
|
||||
[Tooltip("变量尚未被玩家存档覆盖时使用的默认 String 值。")]
|
||||
public string stringValue;
|
||||
|
||||
private bool IsBool() => type == StoryVariableType.Bool;
|
||||
private bool IsInt() => type == StoryVariableType.Int;
|
||||
private bool IsFloat() => type == StoryVariableType.Float;
|
||||
private bool IsString() => type == StoryVariableType.String;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d61a59c6d4a423aae2e04ae3dac5b1a
|
||||
@@ -5,9 +5,9 @@ using UnityEngine;
|
||||
namespace Ichni.Story
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局剧情变量的统一数据枢纽。
|
||||
/// 当前章节剧情变量的统一数据枢纽。
|
||||
/// 所有外部系统(包括 Yarn、UI、小游戏)读写剧情变量的唯一官方入口。
|
||||
/// 自动桥接至 GameSaveManager 的 StorySaveModule 中持久化。
|
||||
/// 自动桥接至 GameSaveManager 的 StorySaveModule 中当前章节的持久化容器。
|
||||
/// </summary>
|
||||
public static class StoryVariables
|
||||
{
|
||||
@@ -19,7 +19,7 @@ namespace Ichni.Story
|
||||
get
|
||||
{
|
||||
if (GameSaveManager.instance != null && GameSaveManager.instance.StorySaveModule != null)
|
||||
return GameSaveManager.instance.StorySaveModule.variables;
|
||||
return GameSaveManager.instance.StorySaveModule.GetActiveChapterVariables();
|
||||
return _fallback;
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,17 @@ namespace Ichni.Story
|
||||
if (vars.floatVariables.TryGetValue(key, out float f)) return f;
|
||||
if (vars.boolVariables.TryGetValue(key, out bool b)) return b ? 1f : 0f;
|
||||
if (vars.stringVariables.TryGetValue(key, out string s) && float.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out float p)) return p;
|
||||
if (TryGetInitialVariable(key, out StoryVariableDefinition definition))
|
||||
{
|
||||
return definition.type switch
|
||||
{
|
||||
StoryVariableType.Bool => definition.boolValue ? 1f : 0f,
|
||||
StoryVariableType.Int => definition.intValue,
|
||||
StoryVariableType.Float => definition.floatValue,
|
||||
StoryVariableType.String when float.TryParse(definition.stringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out float parsed) => parsed,
|
||||
_ => defaultValue
|
||||
};
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@@ -41,6 +52,17 @@ namespace Ichni.Story
|
||||
if (vars.floatVariables.TryGetValue(key, out float f)) return Mathf.RoundToInt(f);
|
||||
if (vars.boolVariables.TryGetValue(key, out bool b)) return b ? 1 : 0;
|
||||
if (vars.stringVariables.TryGetValue(key, out string s) && float.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out float p)) return Mathf.RoundToInt(p);
|
||||
if (TryGetInitialVariable(key, out StoryVariableDefinition definition))
|
||||
{
|
||||
return definition.type switch
|
||||
{
|
||||
StoryVariableType.Bool => definition.boolValue ? 1 : 0,
|
||||
StoryVariableType.Int => definition.intValue,
|
||||
StoryVariableType.Float => Mathf.RoundToInt(definition.floatValue),
|
||||
StoryVariableType.String when float.TryParse(definition.stringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out float parsed) => Mathf.RoundToInt(parsed),
|
||||
_ => defaultValue
|
||||
};
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@@ -50,6 +72,17 @@ namespace Ichni.Story
|
||||
if (vars.boolVariables.TryGetValue(key, out bool b)) return b;
|
||||
if (vars.floatVariables.TryGetValue(key, out float f)) return f != 0f;
|
||||
if (vars.stringVariables.TryGetValue(key, out string s) && bool.TryParse(s, out bool p)) return p;
|
||||
if (TryGetInitialVariable(key, out StoryVariableDefinition definition))
|
||||
{
|
||||
return definition.type switch
|
||||
{
|
||||
StoryVariableType.Bool => definition.boolValue,
|
||||
StoryVariableType.Int => definition.intValue != 0,
|
||||
StoryVariableType.Float => !Mathf.Approximately(definition.floatValue, 0f),
|
||||
StoryVariableType.String when bool.TryParse(definition.stringValue, out bool parsed) => parsed,
|
||||
_ => defaultValue
|
||||
};
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@@ -59,13 +92,25 @@ namespace Ichni.Story
|
||||
if (vars.stringVariables.TryGetValue(key, out string s)) return s;
|
||||
if (vars.floatVariables.TryGetValue(key, out float f)) return f.ToString(CultureInfo.InvariantCulture);
|
||||
if (vars.boolVariables.TryGetValue(key, out bool b)) return b.ToString();
|
||||
if (TryGetInitialVariable(key, out StoryVariableDefinition definition))
|
||||
{
|
||||
return definition.type switch
|
||||
{
|
||||
StoryVariableType.Bool => definition.boolValue.ToString(),
|
||||
StoryVariableType.Int => definition.intValue.ToString(CultureInfo.InvariantCulture),
|
||||
StoryVariableType.Float => definition.floatValue.ToString(CultureInfo.InvariantCulture),
|
||||
StoryVariableType.String => definition.stringValue ?? string.Empty,
|
||||
_ => defaultValue
|
||||
};
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static bool HasVariable(string key)
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
return vars.floatVariables.ContainsKey(key) || vars.boolVariables.ContainsKey(key) || vars.stringVariables.ContainsKey(key);
|
||||
return vars.floatVariables.ContainsKey(key) || vars.boolVariables.ContainsKey(key) || vars.stringVariables.ContainsKey(key) ||
|
||||
TryGetInitialVariable(key, out _);
|
||||
}
|
||||
|
||||
// ── 写入 ────────────────────────────────────────────────────────────────
|
||||
@@ -124,6 +169,20 @@ namespace Ichni.Story
|
||||
if (!keepBool) vars.boolVariables.Remove(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从当前 StoryTree 的 StoryData 查询变量默认值。没有章节上下文时不虚构默认值,
|
||||
/// 由调用方传入的 defaultValue 作为独立测试场景的回退。
|
||||
/// </summary>
|
||||
private static bool TryGetInitialVariable(string key, out StoryVariableDefinition definition)
|
||||
{
|
||||
StoryData storyData = StoryManager.instance?.treeController?.ActiveStoryData;
|
||||
if (storyData != null)
|
||||
return storyData.TryGetInitialVariable(key, out definition);
|
||||
|
||||
definition = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
// ── 字典批量操作(内部供 Yarn Adapter 使用) ─────────────────────────────
|
||||
|
||||
internal static void SetAllVariables(Dictionary<string, float> floats, Dictionary<string, string> strings, Dictionary<string, bool> bools, bool clear = true)
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Ichni.Story.Dialogue
|
||||
/// 【临时 / 调试用】将 Yarn 对话行以"本地化后的文本"输出到 Console 的呈现器。
|
||||
/// <para>用途:在没有 VN 对话 UI 的情况下,验证整条 Yarn 管线是否跑通,以及
|
||||
/// Unity Localization 是否正确返回当前语言的文本(点击文本块即可在 Console 看到结果)。</para>
|
||||
/// <para>阶段 3 接入 <c>VNDialoguePresenter</c> 后,可从 DialogueRunner 的呈现器列表移除本组件并删除此脚本。</para>
|
||||
/// <para>正式运行使用 <c>VNDialoguePresenter</c>;本组件只应在需要观察本地化解析结果时临时启用。</para>
|
||||
/// </summary>
|
||||
public class ConsoleLinePresenter : DialoguePresenterBase
|
||||
{
|
||||
|
||||
56
Assets/Scripts/NewStorySystem/Dialogue/DialogueHistory.cs
Normal file
56
Assets/Scripts/NewStorySystem/Dialogue/DialogueHistory.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ichni.Story.Dialogue
|
||||
{
|
||||
/// <summary>对话记录中一条已经实际显示或采用的内容。</summary>
|
||||
[Serializable]
|
||||
public sealed class DialogueHistoryEntry
|
||||
{
|
||||
public string speakerName;
|
||||
public string content;
|
||||
public bool isChoice;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前一次 TextBlock 对话专用的临时记录。
|
||||
/// <para>记录不会写入 ES3;开始下一次对话、正常结束或点击 Back 取消时都会清空,
|
||||
/// 因而它只承担 DialogUIPage 内的“本次对话回顾”职责。</para>
|
||||
/// </summary>
|
||||
public static class DialogueHistory
|
||||
{
|
||||
private static readonly List<DialogueHistoryEntry> EntriesInternal = new();
|
||||
|
||||
public static IReadOnlyList<DialogueHistoryEntry> Entries => EntriesInternal;
|
||||
|
||||
public static void BeginSession() => EntriesInternal.Clear();
|
||||
|
||||
public static void AddLine(string speakerName, string content)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(content))
|
||||
return;
|
||||
|
||||
EntriesInternal.Add(new DialogueHistoryEntry
|
||||
{
|
||||
speakerName = speakerName ?? string.Empty,
|
||||
content = content,
|
||||
isChoice = false
|
||||
});
|
||||
}
|
||||
|
||||
public static void AddChoice(string content)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(content))
|
||||
return;
|
||||
|
||||
EntriesInternal.Add(new DialogueHistoryEntry
|
||||
{
|
||||
speakerName = string.Empty,
|
||||
content = content,
|
||||
isChoice = true
|
||||
});
|
||||
}
|
||||
|
||||
public static void Clear() => EntriesInternal.Clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd7c83e0353e4fb7b912fb9996f64738
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user