UI系统组件
This commit is contained in:
@@ -15,7 +15,7 @@ MonoBehaviour:
|
|||||||
m_DefaultGroup: 9ce5c865a2d3a0840aabdd8ccb3fd4b1
|
m_DefaultGroup: 9ce5c865a2d3a0840aabdd8ccb3fd4b1
|
||||||
m_currentHash:
|
m_currentHash:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
Hash: 15c2855dcd9c0ee51e3ef23e37c6e24d
|
Hash: 31691697811707650999fb9a02054009
|
||||||
m_OptimizeCatalogSize: 0
|
m_OptimizeCatalogSize: 0
|
||||||
m_BuildRemoteCatalog: 0
|
m_BuildRemoteCatalog: 0
|
||||||
m_BundleLocalCatalog: 0
|
m_BundleLocalCatalog: 0
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ MonoBehaviour:
|
|||||||
m_GetFontFeaturesAtRuntime: 1
|
m_GetFontFeaturesAtRuntime: 1
|
||||||
m_missingGlyphCharacter: 0
|
m_missingGlyphCharacter: 0
|
||||||
m_warningsDisabled: 0
|
m_warningsDisabled: 0
|
||||||
m_defaultFontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
m_defaultFontAsset: {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
m_defaultFontAssetPath: Fonts & Materials/
|
m_defaultFontAssetPath: Fonts & Materials/
|
||||||
m_defaultFontSize: 36
|
m_defaultFontSize: 36
|
||||||
m_defaultAutoSizeMinRatio: 0.5
|
m_defaultAutoSizeMinRatio: 0.5
|
||||||
@@ -29,18 +29,17 @@ MonoBehaviour:
|
|||||||
m_defaultTextMeshProTextContainerSize: {x: 20, y: 5}
|
m_defaultTextMeshProTextContainerSize: {x: 20, y: 5}
|
||||||
m_defaultTextMeshProUITextContainerSize: {x: 200, y: 50}
|
m_defaultTextMeshProUITextContainerSize: {x: 200, y: 50}
|
||||||
m_autoSizeTextContainer: 0
|
m_autoSizeTextContainer: 0
|
||||||
m_fallbackFontAssets: []
|
m_IsTextObjectScaleStatic: 0
|
||||||
|
m_fallbackFontAssets:
|
||||||
|
- {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
m_matchMaterialPreset: 1
|
m_matchMaterialPreset: 1
|
||||||
m_defaultSpriteAsset: {fileID: 11400000, guid: c41005c129ba4d66911b75229fd70b45,
|
m_defaultSpriteAsset: {fileID: 11400000, guid: c41005c129ba4d66911b75229fd70b45, type: 2}
|
||||||
type: 2}
|
|
||||||
m_defaultSpriteAssetPath: Sprite Assets/
|
m_defaultSpriteAssetPath: Sprite Assets/
|
||||||
m_enableEmojiSupport: 1
|
m_enableEmojiSupport: 1
|
||||||
m_MissingCharacterSpriteUnicode: 0
|
m_MissingCharacterSpriteUnicode: 0
|
||||||
m_defaultColorGradientPresetsPath: Color Gradient Presets/
|
m_defaultColorGradientPresetsPath: Color Gradient Presets/
|
||||||
m_defaultStyleSheet: {fileID: 11400000, guid: f952c082cb03451daed3ee968ac6c63e,
|
m_defaultStyleSheet: {fileID: 11400000, guid: f952c082cb03451daed3ee968ac6c63e, type: 2}
|
||||||
type: 2}
|
|
||||||
m_StyleSheetsResourcePath:
|
m_StyleSheetsResourcePath:
|
||||||
m_leadingCharacters: {fileID: 4900000, guid: d82c1b31c7e74239bff1220585707d2b, type: 3}
|
m_leadingCharacters: {fileID: 4900000, guid: d82c1b31c7e74239bff1220585707d2b, type: 3}
|
||||||
m_followingCharacters: {fileID: 4900000, guid: fade42e8bc714b018fac513c043d323b,
|
m_followingCharacters: {fileID: 4900000, guid: fade42e8bc714b018fac513c043d323b, type: 3}
|
||||||
type: 3}
|
|
||||||
m_UseModernHangulLineBreakingRules: 0
|
m_UseModernHangulLineBreakingRules: 0
|
||||||
|
|||||||
8
Assets/_Game/Art/UI/Fonts.meta
Normal file
8
Assets/_Game/Art/UI/Fonts.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c37b3afde8efc6443ba0add644006417
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
2890
Assets/_Game/Art/UI/Fonts/NotoSansSC SDF.asset
Normal file
2890
Assets/_Game/Art/UI/Fonts/NotoSansSC SDF.asset
Normal file
File diff suppressed because one or more lines are too long
8
Assets/_Game/Art/UI/Fonts/NotoSansSC SDF.asset.meta
Normal file
8
Assets/_Game/Art/UI/Fonts/NotoSansSC SDF.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c9ebf78286d2b6345b16575012502acc
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/_Game/Art/UI/Fonts/NotoSansSC-VF.ttf
Normal file
BIN
Assets/_Game/Art/UI/Fonts/NotoSansSC-VF.ttf
Normal file
Binary file not shown.
21
Assets/_Game/Art/UI/Fonts/NotoSansSC-VF.ttf.meta
Normal file
21
Assets/_Game/Art/UI/Fonts/NotoSansSC-VF.ttf.meta
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 028abe651ad4d13458a11b7b8fc8c0ff
|
||||||
|
TrueTypeFontImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
fontSize: 16
|
||||||
|
forceTextureCase: -2
|
||||||
|
characterSpacing: 0
|
||||||
|
characterPadding: 1
|
||||||
|
includeFontData: 1
|
||||||
|
fontNames:
|
||||||
|
- Noto Sans SC
|
||||||
|
fallbackFontReferences: []
|
||||||
|
customCharacters:
|
||||||
|
fontRenderingMode: 0
|
||||||
|
ascentCalculationMode: 1
|
||||||
|
useLegacyBoundsCalculation: 0
|
||||||
|
shouldRoundAdvanceValue: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -1,14 +1,244 @@
|
|||||||
{
|
{
|
||||||
"entries": [
|
"entries": [
|
||||||
{ "key": "TOAST_ACHIEVEMENT_TITLE", "value": "成就解锁" },
|
{
|
||||||
{ "key": "TOAST_ABILITY_TITLE", "value": "能力获得" },
|
"key": "BADGE_STEELSOUL",
|
||||||
{ "key": "REBIND_WAITING_PROMPT", "value": "按下新按键…" },
|
"value": "钢魂"
|
||||||
{ "key": "MAP_PROGRESS_GLOBAL", "value": "已探索 {0:P0}" },
|
},
|
||||||
{ "key": "MAP_PROGRESS_REGION", "value": "{1}:{0:P0}" },
|
{
|
||||||
{ "key": "MAP_CLOSE_HINT", "value": "关闭地图" },
|
"key": "BTN_BACK",
|
||||||
{ "key": "TELEPORT_CONFIRM_TITLE", "value": "快速传送" },
|
"value": "返回"
|
||||||
{ "key": "TELEPORT_CONFIRM_BODY", "value": "传送到:" },
|
},
|
||||||
{ "key": "CONFIRM_YES", "value": "确认" },
|
{
|
||||||
{ "key": "CONFIRM_NO", "value": "取消" }
|
"key": "CONFIRM_DELETE_BODY",
|
||||||
|
"value": "确定删除该存档槽的所有进度吗?此操作不可撤销。"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CONFIRM_DELETE_TITLE",
|
||||||
|
"value": "删除存档"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CONFIRM_NO",
|
||||||
|
"value": "取消"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CONFIRM_OVERWRITE_BODY",
|
||||||
|
"value": "该存档槽已有进度,确定覆盖并开始新游戏吗?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CONFIRM_OVERWRITE_TITLE",
|
||||||
|
"value": "覆盖存档"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CONFIRM_YES",
|
||||||
|
"value": "确认"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CREDITS_BODY",
|
||||||
|
"value": "ZELING\n\n一段 2D 动作冒险\n\n制作 · Joywayer\n\n感谢游玩。"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CREDITS_TITLE",
|
||||||
|
"value": "制作团队"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MAP_CLOSE_HINT",
|
||||||
|
"value": "关闭地图"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MAP_PROGRESS_GLOBAL",
|
||||||
|
"value": "已探索 {0:P0}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MAP_PROGRESS_REGION",
|
||||||
|
"value": "{1}:{0:P0}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MENU_CONTINUE",
|
||||||
|
"value": "继续"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MENU_CREDITS",
|
||||||
|
"value": "制作团队"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MENU_NEW_GAME",
|
||||||
|
"value": "新游戏"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MENU_QUIT",
|
||||||
|
"value": "退出"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MENU_SETTINGS",
|
||||||
|
"value": "设置"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MENU_SUBTITLE",
|
||||||
|
"value": "一段 2D 动作冒险"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MODE_NORMAL",
|
||||||
|
"value": "普通"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MODE_SELECT_TITLE",
|
||||||
|
"value": "选择模式"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MODE_STEELSOUL",
|
||||||
|
"value": "钢铁之魂"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MODE_STEELSOUL_DESC",
|
||||||
|
"value": "钢铁之魂:一命模式,死亡即清空存档。"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "REBIND_WAITING_PROMPT",
|
||||||
|
"value": "按下新按键…"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SAVESLOT_EMPTY",
|
||||||
|
"value": "空槽 · 开始新游戏"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SAVESLOT_TITLE",
|
||||||
|
"value": "选择存档"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_AMBIENT_VOLUME",
|
||||||
|
"value": "环境音量"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_BGM_VOLUME",
|
||||||
|
"value": "音乐音量"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_COLORBLIND",
|
||||||
|
"value": "色盲模式"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_FPS",
|
||||||
|
"value": "帧率上限"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_LANGUAGE",
|
||||||
|
"value": "语言"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_MASTER_VOLUME",
|
||||||
|
"value": "主音量"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_SCREEN_SHAKE",
|
||||||
|
"value": "屏幕震动"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_SFX_VOLUME",
|
||||||
|
"value": "音效音量"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_TITLE",
|
||||||
|
"value": "设置"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_UI_SCALE",
|
||||||
|
"value": "界面缩放"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_VSYNC",
|
||||||
|
"value": "垂直同步"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_AMBIENT_VOLUME",
|
||||||
|
"value": "环境音"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_BGM_VOLUME",
|
||||||
|
"value": "音乐"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_COLORBLIND",
|
||||||
|
"value": "色盲模式"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_COLORBLIND_0",
|
||||||
|
"value": "关闭"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_COLORBLIND_1",
|
||||||
|
"value": "红色弱(Protanopia)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_COLORBLIND_2",
|
||||||
|
"value": "绿色弱(Deuteranopia)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_COLORBLIND_3",
|
||||||
|
"value": "蓝色弱(Tritanopia)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_FPS_UNLIMITED",
|
||||||
|
"value": "无限"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_LANGUAGE",
|
||||||
|
"value": "语言"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_MASTER_VOLUME",
|
||||||
|
"value": "主音量"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_SCREEN_SHAKE",
|
||||||
|
"value": "屏幕震动"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_SECTION_ACCESS",
|
||||||
|
"value": "辅助功能"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_SECTION_AUDIO",
|
||||||
|
"value": "音频"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_SECTION_DISPLAY",
|
||||||
|
"value": "画面"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_SECTION_LANGUAGE",
|
||||||
|
"value": "语言"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_SFX_VOLUME",
|
||||||
|
"value": "音效"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_TARGET_FPS",
|
||||||
|
"value": "目标帧率"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_UI_SCALE",
|
||||||
|
"value": "界面缩放"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_VSYNC",
|
||||||
|
"value": "垂直同步"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "TELEPORT_CONFIRM_BODY",
|
||||||
|
"value": "传送到:"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "TELEPORT_CONFIRM_TITLE",
|
||||||
|
"value": "快速传送"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "TOAST_ABILITY_TITLE",
|
||||||
|
"value": "能力获得"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "TOAST_ACHIEVEMENT_TITLE",
|
||||||
|
"value": "成就解锁"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,244 @@
|
|||||||
{
|
{
|
||||||
"entries": [
|
"entries": [
|
||||||
{ "key": "TOAST_ACHIEVEMENT_TITLE", "value": "Achievement Unlocked" },
|
{
|
||||||
{ "key": "TOAST_ABILITY_TITLE", "value": "Ability Acquired" },
|
"key": "BADGE_STEELSOUL",
|
||||||
{ "key": "REBIND_WAITING_PROMPT", "value": "Press New Key…" },
|
"value": "STEEL"
|
||||||
{ "key": "MAP_PROGRESS_GLOBAL", "value": "Explored {0:P0}" },
|
},
|
||||||
{ "key": "MAP_PROGRESS_REGION", "value": "{1}: {0:P0}" },
|
{
|
||||||
{ "key": "MAP_CLOSE_HINT", "value": "Close Map" },
|
"key": "BTN_BACK",
|
||||||
{ "key": "TELEPORT_CONFIRM_TITLE", "value": "Fast Travel" },
|
"value": "Back"
|
||||||
{ "key": "TELEPORT_CONFIRM_BODY", "value": "Travel to: " },
|
},
|
||||||
{ "key": "CONFIRM_YES", "value": "Confirm" },
|
{
|
||||||
{ "key": "CONFIRM_NO", "value": "Cancel" }
|
"key": "CONFIRM_DELETE_BODY",
|
||||||
|
"value": "Delete all progress in this slot? This cannot be undone."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CONFIRM_DELETE_TITLE",
|
||||||
|
"value": "Delete Save"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CONFIRM_NO",
|
||||||
|
"value": "Cancel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CONFIRM_OVERWRITE_BODY",
|
||||||
|
"value": "This slot already has progress. Overwrite it and start a new game?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CONFIRM_OVERWRITE_TITLE",
|
||||||
|
"value": "Overwrite Save"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CONFIRM_YES",
|
||||||
|
"value": "Confirm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CREDITS_BODY",
|
||||||
|
"value": "ZELING\n\nA 2D Action Adventure\n\nMade by Joywayer\n\nThanks for playing."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "CREDITS_TITLE",
|
||||||
|
"value": "Credits"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MAP_CLOSE_HINT",
|
||||||
|
"value": "Close Map"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MAP_PROGRESS_GLOBAL",
|
||||||
|
"value": "Explored {0:P0}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MAP_PROGRESS_REGION",
|
||||||
|
"value": "{1}: {0:P0}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MENU_CONTINUE",
|
||||||
|
"value": "Continue"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MENU_CREDITS",
|
||||||
|
"value": "Credits"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MENU_NEW_GAME",
|
||||||
|
"value": "New Game"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MENU_QUIT",
|
||||||
|
"value": "Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MENU_SETTINGS",
|
||||||
|
"value": "Settings"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MENU_SUBTITLE",
|
||||||
|
"value": "A 2D Action Adventure"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MODE_NORMAL",
|
||||||
|
"value": "Normal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MODE_SELECT_TITLE",
|
||||||
|
"value": "Select Mode"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MODE_STEELSOUL",
|
||||||
|
"value": "Steel Soul"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "MODE_STEELSOUL_DESC",
|
||||||
|
"value": "Steel Soul: one life. Death wipes the save."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "REBIND_WAITING_PROMPT",
|
||||||
|
"value": "Press New Key…"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SAVESLOT_EMPTY",
|
||||||
|
"value": "Empty Slot · New Game"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SAVESLOT_TITLE",
|
||||||
|
"value": "Select Save"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_AMBIENT_VOLUME",
|
||||||
|
"value": "Ambient Volume"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_BGM_VOLUME",
|
||||||
|
"value": "Music Volume"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_COLORBLIND",
|
||||||
|
"value": "Colorblind Mode"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_FPS",
|
||||||
|
"value": "Frame Rate"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_LANGUAGE",
|
||||||
|
"value": "Language"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_MASTER_VOLUME",
|
||||||
|
"value": "Master Volume"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_SCREEN_SHAKE",
|
||||||
|
"value": "Screen Shake"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_SFX_VOLUME",
|
||||||
|
"value": "SFX Volume"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_TITLE",
|
||||||
|
"value": "Settings"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_UI_SCALE",
|
||||||
|
"value": "UI Scale"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SETTINGS_VSYNC",
|
||||||
|
"value": "V-Sync"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_AMBIENT_VOLUME",
|
||||||
|
"value": "Ambience"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_BGM_VOLUME",
|
||||||
|
"value": "Music"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_COLORBLIND",
|
||||||
|
"value": "Colorblind Mode"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_COLORBLIND_0",
|
||||||
|
"value": "Off"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_COLORBLIND_1",
|
||||||
|
"value": "Protanopia"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_COLORBLIND_2",
|
||||||
|
"value": "Deuteranopia"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_COLORBLIND_3",
|
||||||
|
"value": "Tritanopia"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_FPS_UNLIMITED",
|
||||||
|
"value": "Unlimited"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_LANGUAGE",
|
||||||
|
"value": "Language"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_MASTER_VOLUME",
|
||||||
|
"value": "Master Volume"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_SCREEN_SHAKE",
|
||||||
|
"value": "Screen Shake"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_SECTION_ACCESS",
|
||||||
|
"value": "Accessibility"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_SECTION_AUDIO",
|
||||||
|
"value": "Audio"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_SECTION_DISPLAY",
|
||||||
|
"value": "Display"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_SECTION_LANGUAGE",
|
||||||
|
"value": "Language"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_SFX_VOLUME",
|
||||||
|
"value": "Sound Effects"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_TARGET_FPS",
|
||||||
|
"value": "Target FPS"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_UI_SCALE",
|
||||||
|
"value": "UI Scale"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "SET_VSYNC",
|
||||||
|
"value": "V-Sync"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "TELEPORT_CONFIRM_BODY",
|
||||||
|
"value": "Travel to: "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "TELEPORT_CONFIRM_TITLE",
|
||||||
|
"value": "Fast Travel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "TOAST_ABILITY_TITLE",
|
||||||
|
"value": "Ability Acquired"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "TOAST_ACHIEVEMENT_TITLE",
|
||||||
|
"value": "Achievement Unlocked"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
24
Assets/_Game/Data/Localization/FontConfig.asset
Normal file
24
Assets/_Game/Data/Localization/FontConfig.asset
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: b31f31378d72a8e42b454d4af01e51ab, type: 3}
|
||||||
|
m_Name: FontConfig
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
entries:
|
||||||
|
- language: 0
|
||||||
|
fontAsset: {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
|
fontMaterial: {fileID: 0}
|
||||||
|
- language: 2
|
||||||
|
fontAsset: {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
|
fontMaterial: {fileID: 0}
|
||||||
|
- language: 3
|
||||||
|
fontAsset: {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
|
fontMaterial: {fileID: 0}
|
||||||
8
Assets/_Game/Data/Localization/FontConfig.asset.meta
Normal file
8
Assets/_Game/Data/Localization/FontConfig.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cb61150dde6b0cf4aafcd4ad5f1a7209
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/_Game/Data/UI/Themes.meta
Normal file
8
Assets/_Game/Data/UI/Themes.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b12c09d0cc5d23f4a9c17b3650e01ab9
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
35
Assets/_Game/Data/UI/Themes/UI_Theme_Default.asset
Normal file
35
Assets/_Game/Data/UI/Themes/UI_Theme_Default.asset
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: e1d97086a1337cc47a5d2ee9c85a944d, type: 3}
|
||||||
|
m_Name: UI_Theme_Default
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
Primary: {r: 0.1, g: 0.55, b: 0.95, a: 1}
|
||||||
|
Secondary: {r: 0.2, g: 0.2, b: 0.25, a: 1}
|
||||||
|
Accent: {r: 1, g: 0.78, b: 0.2, a: 1}
|
||||||
|
Background: {r: 0.06, g: 0.07, b: 0.1, a: 1}
|
||||||
|
TextPrimary: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
TextSecondary: {r: 0.75, g: 0.78, b: 0.82, a: 1}
|
||||||
|
TextDisabled: {r: 0.4, g: 0.42, b: 0.45, a: 1}
|
||||||
|
Success: {r: 0.3, g: 0.85, b: 0.45, a: 1}
|
||||||
|
Warning: {r: 0.95, g: 0.7, b: 0.1, a: 1}
|
||||||
|
Danger: {r: 0.95, g: 0.3, b: 0.3, a: 1}
|
||||||
|
HeaderFont: {fileID: 0}
|
||||||
|
BodyFont: {fileID: 0}
|
||||||
|
HeaderFontSize: 36
|
||||||
|
BodyFontSize: 20
|
||||||
|
SmallFontSize: 14
|
||||||
|
ButtonNormal: {r: 0.1, g: 0.55, b: 0.95, a: 1}
|
||||||
|
ButtonHighlighted: {r: 0.2, g: 0.65, b: 1, a: 1}
|
||||||
|
ButtonPressed: {r: 0.05, g: 0.4, b: 0.8, a: 1}
|
||||||
|
ButtonDisabled: {r: 0.3, g: 0.3, b: 0.32, a: 1}
|
||||||
|
ClickSound: {fileID: 0}
|
||||||
|
HoverSound: {fileID: 0}
|
||||||
8
Assets/_Game/Data/UI/Themes/UI_Theme_Default.asset.meta
Normal file
8
Assets/_Game/Data/UI/Themes/UI_Theme_Default.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 88bab5495f6103f4d9d69fa043d4c3e1
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
45
Assets/_Game/Data/UI/UI_MainMenuConfig.asset
Normal file
45
Assets/_Game/Data/UI/UI_MainMenuConfig.asset
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: d78ee6af5c2b0344ea105452f496e85c, type: 3}
|
||||||
|
m_Name: UI_MainMenuConfig
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_items:
|
||||||
|
- labelKey: MENU_NEW_GAME
|
||||||
|
icon: {fileID: 0}
|
||||||
|
action: 0
|
||||||
|
requiresSave: 0
|
||||||
|
sceneKey:
|
||||||
|
eventChannel: {fileID: 0}
|
||||||
|
- labelKey: MENU_CONTINUE
|
||||||
|
icon: {fileID: 0}
|
||||||
|
action: 1
|
||||||
|
requiresSave: 1
|
||||||
|
sceneKey:
|
||||||
|
eventChannel: {fileID: 0}
|
||||||
|
- labelKey: MENU_SETTINGS
|
||||||
|
icon: {fileID: 0}
|
||||||
|
action: 2
|
||||||
|
requiresSave: 0
|
||||||
|
sceneKey:
|
||||||
|
eventChannel: {fileID: 0}
|
||||||
|
- labelKey: MENU_CREDITS
|
||||||
|
icon: {fileID: 0}
|
||||||
|
action: 3
|
||||||
|
requiresSave: 0
|
||||||
|
sceneKey:
|
||||||
|
eventChannel: {fileID: 0}
|
||||||
|
- labelKey: MENU_QUIT
|
||||||
|
icon: {fileID: 0}
|
||||||
|
action: 5
|
||||||
|
requiresSave: 0
|
||||||
|
sceneKey:
|
||||||
|
eventChannel: {fileID: 0}
|
||||||
8
Assets/_Game/Data/UI/UI_MainMenuConfig.asset.meta
Normal file
8
Assets/_Game/Data/UI/UI_MainMenuConfig.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2318fde642d37ef4697873da59a7119e
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
57
Assets/_Game/Data/UI/UI_SettingsSchema.asset
Normal file
57
Assets/_Game/Data/UI/UI_SettingsSchema.asset
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 0edaa79306d53d74da12f1f0cb03ea48, type: 3}
|
||||||
|
m_Name: UI_SettingsSchema
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_items:
|
||||||
|
- isHeader: 1
|
||||||
|
labelKey: SET_SECTION_AUDIO
|
||||||
|
key: 0
|
||||||
|
- isHeader: 0
|
||||||
|
labelKey: SET_MASTER_VOLUME
|
||||||
|
key: 0
|
||||||
|
- isHeader: 0
|
||||||
|
labelKey: SET_BGM_VOLUME
|
||||||
|
key: 1
|
||||||
|
- isHeader: 0
|
||||||
|
labelKey: SET_SFX_VOLUME
|
||||||
|
key: 2
|
||||||
|
- isHeader: 0
|
||||||
|
labelKey: SET_AMBIENT_VOLUME
|
||||||
|
key: 3
|
||||||
|
- isHeader: 1
|
||||||
|
labelKey: SET_SECTION_DISPLAY
|
||||||
|
key: 0
|
||||||
|
- isHeader: 0
|
||||||
|
labelKey: SET_VSYNC
|
||||||
|
key: 4
|
||||||
|
- isHeader: 0
|
||||||
|
labelKey: SET_TARGET_FPS
|
||||||
|
key: 5
|
||||||
|
- isHeader: 1
|
||||||
|
labelKey: SET_SECTION_ACCESS
|
||||||
|
key: 0
|
||||||
|
- isHeader: 0
|
||||||
|
labelKey: SET_UI_SCALE
|
||||||
|
key: 6
|
||||||
|
- isHeader: 0
|
||||||
|
labelKey: SET_COLORBLIND
|
||||||
|
key: 7
|
||||||
|
- isHeader: 0
|
||||||
|
labelKey: SET_SCREEN_SHAKE
|
||||||
|
key: 8
|
||||||
|
- isHeader: 1
|
||||||
|
labelKey: SET_SECTION_LANGUAGE
|
||||||
|
key: 0
|
||||||
|
- isHeader: 0
|
||||||
|
labelKey: SET_LANGUAGE
|
||||||
|
key: 9
|
||||||
8
Assets/_Game/Data/UI/UI_SettingsSchema.asset.meta
Normal file
8
Assets/_Game/Data/UI/UI_SettingsSchema.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e4755a1ee888ca14ab8889635a7d547c
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/_Game/Localization.meta
Normal file
8
Assets/_Game/Localization.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4f79cdf8f0c565f4ea995a926f81cf85
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/_Game/Localization/Export.meta
Normal file
8
Assets/_Game/Localization/Export.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1797fe3bf16d4004b9645a8493e50f70
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
54
Assets/_Game/Localization/Export/UI.csv
Normal file
54
Assets/_Game/Localization/Export/UI.csv
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
key,ChineseSimplified,English,Japanese,Korean
|
||||||
|
BADGE_STEELSOUL,钢魂,STEEL,,
|
||||||
|
BTN_BACK,返回,Back,,
|
||||||
|
CONFIRM_DELETE_BODY,确定删除该存档槽的所有进度吗?此操作不可撤销。,Delete all progress in this slot? This cannot be undone.,,
|
||||||
|
CONFIRM_DELETE_TITLE,删除存档,Delete Save,,
|
||||||
|
CONFIRM_NO,取消,Cancel,,
|
||||||
|
CONFIRM_OVERWRITE_BODY,该存档槽已有进度,确定覆盖并开始新游戏吗?,This slot already has progress. Overwrite it and start a new game?,,
|
||||||
|
CONFIRM_OVERWRITE_TITLE,覆盖存档,Overwrite Save,,
|
||||||
|
CONFIRM_YES,确认,Confirm,,
|
||||||
|
CREDITS_BODY,"ZELING
|
||||||
|
|
||||||
|
一段 2D 动作冒险
|
||||||
|
|
||||||
|
制作 · Joywayer
|
||||||
|
|
||||||
|
感谢游玩。","ZELING
|
||||||
|
|
||||||
|
A 2D Action Adventure
|
||||||
|
|
||||||
|
Made by Joywayer
|
||||||
|
|
||||||
|
Thanks for playing.",,
|
||||||
|
CREDITS_TITLE,制作团队,Credits,,
|
||||||
|
MAP_CLOSE_HINT,关闭地图,Close Map,,
|
||||||
|
MAP_PROGRESS_GLOBAL,已探索 {0:P0},Explored {0:P0},,
|
||||||
|
MAP_PROGRESS_REGION,{1}:{0:P0},{1}: {0:P0},,
|
||||||
|
MENU_CONTINUE,继续,Continue,,
|
||||||
|
MENU_CREDITS,制作团队,Credits,,
|
||||||
|
MENU_NEW_GAME,新游戏,New Game,,
|
||||||
|
MENU_QUIT,退出,Quit,,
|
||||||
|
MENU_SETTINGS,设置,Settings,,
|
||||||
|
MENU_SUBTITLE,一段 2D 动作冒险,A 2D Action Adventure,,
|
||||||
|
MODE_NORMAL,普通,Normal,,
|
||||||
|
MODE_SELECT_TITLE,选择模式,Select Mode,,
|
||||||
|
MODE_STEELSOUL,钢铁之魂,Steel Soul,,
|
||||||
|
MODE_STEELSOUL_DESC,钢铁之魂:一命模式,死亡即清空存档。,Steel Soul: one life. Death wipes the save.,,
|
||||||
|
REBIND_WAITING_PROMPT,按下新按键…,Press New Key…,新しいキーを押してください…,새 키를 누르세요…
|
||||||
|
SAVESLOT_EMPTY,空槽 · 开始新游戏,Empty Slot · New Game,,
|
||||||
|
SAVESLOT_TITLE,选择存档,Select Save,,
|
||||||
|
SETTINGS_AMBIENT_VOLUME,环境音量,Ambient Volume,,
|
||||||
|
SETTINGS_BGM_VOLUME,音乐音量,Music Volume,,
|
||||||
|
SETTINGS_COLORBLIND,色盲模式,Colorblind Mode,,
|
||||||
|
SETTINGS_FPS,帧率上限,Frame Rate,,
|
||||||
|
SETTINGS_LANGUAGE,语言,Language,,
|
||||||
|
SETTINGS_MASTER_VOLUME,主音量,Master Volume,,
|
||||||
|
SETTINGS_SCREEN_SHAKE,屏幕震动,Screen Shake,,
|
||||||
|
SETTINGS_SFX_VOLUME,音效音量,SFX Volume,,
|
||||||
|
SETTINGS_TITLE,设置,Settings,,
|
||||||
|
SETTINGS_UI_SCALE,界面缩放,UI Scale,,
|
||||||
|
SETTINGS_VSYNC,垂直同步,V-Sync,,
|
||||||
|
TELEPORT_CONFIRM_BODY,传送到:,Travel to: ,,
|
||||||
|
TELEPORT_CONFIRM_TITLE,快速传送,Fast Travel,,
|
||||||
|
TOAST_ABILITY_TITLE,能力获得,Ability Acquired,アビリティ獲得,능력 획득
|
||||||
|
TOAST_ACHIEVEMENT_TITLE,成就解锁,Achievement Unlocked,実績アンロック,업적 잊금
|
||||||
|
7
Assets/_Game/Localization/Export/UI.csv.meta
Normal file
7
Assets/_Game/Localization/Export/UI.csv.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 766b94c478152f347a7245501116f2e8
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/_Game/Prefabs/UI/Controls.meta
Normal file
8
Assets/_Game/Prefabs/UI/Controls.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9af40be9037b56d488a7f4e060b0ed3b
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
307
Assets/_Game/Prefabs/UI/Controls/UI_Control_Button.prefab
Normal file
307
Assets/_Game/Prefabs/UI/Controls/UI_Control_Button.prefab
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &4648993278565750863
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 7434669335039776586}
|
||||||
|
- component: {fileID: 4989798412556107440}
|
||||||
|
- component: {fileID: 1446889652086510839}
|
||||||
|
- component: {fileID: 4780358684561283937}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Text (TMP)
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &7434669335039776586
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4648993278565750863}
|
||||||
|
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: 7145670357572348738}
|
||||||
|
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 &4989798412556107440
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4648993278565750863}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &1446889652086510839
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4648993278565750863}
|
||||||
|
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: Button
|
||||||
|
m_isRightToLeft: 0
|
||||||
|
m_fontAsset: {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
|
m_sharedMaterial: {fileID: 1445647621079294416, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
|
m_fontSharedMaterials: []
|
||||||
|
m_fontMaterial: {fileID: 0}
|
||||||
|
m_fontMaterials: []
|
||||||
|
m_fontColor32:
|
||||||
|
serializedVersion: 2
|
||||||
|
rgba: 4294967295
|
||||||
|
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, 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: 0
|
||||||
|
m_overrideHtmlColors: 0
|
||||||
|
m_faceColor:
|
||||||
|
serializedVersion: 2
|
||||||
|
rgba: 4294967295
|
||||||
|
m_fontSize: 14
|
||||||
|
m_fontSizeBase: 14
|
||||||
|
m_fontWeight: 400
|
||||||
|
m_enableAutoSizing: 0
|
||||||
|
m_fontSizeMin: 18
|
||||||
|
m_fontSizeMax: 72
|
||||||
|
m_fontStyle: 0
|
||||||
|
m_HorizontalAlignment: 2
|
||||||
|
m_VerticalAlignment: 512
|
||||||
|
m_textAlignment: 65535
|
||||||
|
m_characterSpacing: 0
|
||||||
|
m_wordSpacing: 0
|
||||||
|
m_lineSpacing: 0
|
||||||
|
m_lineSpacingMax: 0
|
||||||
|
m_paragraphSpacing: 0
|
||||||
|
m_charWidthMaxAdj: 0
|
||||||
|
m_enableWordWrapping: 1
|
||||||
|
m_wordWrappingRatios: 0.4
|
||||||
|
m_overflowMode: 0
|
||||||
|
m_linkedTextComponent: {fileID: 0}
|
||||||
|
parentLinkedComponent: {fileID: 0}
|
||||||
|
m_enableKerning: 1
|
||||||
|
m_enableExtraPadding: 0
|
||||||
|
checkPaddingRequired: 0
|
||||||
|
m_isRichText: 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!114 &4780358684561283937
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4648993278565750863}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1fa7f5f3910b010489199ef7ddee773e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_kind: 7
|
||||||
|
_overrideFontSize: 0
|
||||||
|
--- !u!1 &4798970077294940872
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 7145670357572348738}
|
||||||
|
- component: {fileID: 4133336030444025929}
|
||||||
|
- component: {fileID: 5784682159282604535}
|
||||||
|
- component: {fileID: 2876723545713027670}
|
||||||
|
- component: {fileID: 2961568203053643187}
|
||||||
|
- component: {fileID: 4023577034128914888}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: UI_Control_Button
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &7145670357572348738
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4798970077294940872}
|
||||||
|
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: 7434669335039776586}
|
||||||
|
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: 200, y: 48}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &4133336030444025929
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4798970077294940872}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &5784682159282604535
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4798970077294940872}
|
||||||
|
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: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Type: 1
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 1
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!114 &2876723545713027670
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4798970077294940872}
|
||||||
|
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: 0.1, g: 0.55, b: 0.95, a: 1}
|
||||||
|
m_HighlightedColor: {r: 0.208, g: 0.60400003, b: 0.956, a: 1}
|
||||||
|
m_PressedColor: {r: 0.085, g: 0.4675, b: 0.8075, a: 1}
|
||||||
|
m_SelectedColor: {r: 0.208, g: 0.60400003, b: 0.956, a: 1}
|
||||||
|
m_DisabledColor: {r: 0.3, g: 0.3, b: 0.32, a: 1}
|
||||||
|
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: 5784682159282604535}
|
||||||
|
m_OnClick:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
--- !u!114 &2961568203053643187
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4798970077294940872}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 270b0a121b06dfc4587c060335f18432, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_variant: 0
|
||||||
|
_theme: {fileID: 11400000, guid: 88bab5495f6103f4d9d69fa043d4c3e1, type: 2}
|
||||||
|
_scaleFeedback: 1
|
||||||
|
_selectedScale: 1.06
|
||||||
|
_scaleDuration: 0.08
|
||||||
|
_onClickSfx: {fileID: 0}
|
||||||
|
_onHoverSfx: {fileID: 0}
|
||||||
|
--- !u!114 &4023577034128914888
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4798970077294940872}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1fa7f5f3910b010489199ef7ddee773e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_kind: 11
|
||||||
|
_overrideFontSize: 0
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: af94b3795e225b54985a0c4d6a2f4aa9
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
1206
Assets/_Game/Prefabs/UI/Controls/UI_Control_Dropdown.prefab
Normal file
1206
Assets/_Game/Prefabs/UI/Controls/UI_Control_Dropdown.prefab
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c96b1f39a48501e48954175108c896c0
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
287
Assets/_Game/Prefabs/UI/Controls/UI_Control_Panel.prefab
Normal file
287
Assets/_Game/Prefabs/UI/Controls/UI_Control_Panel.prefab
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &7491264101481992626
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1404081159922799881}
|
||||||
|
- component: {fileID: 6930878104455828636}
|
||||||
|
- component: {fileID: 6084647886258874521}
|
||||||
|
- component: {fileID: 6384349683107319821}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Title
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &1404081159922799881
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7491264101481992626}
|
||||||
|
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: 2078232494173195539}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 1}
|
||||||
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 0, y: -16}
|
||||||
|
m_SizeDelta: {x: -32, y: 40}
|
||||||
|
m_Pivot: {x: 0.5, y: 1}
|
||||||
|
--- !u!222 &6930878104455828636
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7491264101481992626}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &6084647886258874521
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7491264101481992626}
|
||||||
|
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: Panel
|
||||||
|
m_isRightToLeft: 0
|
||||||
|
m_fontAsset: {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
|
m_sharedMaterial: {fileID: 1445647621079294416, guid: c9ebf78286d2b6345b16575012502acc, 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: 0
|
||||||
|
m_overrideHtmlColors: 0
|
||||||
|
m_faceColor:
|
||||||
|
serializedVersion: 2
|
||||||
|
rgba: 4294967295
|
||||||
|
m_fontSize: 28
|
||||||
|
m_fontSizeBase: 28
|
||||||
|
m_fontWeight: 400
|
||||||
|
m_enableAutoSizing: 0
|
||||||
|
m_fontSizeMin: 18
|
||||||
|
m_fontSizeMax: 72
|
||||||
|
m_fontStyle: 0
|
||||||
|
m_HorizontalAlignment: 2
|
||||||
|
m_VerticalAlignment: 256
|
||||||
|
m_textAlignment: 65535
|
||||||
|
m_characterSpacing: 0
|
||||||
|
m_wordSpacing: 0
|
||||||
|
m_lineSpacing: 0
|
||||||
|
m_lineSpacingMax: 0
|
||||||
|
m_paragraphSpacing: 0
|
||||||
|
m_charWidthMaxAdj: 0
|
||||||
|
m_enableWordWrapping: 1
|
||||||
|
m_wordWrappingRatios: 0.4
|
||||||
|
m_overflowMode: 0
|
||||||
|
m_linkedTextComponent: {fileID: 0}
|
||||||
|
parentLinkedComponent: {fileID: 0}
|
||||||
|
m_enableKerning: 1
|
||||||
|
m_enableExtraPadding: 0
|
||||||
|
checkPaddingRequired: 0
|
||||||
|
m_isRichText: 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!114 &6384349683107319821
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7491264101481992626}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1fa7f5f3910b010489199ef7ddee773e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_kind: 9
|
||||||
|
_overrideFontSize: 0
|
||||||
|
--- !u!1 &8217544468495105350
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 2078232494173195539}
|
||||||
|
- component: {fileID: 7015213363194495042}
|
||||||
|
- component: {fileID: 2221117938118938275}
|
||||||
|
- component: {fileID: 1182987514380032191}
|
||||||
|
- component: {fileID: 7022297426914789910}
|
||||||
|
- component: {fileID: 1174997407675126460}
|
||||||
|
- component: {fileID: 8682268969386925379}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: UI_Control_Panel
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &2078232494173195539
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8217544468495105350}
|
||||||
|
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: 1404081159922799881}
|
||||||
|
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: 480, y: 320}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &7015213363194495042
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8217544468495105350}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &2221117938118938275
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8217544468495105350}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 0.06, g: 0.07, b: 0.1, a: 0.96}
|
||||||
|
m_RaycastTarget: 1
|
||||||
|
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_Maskable: 1
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Type: 1
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 1
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!114 &1182987514380032191
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8217544468495105350}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1fa7f5f3910b010489199ef7ddee773e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_kind: 3
|
||||||
|
_overrideFontSize: 0
|
||||||
|
--- !u!225 &7022297426914789910
|
||||||
|
CanvasGroup:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8217544468495105350}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_Alpha: 1
|
||||||
|
m_Interactable: 1
|
||||||
|
m_BlocksRaycasts: 1
|
||||||
|
m_IgnoreParentGroups: 0
|
||||||
|
--- !u!114 &1174997407675126460
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8217544468495105350}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 50572ad108fd3354da04ea8fba66370b, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_theme: {fileID: 11400000, guid: 88bab5495f6103f4d9d69fa043d4c3e1, type: 2}
|
||||||
|
_applyOnEnable: 1
|
||||||
|
--- !u!114 &8682268969386925379
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8217544468495105350}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: c6fa4cf81d2fd2e46b0d922f7b55097c, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_firstSelected: {fileID: 0}
|
||||||
|
_canvasGroup: {fileID: 7022297426914789910}
|
||||||
|
_fadeInDuration: 0.15
|
||||||
|
_selectFirstOnEnable: 1
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9f0d13c44b1b5484b86746e3d696bb79
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
456
Assets/_Game/Prefabs/UI/Controls/UI_Control_SelectableRow.prefab
Normal file
456
Assets/_Game/Prefabs/UI/Controls/UI_Control_SelectableRow.prefab
Normal file
@@ -0,0 +1,456 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &477095832022680696
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 2056370201300175144}
|
||||||
|
- component: {fileID: 9132335891156628336}
|
||||||
|
- component: {fileID: 5198911377577739583}
|
||||||
|
- component: {fileID: 5619472571537383739}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Label
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &2056370201300175144
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 477095832022680696}
|
||||||
|
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: 3293627937247209068}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 20, y: 0}
|
||||||
|
m_SizeDelta: {x: -64, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &9132335891156628336
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 477095832022680696}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &5198911377577739583
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 477095832022680696}
|
||||||
|
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: Row
|
||||||
|
m_isRightToLeft: 0
|
||||||
|
m_fontAsset: {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
|
m_sharedMaterial: {fileID: 1445647621079294416, guid: c9ebf78286d2b6345b16575012502acc, 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: 0
|
||||||
|
m_overrideHtmlColors: 0
|
||||||
|
m_faceColor:
|
||||||
|
serializedVersion: 2
|
||||||
|
rgba: 4294967295
|
||||||
|
m_fontSize: 20
|
||||||
|
m_fontSizeBase: 20
|
||||||
|
m_fontWeight: 400
|
||||||
|
m_enableAutoSizing: 0
|
||||||
|
m_fontSizeMin: 18
|
||||||
|
m_fontSizeMax: 72
|
||||||
|
m_fontStyle: 0
|
||||||
|
m_HorizontalAlignment: 1
|
||||||
|
m_VerticalAlignment: 4096
|
||||||
|
m_textAlignment: 65535
|
||||||
|
m_characterSpacing: 0
|
||||||
|
m_wordSpacing: 0
|
||||||
|
m_lineSpacing: 0
|
||||||
|
m_lineSpacingMax: 0
|
||||||
|
m_paragraphSpacing: 0
|
||||||
|
m_charWidthMaxAdj: 0
|
||||||
|
m_enableWordWrapping: 1
|
||||||
|
m_wordWrappingRatios: 0.4
|
||||||
|
m_overflowMode: 0
|
||||||
|
m_linkedTextComponent: {fileID: 0}
|
||||||
|
parentLinkedComponent: {fileID: 0}
|
||||||
|
m_enableKerning: 1
|
||||||
|
m_enableExtraPadding: 0
|
||||||
|
checkPaddingRequired: 0
|
||||||
|
m_isRichText: 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!114 &5619472571537383739
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 477095832022680696}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1fa7f5f3910b010489199ef7ddee773e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_kind: 7
|
||||||
|
_overrideFontSize: 0
|
||||||
|
--- !u!1 &526907397050529052
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 805913492557441718}
|
||||||
|
- component: {fileID: 5420200537658845125}
|
||||||
|
- component: {fileID: 1739625167890660215}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Icon
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &805913492557441718
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 526907397050529052}
|
||||||
|
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: 3293627937247209068}
|
||||||
|
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: 10, y: 0}
|
||||||
|
m_SizeDelta: {x: 32, y: 32}
|
||||||
|
m_Pivot: {x: 0, y: 0.5}
|
||||||
|
--- !u!222 &5420200537658845125
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 526907397050529052}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &1739625167890660215
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 526907397050529052}
|
||||||
|
m_Enabled: 0
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_RaycastTarget: 1
|
||||||
|
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_Maskable: 1
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_Sprite: {fileID: 0}
|
||||||
|
m_Type: 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!1 &3831138589626733696
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4051871124872751768}
|
||||||
|
- component: {fileID: 7168122679137864546}
|
||||||
|
- component: {fileID: 5561835652314978329}
|
||||||
|
- component: {fileID: 7120742326677395016}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: SelectedHighlight
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 0
|
||||||
|
--- !u!224 &4051871124872751768
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3831138589626733696}
|
||||||
|
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: 3293627937247209068}
|
||||||
|
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 &7168122679137864546
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3831138589626733696}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &5561835652314978329
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3831138589626733696}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 0.2, g: 0.65, b: 1, a: 0.35}
|
||||||
|
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 &7120742326677395016
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3831138589626733696}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1fa7f5f3910b010489199ef7ddee773e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_kind: 2
|
||||||
|
_overrideFontSize: 0
|
||||||
|
--- !u!1 &6596140938478677270
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 3293627937247209068}
|
||||||
|
- component: {fileID: 2266986535621667995}
|
||||||
|
- component: {fileID: 4173014312274757759}
|
||||||
|
- component: {fileID: 9054154986878635174}
|
||||||
|
- component: {fileID: 2527815508985184034}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: UI_Control_SelectableRow
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &3293627937247209068
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6596140938478677270}
|
||||||
|
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: 4051871124872751768}
|
||||||
|
- {fileID: 805913492557441718}
|
||||||
|
- {fileID: 2056370201300175144}
|
||||||
|
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: 320, y: 48}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &2266986535621667995
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6596140938478677270}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &4173014312274757759
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6596140938478677270}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 0.06}
|
||||||
|
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: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Type: 1
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 1
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!114 &9054154986878635174
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6596140938478677270}
|
||||||
|
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: 4173014312274757759}
|
||||||
|
m_OnClick:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
--- !u!114 &2527815508985184034
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6596140938478677270}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 64037ec2ca4c93d40908480eb137ccf3, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_button: {fileID: 9054154986878635174}
|
||||||
|
_label: {fileID: 5198911377577739583}
|
||||||
|
_icon: {fileID: 1739625167890660215}
|
||||||
|
_selectedHighlight: {fileID: 3831138589626733696}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6885ddbf2204e1e49a91ac277cad4e90
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
555
Assets/_Game/Prefabs/UI/Controls/UI_Control_Slider.prefab
Normal file
555
Assets/_Game/Prefabs/UI/Controls/UI_Control_Slider.prefab
Normal file
@@ -0,0 +1,555 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &2892246082093230636
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 6777873855412127507}
|
||||||
|
- component: {fileID: 7943591468316354171}
|
||||||
|
- component: {fileID: 6718276243346542542}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Fill
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &6777873855412127507
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2892246082093230636}
|
||||||
|
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: 2856380859823679016}
|
||||||
|
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: 10, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &7943591468316354171
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2892246082093230636}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &6718276243346542542
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2892246082093230636}
|
||||||
|
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: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Type: 1
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 1
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!1 &2955367232293863162
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 2856380859823679016}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Fill Area
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &2856380859823679016
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2955367232293863162}
|
||||||
|
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: 6777873855412127507}
|
||||||
|
m_Father: {fileID: 4890485910657195775}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0.25}
|
||||||
|
m_AnchorMax: {x: 1, y: 0.75}
|
||||||
|
m_AnchoredPosition: {x: -5, y: 0}
|
||||||
|
m_SizeDelta: {x: -20, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!1 &3036624611908829816
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4890485910657195775}
|
||||||
|
- component: {fileID: 6009437737723481310}
|
||||||
|
- component: {fileID: 5243221914320319692}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: UI_Control_Slider
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &4890485910657195775
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3036624611908829816}
|
||||||
|
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: 6906943864500586170}
|
||||||
|
- {fileID: 2856380859823679016}
|
||||||
|
- {fileID: 3504415066853500042}
|
||||||
|
- {fileID: 3560607011362116889}
|
||||||
|
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: 240, y: 24}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &6009437737723481310
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3036624611908829816}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 67db9e8f0e2ae9c40bc1e2b64352a6b4, 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: 3074083777787071048}
|
||||||
|
m_FillRect: {fileID: 6777873855412127507}
|
||||||
|
m_HandleRect: {fileID: 8095715524730652885}
|
||||||
|
m_Direction: 0
|
||||||
|
m_MinValue: 0
|
||||||
|
m_MaxValue: 1
|
||||||
|
m_WholeNumbers: 0
|
||||||
|
m_Value: 0
|
||||||
|
m_OnValueChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
--- !u!114 &5243221914320319692
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3036624611908829816}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: a1743e750e4f79c43b64e07a1c1a7270, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_slider: {fileID: 6009437737723481310}
|
||||||
|
_valueLabel: {fileID: 5727754088110451924}
|
||||||
|
_format: '{0:0}'
|
||||||
|
--- !u!1 &3158898647431107578
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 3560607011362116889}
|
||||||
|
- component: {fileID: 6883055686052382372}
|
||||||
|
- component: {fileID: 5727754088110451924}
|
||||||
|
- component: {fileID: 8457252421405363693}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: ValueLabel
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &3560607011362116889
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3158898647431107578}
|
||||||
|
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: 4890485910657195775}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 1, y: 0.5}
|
||||||
|
m_AnchorMax: {x: 1, y: 0.5}
|
||||||
|
m_AnchoredPosition: {x: 8, y: 0}
|
||||||
|
m_SizeDelta: {x: 48, y: 24}
|
||||||
|
m_Pivot: {x: 0, y: 0.5}
|
||||||
|
--- !u!222 &6883055686052382372
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3158898647431107578}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &5727754088110451924
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3158898647431107578}
|
||||||
|
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: 0
|
||||||
|
m_isRightToLeft: 0
|
||||||
|
m_fontAsset: {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
|
m_sharedMaterial: {fileID: 1445647621079294416, guid: c9ebf78286d2b6345b16575012502acc, 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: 0
|
||||||
|
m_overrideHtmlColors: 0
|
||||||
|
m_faceColor:
|
||||||
|
serializedVersion: 2
|
||||||
|
rgba: 4294967295
|
||||||
|
m_fontSize: 18
|
||||||
|
m_fontSizeBase: 18
|
||||||
|
m_fontWeight: 400
|
||||||
|
m_enableAutoSizing: 0
|
||||||
|
m_fontSizeMin: 18
|
||||||
|
m_fontSizeMax: 72
|
||||||
|
m_fontStyle: 0
|
||||||
|
m_HorizontalAlignment: 1
|
||||||
|
m_VerticalAlignment: 4096
|
||||||
|
m_textAlignment: 65535
|
||||||
|
m_characterSpacing: 0
|
||||||
|
m_wordSpacing: 0
|
||||||
|
m_lineSpacing: 0
|
||||||
|
m_lineSpacingMax: 0
|
||||||
|
m_paragraphSpacing: 0
|
||||||
|
m_charWidthMaxAdj: 0
|
||||||
|
m_enableWordWrapping: 1
|
||||||
|
m_wordWrappingRatios: 0.4
|
||||||
|
m_overflowMode: 0
|
||||||
|
m_linkedTextComponent: {fileID: 0}
|
||||||
|
parentLinkedComponent: {fileID: 0}
|
||||||
|
m_enableKerning: 1
|
||||||
|
m_enableExtraPadding: 0
|
||||||
|
checkPaddingRequired: 0
|
||||||
|
m_isRichText: 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!114 &8457252421405363693
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3158898647431107578}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1fa7f5f3910b010489199ef7ddee773e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_kind: 8
|
||||||
|
_overrideFontSize: 0
|
||||||
|
--- !u!1 &6664664133928497365
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 6906943864500586170}
|
||||||
|
- component: {fileID: 1618532266414389766}
|
||||||
|
- component: {fileID: 5860135118569899921}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Background
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &6906943864500586170
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6664664133928497365}
|
||||||
|
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: 4890485910657195775}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0.25}
|
||||||
|
m_AnchorMax: {x: 1, y: 0.75}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 0, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &1618532266414389766
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6664664133928497365}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &5860135118569899921
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6664664133928497365}
|
||||||
|
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: 10907, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Type: 1
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 1
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!1 &7693947586556550140
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 8095715524730652885}
|
||||||
|
- component: {fileID: 3392477586643606721}
|
||||||
|
- component: {fileID: 3074083777787071048}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Handle
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &8095715524730652885
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7693947586556550140}
|
||||||
|
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: 3504415066853500042}
|
||||||
|
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: 20, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &3392477586643606721
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7693947586556550140}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &3074083777787071048
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7693947586556550140}
|
||||||
|
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: 10913, guid: 0000000000000000f000000000000000, type: 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!1 &9211551707266728646
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 3504415066853500042}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Handle Slide Area
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &3504415066853500042
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 9211551707266728646}
|
||||||
|
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: 8095715524730652885}
|
||||||
|
m_Father: {fileID: 4890485910657195775}
|
||||||
|
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: -20, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 535b57c53e471bb4c9a2d7940b5ad20a
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
1316
Assets/_Game/Prefabs/UI/Controls/UI_Control_TabBar.prefab
Normal file
1316
Assets/_Game/Prefabs/UI/Controls/UI_Control_TabBar.prefab
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 728889ae05c256f4ca5669ec31fa5be6
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
400
Assets/_Game/Prefabs/UI/Controls/UI_MainMenu_Button.prefab
Normal file
400
Assets/_Game/Prefabs/UI/Controls/UI_MainMenu_Button.prefab
Normal file
@@ -0,0 +1,400 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &157705238739733498
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 7174374360084985875}
|
||||||
|
- component: {fileID: 1331274105184499728}
|
||||||
|
- component: {fileID: 3042592292942350693}
|
||||||
|
- component: {fileID: 3321591285440411207}
|
||||||
|
- component: {fileID: 1171217503679730641}
|
||||||
|
- component: {fileID: 6247134819645328346}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: UI_MainMenu_Button
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &7174374360084985875
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 157705238739733498}
|
||||||
|
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: 813307877032466524}
|
||||||
|
- {fileID: 2269043522301662760}
|
||||||
|
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: 300, y: 56}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &1331274105184499728
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 157705238739733498}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &3042592292942350693
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 157705238739733498}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 0.06}
|
||||||
|
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: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Type: 1
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 1
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!114 &3321591285440411207
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 157705238739733498}
|
||||||
|
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: 0.1, g: 0.55, b: 0.95, a: 1}
|
||||||
|
m_HighlightedColor: {r: 0.208, g: 0.60400003, b: 0.956, a: 1}
|
||||||
|
m_PressedColor: {r: 0.085, g: 0.4675, b: 0.8075, a: 1}
|
||||||
|
m_SelectedColor: {r: 0.208, g: 0.60400003, b: 0.956, a: 1}
|
||||||
|
m_DisabledColor: {r: 0.3, g: 0.3, b: 0.32, a: 1}
|
||||||
|
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: 3042592292942350693}
|
||||||
|
m_OnClick:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
--- !u!114 &1171217503679730641
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 157705238739733498}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 270b0a121b06dfc4587c060335f18432, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_variant: 0
|
||||||
|
_theme: {fileID: 11400000, guid: 88bab5495f6103f4d9d69fa043d4c3e1, type: 2}
|
||||||
|
_scaleFeedback: 1
|
||||||
|
_selectedScale: 1.06
|
||||||
|
_scaleDuration: 0.08
|
||||||
|
_onClickSfx: {fileID: 0}
|
||||||
|
_onHoverSfx: {fileID: 0}
|
||||||
|
--- !u!114 &6247134819645328346
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 157705238739733498}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: aa83d8ead83f78b428cdd2b0d1a89aa7, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_button: {fileID: 3321591285440411207}
|
||||||
|
_label: {fileID: 5199662468546267514}
|
||||||
|
_icon: {fileID: 3358762196943047451}
|
||||||
|
--- !u!1 &1456531517881710782
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 813307877032466524}
|
||||||
|
- component: {fileID: 6811148169943758410}
|
||||||
|
- component: {fileID: 3358762196943047451}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Icon
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &813307877032466524
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1456531517881710782}
|
||||||
|
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: 7174374360084985875}
|
||||||
|
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: 14, y: 0}
|
||||||
|
m_SizeDelta: {x: 32, y: 32}
|
||||||
|
m_Pivot: {x: 0, y: 0.5}
|
||||||
|
--- !u!222 &6811148169943758410
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1456531517881710782}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &3358762196943047451
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1456531517881710782}
|
||||||
|
m_Enabled: 0
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_RaycastTarget: 1
|
||||||
|
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_Maskable: 1
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_Sprite: {fileID: 0}
|
||||||
|
m_Type: 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!1 &6871540172822531622
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 2269043522301662760}
|
||||||
|
- component: {fileID: 9060446448532800869}
|
||||||
|
- component: {fileID: 1310292088589468557}
|
||||||
|
- component: {fileID: 5199662468546267514}
|
||||||
|
- component: {fileID: 4564880767979808658}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Label
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &2269043522301662760
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6871540172822531622}
|
||||||
|
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: 7174374360084985875}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 22, y: 0}
|
||||||
|
m_SizeDelta: {x: -68, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &9060446448532800869
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6871540172822531622}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &1310292088589468557
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6871540172822531622}
|
||||||
|
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: Menu Item
|
||||||
|
m_isRightToLeft: 0
|
||||||
|
m_fontAsset: {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
|
m_sharedMaterial: {fileID: 1445647621079294416, guid: c9ebf78286d2b6345b16575012502acc, 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: 0
|
||||||
|
m_overrideHtmlColors: 0
|
||||||
|
m_faceColor:
|
||||||
|
serializedVersion: 2
|
||||||
|
rgba: 4294967295
|
||||||
|
m_fontSize: 24
|
||||||
|
m_fontSizeBase: 24
|
||||||
|
m_fontWeight: 400
|
||||||
|
m_enableAutoSizing: 0
|
||||||
|
m_fontSizeMin: 18
|
||||||
|
m_fontSizeMax: 72
|
||||||
|
m_fontStyle: 0
|
||||||
|
m_HorizontalAlignment: 1
|
||||||
|
m_VerticalAlignment: 4096
|
||||||
|
m_textAlignment: 65535
|
||||||
|
m_characterSpacing: 0
|
||||||
|
m_wordSpacing: 0
|
||||||
|
m_lineSpacing: 0
|
||||||
|
m_lineSpacingMax: 0
|
||||||
|
m_paragraphSpacing: 0
|
||||||
|
m_charWidthMaxAdj: 0
|
||||||
|
m_enableWordWrapping: 1
|
||||||
|
m_wordWrappingRatios: 0.4
|
||||||
|
m_overflowMode: 0
|
||||||
|
m_linkedTextComponent: {fileID: 0}
|
||||||
|
parentLinkedComponent: {fileID: 0}
|
||||||
|
m_enableKerning: 1
|
||||||
|
m_enableExtraPadding: 0
|
||||||
|
checkPaddingRequired: 0
|
||||||
|
m_isRichText: 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!114 &5199662468546267514
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6871540172822531622}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 964e3a3ab86805244bbde47d5f54950b, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_key:
|
||||||
|
_table: UI
|
||||||
|
_fontConfig: {fileID: 0}
|
||||||
|
--- !u!114 &4564880767979808658
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6871540172822531622}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1fa7f5f3910b010489199ef7ddee773e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_kind: 7
|
||||||
|
_overrideFontSize: 0
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e2fb1298d0d8c754e9329131507a17ee
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
1477
Assets/_Game/Prefabs/UI/Controls/UI_Setting_DropdownRow.prefab
Normal file
1477
Assets/_Game/Prefabs/UI/Controls/UI_Setting_DropdownRow.prefab
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ddba9af2988598d4fa913c21792ed775
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
203
Assets/_Game/Prefabs/UI/Controls/UI_Setting_Header.prefab
Normal file
203
Assets/_Game/Prefabs/UI/Controls/UI_Setting_Header.prefab
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &289442062472622113
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1188174262370179090}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: UI_Setting_Header
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &1188174262370179090
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 289442062472622113}
|
||||||
|
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: 5268560256912078874}
|
||||||
|
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: 480, y: 32}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!1 &6990715320569207602
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 5268560256912078874}
|
||||||
|
- component: {fileID: 9164091955681480904}
|
||||||
|
- component: {fileID: 3435145567134533558}
|
||||||
|
- component: {fileID: 7268257288245050301}
|
||||||
|
- component: {fileID: 7398263746022830265}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Label
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &5268560256912078874
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6990715320569207602}
|
||||||
|
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: 1188174262370179090}
|
||||||
|
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 &9164091955681480904
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6990715320569207602}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &3435145567134533558
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6990715320569207602}
|
||||||
|
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: Section
|
||||||
|
m_isRightToLeft: 0
|
||||||
|
m_fontAsset: {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
|
m_sharedMaterial: {fileID: 1445647621079294416, guid: c9ebf78286d2b6345b16575012502acc, 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: 0
|
||||||
|
m_overrideHtmlColors: 0
|
||||||
|
m_faceColor:
|
||||||
|
serializedVersion: 2
|
||||||
|
rgba: 4294967295
|
||||||
|
m_fontSize: 22
|
||||||
|
m_fontSizeBase: 22
|
||||||
|
m_fontWeight: 400
|
||||||
|
m_enableAutoSizing: 0
|
||||||
|
m_fontSizeMin: 18
|
||||||
|
m_fontSizeMax: 72
|
||||||
|
m_fontStyle: 0
|
||||||
|
m_HorizontalAlignment: 1
|
||||||
|
m_VerticalAlignment: 4096
|
||||||
|
m_textAlignment: 65535
|
||||||
|
m_characterSpacing: 0
|
||||||
|
m_wordSpacing: 0
|
||||||
|
m_lineSpacing: 0
|
||||||
|
m_lineSpacingMax: 0
|
||||||
|
m_paragraphSpacing: 0
|
||||||
|
m_charWidthMaxAdj: 0
|
||||||
|
m_enableWordWrapping: 1
|
||||||
|
m_wordWrappingRatios: 0.4
|
||||||
|
m_overflowMode: 0
|
||||||
|
m_linkedTextComponent: {fileID: 0}
|
||||||
|
parentLinkedComponent: {fileID: 0}
|
||||||
|
m_enableKerning: 1
|
||||||
|
m_enableExtraPadding: 0
|
||||||
|
checkPaddingRequired: 0
|
||||||
|
m_isRichText: 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!114 &7268257288245050301
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6990715320569207602}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 964e3a3ab86805244bbde47d5f54950b, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_key:
|
||||||
|
_table: UI
|
||||||
|
_fontConfig: {fileID: 0}
|
||||||
|
--- !u!114 &7398263746022830265
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6990715320569207602}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1fa7f5f3910b010489199ef7ddee773e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_kind: 9
|
||||||
|
_overrideFontSize: 0
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1fc36ce46442d804189dcff0e57157e8
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
847
Assets/_Game/Prefabs/UI/Controls/UI_Setting_SliderRow.prefab
Normal file
847
Assets/_Game/Prefabs/UI/Controls/UI_Setting_SliderRow.prefab
Normal file
@@ -0,0 +1,847 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &1070957217287351926
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 3792209296828831907}
|
||||||
|
- component: {fileID: 1959550421015514039}
|
||||||
|
- component: {fileID: 9051068453793032797}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Fill
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &3792209296828831907
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1070957217287351926}
|
||||||
|
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: 2658611266293307845}
|
||||||
|
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: 10, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &1959550421015514039
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1070957217287351926}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &9051068453793032797
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1070957217287351926}
|
||||||
|
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: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Type: 1
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 1
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!1 &2702037931686343815
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 3542422590775939441}
|
||||||
|
- component: {fileID: 4479914283644628608}
|
||||||
|
- component: {fileID: 6067219681297384585}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Background
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &3542422590775939441
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2702037931686343815}
|
||||||
|
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: 3284263899435988708}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0.25}
|
||||||
|
m_AnchorMax: {x: 1, y: 0.75}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 0, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &4479914283644628608
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2702037931686343815}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &6067219681297384585
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2702037931686343815}
|
||||||
|
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: 10907, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Type: 1
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 1
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!1 &5544342181587606156
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 7336571758001316545}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Handle Slide Area
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &7336571758001316545
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 5544342181587606156}
|
||||||
|
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: 3732250768482148382}
|
||||||
|
m_Father: {fileID: 3284263899435988708}
|
||||||
|
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: -20, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!1 &6130680863292913750
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 3284263899435988708}
|
||||||
|
- component: {fileID: 6020905755306608269}
|
||||||
|
- component: {fileID: 7951912803875530729}
|
||||||
|
- component: {fileID: 4658929192453894749}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Slider
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &3284263899435988708
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6130680863292913750}
|
||||||
|
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: 3542422590775939441}
|
||||||
|
- {fileID: 2658611266293307845}
|
||||||
|
- {fileID: 7336571758001316545}
|
||||||
|
m_Father: {fileID: 534764500401432470}
|
||||||
|
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: 160, y: 20}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &6020905755306608269
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6130680863292913750}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 67db9e8f0e2ae9c40bc1e2b64352a6b4, 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: 2099364674220670182}
|
||||||
|
m_FillRect: {fileID: 3792209296828831907}
|
||||||
|
m_HandleRect: {fileID: 3732250768482148382}
|
||||||
|
m_Direction: 0
|
||||||
|
m_MinValue: 0
|
||||||
|
m_MaxValue: 1
|
||||||
|
m_WholeNumbers: 0
|
||||||
|
m_Value: 0
|
||||||
|
m_OnValueChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
--- !u!114 &7951912803875530729
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6130680863292913750}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_IgnoreLayout: 0
|
||||||
|
m_MinWidth: -1
|
||||||
|
m_MinHeight: -1
|
||||||
|
m_PreferredWidth: -1
|
||||||
|
m_PreferredHeight: 20
|
||||||
|
m_FlexibleWidth: 1
|
||||||
|
m_FlexibleHeight: -1
|
||||||
|
m_LayoutPriority: 1
|
||||||
|
--- !u!114 &4658929192453894749
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6130680863292913750}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: a1743e750e4f79c43b64e07a1c1a7270, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_slider: {fileID: 6020905755306608269}
|
||||||
|
_valueLabel: {fileID: 4351432712411767913}
|
||||||
|
_format: '{0:0}'
|
||||||
|
--- !u!1 &6513111251415266017
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 685461569274276067}
|
||||||
|
- component: {fileID: 2028758860801033200}
|
||||||
|
- component: {fileID: 8112916051202351531}
|
||||||
|
- component: {fileID: 4375017972804521103}
|
||||||
|
- component: {fileID: 6653917221928333869}
|
||||||
|
- component: {fileID: 2065978793198596394}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Label
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &685461569274276067
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6513111251415266017}
|
||||||
|
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: 534764500401432470}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 0, y: 0}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 0, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &2028758860801033200
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6513111251415266017}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &8112916051202351531
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6513111251415266017}
|
||||||
|
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: Label
|
||||||
|
m_isRightToLeft: 0
|
||||||
|
m_fontAsset: {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
|
m_sharedMaterial: {fileID: 1445647621079294416, guid: c9ebf78286d2b6345b16575012502acc, 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: 20
|
||||||
|
m_fontSizeBase: 20
|
||||||
|
m_fontWeight: 400
|
||||||
|
m_enableAutoSizing: 0
|
||||||
|
m_fontSizeMin: 18
|
||||||
|
m_fontSizeMax: 72
|
||||||
|
m_fontStyle: 0
|
||||||
|
m_HorizontalAlignment: 1
|
||||||
|
m_VerticalAlignment: 4096
|
||||||
|
m_textAlignment: 65535
|
||||||
|
m_characterSpacing: 0
|
||||||
|
m_wordSpacing: 0
|
||||||
|
m_lineSpacing: 0
|
||||||
|
m_lineSpacingMax: 0
|
||||||
|
m_paragraphSpacing: 0
|
||||||
|
m_charWidthMaxAdj: 0
|
||||||
|
m_enableWordWrapping: 1
|
||||||
|
m_wordWrappingRatios: 0.4
|
||||||
|
m_overflowMode: 0
|
||||||
|
m_linkedTextComponent: {fileID: 0}
|
||||||
|
parentLinkedComponent: {fileID: 0}
|
||||||
|
m_enableKerning: 1
|
||||||
|
m_enableExtraPadding: 0
|
||||||
|
checkPaddingRequired: 0
|
||||||
|
m_isRichText: 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!114 &4375017972804521103
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6513111251415266017}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_IgnoreLayout: 0
|
||||||
|
m_MinWidth: -1
|
||||||
|
m_MinHeight: -1
|
||||||
|
m_PreferredWidth: 200
|
||||||
|
m_PreferredHeight: -1
|
||||||
|
m_FlexibleWidth: 0
|
||||||
|
m_FlexibleHeight: -1
|
||||||
|
m_LayoutPriority: 1
|
||||||
|
--- !u!114 &6653917221928333869
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6513111251415266017}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 964e3a3ab86805244bbde47d5f54950b, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_key:
|
||||||
|
_table: UI
|
||||||
|
_fontConfig: {fileID: 0}
|
||||||
|
--- !u!114 &2065978793198596394
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6513111251415266017}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1fa7f5f3910b010489199ef7ddee773e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_kind: 7
|
||||||
|
_overrideFontSize: 0
|
||||||
|
--- !u!1 &7479472690954379399
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 3732250768482148382}
|
||||||
|
- component: {fileID: 3467825019843033312}
|
||||||
|
- component: {fileID: 2099364674220670182}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Handle
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &3732250768482148382
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7479472690954379399}
|
||||||
|
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: 7336571758001316545}
|
||||||
|
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: 20, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &3467825019843033312
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7479472690954379399}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &2099364674220670182
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7479472690954379399}
|
||||||
|
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: 10913, guid: 0000000000000000f000000000000000, type: 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!1 &7890162411181439519
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 3800851516441515564}
|
||||||
|
- component: {fileID: 1697561054443252004}
|
||||||
|
- component: {fileID: 4351432712411767913}
|
||||||
|
- component: {fileID: 6893262776634421921}
|
||||||
|
- component: {fileID: 1140659565093859435}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Value
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &3800851516441515564
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7890162411181439519}
|
||||||
|
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: 534764500401432470}
|
||||||
|
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: 200, y: 50}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &1697561054443252004
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7890162411181439519}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &4351432712411767913
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7890162411181439519}
|
||||||
|
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: 0
|
||||||
|
m_isRightToLeft: 0
|
||||||
|
m_fontAsset: {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
|
m_sharedMaterial: {fileID: 1445647621079294416, guid: c9ebf78286d2b6345b16575012502acc, 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: 0
|
||||||
|
m_overrideHtmlColors: 0
|
||||||
|
m_faceColor:
|
||||||
|
serializedVersion: 2
|
||||||
|
rgba: 4294967295
|
||||||
|
m_fontSize: 18
|
||||||
|
m_fontSizeBase: 18
|
||||||
|
m_fontWeight: 400
|
||||||
|
m_enableAutoSizing: 0
|
||||||
|
m_fontSizeMin: 18
|
||||||
|
m_fontSizeMax: 72
|
||||||
|
m_fontStyle: 0
|
||||||
|
m_HorizontalAlignment: 4
|
||||||
|
m_VerticalAlignment: 4096
|
||||||
|
m_textAlignment: 65535
|
||||||
|
m_characterSpacing: 0
|
||||||
|
m_wordSpacing: 0
|
||||||
|
m_lineSpacing: 0
|
||||||
|
m_lineSpacingMax: 0
|
||||||
|
m_paragraphSpacing: 0
|
||||||
|
m_charWidthMaxAdj: 0
|
||||||
|
m_enableWordWrapping: 1
|
||||||
|
m_wordWrappingRatios: 0.4
|
||||||
|
m_overflowMode: 0
|
||||||
|
m_linkedTextComponent: {fileID: 0}
|
||||||
|
parentLinkedComponent: {fileID: 0}
|
||||||
|
m_enableKerning: 1
|
||||||
|
m_enableExtraPadding: 0
|
||||||
|
checkPaddingRequired: 0
|
||||||
|
m_isRichText: 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!114 &6893262776634421921
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7890162411181439519}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_IgnoreLayout: 0
|
||||||
|
m_MinWidth: -1
|
||||||
|
m_MinHeight: -1
|
||||||
|
m_PreferredWidth: 56
|
||||||
|
m_PreferredHeight: -1
|
||||||
|
m_FlexibleWidth: -1
|
||||||
|
m_FlexibleHeight: -1
|
||||||
|
m_LayoutPriority: 1
|
||||||
|
--- !u!114 &1140659565093859435
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7890162411181439519}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1fa7f5f3910b010489199ef7ddee773e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_kind: 8
|
||||||
|
_overrideFontSize: 0
|
||||||
|
--- !u!1 &8494921200535570368
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 2658611266293307845}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Fill Area
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &2658611266293307845
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8494921200535570368}
|
||||||
|
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: 3792209296828831907}
|
||||||
|
m_Father: {fileID: 3284263899435988708}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0.25}
|
||||||
|
m_AnchorMax: {x: 1, y: 0.75}
|
||||||
|
m_AnchoredPosition: {x: -5, y: 0}
|
||||||
|
m_SizeDelta: {x: -20, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!1 &8959349832593751440
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 534764500401432470}
|
||||||
|
- component: {fileID: 1763515077177812284}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: UI_Setting_SliderRow
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &534764500401432470
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8959349832593751440}
|
||||||
|
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: 685461569274276067}
|
||||||
|
- {fileID: 3284263899435988708}
|
||||||
|
- {fileID: 3800851516441515564}
|
||||||
|
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: 480, y: 44}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &1763515077177812284
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8959349832593751440}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Padding:
|
||||||
|
m_Left: 8
|
||||||
|
m_Right: 8
|
||||||
|
m_Top: 4
|
||||||
|
m_Bottom: 4
|
||||||
|
m_ChildAlignment: 3
|
||||||
|
m_Spacing: 12
|
||||||
|
m_ChildForceExpandWidth: 0
|
||||||
|
m_ChildForceExpandHeight: 0
|
||||||
|
m_ChildControlWidth: 1
|
||||||
|
m_ChildControlHeight: 1
|
||||||
|
m_ChildScaleWidth: 0
|
||||||
|
m_ChildScaleHeight: 0
|
||||||
|
m_ReverseArrangement: 0
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b4d11fea678bb244c961f838a48b8d8a
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
589
Assets/_Game/Prefabs/UI/Controls/UI_Setting_ToggleRow.prefab
Normal file
589
Assets/_Game/Prefabs/UI/Controls/UI_Setting_ToggleRow.prefab
Normal file
@@ -0,0 +1,589 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &3995405466752322
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 8196243737921290128}
|
||||||
|
- component: {fileID: 8800226531137800996}
|
||||||
|
- component: {fileID: 942878399107994917}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Background
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &8196243737921290128
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3995405466752322}
|
||||||
|
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: 2656612968632289128}
|
||||||
|
m_Father: {fileID: 6473902974054121827}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 1}
|
||||||
|
m_AnchorMax: {x: 0, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 10, y: -10}
|
||||||
|
m_SizeDelta: {x: 20, y: 20}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &8800226531137800996
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3995405466752322}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &942878399107994917
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3995405466752322}
|
||||||
|
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: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Type: 1
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 1
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!1 &2451954446105504201
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1673254917135424496}
|
||||||
|
- component: {fileID: 4659366053795274176}
|
||||||
|
- component: {fileID: 95609837900800165}
|
||||||
|
- component: {fileID: 1304675786351196457}
|
||||||
|
- component: {fileID: 301319037677175097}
|
||||||
|
- component: {fileID: 3999780911325784356}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Label
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &1673254917135424496
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2451954446105504201}
|
||||||
|
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: 1428818964736103486}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 0, y: 0}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 0, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &4659366053795274176
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2451954446105504201}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &95609837900800165
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2451954446105504201}
|
||||||
|
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: Label
|
||||||
|
m_isRightToLeft: 0
|
||||||
|
m_fontAsset: {fileID: 11400000, guid: c9ebf78286d2b6345b16575012502acc, type: 2}
|
||||||
|
m_sharedMaterial: {fileID: 1445647621079294416, guid: c9ebf78286d2b6345b16575012502acc, 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: 20
|
||||||
|
m_fontSizeBase: 20
|
||||||
|
m_fontWeight: 400
|
||||||
|
m_enableAutoSizing: 0
|
||||||
|
m_fontSizeMin: 18
|
||||||
|
m_fontSizeMax: 72
|
||||||
|
m_fontStyle: 0
|
||||||
|
m_HorizontalAlignment: 1
|
||||||
|
m_VerticalAlignment: 4096
|
||||||
|
m_textAlignment: 65535
|
||||||
|
m_characterSpacing: 0
|
||||||
|
m_wordSpacing: 0
|
||||||
|
m_lineSpacing: 0
|
||||||
|
m_lineSpacingMax: 0
|
||||||
|
m_paragraphSpacing: 0
|
||||||
|
m_charWidthMaxAdj: 0
|
||||||
|
m_enableWordWrapping: 1
|
||||||
|
m_wordWrappingRatios: 0.4
|
||||||
|
m_overflowMode: 0
|
||||||
|
m_linkedTextComponent: {fileID: 0}
|
||||||
|
parentLinkedComponent: {fileID: 0}
|
||||||
|
m_enableKerning: 1
|
||||||
|
m_enableExtraPadding: 0
|
||||||
|
checkPaddingRequired: 0
|
||||||
|
m_isRichText: 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!114 &1304675786351196457
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2451954446105504201}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_IgnoreLayout: 0
|
||||||
|
m_MinWidth: -1
|
||||||
|
m_MinHeight: -1
|
||||||
|
m_PreferredWidth: 200
|
||||||
|
m_PreferredHeight: -1
|
||||||
|
m_FlexibleWidth: 0
|
||||||
|
m_FlexibleHeight: -1
|
||||||
|
m_LayoutPriority: 1
|
||||||
|
--- !u!114 &301319037677175097
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2451954446105504201}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 964e3a3ab86805244bbde47d5f54950b, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_key:
|
||||||
|
_table: UI
|
||||||
|
_fontConfig: {fileID: 0}
|
||||||
|
--- !u!114 &3999780911325784356
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2451954446105504201}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1fa7f5f3910b010489199ef7ddee773e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_kind: 7
|
||||||
|
_overrideFontSize: 0
|
||||||
|
--- !u!1 &3055060066778635686
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1428818964736103486}
|
||||||
|
- component: {fileID: 4398321019914005696}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: UI_Setting_ToggleRow
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &1428818964736103486
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3055060066778635686}
|
||||||
|
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: 1673254917135424496}
|
||||||
|
- {fileID: 6473902974054121827}
|
||||||
|
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: 480, y: 44}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &4398321019914005696
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 3055060066778635686}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Padding:
|
||||||
|
m_Left: 8
|
||||||
|
m_Right: 8
|
||||||
|
m_Top: 4
|
||||||
|
m_Bottom: 4
|
||||||
|
m_ChildAlignment: 3
|
||||||
|
m_Spacing: 12
|
||||||
|
m_ChildForceExpandWidth: 0
|
||||||
|
m_ChildForceExpandHeight: 0
|
||||||
|
m_ChildControlWidth: 1
|
||||||
|
m_ChildControlHeight: 1
|
||||||
|
m_ChildScaleWidth: 0
|
||||||
|
m_ChildScaleHeight: 0
|
||||||
|
m_ReverseArrangement: 0
|
||||||
|
--- !u!1 &4266586670429411161
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 7493993138355221773}
|
||||||
|
- component: {fileID: 7236726997102272855}
|
||||||
|
- component: {fileID: 5058325138044312319}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Label
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &7493993138355221773
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4266586670429411161}
|
||||||
|
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: 6473902974054121827}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 9, y: -0.5}
|
||||||
|
m_SizeDelta: {x: -28, y: -3}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &7236726997102272855
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4266586670429411161}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &5058325138044312319
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4266586670429411161}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, 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_FontData:
|
||||||
|
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
m_FontSize: 14
|
||||||
|
m_FontStyle: 0
|
||||||
|
m_BestFit: 0
|
||||||
|
m_MinSize: 10
|
||||||
|
m_MaxSize: 40
|
||||||
|
m_Alignment: 0
|
||||||
|
m_AlignByGeometry: 0
|
||||||
|
m_RichText: 1
|
||||||
|
m_HorizontalOverflow: 0
|
||||||
|
m_VerticalOverflow: 0
|
||||||
|
m_LineSpacing: 1
|
||||||
|
m_Text: Toggle
|
||||||
|
--- !u!1 &8258555473425308654
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 2656612968632289128}
|
||||||
|
- component: {fileID: 9027761644858669518}
|
||||||
|
- component: {fileID: 6035592076729699155}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Checkmark
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &2656612968632289128
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8258555473425308654}
|
||||||
|
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: 8196243737921290128}
|
||||||
|
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: 20, y: 20}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &9027761644858669518
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8258555473425308654}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &6035592076729699155
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 8258555473425308654}
|
||||||
|
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: 10901, guid: 0000000000000000f000000000000000, type: 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!1 &9090532220244762198
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 6473902974054121827}
|
||||||
|
- component: {fileID: 6356272649930288434}
|
||||||
|
- component: {fileID: 3779328636036996330}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Toggle
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &6473902974054121827
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 9090532220244762198}
|
||||||
|
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: 8196243737921290128}
|
||||||
|
- {fileID: 7493993138355221773}
|
||||||
|
m_Father: {fileID: 1428818964736103486}
|
||||||
|
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: 160, y: 20}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &6356272649930288434
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 9090532220244762198}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, 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: 942878399107994917}
|
||||||
|
toggleTransition: 1
|
||||||
|
graphic: {fileID: 6035592076729699155}
|
||||||
|
m_Group: {fileID: 0}
|
||||||
|
onValueChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_IsOn: 1
|
||||||
|
--- !u!114 &3779328636036996330
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 9090532220244762198}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_IgnoreLayout: 0
|
||||||
|
m_MinWidth: -1
|
||||||
|
m_MinHeight: -1
|
||||||
|
m_PreferredWidth: 30
|
||||||
|
m_PreferredHeight: 30
|
||||||
|
m_FlexibleWidth: -1
|
||||||
|
m_FlexibleHeight: -1
|
||||||
|
m_LayoutPriority: 1
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f8f9f3d7a98b3e5498882a7d28c4cfe5
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
193
Assets/_Game/Prefabs/UI/Controls/UI_SettingsPanel.prefab
Normal file
193
Assets/_Game/Prefabs/UI/Controls/UI_SettingsPanel.prefab
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &2223001114492423287
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 917245127540703404}
|
||||||
|
- component: {fileID: 4391685559759235234}
|
||||||
|
- component: {fileID: 4856692938931279967}
|
||||||
|
- component: {fileID: 3408593224840790089}
|
||||||
|
- component: {fileID: 1073301951202894995}
|
||||||
|
- component: {fileID: 7181543472462533001}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: UI_SettingsPanel
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &917245127540703404
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2223001114492423287}
|
||||||
|
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: 4833472193421351787}
|
||||||
|
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: 540, y: 640}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &4391685559759235234
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2223001114492423287}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &4856692938931279967
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2223001114492423287}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 0.06, g: 0.07, b: 0.1, a: 0.96}
|
||||||
|
m_RaycastTarget: 1
|
||||||
|
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_Maskable: 1
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Type: 1
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 1
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!114 &3408593224840790089
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2223001114492423287}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1fa7f5f3910b010489199ef7ddee773e, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_kind: 3
|
||||||
|
_overrideFontSize: 0
|
||||||
|
--- !u!114 &1073301951202894995
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2223001114492423287}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 50572ad108fd3354da04ea8fba66370b, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_theme: {fileID: 11400000, guid: 88bab5495f6103f4d9d69fa043d4c3e1, type: 2}
|
||||||
|
_applyOnEnable: 1
|
||||||
|
--- !u!114 &7181543472462533001
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2223001114492423287}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: a7cf26a2f7cc5bb49b573bbe9f5614b5, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
_firstSelected: {fileID: 0}
|
||||||
|
_canvasGroup: {fileID: 0}
|
||||||
|
_fadeInDuration: 0.15
|
||||||
|
_selectFirstOnEnable: 1
|
||||||
|
_schema: {fileID: 11400000, guid: e4755a1ee888ca14ab8889635a7d547c, type: 2}
|
||||||
|
_container: {fileID: 4833472193421351787}
|
||||||
|
_headerPrefab: {fileID: 289442062472622113, guid: 1fc36ce46442d804189dcff0e57157e8, type: 3}
|
||||||
|
_sliderRowPrefab: {fileID: 8959349832593751440, guid: b4d11fea678bb244c961f838a48b8d8a, type: 3}
|
||||||
|
_toggleRowPrefab: {fileID: 3055060066778635686, guid: f8f9f3d7a98b3e5498882a7d28c4cfe5, type: 3}
|
||||||
|
_dropdownRowPrefab: {fileID: 2833855665454200082, guid: ddba9af2988598d4fa913c21792ed775, type: 3}
|
||||||
|
--- !u!1 &4104686635909379854
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4833472193421351787}
|
||||||
|
- component: {fileID: 7986706200646771626}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Content
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &4833472193421351787
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4104686635909379854}
|
||||||
|
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: 917245127540703404}
|
||||||
|
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: -32, y: -32}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &7986706200646771626
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4104686635909379854}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Padding:
|
||||||
|
m_Left: 0
|
||||||
|
m_Right: 0
|
||||||
|
m_Top: 0
|
||||||
|
m_Bottom: 0
|
||||||
|
m_ChildAlignment: 1
|
||||||
|
m_Spacing: 6
|
||||||
|
m_ChildForceExpandWidth: 1
|
||||||
|
m_ChildForceExpandHeight: 0
|
||||||
|
m_ChildControlWidth: 1
|
||||||
|
m_ChildControlHeight: 1
|
||||||
|
m_ChildScaleWidth: 0
|
||||||
|
m_ChildScaleHeight: 0
|
||||||
|
m_ReverseArrangement: 0
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: af91076953b254749b310d9184a34d49
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -2013,6 +2013,7 @@ GameObject:
|
|||||||
- component: {fileID: 359293281}
|
- component: {fileID: 359293281}
|
||||||
- component: {fileID: 359293283}
|
- component: {fileID: 359293283}
|
||||||
- component: {fileID: 359293282}
|
- component: {fileID: 359293282}
|
||||||
|
- component: {fileID: 359293284}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: EventSystem
|
m_Name: EventSystem
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@@ -2081,6 +2082,18 @@ MonoBehaviour:
|
|||||||
m_FirstSelected: {fileID: 0}
|
m_FirstSelected: {fileID: 0}
|
||||||
m_sendNavigationEvents: 1
|
m_sendNavigationEvents: 1
|
||||||
m_DragThreshold: 10
|
m_DragThreshold: 10
|
||||||
|
--- !u!114 &359293284
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 359293280}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: a95115526c2b68e469f425df962742e4, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
--- !u!1 &377842515
|
--- !u!1 &377842515
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -4010,9 +4023,6 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 1136785156}
|
m_Script: {fileID: 1136785156}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
_mode: 0
|
|
||||||
_actionName:
|
|
||||||
_bindingPath:
|
|
||||||
--- !u!114 &639737772
|
--- !u!114 &639737772
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@@ -5000,6 +5010,7 @@ GameObject:
|
|||||||
- component: {fileID: 814710354}
|
- component: {fileID: 814710354}
|
||||||
- component: {fileID: 814710353}
|
- component: {fileID: 814710353}
|
||||||
- component: {fileID: 814710352}
|
- component: {fileID: 814710352}
|
||||||
|
- component: {fileID: 814710356}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: Main Camera
|
m_Name: Main Camera
|
||||||
m_TagString: MainCamera
|
m_TagString: MainCamera
|
||||||
@@ -5113,6 +5124,50 @@ Transform:
|
|||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 1800597369}
|
m_Father: {fileID: 1800597369}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &814710356
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 814710351}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_RenderShadows: 1
|
||||||
|
m_RequiresDepthTextureOption: 2
|
||||||
|
m_RequiresOpaqueTextureOption: 2
|
||||||
|
m_CameraType: 0
|
||||||
|
m_Cameras: []
|
||||||
|
m_RendererIndex: -1
|
||||||
|
m_VolumeLayerMask:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 1
|
||||||
|
m_VolumeTrigger: {fileID: 0}
|
||||||
|
m_VolumeFrameworkUpdateModeOption: 2
|
||||||
|
m_RenderPostProcessing: 0
|
||||||
|
m_Antialiasing: 0
|
||||||
|
m_AntialiasingQuality: 2
|
||||||
|
m_StopNaN: 0
|
||||||
|
m_Dithering: 0
|
||||||
|
m_ClearDepth: 1
|
||||||
|
m_AllowXRRendering: 1
|
||||||
|
m_AllowHDROutput: 1
|
||||||
|
m_UseScreenCoordOverride: 0
|
||||||
|
m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_RequiresDepthTexture: 0
|
||||||
|
m_RequiresColorTexture: 0
|
||||||
|
m_Version: 2
|
||||||
|
m_TaaSettings:
|
||||||
|
m_Quality: 3
|
||||||
|
m_FrameInfluence: 0.1
|
||||||
|
m_JitterScale: 1
|
||||||
|
m_MipBias: 0
|
||||||
|
m_VarianceClampScale: 0.9
|
||||||
|
m_ContrastAdaptiveSharpening: 0
|
||||||
--- !u!1 &825595902
|
--- !u!1 &825595902
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using BaseGames.Dialogue;
|
using BaseGames.Dialogue;
|
||||||
|
using BaseGames.Editor.Localization;
|
||||||
|
|
||||||
namespace BaseGames.Editor.Dialogue
|
namespace BaseGames.Editor.Dialogue
|
||||||
{
|
{
|
||||||
@@ -78,30 +79,10 @@ namespace BaseGames.Editor.Dialogue
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 在 Project 窗口中 Ping 指定表名对应的本地化 JSON 文件(Resources/Localization/…/{tableName}.json)。
|
/// 在 Project 窗口中 Ping 指定表名对应的本地化 JSON 文件
|
||||||
/// 遍历所有语言目录,以第一个找到的文件为准。
|
/// (Assets/_Game/Data/Localization/…/{tableName}.json,优先简体中文 → 英文)。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void PingLocalizationFile(string tableName)
|
private static void PingLocalizationFile(string tableName)
|
||||||
{
|
=> LocalizationFileIO.PingAny(tableName);
|
||||||
string[] guids = AssetDatabase.FindAssets(
|
|
||||||
$"t:TextAsset {tableName}",
|
|
||||||
new[] { "Assets/Resources/Localization" });
|
|
||||||
|
|
||||||
foreach (var guid in guids)
|
|
||||||
{
|
|
||||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
|
||||||
// 文件名(不含扩展名)必须完全匹配 tableName
|
|
||||||
if (!path.EndsWith($"/{tableName}.json", System.StringComparison.OrdinalIgnoreCase)) continue;
|
|
||||||
|
|
||||||
var asset = AssetDatabase.LoadAssetAtPath<TextAsset>(path);
|
|
||||||
if (asset == null) continue;
|
|
||||||
|
|
||||||
EditorGUIUtility.PingObject(asset);
|
|
||||||
Selection.activeObject = asset;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug.LogWarning($"[NpcSOEditor] 未找到本地化表文件:Resources/Localization/…/{tableName}.json");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
205
Assets/_Game/Scripts/Editor/Localization/LocalizationCsv.cs
Normal file
205
Assets/_Game/Scripts/Editor/Localization/LocalizationCsv.cs
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using BaseGames.Localization;
|
||||||
|
|
||||||
|
namespace BaseGames.Editor.Localization
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 本地化 CSV(Excel 往返)读写共享工具。
|
||||||
|
///
|
||||||
|
/// CSV 约定:
|
||||||
|
/// - 列顺序:<c>key, ChineseSimplified, English, Japanese, Korean</c>(表头用 <see cref="Language"/> 枚举名)。
|
||||||
|
/// - 以 <b>UTF-8 BOM</b> 写出,使 Excel 双击打开时中日韩文不乱码。
|
||||||
|
/// - 解析遵循 RFC 4180(带引号字段可含逗号 / 换行 / 双引号转义),并自动剥离前导 BOM。
|
||||||
|
/// - 导入语义:合并(覆盖已有 key、追加新 key、不删除多余 key)。
|
||||||
|
/// </summary>
|
||||||
|
public static class LocalizationCsv
|
||||||
|
{
|
||||||
|
/// <summary>导出列顺序(与导入表头解析共用)。</summary>
|
||||||
|
public static readonly Language[] Columns = LocalizationFileIO.AllLanguages;
|
||||||
|
|
||||||
|
// 带 BOM 的 UTF-8(Excel 友好)
|
||||||
|
private static readonly Encoding Utf8Bom = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true);
|
||||||
|
|
||||||
|
// ── 高层:表 ⇄ CSV 文件 ─────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将给定的"语言→字典"导出为该表的 CSV 文件(含 BOM)。返回写出的资产路径。
|
||||||
|
/// </summary>
|
||||||
|
public static string ExportToFile(string table,
|
||||||
|
IReadOnlyDictionary<Language, Dictionary<string, string>> langDicts)
|
||||||
|
{
|
||||||
|
// 汇总所有语言出现过的 key(排序,保证稳定 diff)
|
||||||
|
var allKeys = new SortedSet<string>(StringComparer.Ordinal);
|
||||||
|
foreach (var lang in Columns)
|
||||||
|
if (langDicts.TryGetValue(lang, out var d) && d != null)
|
||||||
|
foreach (var k in d.Keys) allKeys.Add(k);
|
||||||
|
|
||||||
|
string csvText = BuildCsvText(allKeys, langDicts);
|
||||||
|
|
||||||
|
EditorScaffoldUtils.EnsureFolder(LocalizationPaths.ExportRoot);
|
||||||
|
string assetPath = LocalizationPaths.CsvPath(table);
|
||||||
|
File.WriteAllText(ToFullPath(assetPath), csvText, Utf8Bom);
|
||||||
|
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||||
|
return assetPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 读取该表的 CSV 文件并解析为"语言→字典"(仅含表头出现的语言列)。
|
||||||
|
/// CSV 文件不存在时返回 null。
|
||||||
|
/// </summary>
|
||||||
|
public static Dictionary<Language, Dictionary<string, string>> ParseFile(string table)
|
||||||
|
{
|
||||||
|
string assetPath = LocalizationPaths.CsvPath(table);
|
||||||
|
string fullPath = ToFullPath(assetPath);
|
||||||
|
if (!File.Exists(fullPath)) return null;
|
||||||
|
|
||||||
|
return ParseText(File.ReadAllText(fullPath, Encoding.UTF8));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将该表的 CSV 合并写回磁盘 JSON(供批处理工具用):
|
||||||
|
/// 对 CSV 表头出现的每个语言,读现有 JSON → 合并 CSV → <see cref="LocalizationFileIO.Write"/>。
|
||||||
|
/// 返回受影响的语言数;CSV 不存在时返回 0。
|
||||||
|
/// </summary>
|
||||||
|
public static int ImportFileToJson(string table)
|
||||||
|
{
|
||||||
|
var parsed = ParseFile(table);
|
||||||
|
if (parsed == null) return 0;
|
||||||
|
|
||||||
|
foreach (var (lang, csvDict) in parsed)
|
||||||
|
{
|
||||||
|
var merged = LocalizationFileIO.Read(lang, table); // 现有 JSON 副本
|
||||||
|
foreach (var kv in csvDict) merged[kv.Key] = kv.Value;
|
||||||
|
LocalizationFileIO.Write(lang, table, merged);
|
||||||
|
}
|
||||||
|
return parsed.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 低层:文本 ⇄ 行 ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// <summary>构造 CSV 文本(表头 + 数据行,按 allKeys 顺序)。</summary>
|
||||||
|
public static string BuildCsvText(IEnumerable<string> orderedKeys,
|
||||||
|
IReadOnlyDictionary<Language, Dictionary<string, string>> langDicts)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
sb.Append("key");
|
||||||
|
foreach (var lang in Columns) sb.Append(',').Append(lang);
|
||||||
|
sb.Append('\n');
|
||||||
|
|
||||||
|
foreach (var key in orderedKeys)
|
||||||
|
{
|
||||||
|
sb.Append(Escape(key));
|
||||||
|
foreach (var lang in Columns)
|
||||||
|
{
|
||||||
|
string val = "";
|
||||||
|
if (langDicts.TryGetValue(lang, out var d) && d != null)
|
||||||
|
d.TryGetValue(key, out val);
|
||||||
|
sb.Append(',').Append(Escape(val ?? ""));
|
||||||
|
}
|
||||||
|
sb.Append('\n');
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>解析 CSV 文本为"语言→字典"(仅表头识别出的 Language 列)。</summary>
|
||||||
|
public static Dictionary<Language, Dictionary<string, string>> ParseText(string text)
|
||||||
|
{
|
||||||
|
var rows = ParseRows(text);
|
||||||
|
var result = new Dictionary<Language, Dictionary<string, string>>();
|
||||||
|
if (rows.Count < 2) return result;
|
||||||
|
|
||||||
|
// 表头:列号 → Language
|
||||||
|
var header = rows[0];
|
||||||
|
var langCols = new List<(int col, Language lang)>();
|
||||||
|
for (int col = 1; col < header.Count; col++)
|
||||||
|
if (Enum.TryParse<Language>(header[col].Trim(), out var lang))
|
||||||
|
{
|
||||||
|
langCols.Add((col, lang));
|
||||||
|
result[lang] = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int row = 1; row < rows.Count; row++)
|
||||||
|
{
|
||||||
|
var cells = rows[row];
|
||||||
|
if (cells.Count == 0 || string.IsNullOrWhiteSpace(cells[0])) continue;
|
||||||
|
string key = cells[0];
|
||||||
|
foreach (var (col, lang) in langCols)
|
||||||
|
result[lang][key] = col < cells.Count ? cells[col] : "";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>按 RFC 4180 规范转义单元格(含逗号 / 引号 / 换行时用双引号包裹)。</summary>
|
||||||
|
public static string Escape(string value)
|
||||||
|
{
|
||||||
|
if (value == null) return "";
|
||||||
|
bool needsQuote = value.IndexOf(',') >= 0 || value.IndexOf('"') >= 0
|
||||||
|
|| value.IndexOf('\n') >= 0 || value.IndexOf('\r') >= 0;
|
||||||
|
if (!needsQuote) return value;
|
||||||
|
return "\"" + value.Replace("\"", "\"\"") + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>RFC 4180 CSV 解析器,支持带引号字段(含换行),并剥离前导 UTF-8 BOM。</summary>
|
||||||
|
public static List<List<string>> ParseRows(string text)
|
||||||
|
{
|
||||||
|
var rows = new List<List<string>>();
|
||||||
|
if (string.IsNullOrEmpty(text)) return rows;
|
||||||
|
|
||||||
|
// 剥离前导 BOM(File.ReadAllText 以 UTF8 读时若文件带 BOM 会保留为 U+FEFF)
|
||||||
|
if (text[0] == '') text = text.Substring(1);
|
||||||
|
|
||||||
|
var row = new List<string>();
|
||||||
|
var cell = new StringBuilder();
|
||||||
|
bool inQuote = false;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (i < text.Length)
|
||||||
|
{
|
||||||
|
char c = text[i];
|
||||||
|
if (inQuote)
|
||||||
|
{
|
||||||
|
if (c == '"')
|
||||||
|
{
|
||||||
|
if (i + 1 < text.Length && text[i + 1] == '"') { cell.Append('"'); i += 2; }
|
||||||
|
else { inQuote = false; i++; }
|
||||||
|
}
|
||||||
|
else { cell.Append(c); i++; }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (c == '"') { inQuote = true; i++; }
|
||||||
|
else if (c == ',') { row.Add(cell.ToString()); cell.Clear(); i++; }
|
||||||
|
else if (c == '\r')
|
||||||
|
{
|
||||||
|
row.Add(cell.ToString()); cell.Clear();
|
||||||
|
rows.Add(row); row = new List<string>();
|
||||||
|
if (i + 1 < text.Length && text[i + 1] == '\n') i++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else if (c == '\n')
|
||||||
|
{ row.Add(cell.ToString()); cell.Clear(); rows.Add(row); row = new List<string>(); i++; }
|
||||||
|
else { cell.Append(c); i++; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell.Length > 0 || row.Count > 0)
|
||||||
|
{
|
||||||
|
row.Add(cell.ToString());
|
||||||
|
rows.Add(row);
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ToFullPath(string assetPath)
|
||||||
|
{
|
||||||
|
string projectRoot = Path.GetDirectoryName(Application.dataPath)!;
|
||||||
|
return Path.Combine(projectRoot, assetPath.Replace('/', Path.DirectorySeparatorChar));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bd6037390f5ea7b4b93dd91283193c9a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using BaseGames.Localization;
|
using BaseGames.Localization;
|
||||||
@@ -11,11 +9,12 @@ namespace BaseGames.Editor.Localization
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 本地化 CSV 导入/导出工具。
|
/// 本地化 CSV 导入/导出工具。
|
||||||
///
|
///
|
||||||
/// 每个表导出为独立 CSV,列顺序:key, ChineseSimplified, English, Japanese, Korean。
|
/// 每个表导出为独立 CSV(含 UTF-8 BOM,Excel 中文不乱码),列顺序:key, ChineseSimplified, English, Japanese, Korean。
|
||||||
/// 文件存放路径:Assets/_Game/Localization/Export/{TableName}.csv
|
/// 文件存放路径:Assets/_Game/Localization/Export/{TableName}.csv
|
||||||
///
|
///
|
||||||
/// 导入:读取 CSV → 回写 Resources/Localization/{Language}/{TableName}.json
|
/// 导入:读取 CSV → 合并回写 Assets/_Game/Data/Localization/{Language}/{TableName}.json(经 LocalizationFileIO)
|
||||||
///
|
///
|
||||||
|
/// 注:日常单表编辑请用「BaseGames / Localization / 表格编辑器」,此窗口用于批量多表导入导出。
|
||||||
/// 菜单:BaseGames / Localization / CSV 导入导出工具
|
/// 菜单:BaseGames / Localization / CSV 导入导出工具
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LocalizationCsvTool : EditorWindow
|
public class LocalizationCsvTool : EditorWindow
|
||||||
@@ -29,9 +28,6 @@ namespace BaseGames.Editor.Localization
|
|||||||
|
|
||||||
// ── 状态 ─────────────────────────────────────────────────────────────
|
// ── 状态 ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
private static readonly Language[] s_allLanguages =
|
|
||||||
(Language[])Enum.GetValues(typeof(Language));
|
|
||||||
|
|
||||||
private static readonly string[] s_allTables =
|
private static readonly string[] s_allTables =
|
||||||
{
|
{
|
||||||
LocalizationTable.UI,
|
LocalizationTable.UI,
|
||||||
@@ -45,6 +41,7 @@ namespace BaseGames.Editor.Localization
|
|||||||
};
|
};
|
||||||
|
|
||||||
private const string ExportDir = "Assets/_Game/Localization/Export";
|
private const string ExportDir = "Assets/_Game/Localization/Export";
|
||||||
|
private const string DataDir = LocalizationPaths.DataRoot;
|
||||||
|
|
||||||
private readonly bool[] _exportSelected = new bool[s_allTables.Length];
|
private readonly bool[] _exportSelected = new bool[s_allTables.Length];
|
||||||
private readonly bool[] _importSelected = new bool[s_allTables.Length];
|
private readonly bool[] _importSelected = new bool[s_allTables.Length];
|
||||||
@@ -61,7 +58,7 @@ namespace BaseGames.Editor.Localization
|
|||||||
EditorGUILayout.Space(6);
|
EditorGUILayout.Space(6);
|
||||||
GUILayout.Label("📤 导出 → CSV", EditorStyles.boldLabel);
|
GUILayout.Label("📤 导出 → CSV", EditorStyles.boldLabel);
|
||||||
EditorGUILayout.HelpBox(
|
EditorGUILayout.HelpBox(
|
||||||
$"将 Resources/Localization/ 中的 JSON 表导出为 CSV 文件。\n" +
|
$"将 {DataDir}/ 中的 JSON 表导出为 CSV 文件(UTF-8 BOM,Excel 可直接打开)。\n" +
|
||||||
$"目标目录:{ExportDir}/",
|
$"目标目录:{ExportDir}/",
|
||||||
MessageType.Info);
|
MessageType.Info);
|
||||||
|
|
||||||
@@ -84,7 +81,7 @@ namespace BaseGames.Editor.Localization
|
|||||||
|
|
||||||
GUILayout.Label("📥 导入 ← CSV", EditorStyles.boldLabel);
|
GUILayout.Label("📥 导入 ← CSV", EditorStyles.boldLabel);
|
||||||
EditorGUILayout.HelpBox(
|
EditorGUILayout.HelpBox(
|
||||||
$"读取 {ExportDir}/ 中的 CSV,回写至 Resources/Localization/ JSON 文件。\n" +
|
$"读取 {ExportDir}/ 中的 CSV,合并回写至 {DataDir}/ JSON 文件。\n" +
|
||||||
"已有 Key 覆盖,新增 Key 追加,不删除多余 Key。",
|
"已有 Key 覆盖,新增 Key 追加,不删除多余 Key。",
|
||||||
MessageType.Info);
|
MessageType.Info);
|
||||||
|
|
||||||
@@ -114,7 +111,7 @@ namespace BaseGames.Editor.Localization
|
|||||||
|
|
||||||
private void RunExport()
|
private void RunExport()
|
||||||
{
|
{
|
||||||
EnsureDirectory(ExportDir);
|
LocalizationManager.ClearEditorPreviewCache();
|
||||||
int exported = 0;
|
int exported = 0;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -126,50 +123,23 @@ namespace BaseGames.Editor.Localization
|
|||||||
|
|
||||||
EditorUtility.DisplayProgressBar("导出 CSV", $"导出 {tableName}…", (float)ti / s_allTables.Length);
|
EditorUtility.DisplayProgressBar("导出 CSV", $"导出 {tableName}…", (float)ti / s_allTables.Length);
|
||||||
|
|
||||||
// 收集所有语言的字典(以第一个语言的 Key 集合为主键集)
|
// 经统一门面读取各语言字典(正确路径),交给 LocalizationCsv 写出(含 BOM)
|
||||||
var langDicts = new Dictionary<Language, Dictionary<string, string>>();
|
var langDicts = new Dictionary<Language, Dictionary<string, string>>();
|
||||||
var allKeys = new SortedSet<string>(StringComparer.Ordinal);
|
bool any = false;
|
||||||
|
foreach (var lang in LocalizationFileIO.AllLanguages)
|
||||||
foreach (var lang in s_allLanguages)
|
|
||||||
{
|
|
||||||
LocalizationManager.ClearEditorPreviewCache();
|
|
||||||
var dict = LocalizationManager.GetEditorTable(lang, tableName);
|
|
||||||
if (dict != null)
|
|
||||||
{
|
{
|
||||||
|
var dict = LocalizationFileIO.Read(lang, tableName);
|
||||||
langDicts[lang] = dict;
|
langDicts[lang] = dict;
|
||||||
foreach (var k in dict.Keys) allKeys.Add(k);
|
if (dict.Count > 0) any = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allKeys.Count == 0)
|
if (!any)
|
||||||
{
|
{
|
||||||
Debug.LogWarning($"[CsvTool] 表「{tableName}」无数据,跳过导出。");
|
Debug.LogWarning($"[CsvTool] 表「{tableName}」无数据,跳过导出。");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
LocalizationCsv.ExportToFile(tableName, langDicts);
|
||||||
// 表头
|
|
||||||
sb.Append("key");
|
|
||||||
foreach (var lang in s_allLanguages)
|
|
||||||
sb.Append(',').Append(lang);
|
|
||||||
sb.AppendLine();
|
|
||||||
|
|
||||||
// 数据行
|
|
||||||
foreach (var key in allKeys)
|
|
||||||
{
|
|
||||||
sb.Append(CsvEscape(key));
|
|
||||||
foreach (var lang in s_allLanguages)
|
|
||||||
{
|
|
||||||
string val = "";
|
|
||||||
if (langDicts.TryGetValue(lang, out var d))
|
|
||||||
d.TryGetValue(key, out val);
|
|
||||||
sb.Append(',').Append(CsvEscape(val ?? ""));
|
|
||||||
}
|
|
||||||
sb.AppendLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
string csvPath = $"{ExportDir}/{tableName}.csv";
|
|
||||||
File.WriteAllText(csvPath, sb.ToString(), Encoding.UTF8);
|
|
||||||
exported++;
|
exported++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,61 +165,18 @@ namespace BaseGames.Editor.Localization
|
|||||||
{
|
{
|
||||||
if (!_importSelected[ti]) continue;
|
if (!_importSelected[ti]) continue;
|
||||||
string tableName = s_allTables[ti];
|
string tableName = s_allTables[ti];
|
||||||
string csvPath = Path.Combine(Path.GetDirectoryName(Application.dataPath)!, $"{ExportDir}/{tableName}.csv");
|
|
||||||
|
|
||||||
EditorUtility.DisplayProgressBar("导入 CSV", $"导入 {tableName}…", (float)ti / s_allTables.Length);
|
EditorUtility.DisplayProgressBar("导入 CSV", $"导入 {tableName}…", (float)ti / s_allTables.Length);
|
||||||
|
|
||||||
if (!File.Exists(csvPath))
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"[CsvTool] CSV 文件不存在,跳过:{ExportDir}/{tableName}.csv");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var rows = ParseCsv(File.ReadAllText(csvPath, Encoding.UTF8));
|
// 合并语义 + 正确格式/目录/Addressable 注册,全部由统一门面处理
|
||||||
if (rows.Count < 2) continue;
|
int affected = LocalizationCsv.ImportFileToJson(tableName);
|
||||||
|
if (affected == 0)
|
||||||
// 表头行解析出列对应的语言
|
|
||||||
var header = rows[0];
|
|
||||||
var langCols = new List<(int col, Language lang)>();
|
|
||||||
for (int col = 1; col < header.Count; col++)
|
|
||||||
{
|
{
|
||||||
if (Enum.TryParse<Language>(header[col].Trim(), out var lang))
|
Debug.LogWarning($"[CsvTool] CSV 文件不存在或为空,跳过:{ExportDir}/{tableName}.csv");
|
||||||
langCols.Add((col, lang));
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 为每个语言准备合并后的字典
|
|
||||||
var mergedDicts = new Dictionary<Language, Dictionary<string, string>>();
|
|
||||||
foreach (var (_, lang) in langCols)
|
|
||||||
{
|
|
||||||
LocalizationManager.ClearEditorPreviewCache();
|
|
||||||
var existing = LocalizationManager.GetEditorTable(lang, tableName)
|
|
||||||
?? new Dictionary<string, string>(StringComparer.Ordinal);
|
|
||||||
mergedDicts[lang] = new Dictionary<string, string>(existing, StringComparer.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用 CSV 数据覆盖/追加
|
|
||||||
for (int row = 1; row < rows.Count; row++)
|
|
||||||
{
|
|
||||||
var cells = rows[row];
|
|
||||||
if (cells.Count == 0 || string.IsNullOrWhiteSpace(cells[0])) continue;
|
|
||||||
string key = cells[0];
|
|
||||||
foreach (var (col, lang) in langCols)
|
|
||||||
{
|
|
||||||
string val = col < cells.Count ? cells[col] : "";
|
|
||||||
mergedDicts[lang][key] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 写回 JSON
|
|
||||||
foreach (var (lang, dict) in mergedDicts)
|
|
||||||
{
|
|
||||||
string jsonPath = GetJsonPath(lang, tableName);
|
|
||||||
EnsureDirectory(Path.GetDirectoryName(jsonPath));
|
|
||||||
File.WriteAllText(jsonPath, DictToJson(dict), Encoding.UTF8);
|
|
||||||
}
|
|
||||||
|
|
||||||
imported++;
|
imported++;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -275,104 +202,6 @@ namespace BaseGames.Editor.Localization
|
|||||||
|
|
||||||
// ── 工具函数 ─────────────────────────────────────────────────────────
|
// ── 工具函数 ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
/// <summary>将 value 按 RFC 4180 规范包裹(含逗号/双引号/换行时用双引号包裹,内部双引号转义为 "")。</summary>
|
|
||||||
private static string CsvEscape(string value)
|
|
||||||
{
|
|
||||||
if (value == null) return "";
|
|
||||||
bool needsQuote = value.Contains(',') || value.Contains('"') || value.Contains('\n') || value.Contains('\r');
|
|
||||||
if (!needsQuote) return value;
|
|
||||||
return "\"" + value.Replace("\"", "\"\"") + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>简单 CSV 解析器,支持 RFC 4180 带引号字段(含换行)。</summary>
|
|
||||||
private static List<List<string>> ParseCsv(string text)
|
|
||||||
{
|
|
||||||
var rows = new List<List<string>>();
|
|
||||||
var row = new List<string>();
|
|
||||||
var cell = new StringBuilder();
|
|
||||||
bool inQuote = false;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while (i < text.Length)
|
|
||||||
{
|
|
||||||
char c = text[i];
|
|
||||||
if (inQuote)
|
|
||||||
{
|
|
||||||
if (c == '"')
|
|
||||||
{
|
|
||||||
if (i + 1 < text.Length && text[i + 1] == '"')
|
|
||||||
{ cell.Append('"'); i += 2; }
|
|
||||||
else
|
|
||||||
{ inQuote = false; i++; }
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ cell.Append(c); i++; }
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (c == '"')
|
|
||||||
{ inQuote = true; i++; }
|
|
||||||
else if (c == ',')
|
|
||||||
{ row.Add(cell.ToString()); cell.Clear(); i++; }
|
|
||||||
else if (c == '\r')
|
|
||||||
{
|
|
||||||
row.Add(cell.ToString()); cell.Clear();
|
|
||||||
rows.Add(row); row = new List<string>();
|
|
||||||
if (i + 1 < text.Length && text[i + 1] == '\n') i++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else if (c == '\n')
|
|
||||||
{ row.Add(cell.ToString()); cell.Clear(); rows.Add(row); row = new List<string>(); i++; }
|
|
||||||
else
|
|
||||||
{ cell.Append(c); i++; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cell.Length > 0 || row.Count > 0)
|
|
||||||
{
|
|
||||||
row.Add(cell.ToString());
|
|
||||||
rows.Add(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>将字符串字典序列化为最小 JSON 对象(UTF-8,适合直接写入 Resources JSON)。</summary>
|
|
||||||
private static string DictToJson(Dictionary<string, string> dict)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine("{");
|
|
||||||
int written = 0;
|
|
||||||
foreach (var kv in dict)
|
|
||||||
{
|
|
||||||
sb.Append(" ").Append(JsonString(kv.Key)).Append(": ").Append(JsonString(kv.Value));
|
|
||||||
if (++written < dict.Count) sb.Append(',');
|
|
||||||
sb.AppendLine();
|
|
||||||
}
|
|
||||||
sb.Append('}');
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string JsonString(string s)
|
|
||||||
{
|
|
||||||
if (s == null) return "\"\"";
|
|
||||||
s = s.Replace("\\", "\\\\")
|
|
||||||
.Replace("\"", "\\\"")
|
|
||||||
.Replace("\n", "\\n")
|
|
||||||
.Replace("\r", "\\r")
|
|
||||||
.Replace("\t", "\\t");
|
|
||||||
return $"\"{s}\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetJsonPath(Language lang, string tableName)
|
|
||||||
=> $"Assets/Resources/Localization/{lang}/{tableName}.json";
|
|
||||||
|
|
||||||
private static void EnsureDirectory(string dir)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
|
|
||||||
Directory.CreateDirectory(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SetAll(bool[] arr, bool v)
|
private static void SetAll(bool[] arr, bool v)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < arr.Length; i++) arr[i] = v;
|
for (int i = 0; i < arr.Length; i++) arr[i] = v;
|
||||||
|
|||||||
160
Assets/_Game/Scripts/Editor/Localization/LocalizationFileIO.cs
Normal file
160
Assets/_Game/Scripts/Editor/Localization/LocalizationFileIO.cs
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.AddressableAssets;
|
||||||
|
using UnityEditor.AddressableAssets.Settings;
|
||||||
|
using UnityEngine;
|
||||||
|
using BaseGames.Localization;
|
||||||
|
|
||||||
|
namespace BaseGames.Editor.Localization
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 本地化 JSON 表的编辑器侧磁盘读写门面(唯一入口)。
|
||||||
|
///
|
||||||
|
/// 所有编辑器工具(表格编辑器、CSV 工具、审计模块、各 Inspector)读写本地化文件
|
||||||
|
/// 都必须经此类,统一:路径(<see cref="LocalizationPaths"/>)、格式
|
||||||
|
/// (<see cref="LocalizationSerializer"/>)、Addressable 注册、编辑器缓存刷新。
|
||||||
|
///
|
||||||
|
/// 这样运行时加载与编辑器写盘永不脱节——杜绝"编辑器看着正常、Play 加载不到"的隐藏 bug。
|
||||||
|
/// </summary>
|
||||||
|
public static class LocalizationFileIO
|
||||||
|
{
|
||||||
|
/// <summary>所有受支持语言(枚举顺序)。</summary>
|
||||||
|
public static readonly Language[] AllLanguages =
|
||||||
|
(Language[])Enum.GetValues(typeof(Language));
|
||||||
|
|
||||||
|
// ── 读 ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 读取指定语言 + 表的 key→value 字典(返回可安全修改的副本,不存在时返回空字典)。
|
||||||
|
/// 内部走 <see cref="LocalizationManager.GetEditorTable"/> 复用其静态缓存。
|
||||||
|
/// </summary>
|
||||||
|
public static Dictionary<string, string> Read(Language language, string table)
|
||||||
|
{
|
||||||
|
var src = LocalizationManager.GetEditorTable(language, table);
|
||||||
|
return src == null
|
||||||
|
? new Dictionary<string, string>(StringComparer.Ordinal)
|
||||||
|
: new Dictionary<string, string>(src, StringComparer.Ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>该表的 JSON 文件是否已存在于磁盘。</summary>
|
||||||
|
public static bool TableExists(Language language, string table)
|
||||||
|
=> AssetDatabase.LoadAssetAtPath<TextAsset>(LocalizationPaths.AssetPath(language, table)) != null;
|
||||||
|
|
||||||
|
/// <summary>扫描数据根目录,返回磁盘上实际存在子目录的语言。</summary>
|
||||||
|
public static List<Language> DiscoverLanguages()
|
||||||
|
{
|
||||||
|
var result = new List<Language>();
|
||||||
|
if (!AssetDatabase.IsValidFolder(LocalizationPaths.DataRoot)) return result;
|
||||||
|
|
||||||
|
foreach (var langFolder in AssetDatabase.GetSubFolders(LocalizationPaths.DataRoot))
|
||||||
|
{
|
||||||
|
string langName = Path.GetFileName(langFolder);
|
||||||
|
if (Enum.TryParse<Language>(langName, out var lang))
|
||||||
|
result.Add(lang);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 写 ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将字典写回指定语言 + 表的 JSON 文件(正确的 <c>{entries:[…]}</c> 格式 + 正确目录)。
|
||||||
|
/// 新文件会自动注册到 Addressables(地址 <see cref="LocalizationPaths.Address"/>),
|
||||||
|
/// 写盘后清除编辑器预览缓存。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="language">目标语言。</param>
|
||||||
|
/// <param name="table">目标表名(<see cref="LocalizationTable"/> 常量)。</param>
|
||||||
|
/// <param name="dict">key→value 字典。</param>
|
||||||
|
/// <param name="registerAddressable">是否确保 Addressable 注册(默认 true)。</param>
|
||||||
|
public static void Write(Language language, string table,
|
||||||
|
IReadOnlyDictionary<string, string> dict, bool registerAddressable = true)
|
||||||
|
{
|
||||||
|
string assetPath = LocalizationPaths.AssetPath(language, table);
|
||||||
|
EditorScaffoldUtils.EnsureFolder(LocalizationPaths.LanguageFolder(language));
|
||||||
|
|
||||||
|
// JSON 文件不写 BOM(Addressables/TextAsset 解析期望纯 UTF-8)。
|
||||||
|
string json = LocalizationSerializer.Serialize(dict, sortKeys: true);
|
||||||
|
string fullPath = ToFullPath(assetPath);
|
||||||
|
File.WriteAllText(fullPath, json, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
|
||||||
|
|
||||||
|
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||||
|
|
||||||
|
if (registerAddressable)
|
||||||
|
EnsureAddressable(language, table, assetPath);
|
||||||
|
|
||||||
|
LocalizationManager.ClearEditorPreviewCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ping ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// <summary>在 Project 窗口中定位指定语言 + 表的 JSON 文件。</summary>
|
||||||
|
public static TextAsset Ping(Language language, string table)
|
||||||
|
{
|
||||||
|
var asset = AssetDatabase.LoadAssetAtPath<TextAsset>(LocalizationPaths.AssetPath(language, table));
|
||||||
|
if (asset != null) EditorScaffoldUtils.PingAndSelect(asset);
|
||||||
|
return asset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>在 Project 窗口中定位指定表的任一存在语言文件(优先简体中文 → 英文 → 其余)。</summary>
|
||||||
|
public static TextAsset PingAny(string table)
|
||||||
|
{
|
||||||
|
foreach (var lang in OrderedForPing())
|
||||||
|
{
|
||||||
|
var asset = AssetDatabase.LoadAssetAtPath<TextAsset>(LocalizationPaths.AssetPath(lang, table));
|
||||||
|
if (asset != null) { EditorScaffoldUtils.PingAndSelect(asset); return asset; }
|
||||||
|
}
|
||||||
|
Debug.LogWarning($"[LocalizationFileIO] 未找到本地化表文件:{LocalizationPaths.DataRoot}/…/{table}.json");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 内部 ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
private static IEnumerable<Language> OrderedForPing()
|
||||||
|
{
|
||||||
|
yield return Language.ChineseSimplified;
|
||||||
|
yield return Language.English;
|
||||||
|
foreach (var lang in AllLanguages)
|
||||||
|
if (lang != Language.ChineseSimplified && lang != Language.English)
|
||||||
|
yield return lang;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 确保该 JSON 文件已注册为对应 Addressable 地址。
|
||||||
|
/// 复用 <see cref="BaseGames.Editor.Addressables.CoreSceneRegistrar"/> 的 FindEntry-or-Create 幂等范式。
|
||||||
|
/// </summary>
|
||||||
|
private static void EnsureAddressable(Language language, string table, string assetPath)
|
||||||
|
{
|
||||||
|
var settings = AddressableAssetSettingsDefaultObject.Settings;
|
||||||
|
if (settings == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning(
|
||||||
|
$"[LocalizationFileIO] Addressable Settings 未初始化,未能注册 " +
|
||||||
|
$"{LocalizationPaths.Address(language, table)}。运行时可能加载不到该表。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string guid = AssetDatabase.AssetPathToGUID(assetPath);
|
||||||
|
if (string.IsNullOrEmpty(guid)) return;
|
||||||
|
|
||||||
|
string address = LocalizationPaths.Address(language, table);
|
||||||
|
var entry = settings.FindAssetEntry(guid)
|
||||||
|
?? settings.CreateOrMoveEntry(guid, settings.DefaultGroup, false, false);
|
||||||
|
|
||||||
|
// 已注册且地址正确则无需改动(避免无意义的 SetDirty)。
|
||||||
|
if (entry.address == address) return;
|
||||||
|
|
||||||
|
entry.address = address;
|
||||||
|
EditorUtility.SetDirty(settings);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ToFullPath(string assetPath)
|
||||||
|
{
|
||||||
|
string projectRoot = Path.GetDirectoryName(Application.dataPath)!;
|
||||||
|
return Path.Combine(projectRoot, assetPath.Replace('/', Path.DirectorySeparatorChar));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 96378ff704ef55a4db9c6d7ee55c12a0
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -60,7 +60,7 @@ namespace BaseGames.Editor.Localization
|
|||||||
{
|
{
|
||||||
EditorUtility.DisplayDialog("Key 选择器",
|
EditorUtility.DisplayDialog("Key 选择器",
|
||||||
$"表「{table}」尚无可用 Key。\n" +
|
$"表「{table}」尚无可用 Key。\n" +
|
||||||
$"请先在 Resources/Localization/{{语言}}/{table}.json 中添加条目。",
|
$"请先用「BaseGames / Localization / 表格编辑器」或在 {LocalizationPaths.DataRoot}/{{语言}}/{table}.json 中添加条目。",
|
||||||
"确定");
|
"确定");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,463 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using BaseGames.Localization;
|
||||||
|
|
||||||
|
namespace BaseGames.Editor.Localization
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 本地化表格编辑器(策划录入中心)。
|
||||||
|
///
|
||||||
|
/// 以 (Key × 语言) 网格直接编辑一张本地化表,无需手改 JSON:
|
||||||
|
/// - 表切换、搜索过滤、"仅显示缺失"。
|
||||||
|
/// - 新增 / 重命名 / 删除 Key(跨所有语言同步)。
|
||||||
|
/// - 缺失单元格红底高亮。
|
||||||
|
/// - 保存:经 <see cref="LocalizationFileIO"/> 写回所有语言 JSON(正确 entries 格式 + 自动注册 Addressables)。
|
||||||
|
/// - 工具栏内置 Excel/CSV 双向:导出 CSV(UTF-8 BOM)、导入 CSV(合并后即时刷新网格)。
|
||||||
|
/// - 1000+ 行虚拟化渲染(仅绘制可见行)。
|
||||||
|
///
|
||||||
|
/// 菜单:BaseGames / Localization / 表格编辑器
|
||||||
|
/// </summary>
|
||||||
|
public class LocalizationTableEditorWindow : EditorWindow
|
||||||
|
{
|
||||||
|
[MenuItem("BaseGames/Localization/表格编辑器")]
|
||||||
|
private static void Open()
|
||||||
|
{
|
||||||
|
var win = GetWindow<LocalizationTableEditorWindow>("本地化表格编辑器");
|
||||||
|
win.minSize = new Vector2(720, 480);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 常量 ─────────────────────────────────────────────────────────────
|
||||||
|
private static readonly Language[] s_langs = LocalizationFileIO.AllLanguages;
|
||||||
|
private const float RowHeight = 22f;
|
||||||
|
private const float KeyColWidth = 240f;
|
||||||
|
private const float MinLangCol = 140f;
|
||||||
|
private const float Scrollbar = 16f;
|
||||||
|
|
||||||
|
// ── 状态 ─────────────────────────────────────────────────────────────
|
||||||
|
private string[] _tables;
|
||||||
|
private int _tableIndex;
|
||||||
|
private string _currentTable;
|
||||||
|
|
||||||
|
// 工作副本:语言 → (key → value)
|
||||||
|
private readonly Dictionary<Language, Dictionary<string, string>> _data = new();
|
||||||
|
private readonly List<string> _keys = new(); // 全部 key(已排序)
|
||||||
|
private readonly List<string> _filtered = new(); // 过滤后用于显示
|
||||||
|
|
||||||
|
private string _search = "";
|
||||||
|
private bool _onlyMissing;
|
||||||
|
private bool _dirty;
|
||||||
|
private Vector2 _scroll;
|
||||||
|
|
||||||
|
// 行内输入状态机(新增 / 重命名 Key)
|
||||||
|
private enum InputMode { None, AddKey, RenameKey }
|
||||||
|
private InputMode _inputMode = InputMode.None;
|
||||||
|
private string _inputText = "";
|
||||||
|
private string _renameTarget;
|
||||||
|
|
||||||
|
private GUIStyle _keyBtnStyle;
|
||||||
|
|
||||||
|
// ── 生命周期 ──────────────────────────────────────────────────────────
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
_tables = LocalizationTable.All;
|
||||||
|
_tableIndex = 0;
|
||||||
|
LoadTable(_tables[_tableIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 数据加载 / 保存 ───────────────────────────────────────────────────
|
||||||
|
private void LoadTable(string table)
|
||||||
|
{
|
||||||
|
_currentTable = table;
|
||||||
|
_data.Clear();
|
||||||
|
LocalizationManager.ClearEditorPreviewCache();
|
||||||
|
|
||||||
|
var union = new SortedSet<string>(StringComparer.Ordinal);
|
||||||
|
foreach (var lang in s_langs)
|
||||||
|
{
|
||||||
|
var dict = LocalizationFileIO.Read(lang, table);
|
||||||
|
_data[lang] = dict;
|
||||||
|
foreach (var k in dict.Keys) union.Add(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
_keys.Clear();
|
||||||
|
_keys.AddRange(union);
|
||||||
|
_dirty = false;
|
||||||
|
_inputMode = InputMode.None;
|
||||||
|
ApplyFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Save()
|
||||||
|
{
|
||||||
|
foreach (var lang in s_langs)
|
||||||
|
LocalizationFileIO.Write(lang, _currentTable, _data[lang]);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
_dirty = false;
|
||||||
|
ShowNotification(new GUIContent($"已保存 {_currentTable}({_keys.Count} 个 Key × {s_langs.Length} 语言)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>切换表 / 关闭前:若有未保存改动,询问保存。返回 false 表示用户取消操作。</summary>
|
||||||
|
private bool ConfirmDiscardIfDirty(string actionDesc)
|
||||||
|
{
|
||||||
|
if (!_dirty) return true;
|
||||||
|
int choice = EditorUtility.DisplayDialogComplex(
|
||||||
|
"有未保存的改动",
|
||||||
|
$"表「{_currentTable}」有未保存的改动。{actionDesc}前要保存吗?",
|
||||||
|
"保存", "取消", "丢弃");
|
||||||
|
switch (choice)
|
||||||
|
{
|
||||||
|
case 0: Save(); return true; // 保存
|
||||||
|
case 2: return true; // 丢弃
|
||||||
|
default: return false; // 取消
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── GUI ───────────────────────────────────────────────────────────────
|
||||||
|
private void OnGUI()
|
||||||
|
{
|
||||||
|
EnsureStyles();
|
||||||
|
DrawToolbar();
|
||||||
|
if (_inputMode != InputMode.None) DrawInputBar();
|
||||||
|
DrawHeader();
|
||||||
|
DrawGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawToolbar()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||||||
|
|
||||||
|
// 表切换
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
int newIndex = EditorGUILayout.Popup(_tableIndex, _tables, EditorStyles.toolbarPopup, GUILayout.Width(160));
|
||||||
|
if (EditorGUI.EndChangeCheck() && newIndex != _tableIndex)
|
||||||
|
{
|
||||||
|
if (ConfirmDiscardIfDirty("切换表"))
|
||||||
|
{
|
||||||
|
_tableIndex = newIndex;
|
||||||
|
LoadTable(_tables[_tableIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
_search = EditorGUILayout.TextField(_search, EditorStyles.toolbarSearchField, GUILayout.MinWidth(120));
|
||||||
|
if (EditorGUI.EndChangeCheck()) ApplyFilter();
|
||||||
|
|
||||||
|
bool prevOnlyMissing = _onlyMissing;
|
||||||
|
_onlyMissing = GUILayout.Toggle(_onlyMissing, "仅显示缺失", EditorStyles.toolbarButton, GUILayout.Width(80));
|
||||||
|
if (_onlyMissing != prevOnlyMissing) ApplyFilter();
|
||||||
|
|
||||||
|
GUILayout.FlexibleSpace();
|
||||||
|
|
||||||
|
if (GUILayout.Button("+ 新增 Key", EditorStyles.toolbarButton, GUILayout.Width(80)))
|
||||||
|
BeginAddKey();
|
||||||
|
|
||||||
|
if (GUILayout.Button("导出 CSV", EditorStyles.toolbarButton, GUILayout.Width(64)))
|
||||||
|
ExportCsv();
|
||||||
|
if (GUILayout.Button("导入 CSV", EditorStyles.toolbarButton, GUILayout.Width(64)))
|
||||||
|
ImportCsv();
|
||||||
|
|
||||||
|
using (new EditorGUI.DisabledScope(!_dirty))
|
||||||
|
{
|
||||||
|
var saveContent = new GUIContent(_dirty ? "● 保存" : "保存");
|
||||||
|
if (GUILayout.Button(saveContent, EditorStyles.toolbarButton, GUILayout.Width(64)))
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("刷新", EditorStyles.toolbarButton, GUILayout.Width(44)))
|
||||||
|
{
|
||||||
|
if (ConfirmDiscardIfDirty("刷新")) LoadTable(_currentTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawInputBar()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||||
|
GUILayout.Label(_inputMode == InputMode.AddKey ? "新增 Key:" : $"重命名「{_renameTarget}」为:",
|
||||||
|
GUILayout.Width(_inputMode == InputMode.AddKey ? 70 : 200));
|
||||||
|
|
||||||
|
GUI.SetNextControlName("LocInputField");
|
||||||
|
_inputText = EditorGUILayout.TextField(_inputText);
|
||||||
|
|
||||||
|
bool submit = false;
|
||||||
|
var e = Event.current;
|
||||||
|
if (e.type == EventType.KeyDown && (e.keyCode == KeyCode.Return || e.keyCode == KeyCode.KeypadEnter)
|
||||||
|
&& GUI.GetNameOfFocusedControl() == "LocInputField")
|
||||||
|
{ submit = true; e.Use(); }
|
||||||
|
if (e.type == EventType.KeyDown && e.keyCode == KeyCode.Escape) { CancelInput(); e.Use(); }
|
||||||
|
|
||||||
|
if (GUILayout.Button("确认", GUILayout.Width(48)) || submit) CommitInput();
|
||||||
|
if (GUILayout.Button("取消", GUILayout.Width(48))) CancelInput();
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
// 命名提示
|
||||||
|
if (!string.IsNullOrEmpty(_inputText) && !IsValidKey(_inputText))
|
||||||
|
EditorGUILayout.HelpBox("建议使用 UPPER_SNAKE_CASE(大写字母开头,大写字母/数字/下划线)。", MessageType.Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawHeader()
|
||||||
|
{
|
||||||
|
float langW = LangColWidth();
|
||||||
|
var rect = GUILayoutUtility.GetRect(0, RowHeight, GUILayout.ExpandWidth(true));
|
||||||
|
EditorGUI.DrawRect(rect, new Color(0.18f, 0.18f, 0.18f, 1f));
|
||||||
|
|
||||||
|
var keyRect = new Rect(rect.x + 4, rect.y + 3, KeyColWidth - 6, RowHeight - 4);
|
||||||
|
EditorGUI.LabelField(keyRect, $"Key({_filtered.Count}/{_keys.Count})", EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
for (int c = 0; c < s_langs.Length; c++)
|
||||||
|
{
|
||||||
|
var lr = new Rect(rect.x + KeyColWidth + c * langW + 4, rect.y + 3, langW - 6, RowHeight - 4);
|
||||||
|
int missing = CountMissing(s_langs[c]);
|
||||||
|
string label = missing > 0 ? $"{s_langs[c]} (缺{missing})" : s_langs[c].ToString();
|
||||||
|
EditorGUI.LabelField(lr, label, EditorStyles.boldLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawGrid()
|
||||||
|
{
|
||||||
|
float langW = LangColWidth();
|
||||||
|
float viewH = position.height - GUILayoutUtility.GetLastRect().yMax;
|
||||||
|
float contentH = _filtered.Count * RowHeight;
|
||||||
|
|
||||||
|
_scroll = GUI.BeginScrollView(
|
||||||
|
new Rect(0, GUILayoutUtility.GetLastRect().yMax, position.width, viewH),
|
||||||
|
_scroll,
|
||||||
|
new Rect(0, 0, position.width - Scrollbar, contentH));
|
||||||
|
|
||||||
|
int first = Mathf.Max(0, (int)(_scroll.y / RowHeight) - 1);
|
||||||
|
int last = Mathf.Min(_filtered.Count - 1, (int)((_scroll.y + viewH) / RowHeight) + 1);
|
||||||
|
|
||||||
|
for (int i = first; i <= last && i < _filtered.Count; i++)
|
||||||
|
DrawRow(i, _filtered[i], langW);
|
||||||
|
|
||||||
|
GUI.EndScrollView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawRow(int index, string key, float langW)
|
||||||
|
{
|
||||||
|
float y = index * RowHeight;
|
||||||
|
var rowRect = new Rect(0, y, position.width - Scrollbar, RowHeight);
|
||||||
|
|
||||||
|
if (index % 2 == 0)
|
||||||
|
EditorGUI.DrawRect(rowRect, new Color(1f, 1f, 1f, 0.025f));
|
||||||
|
|
||||||
|
// Key 列(点击弹出 重命名/删除/复制 菜单)
|
||||||
|
var keyRect = new Rect(2, y + 1, KeyColWidth - 4, RowHeight - 2);
|
||||||
|
if (GUI.Button(keyRect, key, _keyBtnStyle))
|
||||||
|
ShowKeyContextMenu(key);
|
||||||
|
|
||||||
|
// 各语言可编辑单元格
|
||||||
|
for (int c = 0; c < s_langs.Length; c++)
|
||||||
|
{
|
||||||
|
var lang = s_langs[c];
|
||||||
|
var cellRect = new Rect(KeyColWidth + c * langW + 1, y + 1, langW - 2, RowHeight - 2);
|
||||||
|
|
||||||
|
_data[lang].TryGetValue(key, out var val);
|
||||||
|
if (string.IsNullOrEmpty(val))
|
||||||
|
EditorGUI.DrawRect(cellRect, new Color(0.5f, 0.15f, 0.1f, 0.28f)); // 缺失高亮
|
||||||
|
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
string newVal = EditorGUI.DelayedTextField(cellRect, val ?? "");
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
_data[lang][key] = newVal;
|
||||||
|
MarkDirty();
|
||||||
|
if (_onlyMissing) ApplyFilter(); // 填上后可能从"缺失"列表消失
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Key 增删改 ────────────────────────────────────────────────────────
|
||||||
|
private void ShowKeyContextMenu(string key)
|
||||||
|
{
|
||||||
|
var menu = new GenericMenu();
|
||||||
|
menu.AddItem(new GUIContent("重命名"), false, () => BeginRename(key));
|
||||||
|
menu.AddItem(new GUIContent("删除"), false, () => DeleteKey(key));
|
||||||
|
menu.AddItem(new GUIContent("复制 Key"), false, () => EditorGUIUtility.systemCopyBuffer = key);
|
||||||
|
menu.ShowAsContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BeginAddKey()
|
||||||
|
{
|
||||||
|
_inputMode = InputMode.AddKey;
|
||||||
|
_inputText = "";
|
||||||
|
_renameTarget = null;
|
||||||
|
EditorGUI.FocusTextInControl("LocInputField");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BeginRename(string key)
|
||||||
|
{
|
||||||
|
_inputMode = InputMode.RenameKey;
|
||||||
|
_inputText = key;
|
||||||
|
_renameTarget = key;
|
||||||
|
EditorGUI.FocusTextInControl("LocInputField");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CommitInput()
|
||||||
|
{
|
||||||
|
string newKey = _inputText?.Trim();
|
||||||
|
if (string.IsNullOrEmpty(newKey)) { CancelInput(); return; }
|
||||||
|
|
||||||
|
if (_inputMode == InputMode.AddKey)
|
||||||
|
{
|
||||||
|
if (_keys.Contains(newKey))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("新增 Key", $"Key「{newKey}」已存在。", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
foreach (var lang in s_langs) _data[lang][newKey] = "";
|
||||||
|
_keys.Add(newKey);
|
||||||
|
_keys.Sort(StringComparer.Ordinal);
|
||||||
|
MarkDirty();
|
||||||
|
}
|
||||||
|
else if (_inputMode == InputMode.RenameKey && _renameTarget != null)
|
||||||
|
{
|
||||||
|
if (newKey == _renameTarget) { CancelInput(); return; }
|
||||||
|
if (_keys.Contains(newKey))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("重命名", $"Key「{newKey}」已存在。", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
foreach (var lang in s_langs)
|
||||||
|
{
|
||||||
|
_data[lang].TryGetValue(_renameTarget, out var v);
|
||||||
|
_data[lang].Remove(_renameTarget);
|
||||||
|
_data[lang][newKey] = v ?? "";
|
||||||
|
}
|
||||||
|
_keys.Remove(_renameTarget);
|
||||||
|
_keys.Add(newKey);
|
||||||
|
_keys.Sort(StringComparer.Ordinal);
|
||||||
|
MarkDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
_inputMode = InputMode.None;
|
||||||
|
ApplyFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CancelInput()
|
||||||
|
{
|
||||||
|
_inputMode = InputMode.None;
|
||||||
|
_inputText = "";
|
||||||
|
_renameTarget = null;
|
||||||
|
GUI.FocusControl(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteKey(string key)
|
||||||
|
{
|
||||||
|
if (!EditorUtility.DisplayDialog("删除 Key", $"确定删除「{key}」(所有语言)?", "删除", "取消"))
|
||||||
|
return;
|
||||||
|
foreach (var lang in s_langs) _data[lang].Remove(key);
|
||||||
|
_keys.Remove(key);
|
||||||
|
MarkDirty();
|
||||||
|
ApplyFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── CSV 双向 ─────────────────────────────────────────────────────────
|
||||||
|
private void ExportCsv()
|
||||||
|
{
|
||||||
|
string path = LocalizationCsv.ExportToFile(_currentTable, _data);
|
||||||
|
var asset = AssetDatabase.LoadAssetAtPath<TextAsset>(path);
|
||||||
|
if (asset != null) EditorGUIUtility.PingObject(asset);
|
||||||
|
ShowNotification(new GUIContent($"已导出 {path}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ImportCsv()
|
||||||
|
{
|
||||||
|
var parsed = LocalizationCsv.ParseFile(_currentTable);
|
||||||
|
if (parsed == null)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("导入 CSV",
|
||||||
|
$"未找到 CSV 文件:\n{LocalizationPaths.CsvPath(_currentTable)}\n\n请先「导出 CSV」或将文件放到该路径。",
|
||||||
|
"确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 合并进内存网格(覆盖已有 key、追加新 key、不删多余),随后置脏待保存
|
||||||
|
int added = 0, updated = 0;
|
||||||
|
foreach (var (lang, csvDict) in parsed)
|
||||||
|
{
|
||||||
|
if (!_data.ContainsKey(lang)) _data[lang] = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||||
|
foreach (var kv in csvDict)
|
||||||
|
{
|
||||||
|
bool isNew = !_keys.Contains(kv.Key);
|
||||||
|
if (isNew && !_data[lang].ContainsKey(kv.Key)) added++;
|
||||||
|
else updated++;
|
||||||
|
_data[lang][kv.Key] = kv.Value;
|
||||||
|
if (!_keys.Contains(kv.Key)) _keys.Add(kv.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_keys.Sort(StringComparer.Ordinal);
|
||||||
|
MarkDirty();
|
||||||
|
ApplyFilter();
|
||||||
|
ShowNotification(new GUIContent($"已导入并刷新网格(新增 {added}、更新 {updated})。记得点「保存」写回。"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 过滤 / 工具 ───────────────────────────────────────────────────────
|
||||||
|
private void ApplyFilter()
|
||||||
|
{
|
||||||
|
_filtered.Clear();
|
||||||
|
foreach (var key in _keys)
|
||||||
|
{
|
||||||
|
if (_onlyMissing && !HasMissing(key)) continue;
|
||||||
|
if (!string.IsNullOrEmpty(_search) && !MatchesSearch(key)) continue;
|
||||||
|
_filtered.Add(key);
|
||||||
|
}
|
||||||
|
Repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool MatchesSearch(string key)
|
||||||
|
{
|
||||||
|
if (key.IndexOf(_search, StringComparison.OrdinalIgnoreCase) >= 0) return true;
|
||||||
|
foreach (var lang in s_langs)
|
||||||
|
if (_data[lang].TryGetValue(key, out var v) && !string.IsNullOrEmpty(v)
|
||||||
|
&& v.IndexOf(_search, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasMissing(string key)
|
||||||
|
{
|
||||||
|
foreach (var lang in s_langs)
|
||||||
|
if (!_data[lang].TryGetValue(key, out var v) || string.IsNullOrEmpty(v)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int CountMissing(Language lang)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
foreach (var key in _keys)
|
||||||
|
if (!_data[lang].TryGetValue(key, out var v) || string.IsNullOrEmpty(v)) n++;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float LangColWidth()
|
||||||
|
{
|
||||||
|
float avail = position.width - KeyColWidth - Scrollbar;
|
||||||
|
return Mathf.Max(MinLangCol, avail / s_langs.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsValidKey(string key)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(key) || !char.IsUpper(key[0])) return false;
|
||||||
|
foreach (char c in key)
|
||||||
|
if (!(char.IsUpper(c) || char.IsDigit(c) || c == '_')) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MarkDirty() => _dirty = true;
|
||||||
|
|
||||||
|
private void EnsureStyles()
|
||||||
|
{
|
||||||
|
_keyBtnStyle ??= new GUIStyle(EditorStyles.label)
|
||||||
|
{
|
||||||
|
alignment = TextAnchor.MiddleLeft,
|
||||||
|
padding = new RectOffset(4, 2, 0, 0),
|
||||||
|
fontSize = 11,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d25d80dd8535edd4c95436a6f9d2f5a4
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -64,7 +64,7 @@ namespace BaseGames.Editor.Localization
|
|||||||
{
|
{
|
||||||
EditorGUILayout.HelpBox(
|
EditorGUILayout.HelpBox(
|
||||||
$"Key「{key}」在表「{table}」中未找到(简体中文表与英文表均未命中)。\n" +
|
$"Key「{key}」在表「{table}」中未找到(简体中文表与英文表均未命中)。\n" +
|
||||||
$"请检查 Resources/Localization/{{Language}}/{table}.json 文件。",
|
$"请检查 {LocalizationPaths.DataRoot}/{{Language}}/{table}.json 文件。",
|
||||||
MessageType.Warning);
|
MessageType.Warning);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -101,7 +101,7 @@ namespace BaseGames.Editor.Localization
|
|||||||
Repaint();
|
Repaint();
|
||||||
}
|
}
|
||||||
if (GUILayout.Button($"跳转到表文件({table})", GUILayout.Width(160)))
|
if (GUILayout.Button($"跳转到表文件({table})", GUILayout.Width(160)))
|
||||||
PingLocalizationFile(table);
|
LocalizationFileIO.PingAny(table);
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,24 +120,5 @@ namespace BaseGames.Editor.Localization
|
|||||||
catch { return template; }
|
catch { return template; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void PingLocalizationFile(string tableName)
|
|
||||||
{
|
|
||||||
string[] guids = AssetDatabase.FindAssets(
|
|
||||||
$"t:TextAsset {tableName}",
|
|
||||||
new[] { "Assets/Resources/Localization" });
|
|
||||||
|
|
||||||
foreach (var guid in guids)
|
|
||||||
{
|
|
||||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
|
||||||
if (!path.EndsWith($"/{tableName}.json", System.StringComparison.OrdinalIgnoreCase)) continue;
|
|
||||||
var asset = AssetDatabase.LoadAssetAtPath<TextAsset>(path);
|
|
||||||
if (asset == null) continue;
|
|
||||||
EditorGUIUtility.PingObject(asset);
|
|
||||||
Selection.activeObject = asset;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Debug.LogWarning($"[LocalizedTextEditor] 未找到本地化表文件:Resources/Localization/…/{tableName}.json");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ using UnityEditor;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UIElements;
|
using UnityEngine.UIElements;
|
||||||
using BaseGames.Localization;
|
using BaseGames.Localization;
|
||||||
|
using BaseGames.Editor.Localization;
|
||||||
|
|
||||||
namespace BaseGames.Editor.Modules
|
namespace BaseGames.Editor.Modules
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DataHub 本地化审计模块。
|
/// DataHub 本地化审计模块。
|
||||||
/// 通过 <see cref="ILocalizableAsset"/> 接口扫描项目中所有 ScriptableObject 的本地化 Key,
|
/// 通过 <see cref="ILocalizableAsset"/> 接口扫描项目中所有 ScriptableObject 的本地化 Key,
|
||||||
/// 与 Resources/Localization/ JSON 表比对,列出缺失条目和命名不规范条目。
|
/// 与 Assets/_Game/Data/Localization/ JSON 表比对,列出缺失条目和命名不规范条目。
|
||||||
///
|
///
|
||||||
/// 菜单入口:DataHub → "本地化审计"
|
/// 菜单入口:DataHub → "本地化审计"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -168,15 +169,8 @@ namespace BaseGames.Editor.Modules
|
|||||||
|
|
||||||
private void DiscoverLanguages()
|
private void DiscoverLanguages()
|
||||||
{
|
{
|
||||||
string root = "Assets/Resources/Localization";
|
// 统一经 LocalizationFileIO 扫描真相源目录(Assets/_Game/Data/Localization)
|
||||||
if (!AssetDatabase.IsValidFolder(root)) return;
|
_availableLanguages.AddRange(LocalizationFileIO.DiscoverLanguages());
|
||||||
|
|
||||||
foreach (var langFolder in AssetDatabase.GetSubFolders(root))
|
|
||||||
{
|
|
||||||
string langName = Path.GetFileName(langFolder);
|
|
||||||
if (Enum.TryParse<Language>(langName, out var lang))
|
|
||||||
_availableLanguages.Add(lang);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── 通用 ILocalizableAsset 扫描 ───────────────────────────────────────
|
// ── 通用 ILocalizableAsset 扫描 ───────────────────────────────────────
|
||||||
@@ -556,16 +550,14 @@ namespace BaseGames.Editor.Modules
|
|||||||
|
|
||||||
private static void PingTableFile(string language, string tableName)
|
private static void PingTableFile(string language, string tableName)
|
||||||
{
|
{
|
||||||
string path = $"Assets/Resources/Localization/{language}/{tableName}.json";
|
if (Enum.TryParse<Language>(language, out var lang))
|
||||||
var asset = AssetDatabase.LoadAssetAtPath<TextAsset>(path);
|
|
||||||
if (asset != null)
|
|
||||||
{
|
{
|
||||||
EditorGUIUtility.PingObject(asset);
|
if (LocalizationFileIO.Ping(lang, tableName) == null)
|
||||||
Selection.activeObject = asset;
|
Debug.LogWarning($"[LocalizationAudit] 未找到表文件:{LocalizationPaths.AssetPath(lang, tableName)}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.LogWarning($"[LocalizationAudit] 未找到表文件:{path}");
|
LocalizationFileIO.PingAny(tableName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -313,9 +313,25 @@ namespace BaseGames.Editor
|
|||||||
// ── 流式加载系统 ──────────────────────────────────────────────────
|
// ── 流式加载系统 ──────────────────────────────────────────────────
|
||||||
ScaffoldStreamingSystem(services, report);
|
ScaffoldStreamingSystem(services, report);
|
||||||
|
|
||||||
|
// ── 多设备 UI 焦点守护(EventSystem 上挂 UISelectionRestorer)──────────
|
||||||
|
EnsureUISelectionRestorer(report);
|
||||||
|
|
||||||
MarkDirtyAndLog("Persistent 场景脚手架", root, report);
|
MarkDirtyAndLog("Persistent 场景脚手架", root, report);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>确保场景中的 EventSystem 挂有 <see cref="BaseGames.UI.UISelectionRestorer"/>(多设备焦点守护,幂等)。</summary>
|
||||||
|
private static void EnsureUISelectionRestorer(List<string> report)
|
||||||
|
{
|
||||||
|
var es = Object.FindObjectOfType<UnityEngine.EventSystems.EventSystem>();
|
||||||
|
if (es == null)
|
||||||
|
{
|
||||||
|
report.Add("未找到 EventSystem,UISelectionRestorer 未挂载(键盘/手柄丢失焦点后无法自动恢复)。请确认 Persistent 场景含 EventSystem + InputSystemUIInputModule。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (es.GetComponent<BaseGames.UI.UISelectionRestorer>() == null)
|
||||||
|
Undo.AddComponent<BaseGames.UI.UISelectionRestorer>(es.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────
|
||||||
// Scaffold Main Menu Scene
|
// Scaffold Main Menu Scene
|
||||||
// ─────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────
|
||||||
@@ -357,6 +373,7 @@ namespace BaseGames.Editor
|
|||||||
var subTmp = GetOrAddComponent<TextMeshProUGUI>(subtitleRt.gameObject);
|
var subTmp = GetOrAddComponent<TextMeshProUGUI>(subtitleRt.gameObject);
|
||||||
subTmp.text = "A 2D Action Adventure"; subTmp.fontSize = 40f; subTmp.alignment = TextAlignmentOptions.Center;
|
subTmp.text = "A 2D Action Adventure"; subTmp.fontSize = 40f; subTmp.alignment = TextAlignmentOptions.Center;
|
||||||
subTmp.color = new Color(0.7f, 0.66f, 0.55f, 0.9f); subTmp.raycastTarget = false; subTmp.characterSpacing = 8f;
|
subTmp.color = new Color(0.7f, 0.66f, 0.55f, 0.9f); subTmp.raycastTarget = false; subTmp.characterSpacing = 8f;
|
||||||
|
BindLocalizedText(subtitleRt.gameObject, "MENU_SUBTITLE");
|
||||||
|
|
||||||
// ── 主菜单控制器 ──────────────────────────────────────────────────
|
// ── 主菜单控制器 ──────────────────────────────────────────────────
|
||||||
MainMenuController menuCtrl = GetOrAddComponent<MainMenuController>(canvasGo);
|
MainMenuController menuCtrl = GetOrAddComponent<MainMenuController>(canvasGo);
|
||||||
@@ -386,6 +403,11 @@ namespace BaseGames.Editor
|
|||||||
var le = GetOrAddComponent<LayoutElement>(b);
|
var le = GetOrAddComponent<LayoutElement>(b);
|
||||||
le.preferredHeight = 64f; le.minHeight = 56f;
|
le.preferredHeight = 64f; le.minHeight = 56f;
|
||||||
}
|
}
|
||||||
|
BindLocalizedButton(btnNewGameGo, "MENU_NEW_GAME");
|
||||||
|
BindLocalizedButton(btnContinueGo, "MENU_CONTINUE");
|
||||||
|
BindLocalizedButton(btnSettingsGo, "MENU_SETTINGS");
|
||||||
|
BindLocalizedButton(btnCreditsGo, "MENU_CREDITS");
|
||||||
|
BindLocalizedButton(btnQuitGo, "MENU_QUIT");
|
||||||
|
|
||||||
AssignReference(menuCtrl, "_btnNewGame", btnNewGameGo.GetComponent<Button>());
|
AssignReference(menuCtrl, "_btnNewGame", btnNewGameGo.GetComponent<Button>());
|
||||||
AssignReference(menuCtrl, "_btnContinue", btnContinueGo.GetComponent<Button>());
|
AssignReference(menuCtrl, "_btnContinue", btnContinueGo.GetComponent<Button>());
|
||||||
@@ -416,6 +438,7 @@ namespace BaseGames.Editor
|
|||||||
var slotTitleTmp = GetOrAddComponent<TextMeshProUGUI>(slotTitleRt.gameObject);
|
var slotTitleTmp = GetOrAddComponent<TextMeshProUGUI>(slotTitleRt.gameObject);
|
||||||
slotTitleTmp.text = "Select Save"; slotTitleTmp.fontSize = 56f; slotTitleTmp.fontStyle = FontStyles.Bold;
|
slotTitleTmp.text = "Select Save"; slotTitleTmp.fontSize = 56f; slotTitleTmp.fontStyle = FontStyles.Bold;
|
||||||
slotTitleTmp.alignment = TextAlignmentOptions.Center; slotTitleTmp.color = GoldText; slotTitleTmp.raycastTarget = false;
|
slotTitleTmp.alignment = TextAlignmentOptions.Center; slotTitleTmp.color = GoldText; slotTitleTmp.raycastTarget = false;
|
||||||
|
BindLocalizedText(slotTitleRt.gameObject, "SAVESLOT_TITLE");
|
||||||
|
|
||||||
// 卡片容器(居中竖排)
|
// 卡片容器(居中竖排)
|
||||||
var slotsContainerRt = GetOrCreateUIChild(saveSlotPanelGo.transform, "SlotsContainer");
|
var slotsContainerRt = GetOrCreateUIChild(saveSlotPanelGo.transform, "SlotsContainer");
|
||||||
@@ -450,6 +473,7 @@ namespace BaseGames.Editor
|
|||||||
SetRect(slotBackRt, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f),
|
SetRect(slotBackRt, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f),
|
||||||
new Vector2(0f, 70f), new Vector2(260f, 64f));
|
new Vector2(0f, 70f), new Vector2(260f, 64f));
|
||||||
StyleAsTextButton(slotBackGo, 30f);
|
StyleAsTextButton(slotBackGo, 30f);
|
||||||
|
BindLocalizedButton(slotBackGo, "BTN_BACK");
|
||||||
AssignReference(menuCtrl, "_btnCloseSaveSlot", slotBackGo.GetComponent<Button>());
|
AssignReference(menuCtrl, "_btnCloseSaveSlot", slotBackGo.GetComponent<Button>());
|
||||||
|
|
||||||
// ── ConfirmDialog(覆盖 / 删除确认)─────────────────────
|
// ── ConfirmDialog(覆盖 / 删除确认)─────────────────────
|
||||||
@@ -460,15 +484,17 @@ namespace BaseGames.Editor
|
|||||||
NewGameModeController modeCtrl = BuildNewGameMode(saveSlotPanelGo.transform);
|
NewGameModeController modeCtrl = BuildNewGameMode(saveSlotPanelGo.transform);
|
||||||
AssignReference(saveSlotCtrl, "_modeSelect", modeCtrl);
|
AssignReference(saveSlotCtrl, "_modeSelect", modeCtrl);
|
||||||
|
|
||||||
// ── SettingsPanel ─────────────────────────────────────────────────
|
// ── SettingsPanel(音量 / 画面 / 可访问性 / 语言)──────────────────
|
||||||
var settingsPanelRt = GetOrCreateUIChild(canvasGo.transform, "SettingsPanel");
|
var settingsPanelRt = GetOrCreateUIChild(canvasGo.transform, "SettingsPanel");
|
||||||
StretchFull(settingsPanelRt);
|
StretchFull(settingsPanelRt);
|
||||||
|
BuildSettingsPanel(settingsPanelRt.gameObject, menuCtrl, report);
|
||||||
settingsPanelRt.gameObject.SetActive(false);
|
settingsPanelRt.gameObject.SetActive(false);
|
||||||
AssignReference(menuCtrl, "_settingsPanel", settingsPanelRt.gameObject);
|
AssignReference(menuCtrl, "_settingsPanel", settingsPanelRt.gameObject);
|
||||||
|
|
||||||
// ── CreditsPanel ──────────────────────────────────────────────────
|
// ── CreditsPanel(制作团队)────────────────────────────────────────
|
||||||
var creditsPanelRt = GetOrCreateUIChild(canvasGo.transform, "CreditsPanel");
|
var creditsPanelRt = GetOrCreateUIChild(canvasGo.transform, "CreditsPanel");
|
||||||
StretchFull(creditsPanelRt);
|
StretchFull(creditsPanelRt);
|
||||||
|
BuildCreditsPanel(creditsPanelRt.gameObject, menuCtrl, report);
|
||||||
creditsPanelRt.gameObject.SetActive(false);
|
creditsPanelRt.gameObject.SetActive(false);
|
||||||
AssignReference(menuCtrl, "_creditsPanel", creditsPanelRt.gameObject);
|
AssignReference(menuCtrl, "_creditsPanel", creditsPanelRt.gameObject);
|
||||||
|
|
||||||
@@ -505,20 +531,38 @@ namespace BaseGames.Editor
|
|||||||
bgImg.type = Image.Type.Simple; bgImg.preserveAspect = true; bgImg.enabled = false;
|
bgImg.type = Image.Type.Simple; bgImg.preserveAspect = true; bgImg.enabled = false;
|
||||||
bgImg.transform.SetSiblingIndex(1);
|
bgImg.transform.SetSiblingIndex(1);
|
||||||
|
|
||||||
// 全覆盖选择按钮(透明,金色高亮;位于信息层之下,靠 raycast 接收点击)
|
// 选中/悬停高亮叠加(基色白不透明;显隐由按钮 ColorBlock 的 alpha 控制 → 可见的选中反馈)
|
||||||
|
var hlImg = GetOrCreateImage(slotGo.transform, "Highlight", Color.white, false);
|
||||||
|
hlImg.transform.SetSiblingIndex(2);
|
||||||
|
|
||||||
|
// 全覆盖选择按钮(透明,靠 raycast 接收点击;着色目标为 Highlight 叠加图)
|
||||||
GameObject selectGo = GetOrCreateButtonChild(slotGo.transform, "SelectButton", "");
|
GameObject selectGo = GetOrCreateButtonChild(slotGo.transform, "SelectButton", "");
|
||||||
StretchFull((RectTransform)selectGo.transform);
|
StretchFull((RectTransform)selectGo.transform);
|
||||||
var selImg = selectGo.GetComponent<Image>();
|
var selImg = selectGo.GetComponent<Image>();
|
||||||
if (selImg != null) selImg.color = new Color(1f, 1f, 1f, 0f);
|
if (selImg != null) selImg.color = new Color(1f, 1f, 1f, 0f);
|
||||||
var selLabel = GetButtonLabel(selectGo);
|
var selLabel = GetButtonLabel(selectGo);
|
||||||
if (selLabel != null) selLabel.gameObject.SetActive(false);
|
if (selLabel != null) selLabel.gameObject.SetActive(false);
|
||||||
|
var selBtn = selectGo.GetComponent<Button>();
|
||||||
|
if (selBtn != null)
|
||||||
|
{
|
||||||
|
selBtn.targetGraphic = hlImg;
|
||||||
|
var cc = selBtn.colors;
|
||||||
|
cc.normalColor = new Color(1f, 0.85f, 0.45f, 0f); // 静态:透明
|
||||||
|
cc.highlightedColor = new Color(1f, 0.86f, 0.5f, 0.08f); // 悬停:极淡金
|
||||||
|
cc.selectedColor = new Color(1f, 0.86f, 0.5f, 0.13f); // 键盘/手柄选中:淡金叠加
|
||||||
|
cc.pressedColor = new Color(1f, 0.86f, 0.5f, 0.22f);
|
||||||
|
cc.disabledColor = new Color(1f, 1f, 1f, 0f);
|
||||||
|
cc.colorMultiplier = 1f; cc.fadeDuration = 0.1f;
|
||||||
|
selBtn.colors = cc;
|
||||||
|
}
|
||||||
|
|
||||||
// 空槽提示
|
// 空槽提示
|
||||||
var emptyRt = GetOrCreateUIChild(slotGo.transform, "EmptyIndicator");
|
var emptyRt = GetOrCreateUIChild(slotGo.transform, "EmptyIndicator");
|
||||||
StretchFull(emptyRt);
|
StretchFull(emptyRt);
|
||||||
GameObject emptyGo = emptyRt.gameObject;
|
GameObject emptyGo = emptyRt.gameObject;
|
||||||
GetOrCreateText(emptyGo.transform, "EmptyText", "Empty Slot · New Game", 34f,
|
var emptyText = GetOrCreateText(emptyGo.transform, "EmptyText", "Empty Slot · New Game", 34f,
|
||||||
new Color(0.7f, 0.66f, 0.55f, 0.85f), TextAlignmentOptions.Center);
|
new Color(0.7f, 0.66f, 0.55f, 0.85f), TextAlignmentOptions.Center);
|
||||||
|
BindLocalizedText(emptyText.gameObject, "SAVESLOT_EMPTY");
|
||||||
|
|
||||||
// 有档信息区(左侧竖排:区域 / 时长 / 时间)+ 右侧(灵珠 / 生命 / 钢魂)
|
// 有档信息区(左侧竖排:区域 / 时长 / 时间)+ 右侧(灵珠 / 生命 / 钢魂)
|
||||||
var dataRt = GetOrCreateUIChild(slotGo.transform, "DataIndicator");
|
var dataRt = GetOrCreateUIChild(slotGo.transform, "DataIndicator");
|
||||||
@@ -540,7 +584,8 @@ namespace BaseGames.Editor
|
|||||||
var badgeRt = GetOrCreateUIChild(dataGo.transform, "SteelSoulBadge");
|
var badgeRt = GetOrCreateUIChild(dataGo.transform, "SteelSoulBadge");
|
||||||
SetRect(badgeRt, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(0f, 4f), new Vector2(120f, 40f));
|
SetRect(badgeRt, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(0f, 4f), new Vector2(120f, 40f));
|
||||||
GetOrAddComponent<Image>(badgeRt.gameObject).color = new Color(0.5f, 0.55f, 0.6f, 0.5f);
|
GetOrAddComponent<Image>(badgeRt.gameObject).color = new Color(0.5f, 0.55f, 0.6f, 0.5f);
|
||||||
GetOrCreateText(badgeRt.transform, "BadgeText", "STEEL", 22f, new Color(0.85f,0.9f,1f,1f), TextAlignmentOptions.Center);
|
var badgeText = GetOrCreateText(badgeRt.transform, "BadgeText", "STEEL", 22f, new Color(0.85f,0.9f,1f,1f), TextAlignmentOptions.Center);
|
||||||
|
BindLocalizedText(badgeText.gameObject, "BADGE_STEELSOUL");
|
||||||
GameObject badgeGo = badgeRt.gameObject;
|
GameObject badgeGo = badgeRt.gameObject;
|
||||||
|
|
||||||
// 删除按钮(右上角小 ×)
|
// 删除按钮(右上角小 ×)
|
||||||
@@ -597,6 +642,8 @@ namespace BaseGames.Editor
|
|||||||
yesGo.GetComponent<Image>().color = new Color(0.45f, 0.12f, 0.12f, 0.85f);
|
yesGo.GetComponent<Image>().color = new Color(0.45f, 0.12f, 0.12f, 0.85f);
|
||||||
GameObject noGo = GetOrCreateButtonChild(boxRt.transform, "Btn_Cancel", "Cancel");
|
GameObject noGo = GetOrCreateButtonChild(boxRt.transform, "Btn_Cancel", "Cancel");
|
||||||
SetRect((RectTransform)noGo.transform, new Vector2(0.5f,0f), new Vector2(0.5f,0f), new Vector2(0.5f,0f), new Vector2(150f,40f), new Vector2(220f,64f));
|
SetRect((RectTransform)noGo.transform, new Vector2(0.5f,0f), new Vector2(0.5f,0f), new Vector2(0.5f,0f), new Vector2(150f,40f), new Vector2(220f,64f));
|
||||||
|
BindLocalizedButton(yesGo, "CONFIRM_YES");
|
||||||
|
BindLocalizedButton(noGo, "CONFIRM_NO");
|
||||||
|
|
||||||
AssignReference(confirmCtrl, "_root", confirmGo);
|
AssignReference(confirmCtrl, "_root", confirmGo);
|
||||||
AssignReference(confirmCtrl, "_titleText", titleTmp);
|
AssignReference(confirmCtrl, "_titleText", titleTmp);
|
||||||
@@ -638,6 +685,10 @@ namespace BaseGames.Editor
|
|||||||
GameObject backGo = GetOrCreateButtonChild(boxRt.transform, "Btn_Back", "Back");
|
GameObject backGo = GetOrCreateButtonChild(boxRt.transform, "Btn_Back", "Back");
|
||||||
SetRect((RectTransform)backGo.transform, new Vector2(0.5f,0f), new Vector2(0.5f,0f), new Vector2(0.5f,0f), new Vector2(0f,46f), new Vector2(260f,60f));
|
SetRect((RectTransform)backGo.transform, new Vector2(0.5f,0f), new Vector2(0.5f,0f), new Vector2(0.5f,0f), new Vector2(0f,46f), new Vector2(260f,60f));
|
||||||
StyleAsTextButton(backGo, 28f);
|
StyleAsTextButton(backGo, 28f);
|
||||||
|
BindLocalizedText(modeTitle.gameObject, "MODE_SELECT_TITLE");
|
||||||
|
BindLocalizedButton(normalGo, "MODE_NORMAL");
|
||||||
|
BindLocalizedButton(steelGo, "MODE_STEELSOUL");
|
||||||
|
BindLocalizedButton(backGo, "BTN_BACK");
|
||||||
|
|
||||||
AssignReference(modeCtrl, "_root", modeGo);
|
AssignReference(modeCtrl, "_root", modeGo);
|
||||||
AssignReference(modeCtrl, "_btnNormal", normalGo.GetComponent<Button>());
|
AssignReference(modeCtrl, "_btnNormal", normalGo.GetComponent<Button>());
|
||||||
@@ -1073,18 +1124,273 @@ namespace BaseGames.Editor
|
|||||||
return t != null ? t.GetComponent<TextMeshProUGUI>() : null;
|
return t != null ? t.GetComponent<TextMeshProUGUI>() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>将按钮改造为"纯文字"风格(透明底,仅金色高亮),用于主菜单主按钮列表。</summary>
|
/// <summary>
|
||||||
|
/// 将按钮改造为"纯文字"风格(透明底)。关键:把 Button 的 targetGraphic 指向文字 Label,
|
||||||
|
/// 这样鼠标悬停(Highlighted)与键盘/手柄选中(Selected)会直接给文字着色 → 导航有可见反馈。
|
||||||
|
/// Label 基色设为白,由 ColorBlock 决定静态/高亮/选中的可见色。
|
||||||
|
/// </summary>
|
||||||
private static void StyleAsTextButton(GameObject buttonGo, float fontSize = 34f)
|
private static void StyleAsTextButton(GameObject buttonGo, float fontSize = 34f)
|
||||||
{
|
{
|
||||||
var img = buttonGo.GetComponent<Image>();
|
var img = buttonGo.GetComponent<Image>();
|
||||||
if (img != null) img.color = new Color(1f, 1f, 1f, 0f); // 透明底,仍可作 raycast target
|
if (img != null) { img.color = new Color(1f, 1f, 1f, 0f); img.raycastTarget = true; } // 透明底仍作 raycast target
|
||||||
var label = GetButtonLabel(buttonGo);
|
var label = GetButtonLabel(buttonGo);
|
||||||
if (label != null)
|
if (label == null) return;
|
||||||
{
|
|
||||||
label.fontSize = fontSize;
|
label.fontSize = fontSize;
|
||||||
label.fontStyle = FontStyles.Normal;
|
label.fontStyle = FontStyles.Normal;
|
||||||
label.color = GoldText;
|
label.color = Color.white; // 基色白,实际可见色由 ColorBlock × 该色得到
|
||||||
|
|
||||||
|
var btn = buttonGo.GetComponent<Button>();
|
||||||
|
if (btn == null) return;
|
||||||
|
btn.targetGraphic = label; // 文字作为着色目标 → 选中/悬停可见
|
||||||
|
var c = btn.colors;
|
||||||
|
c.normalColor = new Color(0.60f, 0.56f, 0.42f, 1f); // 静态:暗金
|
||||||
|
c.highlightedColor = new Color(1f, 0.95f, 0.72f, 1f); // 鼠标悬停:亮金
|
||||||
|
c.selectedColor = new Color(1f, 0.95f, 0.72f, 1f); // 键盘/手柄选中:亮金
|
||||||
|
c.pressedColor = new Color(1f, 0.82f, 0.38f, 1f);
|
||||||
|
c.disabledColor = new Color(0.4f, 0.4f, 0.4f, 0.5f);
|
||||||
|
c.colorMultiplier = 1f; c.fadeDuration = 0.1f;
|
||||||
|
btn.colors = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 给含 TMP_Text 的节点挂上 <see cref="BaseGames.Localization.LocalizedText"/> 并绑定本地化 key(UI 表)。
|
||||||
|
/// 自动绑定 FontConfig(语言切换时换 CJK 字体),并立即刷新编辑器预览(显示当前语言文本)。
|
||||||
|
/// </summary>
|
||||||
|
private static void BindLocalizedText(GameObject textGo, string key)
|
||||||
|
{
|
||||||
|
if (textGo == null || textGo.GetComponent<TMP_Text>() == null) return;
|
||||||
|
var loc = GetOrAddComponent<BaseGames.Localization.LocalizedText>(textGo);
|
||||||
|
var so = new SerializedObject(loc);
|
||||||
|
so.FindProperty("_key").stringValue = key;
|
||||||
|
var fontCfg = FindFirstAssetByType<BaseGames.Localization.LanguageFontConfigSO>("FontConfig");
|
||||||
|
if (fontCfg != null) so.FindProperty("_fontConfig").objectReferenceValue = fontCfg;
|
||||||
|
so.ApplyModifiedPropertiesWithoutUndo();
|
||||||
|
loc.UpdateEditorPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>给 GetOrCreateButtonChild 生成的按钮的 "Label" 子节点绑定本地化 key。</summary>
|
||||||
|
private static void BindLocalizedButton(GameObject buttonGo, string key)
|
||||||
|
{
|
||||||
|
var label = GetButtonLabel(buttonGo);
|
||||||
|
if (label != null) BindLocalizedText(label.gameObject, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────────────────────────────
|
||||||
|
// 设置控件辅助(复用 Unity DefaultControls / TMP_DefaultControls 标准控件层级)
|
||||||
|
// ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
private static UnityEngine.UI.DefaultControls.Resources _uiRes;
|
||||||
|
private static UnityEngine.UI.DefaultControls.Resources UIRes()
|
||||||
|
{
|
||||||
|
if (_uiRes.standard == null)
|
||||||
|
_uiRes = new UnityEngine.UI.DefaultControls.Resources
|
||||||
|
{
|
||||||
|
standard = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/UISprite.psd"),
|
||||||
|
background = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/Background.psd"),
|
||||||
|
inputField = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/InputFieldBackground.psd"),
|
||||||
|
knob = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/Knob.psd"),
|
||||||
|
checkmark = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/Checkmark.psd"),
|
||||||
|
dropdown = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/DropdownArrow.psd"),
|
||||||
|
mask = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/UIMask.psd"),
|
||||||
|
};
|
||||||
|
return _uiRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TMPro.TMP_DefaultControls.Resources _tmpRes;
|
||||||
|
private static TMPro.TMP_DefaultControls.Resources TMPRes()
|
||||||
|
{
|
||||||
|
if (_tmpRes.standard == null)
|
||||||
|
_tmpRes = new TMPro.TMP_DefaultControls.Resources
|
||||||
|
{
|
||||||
|
standard = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/UISprite.psd"),
|
||||||
|
background = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/Background.psd"),
|
||||||
|
inputField = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/InputFieldBackground.psd"),
|
||||||
|
knob = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/Knob.psd"),
|
||||||
|
checkmark = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/Checkmark.psd"),
|
||||||
|
dropdown = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/DropdownArrow.psd"),
|
||||||
|
mask = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/UIMask.psd"),
|
||||||
|
};
|
||||||
|
return _tmpRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>将控件 RectTransform 放到行的右半区(横向拉伸、固定高度、垂直居中)。</summary>
|
||||||
|
private static void PlaceRightHalf(RectTransform rt, float height, float rightInset = 12f)
|
||||||
|
{
|
||||||
|
rt.anchorMin = new Vector2(0.5f, 0.5f);
|
||||||
|
rt.anchorMax = new Vector2(1f, 0.5f);
|
||||||
|
rt.pivot = new Vector2(0.5f, 0.5f);
|
||||||
|
rt.offsetMin = new Vector2(8f, -height / 2f);
|
||||||
|
rt.offsetMax = new Vector2(-rightInset, height / 2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>创建/获取一行设置项(左侧本地化标签 + 右半区控件,由调用方填充),返回行 RectTransform。</summary>
|
||||||
|
private static RectTransform CreateSettingRow(Transform content, string name, string labelKey)
|
||||||
|
{
|
||||||
|
var row = GetOrCreateUIChild(content, name);
|
||||||
|
var le = GetOrAddComponent<LayoutElement>(row.gameObject);
|
||||||
|
le.preferredHeight = 56f; le.minHeight = 50f;
|
||||||
|
var label = GetOrCreateText(row, "Label", labelKey, 26f, GoldText, TextAlignmentOptions.MidlineLeft);
|
||||||
|
SetRect((RectTransform)label.transform, new Vector2(0f, 0f), new Vector2(0.5f, 1f), new Vector2(0f, 0.5f), new Vector2(12f, 0f), Vector2.zero);
|
||||||
|
((RectTransform)label.transform).offsetMin = new Vector2(12f, 0f);
|
||||||
|
((RectTransform)label.transform).offsetMax = new Vector2(0f, 0f);
|
||||||
|
BindLocalizedText(label.gameObject, labelKey);
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Slider GetOrCreateSliderInRow(RectTransform row, float min, float max, float val, float rightInset = 12f)
|
||||||
|
{
|
||||||
|
var existing = row.Find("Slider");
|
||||||
|
GameObject go;
|
||||||
|
if (existing != null && existing.GetComponent<Slider>() != null) go = existing.gameObject;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (existing != null) Undo.DestroyObjectImmediate(existing.gameObject);
|
||||||
|
go = UnityEngine.UI.DefaultControls.CreateSlider(UIRes());
|
||||||
|
go.name = "Slider";
|
||||||
|
Undo.RegisterCreatedObjectUndo(go, "Create Slider");
|
||||||
|
go.transform.SetParent(row, false);
|
||||||
|
}
|
||||||
|
PlaceRightHalf((RectTransform)go.transform, 20f, rightInset);
|
||||||
|
var s = go.GetComponent<Slider>();
|
||||||
|
s.minValue = min; s.maxValue = max; s.value = val;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Toggle GetOrCreateToggleInRow(RectTransform row)
|
||||||
|
{
|
||||||
|
var existing = row.Find("Toggle");
|
||||||
|
GameObject go;
|
||||||
|
if (existing != null && existing.GetComponent<Toggle>() != null) go = existing.gameObject;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (existing != null) Undo.DestroyObjectImmediate(existing.gameObject);
|
||||||
|
go = UnityEngine.UI.DefaultControls.CreateToggle(UIRes());
|
||||||
|
go.name = "Toggle";
|
||||||
|
Undo.RegisterCreatedObjectUndo(go, "Create Toggle");
|
||||||
|
go.transform.SetParent(row, false);
|
||||||
|
}
|
||||||
|
// 隐藏勾选框自带的 Label(设置项标签由行左侧统一提供)
|
||||||
|
var lbl = go.transform.Find("Label");
|
||||||
|
if (lbl != null) lbl.gameObject.SetActive(false);
|
||||||
|
PlaceRightHalf((RectTransform)go.transform, 28f);
|
||||||
|
return go.GetComponent<Toggle>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TMPro.TMP_Dropdown GetOrCreateDropdownInRow(RectTransform row, string[] options)
|
||||||
|
{
|
||||||
|
var existing = row.Find("Dropdown");
|
||||||
|
GameObject go;
|
||||||
|
if (existing != null && existing.GetComponent<TMPro.TMP_Dropdown>() != null) go = existing.gameObject;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (existing != null) Undo.DestroyObjectImmediate(existing.gameObject);
|
||||||
|
go = TMPro.TMP_DefaultControls.CreateDropdown(TMPRes());
|
||||||
|
go.name = "Dropdown";
|
||||||
|
Undo.RegisterCreatedObjectUndo(go, "Create Dropdown");
|
||||||
|
go.transform.SetParent(row, false);
|
||||||
|
}
|
||||||
|
PlaceRightHalf((RectTransform)go.transform, 36f);
|
||||||
|
var dd = go.GetComponent<TMPro.TMP_Dropdown>();
|
||||||
|
dd.options.Clear();
|
||||||
|
foreach (var o in options) dd.options.Add(new TMPro.TMP_Dropdown.OptionData(o));
|
||||||
|
dd.value = 0;
|
||||||
|
dd.RefreshShownValue();
|
||||||
|
return dd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────────────────────────────
|
||||||
|
// 设置面板 / 制作团队面板构建器
|
||||||
|
// ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// <summary>构建设置面板内容(音量 / 画面 / 可访问性 / 语言)并绑定 SettingsPanelController 全部字段。</summary>
|
||||||
|
private static void BuildSettingsPanel(GameObject panelGo, MainMenuController menuCtrl, List<string> report)
|
||||||
|
{
|
||||||
|
var ctrl = GetOrAddComponent<BaseGames.UI.SettingsPanelController>(panelGo);
|
||||||
|
|
||||||
|
GetOrCreateImage(panelGo.transform, "Overlay", new Color(0.04f, 0.05f, 0.08f, 0.97f), true).transform.SetAsFirstSibling();
|
||||||
|
|
||||||
|
var titleTmp = GetOrCreateText(panelGo.transform, "PanelTitle", "Settings", 56f, GoldText, TextAlignmentOptions.Center);
|
||||||
|
titleTmp.fontStyle = FontStyles.Bold;
|
||||||
|
SetRect((RectTransform)titleTmp.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -70f), new Vector2(900f, 80f));
|
||||||
|
BindLocalizedText(titleTmp.gameObject, "SETTINGS_TITLE");
|
||||||
|
|
||||||
|
var content = GetOrCreateUIChild(panelGo.transform, "Content");
|
||||||
|
SetRect(content, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, -10f), new Vector2(860f, 720f));
|
||||||
|
var vlg = GetOrAddComponent<VerticalLayoutGroup>(content.gameObject);
|
||||||
|
vlg.spacing = 8f; vlg.childAlignment = TextAnchor.UpperCenter;
|
||||||
|
vlg.childControlWidth = true; vlg.childControlHeight = true;
|
||||||
|
vlg.childForceExpandWidth = true; vlg.childForceExpandHeight = false;
|
||||||
|
|
||||||
|
// 音量
|
||||||
|
var rMaster = CreateSettingRow(content, "Row_Master", "SETTINGS_MASTER_VOLUME");
|
||||||
|
var rBgm = CreateSettingRow(content, "Row_BGM", "SETTINGS_BGM_VOLUME");
|
||||||
|
var rSfx = CreateSettingRow(content, "Row_SFX", "SETTINGS_SFX_VOLUME");
|
||||||
|
var rAmbient = CreateSettingRow(content, "Row_Ambient", "SETTINGS_AMBIENT_VOLUME");
|
||||||
|
var sMaster = GetOrCreateSliderInRow(rMaster, 0f, 1f, 1f);
|
||||||
|
var sBgm = GetOrCreateSliderInRow(rBgm, 0f, 1f, 0.8f);
|
||||||
|
var sSfx = GetOrCreateSliderInRow(rSfx, 0f, 1f, 1f);
|
||||||
|
var sAmbient = GetOrCreateSliderInRow(rAmbient, 0f, 1f, 0.8f);
|
||||||
|
|
||||||
|
// 画面
|
||||||
|
var rVsync = CreateSettingRow(content, "Row_VSync", "SETTINGS_VSYNC");
|
||||||
|
var tVsync = GetOrCreateToggleInRow(rVsync);
|
||||||
|
var rFps = CreateSettingRow(content, "Row_FPS", "SETTINGS_FPS");
|
||||||
|
var dFps = GetOrCreateDropdownInRow(rFps, new[] { "30", "60", "120", "∞" });
|
||||||
|
|
||||||
|
// 可访问性
|
||||||
|
var rUiScale = CreateSettingRow(content, "Row_UIScale", "SETTINGS_UI_SCALE");
|
||||||
|
var sUiScale = GetOrCreateSliderInRow(rUiScale, 0.8f, 1.5f, 1f, 76f);
|
||||||
|
var uiScaleVal = GetOrCreateText(rUiScale, "ValueText", "100%", 22f, new Color(0.8f,0.78f,0.7f,1f), TextAlignmentOptions.MidlineRight);
|
||||||
|
SetRect((RectTransform)uiScaleVal.transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-12f, 0f), new Vector2(64f, 36f));
|
||||||
|
var rColorblind = CreateSettingRow(content, "Row_Colorblind", "SETTINGS_COLORBLIND");
|
||||||
|
var dColorblind = GetOrCreateDropdownInRow(rColorblind, new[] { "关闭", "红色盲", "绿色盲", "蓝黄色盲" });
|
||||||
|
var rShake = CreateSettingRow(content, "Row_ScreenShake", "SETTINGS_SCREEN_SHAKE");
|
||||||
|
var tShake = GetOrCreateToggleInRow(rShake);
|
||||||
|
|
||||||
|
// 语言
|
||||||
|
var rLang = CreateSettingRow(content, "Row_Language", "SETTINGS_LANGUAGE");
|
||||||
|
var dLang = GetOrCreateDropdownInRow(rLang, new[] { "中文", "English", "日本語", "한국어" });
|
||||||
|
|
||||||
|
// 绑定 SettingsPanelController 字段
|
||||||
|
AssignReference(ctrl, "_masterVolume", sMaster);
|
||||||
|
AssignReference(ctrl, "_bgmVolume", sBgm);
|
||||||
|
AssignReference(ctrl, "_sfxVolume", sSfx);
|
||||||
|
AssignReference(ctrl, "_ambientVolume", sAmbient);
|
||||||
|
AssignReference(ctrl, "_vSyncToggle", tVsync);
|
||||||
|
AssignReference(ctrl, "_fpsDropdown", dFps);
|
||||||
|
AssignReference(ctrl, "_uiScaleSlider", sUiScale);
|
||||||
|
AssignReference(ctrl, "_uiScaleValueText", uiScaleVal);
|
||||||
|
AssignReference(ctrl, "_colorblindDropdown", dColorblind);
|
||||||
|
AssignReference(ctrl, "_screenShakeToggle", tShake);
|
||||||
|
AssignReference(ctrl, "_languageDropdown", dLang);
|
||||||
|
|
||||||
|
// 返回按钮
|
||||||
|
GameObject backGo = GetOrCreateButtonChild(panelGo.transform, "BackButton", "Back");
|
||||||
|
SetRect((RectTransform)backGo.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 60f), new Vector2(260f, 64f));
|
||||||
|
StyleAsTextButton(backGo, 30f);
|
||||||
|
BindLocalizedButton(backGo, "BTN_BACK");
|
||||||
|
AssignReference(menuCtrl, "_btnCloseSettings", backGo.GetComponent<Button>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>构建制作团队面板(标题 + 滚动正文 + 返回)。</summary>
|
||||||
|
private static void BuildCreditsPanel(GameObject panelGo, MainMenuController menuCtrl, List<string> report)
|
||||||
|
{
|
||||||
|
GetOrCreateImage(panelGo.transform, "Overlay", new Color(0.04f, 0.05f, 0.08f, 0.97f), true).transform.SetAsFirstSibling();
|
||||||
|
|
||||||
|
var titleTmp = GetOrCreateText(panelGo.transform, "PanelTitle", "Credits", 56f, GoldText, TextAlignmentOptions.Center);
|
||||||
|
titleTmp.fontStyle = FontStyles.Bold;
|
||||||
|
SetRect((RectTransform)titleTmp.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -70f), new Vector2(900f, 80f));
|
||||||
|
BindLocalizedText(titleTmp.gameObject, "CREDITS_TITLE");
|
||||||
|
|
||||||
|
var body = GetOrCreateText(panelGo.transform, "Body", "Credits", 30f, new Color(0.82f, 0.8f, 0.74f, 1f), TextAlignmentOptions.Top);
|
||||||
|
SetRect((RectTransform)body.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), new Vector2(900f, 600f));
|
||||||
|
BindLocalizedText(body.gameObject, "CREDITS_BODY");
|
||||||
|
|
||||||
|
GameObject backGo = GetOrCreateButtonChild(panelGo.transform, "BackButton", "Back");
|
||||||
|
SetRect((RectTransform)backGo.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 60f), new Vector2(260f, 64f));
|
||||||
|
StyleAsTextButton(backGo, 30f);
|
||||||
|
BindLocalizedButton(backGo, "BTN_BACK");
|
||||||
|
AssignReference(menuCtrl, "_btnCloseCredits", backGo.GetComponent<Button>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AssignReference(Object target, string propertyName, Object value)
|
private static void AssignReference(Object target, string propertyName, Object value)
|
||||||
|
|||||||
759
Assets/_Game/Scripts/Editor/UI/UIControlLibraryScaffold.cs
Normal file
759
Assets/_Game/Scripts/Editor/UI/UIControlLibraryScaffold.cs
Normal file
@@ -0,0 +1,759 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using TMPro;
|
||||||
|
using BaseGames.UI;
|
||||||
|
using BaseGames.UI.Settings;
|
||||||
|
using BaseGames.UI.MainMenu;
|
||||||
|
using BaseGames.UI.Theme;
|
||||||
|
using BaseGames.Localization;
|
||||||
|
using BaseGames.Editor.Localization;
|
||||||
|
|
||||||
|
namespace BaseGames.Editor.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// UI 通用控件库脚手架。
|
||||||
|
///
|
||||||
|
/// 一键生成 / 更新 themed 控件预制件(UIButton / UISelectableRow / UISlider / UIDropdown /
|
||||||
|
/// UISimplePanel / UITabGroup),并提供"向选中节点放置控件"菜单,使策划可拖拽即用。
|
||||||
|
///
|
||||||
|
/// 预制件输出目录:Assets/_Game/Prefabs/UI/Controls/(命名前缀 UI_,符合 AssetFolderSpec)。
|
||||||
|
/// 构建方式复用 Unity/TMP 的 DefaultControls 标准层级,再挂上本项目的封装组件与 UIThemeRole 标记。
|
||||||
|
///
|
||||||
|
/// 菜单:BaseGames/UI/控件库/...
|
||||||
|
/// </summary>
|
||||||
|
public static class UIControlLibraryScaffold
|
||||||
|
{
|
||||||
|
private const string ControlsDir = "Assets/_Game/Prefabs/UI/Controls";
|
||||||
|
private const string ThemeDir = "Assets/_Game/Data/UI/Themes";
|
||||||
|
private const string ThemeName = "UI_Theme_Default";
|
||||||
|
|
||||||
|
// 生成期间的默认主题(GenerateAll 开头确保存在;各 Build 方法读取)
|
||||||
|
private static UIThemeSO s_theme;
|
||||||
|
|
||||||
|
// 预制件文件名
|
||||||
|
private const string PfButton = "UI_Control_Button";
|
||||||
|
private const string PfRow = "UI_Control_SelectableRow";
|
||||||
|
private const string PfSlider = "UI_Control_Slider";
|
||||||
|
private const string PfDropdown = "UI_Control_Dropdown";
|
||||||
|
private const string PfPanel = "UI_Control_Panel";
|
||||||
|
private const string PfTabBar = "UI_Control_TabBar";
|
||||||
|
|
||||||
|
// ── 生成 ─────────────────────────────────────────────────────────────
|
||||||
|
[MenuItem("BaseGames/UI/控件库/生成或更新控件预制件")]
|
||||||
|
public static void GenerateAll()
|
||||||
|
{
|
||||||
|
EnsureFolder(ControlsDir);
|
||||||
|
var report = new List<string>();
|
||||||
|
s_theme = EnsureDefaultTheme(report);
|
||||||
|
|
||||||
|
BuildButton(report);
|
||||||
|
BuildSelectableRow(report);
|
||||||
|
BuildSlider(report);
|
||||||
|
BuildDropdown(report);
|
||||||
|
BuildPanel(report);
|
||||||
|
BuildTabBar(report);
|
||||||
|
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
|
||||||
|
var sb = new System.Text.StringBuilder("[UIControlLibrary] 控件预制件已生成/更新:\n");
|
||||||
|
foreach (var r in report) sb.AppendLine(" • " + r);
|
||||||
|
sb.AppendLine($"目录:{ControlsDir}/(占位配色,可挂 UIThemeApplier + UIThemeSO 统一主题)");
|
||||||
|
Debug.Log(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 放置 ─────────────────────────────────────────────────────────────
|
||||||
|
[MenuItem("BaseGames/UI/控件库/向选中节点放置 ▸ Button")]
|
||||||
|
private static void PlaceButton() => Place(PfButton);
|
||||||
|
[MenuItem("BaseGames/UI/控件库/向选中节点放置 ▸ SelectableRow")]
|
||||||
|
private static void PlaceRow() => Place(PfRow);
|
||||||
|
[MenuItem("BaseGames/UI/控件库/向选中节点放置 ▸ Slider")]
|
||||||
|
private static void PlaceSlider() => Place(PfSlider);
|
||||||
|
[MenuItem("BaseGames/UI/控件库/向选中节点放置 ▸ Dropdown")]
|
||||||
|
private static void PlaceDropdown() => Place(PfDropdown);
|
||||||
|
[MenuItem("BaseGames/UI/控件库/向选中节点放置 ▸ Panel")]
|
||||||
|
private static void PlacePanel() => Place(PfPanel);
|
||||||
|
[MenuItem("BaseGames/UI/控件库/向选中节点放置 ▸ TabBar")]
|
||||||
|
private static void PlaceTabBar() => Place(PfTabBar);
|
||||||
|
|
||||||
|
private static void Place(string prefabName)
|
||||||
|
{
|
||||||
|
string path = $"{ControlsDir}/{prefabName}.prefab";
|
||||||
|
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
||||||
|
if (prefab == null)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("控件库",
|
||||||
|
$"未找到预制件:{path}\n请先执行「生成或更新控件预制件」。", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 父节点:当前选中的 Transform,否则活动场景中的第一个 Canvas
|
||||||
|
Transform parent = Selection.activeTransform;
|
||||||
|
if (parent == null)
|
||||||
|
{
|
||||||
|
var canvas = Object.FindObjectOfType<Canvas>();
|
||||||
|
parent = canvas != null ? canvas.transform : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var instance = (GameObject)PrefabUtility.InstantiatePrefab(prefab, parent);
|
||||||
|
if (instance == null) return;
|
||||||
|
Undo.RegisterCreatedObjectUndo(instance, $"Place {prefabName}");
|
||||||
|
Selection.activeGameObject = instance;
|
||||||
|
EditorGUIUtility.PingObject(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 默认主题 ─────────────────────────────────────────────────────────
|
||||||
|
private static UIThemeSO EnsureDefaultTheme(List<string> report)
|
||||||
|
{
|
||||||
|
EnsureFolder(ThemeDir);
|
||||||
|
string path = $"{ThemeDir}/{ThemeName}.asset";
|
||||||
|
var theme = AssetDatabase.LoadAssetAtPath<UIThemeSO>(path);
|
||||||
|
if (theme == null)
|
||||||
|
{
|
||||||
|
theme = ScriptableObject.CreateInstance<UIThemeSO>(); // 字段含默认配色
|
||||||
|
AssetDatabase.CreateAsset(theme, path);
|
||||||
|
report.Add($"{path}(默认主题,可调色板/字体)");
|
||||||
|
}
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 各控件构建 ───────────────────────────────────────────────────────
|
||||||
|
private static void BuildButton(List<string> report)
|
||||||
|
{
|
||||||
|
var go = TMP_DefaultControls.CreateButton(TmpResources());
|
||||||
|
go.name = PfButton;
|
||||||
|
Size(go, 200, 48);
|
||||||
|
|
||||||
|
var uiBtn = GetOrAdd<UIButton>(go);
|
||||||
|
if (s_theme != null) AssignRef(uiBtn, "_theme", s_theme);
|
||||||
|
SetEnum(GetOrAdd<UIThemeRole>(go), "_kind", (int)UIThemeRoleKind.Button);
|
||||||
|
|
||||||
|
var label = go.GetComponentInChildren<TMP_Text>();
|
||||||
|
if (label != null)
|
||||||
|
{
|
||||||
|
label.text = "Button";
|
||||||
|
SetEnum(GetOrAdd<UIThemeRole>(label.gameObject), "_kind", (int)UIThemeRoleKind.Text_Primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveAsPrefab(go, PfButton, report);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void BuildSelectableRow(List<string> report)
|
||||||
|
{
|
||||||
|
var go = NewUI(PfRow, 320, 48);
|
||||||
|
var bg = go.AddComponent<Image>();
|
||||||
|
bg.sprite = Standard(); bg.type = Image.Type.Sliced;
|
||||||
|
bg.color = new Color(1f, 1f, 1f, 0.06f);
|
||||||
|
|
||||||
|
var btn = go.AddComponent<Button>();
|
||||||
|
btn.targetGraphic = bg;
|
||||||
|
var row = go.AddComponent<UISelectableRow>();
|
||||||
|
|
||||||
|
// 选中高亮(铺底,置于内容之下,默认隐藏)
|
||||||
|
var highlight = NewUIChild(go.transform, "SelectedHighlight", out var hlRt);
|
||||||
|
Stretch(hlRt);
|
||||||
|
var hlImg = highlight.AddComponent<Image>();
|
||||||
|
hlImg.color = new Color(0.20f, 0.65f, 1f, 0.35f);
|
||||||
|
SetEnum(highlight.AddComponent<UIThemeRole>(), "_kind", (int)UIThemeRoleKind.Graphic_Accent);
|
||||||
|
highlight.SetActive(false);
|
||||||
|
|
||||||
|
// 图标
|
||||||
|
var iconGo = NewUIChild(go.transform, "Icon", out var iconRt);
|
||||||
|
iconRt.anchorMin = new Vector2(0, 0.5f); iconRt.anchorMax = new Vector2(0, 0.5f);
|
||||||
|
iconRt.pivot = new Vector2(0, 0.5f); iconRt.anchoredPosition = new Vector2(10, 0);
|
||||||
|
iconRt.sizeDelta = new Vector2(32, 32);
|
||||||
|
var icon = iconGo.AddComponent<Image>(); icon.enabled = false;
|
||||||
|
|
||||||
|
// 标签
|
||||||
|
var labelGo = NewUIChild(go.transform, "Label", out var labelRt);
|
||||||
|
labelRt.anchorMin = new Vector2(0, 0); labelRt.anchorMax = new Vector2(1, 1);
|
||||||
|
labelRt.offsetMin = new Vector2(52, 0); labelRt.offsetMax = new Vector2(-12, 0);
|
||||||
|
var label = labelGo.AddComponent<TextMeshProUGUI>();
|
||||||
|
label.text = "Row"; label.alignment = TextAlignmentOptions.MidlineLeft; label.fontSize = 20;
|
||||||
|
SetEnum(labelGo.AddComponent<UIThemeRole>(), "_kind", (int)UIThemeRoleKind.Text_Primary);
|
||||||
|
|
||||||
|
AssignRef(row, "_button", btn);
|
||||||
|
AssignRef(row, "_label", label);
|
||||||
|
AssignRef(row, "_icon", icon);
|
||||||
|
AssignRef(row, "_selectedHighlight", highlight);
|
||||||
|
|
||||||
|
SaveAsPrefab(go, PfRow, report);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void BuildSlider(List<string> report)
|
||||||
|
{
|
||||||
|
var go = DefaultControls.CreateSlider(UiResources());
|
||||||
|
go.name = PfSlider;
|
||||||
|
Size(go, 240, 24);
|
||||||
|
|
||||||
|
var slider = go.GetComponent<Slider>();
|
||||||
|
var ui = GetOrAdd<UISlider>(go);
|
||||||
|
|
||||||
|
// 数值标签(右侧)
|
||||||
|
var labelGo = NewUIChild(go.transform, "ValueLabel", out var labelRt);
|
||||||
|
labelRt.anchorMin = new Vector2(1, 0.5f); labelRt.anchorMax = new Vector2(1, 0.5f);
|
||||||
|
labelRt.pivot = new Vector2(0, 0.5f); labelRt.anchoredPosition = new Vector2(8, 0);
|
||||||
|
labelRt.sizeDelta = new Vector2(48, 24);
|
||||||
|
var label = labelGo.AddComponent<TextMeshProUGUI>();
|
||||||
|
label.text = "0"; label.alignment = TextAlignmentOptions.MidlineLeft; label.fontSize = 18;
|
||||||
|
SetEnum(labelGo.AddComponent<UIThemeRole>(), "_kind", (int)UIThemeRoleKind.Text_Secondary);
|
||||||
|
|
||||||
|
AssignRef(ui, "_slider", slider);
|
||||||
|
AssignRef(ui, "_valueLabel", label);
|
||||||
|
|
||||||
|
SaveAsPrefab(go, PfSlider, report);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void BuildDropdown(List<string> report)
|
||||||
|
{
|
||||||
|
var go = TMP_DefaultControls.CreateDropdown(TmpResources());
|
||||||
|
go.name = PfDropdown;
|
||||||
|
Size(go, 200, 40);
|
||||||
|
|
||||||
|
var dd = go.GetComponent<TMP_Dropdown>();
|
||||||
|
var ui = GetOrAdd<UIDropdown>(go);
|
||||||
|
AssignRef(ui, "_dropdown", dd);
|
||||||
|
|
||||||
|
SaveAsPrefab(go, PfDropdown, report);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void BuildPanel(List<string> report)
|
||||||
|
{
|
||||||
|
var go = NewUI(PfPanel, 480, 320);
|
||||||
|
var bg = go.AddComponent<Image>();
|
||||||
|
bg.sprite = Background(); bg.type = Image.Type.Sliced;
|
||||||
|
bg.color = new Color(0.06f, 0.07f, 0.10f, 0.96f);
|
||||||
|
SetEnum(go.AddComponent<UIThemeRole>(), "_kind", (int)UIThemeRoleKind.Graphic_Background);
|
||||||
|
|
||||||
|
go.AddComponent<CanvasGroup>();
|
||||||
|
var applier = go.AddComponent<UIThemeApplier>();
|
||||||
|
if (s_theme != null) AssignRef(applier, "_theme", s_theme);
|
||||||
|
var panel = go.AddComponent<UISimplePanel>();
|
||||||
|
AssignRef(panel, "_canvasGroup", go.GetComponent<CanvasGroup>());
|
||||||
|
|
||||||
|
// 标题
|
||||||
|
var titleGo = NewUIChild(go.transform, "Title", out var titleRt);
|
||||||
|
titleRt.anchorMin = new Vector2(0, 1); titleRt.anchorMax = new Vector2(1, 1);
|
||||||
|
titleRt.pivot = new Vector2(0.5f, 1); titleRt.anchoredPosition = new Vector2(0, -16);
|
||||||
|
titleRt.sizeDelta = new Vector2(-32, 40);
|
||||||
|
var title = titleGo.AddComponent<TextMeshProUGUI>();
|
||||||
|
title.text = "Panel"; title.alignment = TextAlignmentOptions.Top; title.fontSize = 28;
|
||||||
|
SetEnum(titleGo.AddComponent<UIThemeRole>(), "_kind", (int)UIThemeRoleKind.Text_Header);
|
||||||
|
|
||||||
|
SaveAsPrefab(go, PfPanel, report);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void BuildTabBar(List<string> report)
|
||||||
|
{
|
||||||
|
var go = NewUI(PfTabBar, 480, 360);
|
||||||
|
var tabGroup = go.AddComponent<UITabGroup>();
|
||||||
|
|
||||||
|
// 头部按钮行
|
||||||
|
var headerGo = NewUIChild(go.transform, "Header", out var headerRt);
|
||||||
|
headerRt.anchorMin = new Vector2(0, 1); headerRt.anchorMax = new Vector2(1, 1);
|
||||||
|
headerRt.pivot = new Vector2(0.5f, 1); headerRt.anchoredPosition = Vector2.zero;
|
||||||
|
headerRt.sizeDelta = new Vector2(0, 44);
|
||||||
|
var hLayout = headerGo.AddComponent<HorizontalLayoutGroup>();
|
||||||
|
hLayout.spacing = 4; hLayout.childForceExpandWidth = true; hLayout.childForceExpandHeight = true;
|
||||||
|
|
||||||
|
// 内容容器
|
||||||
|
var contentGo = NewUIChild(go.transform, "Content", out var contentRt);
|
||||||
|
contentRt.anchorMin = Vector2.zero; contentRt.anchorMax = Vector2.one;
|
||||||
|
contentRt.offsetMin = new Vector2(0, 0); contentRt.offsetMax = new Vector2(0, -48);
|
||||||
|
|
||||||
|
var tabs = new (GameObject content, Button btn, GameObject hl)[2];
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
var (btn, hl) = MakeTabHeader(headerGo.transform, $"Tab{i}Header", $"Tab {i + 1}");
|
||||||
|
var tabContent = NewUIChild(contentGo.transform, $"Tab{i}Content", out var tcRt);
|
||||||
|
Stretch(tcRt);
|
||||||
|
var tcImg = tabContent.AddComponent<Image>();
|
||||||
|
tcImg.color = new Color(1f, 1f, 1f, 0.03f);
|
||||||
|
var lblGo = NewUIChild(tabContent.transform, "Label", out var lblRt);
|
||||||
|
Stretch(lblRt);
|
||||||
|
var lbl = lblGo.AddComponent<TextMeshProUGUI>();
|
||||||
|
lbl.text = $"Tab {i + 1} 内容"; lbl.alignment = TextAlignmentOptions.Center; lbl.fontSize = 22;
|
||||||
|
if (i != 0) tabContent.SetActive(false);
|
||||||
|
tabs[i] = (tabContent, btn, hl);
|
||||||
|
}
|
||||||
|
|
||||||
|
WireTabGroup(tabGroup, tabs);
|
||||||
|
SaveAsPrefab(go, PfTabBar, report);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static (Button btn, GameObject highlight) MakeTabHeader(Transform parent, string name, string text)
|
||||||
|
{
|
||||||
|
var go = NewUIChild(parent, name, out _);
|
||||||
|
var bg = go.AddComponent<Image>();
|
||||||
|
bg.sprite = Standard(); bg.type = Image.Type.Sliced;
|
||||||
|
bg.color = new Color(1f, 1f, 1f, 0.08f);
|
||||||
|
var btn = go.AddComponent<Button>(); btn.targetGraphic = bg;
|
||||||
|
var uiBtn = GetOrAdd<UIButton>(go);
|
||||||
|
if (s_theme != null) AssignRef(uiBtn, "_theme", s_theme);
|
||||||
|
|
||||||
|
var hl = NewUIChild(go.transform, "Highlight", out var hlRt);
|
||||||
|
Stretch(hlRt);
|
||||||
|
var hlImg = hl.AddComponent<Image>();
|
||||||
|
hlImg.color = new Color(0.20f, 0.65f, 1f, 0.30f);
|
||||||
|
hl.SetActive(false);
|
||||||
|
|
||||||
|
var lblGo = NewUIChild(go.transform, "Label", out var lblRt);
|
||||||
|
Stretch(lblRt);
|
||||||
|
var lbl = lblGo.AddComponent<TextMeshProUGUI>();
|
||||||
|
lbl.text = text; lbl.alignment = TextAlignmentOptions.Center; lbl.fontSize = 20;
|
||||||
|
SetEnum(lblGo.AddComponent<UIThemeRole>(), "_kind", (int)UIThemeRoleKind.Text_Primary);
|
||||||
|
|
||||||
|
return (btn, hl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WireTabGroup(UITabGroup tabGroup, (GameObject content, Button btn, GameObject hl)[] tabs)
|
||||||
|
{
|
||||||
|
var so = new SerializedObject(tabGroup);
|
||||||
|
var prop = so.FindProperty("_tabs");
|
||||||
|
prop.arraySize = tabs.Length;
|
||||||
|
for (int i = 0; i < tabs.Length; i++)
|
||||||
|
{
|
||||||
|
var el = prop.GetArrayElementAtIndex(i);
|
||||||
|
el.FindPropertyRelative("content").objectReferenceValue = tabs[i].content;
|
||||||
|
el.FindPropertyRelative("headerButton").objectReferenceValue = tabs[i].btn;
|
||||||
|
el.FindPropertyRelative("headerHighlight").objectReferenceValue = tabs[i].hl;
|
||||||
|
}
|
||||||
|
so.ApplyModifiedPropertiesWithoutUndo();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ══ 设置面板(数据驱动)════════════════════════════════════════════════
|
||||||
|
private const string SchemaDir = "Assets/_Game/Data/UI";
|
||||||
|
private const string SchemaName = "UI_SettingsSchema";
|
||||||
|
private const string PfSettingHeader = "UI_Setting_Header";
|
||||||
|
private const string PfSettingSlider = "UI_Setting_SliderRow";
|
||||||
|
private const string PfSettingToggle = "UI_Setting_ToggleRow";
|
||||||
|
private const string PfSettingDrop = "UI_Setting_DropdownRow";
|
||||||
|
private const string PfSettingsPanel = "UI_SettingsPanel";
|
||||||
|
|
||||||
|
[MenuItem("BaseGames/UI/控件库/生成设置面板(行预制件 + 默认表 + 面板)")]
|
||||||
|
public static void GenerateSettings()
|
||||||
|
{
|
||||||
|
EnsureFolder(ControlsDir);
|
||||||
|
EnsureFolder(SchemaDir);
|
||||||
|
var report = new List<string>();
|
||||||
|
s_theme = EnsureDefaultTheme(report);
|
||||||
|
|
||||||
|
var header = BuildSettingHeader(report);
|
||||||
|
var slider = BuildSettingSliderRow(report);
|
||||||
|
var toggle = BuildSettingToggleRow(report);
|
||||||
|
var dropdown = BuildSettingDropdownRow(report);
|
||||||
|
var schema = EnsureDefaultSchema(report);
|
||||||
|
BuildSettingsPanel(report, header, slider, toggle, dropdown, schema);
|
||||||
|
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
|
||||||
|
var sb = new System.Text.StringBuilder("[UIControlLibrary] 数据驱动设置面板已生成:\n");
|
||||||
|
foreach (var r in report) sb.AppendLine(" • " + r);
|
||||||
|
sb.AppendLine("标签 Key(SET_*)请用「BaseGames/Localization/表格编辑器」补译文;改 UI_SettingsSchema 即可增删/重排设置项。");
|
||||||
|
Debug.Log(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GameObject BuildSettingHeader(List<string> report)
|
||||||
|
{
|
||||||
|
var go = NewUI(PfSettingHeader, 480, 32);
|
||||||
|
var lblGo = NewUIChild(go.transform, "Label", out var rt);
|
||||||
|
Stretch(rt);
|
||||||
|
var lbl = lblGo.AddComponent<TextMeshProUGUI>();
|
||||||
|
lbl.text = "Section"; lbl.fontSize = 22; lbl.alignment = TextAlignmentOptions.MidlineLeft;
|
||||||
|
lblGo.AddComponent<BaseGames.Localization.LocalizedText>();
|
||||||
|
SetEnum(lblGo.AddComponent<UIThemeRole>(), "_kind", (int)UIThemeRoleKind.Text_Header);
|
||||||
|
return SaveAsPrefab(go, PfSettingHeader, report);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GameObject BuildSettingSliderRow(List<string> report)
|
||||||
|
{
|
||||||
|
var go = SettingRowRoot(PfSettingSlider, out _);
|
||||||
|
|
||||||
|
var sliderGo = DefaultControls.CreateSlider(UiResources());
|
||||||
|
sliderGo.name = "Slider"; sliderGo.transform.SetParent(go.transform, false);
|
||||||
|
var sle = sliderGo.AddComponent<LayoutElement>(); sle.flexibleWidth = 1; sle.preferredHeight = 20;
|
||||||
|
var slider = sliderGo.GetComponent<Slider>();
|
||||||
|
var uiSlider = sliderGo.AddComponent<UISlider>();
|
||||||
|
|
||||||
|
var valGo = NewUIChild(go.transform, "Value", out _);
|
||||||
|
var val = valGo.AddComponent<TextMeshProUGUI>();
|
||||||
|
val.text = "0"; val.fontSize = 18; val.alignment = TextAlignmentOptions.MidlineRight;
|
||||||
|
var vle = valGo.AddComponent<LayoutElement>(); vle.preferredWidth = 56;
|
||||||
|
SetEnum(valGo.AddComponent<UIThemeRole>(), "_kind", (int)UIThemeRoleKind.Text_Secondary);
|
||||||
|
|
||||||
|
AssignRef(uiSlider, "_slider", slider);
|
||||||
|
AssignRef(uiSlider, "_valueLabel", val);
|
||||||
|
return SaveAsPrefab(go, PfSettingSlider, report);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GameObject BuildSettingToggleRow(List<string> report)
|
||||||
|
{
|
||||||
|
var go = SettingRowRoot(PfSettingToggle, out _);
|
||||||
|
var toggleGo = DefaultControls.CreateToggle(UiResources());
|
||||||
|
toggleGo.name = "Toggle"; toggleGo.transform.SetParent(go.transform, false);
|
||||||
|
var tle = toggleGo.AddComponent<LayoutElement>(); tle.preferredWidth = 30; tle.preferredHeight = 30;
|
||||||
|
return SaveAsPrefab(go, PfSettingToggle, report);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GameObject BuildSettingDropdownRow(List<string> report)
|
||||||
|
{
|
||||||
|
var go = SettingRowRoot(PfSettingDrop, out _);
|
||||||
|
var ddGo = TMP_DefaultControls.CreateDropdown(TmpResources());
|
||||||
|
ddGo.name = "Dropdown"; ddGo.transform.SetParent(go.transform, false);
|
||||||
|
var dle = ddGo.AddComponent<LayoutElement>(); dle.flexibleWidth = 1; dle.preferredHeight = 32;
|
||||||
|
var dd = ddGo.GetComponent<TMP_Dropdown>();
|
||||||
|
var ui = ddGo.AddComponent<UIDropdown>();
|
||||||
|
AssignRef(ui, "_dropdown", dd);
|
||||||
|
return SaveAsPrefab(go, PfSettingDrop, report);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>构建带左侧本地化标签的设置行根(HorizontalLayout)。返回根,out 标签 TMP。</summary>
|
||||||
|
private static GameObject SettingRowRoot(string name, out TMP_Text label)
|
||||||
|
{
|
||||||
|
var go = NewUI(name, 480, 44);
|
||||||
|
var h = go.AddComponent<HorizontalLayoutGroup>();
|
||||||
|
h.spacing = 12; h.childAlignment = TextAnchor.MiddleLeft;
|
||||||
|
h.childForceExpandWidth = false; h.childForceExpandHeight = false;
|
||||||
|
h.childControlWidth = true; h.childControlHeight = true;
|
||||||
|
h.padding = new RectOffset(8, 8, 4, 4);
|
||||||
|
|
||||||
|
var lblGo = NewUIChild(go.transform, "Label", out _);
|
||||||
|
label = lblGo.AddComponent<TextMeshProUGUI>();
|
||||||
|
label.text = "Label"; label.fontSize = 20; label.alignment = TextAlignmentOptions.MidlineLeft;
|
||||||
|
var le = lblGo.AddComponent<LayoutElement>(); le.preferredWidth = 200; le.flexibleWidth = 0;
|
||||||
|
lblGo.AddComponent<BaseGames.Localization.LocalizedText>();
|
||||||
|
SetEnum(lblGo.AddComponent<UIThemeRole>(), "_kind", (int)UIThemeRoleKind.Text_Primary);
|
||||||
|
return go;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SettingsSchemaSO EnsureDefaultSchema(List<string> report)
|
||||||
|
{
|
||||||
|
string path = $"{SchemaDir}/{SchemaName}.asset";
|
||||||
|
var schema = AssetDatabase.LoadAssetAtPath<SettingsSchemaSO>(path);
|
||||||
|
bool created = schema == null;
|
||||||
|
if (created) { schema = ScriptableObject.CreateInstance<SettingsSchemaSO>(); AssetDatabase.CreateAsset(schema, path); }
|
||||||
|
|
||||||
|
// 仅在新建时填充默认项,避免覆盖策划已有编辑
|
||||||
|
if (created)
|
||||||
|
{
|
||||||
|
var items = new (bool h, string key, SettingKey s)[]
|
||||||
|
{
|
||||||
|
(true, "SET_SECTION_AUDIO", default),
|
||||||
|
(false, "SET_MASTER_VOLUME", SettingKey.MasterVolume),
|
||||||
|
(false, "SET_BGM_VOLUME", SettingKey.BGMVolume),
|
||||||
|
(false, "SET_SFX_VOLUME", SettingKey.SFXVolume),
|
||||||
|
(false, "SET_AMBIENT_VOLUME", SettingKey.AmbientVolume),
|
||||||
|
(true, "SET_SECTION_DISPLAY", default),
|
||||||
|
(false, "SET_VSYNC", SettingKey.VSync),
|
||||||
|
(false, "SET_TARGET_FPS", SettingKey.TargetFPS),
|
||||||
|
(true, "SET_SECTION_ACCESS", default),
|
||||||
|
(false, "SET_UI_SCALE", SettingKey.UIScale),
|
||||||
|
(false, "SET_COLORBLIND", SettingKey.ColorblindMode),
|
||||||
|
(false, "SET_SCREEN_SHAKE", SettingKey.ScreenShake),
|
||||||
|
(true, "SET_SECTION_LANGUAGE", default),
|
||||||
|
(false, "SET_LANGUAGE", SettingKey.Language),
|
||||||
|
};
|
||||||
|
var so = new SerializedObject(schema);
|
||||||
|
var prop = so.FindProperty("_items");
|
||||||
|
prop.arraySize = items.Length;
|
||||||
|
for (int i = 0; i < items.Length; i++)
|
||||||
|
{
|
||||||
|
var el = prop.GetArrayElementAtIndex(i);
|
||||||
|
el.FindPropertyRelative("isHeader").boolValue = items[i].h;
|
||||||
|
el.FindPropertyRelative("labelKey").stringValue = items[i].key;
|
||||||
|
el.FindPropertyRelative("key").enumValueIndex = (int)items[i].s;
|
||||||
|
}
|
||||||
|
so.ApplyModifiedPropertiesWithoutUndo();
|
||||||
|
report.Add($"{path}(默认 {items.Length} 项,可增删/重排)");
|
||||||
|
}
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void BuildSettingsPanel(List<string> report, GameObject header, GameObject slider,
|
||||||
|
GameObject toggle, GameObject dropdown, SettingsSchemaSO schema)
|
||||||
|
{
|
||||||
|
var go = NewUI(PfSettingsPanel, 540, 640);
|
||||||
|
var bg = go.AddComponent<Image>();
|
||||||
|
bg.sprite = Background(); bg.type = Image.Type.Sliced;
|
||||||
|
bg.color = new Color(0.06f, 0.07f, 0.10f, 0.96f);
|
||||||
|
SetEnum(go.AddComponent<UIThemeRole>(), "_kind", (int)UIThemeRoleKind.Graphic_Background);
|
||||||
|
var applier = go.AddComponent<UIThemeApplier>();
|
||||||
|
if (s_theme != null) AssignRef(applier, "_theme", s_theme);
|
||||||
|
|
||||||
|
var panel = go.AddComponent<DataDrivenSettingsPanel>();
|
||||||
|
|
||||||
|
// 行容器(竖向布局)
|
||||||
|
var content = NewUIChild(go.transform, "Content", out var crt);
|
||||||
|
crt.anchorMin = Vector2.zero; crt.anchorMax = Vector2.one;
|
||||||
|
crt.offsetMin = new Vector2(16, 16); crt.offsetMax = new Vector2(-16, -16);
|
||||||
|
var v = content.AddComponent<VerticalLayoutGroup>();
|
||||||
|
v.spacing = 6; v.childForceExpandWidth = true; v.childForceExpandHeight = false;
|
||||||
|
v.childControlWidth = true; v.childControlHeight = true;
|
||||||
|
v.childAlignment = TextAnchor.UpperCenter;
|
||||||
|
|
||||||
|
AssignRef(panel, "_schema", schema);
|
||||||
|
AssignRef(panel, "_container", content.transform);
|
||||||
|
AssignRef(panel, "_headerPrefab", header);
|
||||||
|
AssignRef(panel, "_sliderRowPrefab", slider);
|
||||||
|
AssignRef(panel, "_toggleRowPrefab", toggle);
|
||||||
|
AssignRef(panel, "_dropdownRowPrefab", dropdown);
|
||||||
|
|
||||||
|
SaveAsPrefab(go, PfSettingsPanel, report);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ══ 主菜单(数据驱动)════════════════════════════════════════════════
|
||||||
|
private const string PfMenuButton = "UI_MainMenu_Button";
|
||||||
|
private const string MenuConfigName = "UI_MainMenuConfig";
|
||||||
|
|
||||||
|
[MenuItem("BaseGames/UI/控件库/生成主菜单(按钮预制件 + 默认表)")]
|
||||||
|
public static void GenerateMainMenu()
|
||||||
|
{
|
||||||
|
EnsureFolder(ControlsDir);
|
||||||
|
EnsureFolder(SchemaDir);
|
||||||
|
var report = new List<string>();
|
||||||
|
s_theme = EnsureDefaultTheme(report);
|
||||||
|
|
||||||
|
BuildMainMenuButton(report);
|
||||||
|
EnsureDefaultMenuConfig(report);
|
||||||
|
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
|
||||||
|
var sb = new System.Text.StringBuilder("[UIControlLibrary] 数据驱动主菜单已生成:\n");
|
||||||
|
foreach (var r in report) sb.AppendLine(" • " + r);
|
||||||
|
sb.AppendLine("标签 MENU_* 请补译文;改 UI_MainMenuConfig 即可增删/重排菜单项。");
|
||||||
|
sb.AppendLine("用法:在 Scene_MainMenu 挂 DataDrivenMainMenuController,指定 config/container/buttonPrefab + 子面板引用。");
|
||||||
|
Debug.Log(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GameObject BuildMainMenuButton(List<string> report)
|
||||||
|
{
|
||||||
|
var go = NewUI(PfMenuButton, 300, 56);
|
||||||
|
var bg = go.AddComponent<Image>();
|
||||||
|
bg.sprite = Standard(); bg.type = Image.Type.Sliced; bg.color = new Color(1f, 1f, 1f, 0.06f);
|
||||||
|
var btn = go.AddComponent<Button>(); btn.targetGraphic = bg;
|
||||||
|
var uiBtn = GetOrAdd<UIButton>(go);
|
||||||
|
if (s_theme != null) AssignRef(uiBtn, "_theme", s_theme);
|
||||||
|
var view = go.AddComponent<MainMenuButtonView>();
|
||||||
|
|
||||||
|
var iconGo = NewUIChild(go.transform, "Icon", out var irt);
|
||||||
|
irt.anchorMin = new Vector2(0, 0.5f); irt.anchorMax = new Vector2(0, 0.5f); irt.pivot = new Vector2(0, 0.5f);
|
||||||
|
irt.anchoredPosition = new Vector2(14, 0); irt.sizeDelta = new Vector2(32, 32);
|
||||||
|
var icon = iconGo.AddComponent<Image>(); icon.enabled = false;
|
||||||
|
|
||||||
|
var lblGo = NewUIChild(go.transform, "Label", out var lrt);
|
||||||
|
lrt.anchorMin = Vector2.zero; lrt.anchorMax = Vector2.one;
|
||||||
|
lrt.offsetMin = new Vector2(56, 0); lrt.offsetMax = new Vector2(-12, 0);
|
||||||
|
var lbl = lblGo.AddComponent<TextMeshProUGUI>();
|
||||||
|
lbl.text = "Menu Item"; lbl.alignment = TextAlignmentOptions.MidlineLeft; lbl.fontSize = 24;
|
||||||
|
var loc = lblGo.AddComponent<BaseGames.Localization.LocalizedText>();
|
||||||
|
SetEnum(lblGo.AddComponent<UIThemeRole>(), "_kind", (int)UIThemeRoleKind.Text_Primary);
|
||||||
|
|
||||||
|
AssignRef(view, "_button", btn);
|
||||||
|
AssignRef(view, "_label", loc);
|
||||||
|
AssignRef(view, "_icon", icon);
|
||||||
|
return SaveAsPrefab(go, PfMenuButton, report);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MainMenuConfigSO EnsureDefaultMenuConfig(List<string> report)
|
||||||
|
{
|
||||||
|
string path = $"{SchemaDir}/{MenuConfigName}.asset";
|
||||||
|
var cfg = AssetDatabase.LoadAssetAtPath<MainMenuConfigSO>(path);
|
||||||
|
bool created = cfg == null;
|
||||||
|
if (created) { cfg = ScriptableObject.CreateInstance<MainMenuConfigSO>(); AssetDatabase.CreateAsset(cfg, path); }
|
||||||
|
|
||||||
|
if (created)
|
||||||
|
{
|
||||||
|
var items = new (string key, MainMenuAction a, bool req)[]
|
||||||
|
{
|
||||||
|
("MENU_NEW_GAME", MainMenuAction.NewGame, false),
|
||||||
|
("MENU_CONTINUE", MainMenuAction.Continue, true),
|
||||||
|
("MENU_SETTINGS", MainMenuAction.OpenSettings, false),
|
||||||
|
("MENU_CREDITS", MainMenuAction.OpenCredits, false),
|
||||||
|
("MENU_QUIT", MainMenuAction.Quit, false),
|
||||||
|
};
|
||||||
|
var so = new SerializedObject(cfg);
|
||||||
|
var prop = so.FindProperty("_items");
|
||||||
|
prop.arraySize = items.Length;
|
||||||
|
for (int i = 0; i < items.Length; i++)
|
||||||
|
{
|
||||||
|
var el = prop.GetArrayElementAtIndex(i);
|
||||||
|
el.FindPropertyRelative("labelKey").stringValue = items[i].key;
|
||||||
|
el.FindPropertyRelative("action").enumValueIndex = (int)items[i].a;
|
||||||
|
el.FindPropertyRelative("requiresSave").boolValue = items[i].req;
|
||||||
|
el.FindPropertyRelative("sceneKey").stringValue = "";
|
||||||
|
}
|
||||||
|
so.ApplyModifiedPropertiesWithoutUndo();
|
||||||
|
report.Add($"{path}(默认 {items.Length} 项菜单)");
|
||||||
|
}
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ══ 本地化补全(数据驱动面板的 SET_*/MENU_* 标签)══════════════════════
|
||||||
|
[MenuItem("BaseGames/UI/控件库/补充设置与菜单本地化(中/英)")]
|
||||||
|
public static void SeedDataDrivenUILocalization()
|
||||||
|
{
|
||||||
|
var zh = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "SET_SECTION_AUDIO", "音频" },
|
||||||
|
{ "SET_MASTER_VOLUME", "主音量" },
|
||||||
|
{ "SET_BGM_VOLUME", "音乐" },
|
||||||
|
{ "SET_SFX_VOLUME", "音效" },
|
||||||
|
{ "SET_AMBIENT_VOLUME", "环境音" },
|
||||||
|
{ "SET_SECTION_DISPLAY", "画面" },
|
||||||
|
{ "SET_VSYNC", "垂直同步" },
|
||||||
|
{ "SET_TARGET_FPS", "目标帧率" },
|
||||||
|
{ "SET_SECTION_ACCESS", "辅助功能" },
|
||||||
|
{ "SET_UI_SCALE", "界面缩放" },
|
||||||
|
{ "SET_COLORBLIND", "色盲模式" },
|
||||||
|
{ "SET_SCREEN_SHAKE", "屏幕震动" },
|
||||||
|
{ "SET_SECTION_LANGUAGE", "语言" },
|
||||||
|
{ "SET_LANGUAGE", "语言" },
|
||||||
|
{ "SET_FPS_UNLIMITED", "无限" },
|
||||||
|
{ "SET_COLORBLIND_0", "关闭" },
|
||||||
|
{ "SET_COLORBLIND_1", "红色弱(Protanopia)" },
|
||||||
|
{ "SET_COLORBLIND_2", "绿色弱(Deuteranopia)" },
|
||||||
|
{ "SET_COLORBLIND_3", "蓝色弱(Tritanopia)" },
|
||||||
|
{ "MENU_NEW_GAME", "新游戏" },
|
||||||
|
{ "MENU_CONTINUE", "继续" },
|
||||||
|
{ "MENU_SETTINGS", "设置" },
|
||||||
|
{ "MENU_CREDITS", "制作团队" },
|
||||||
|
{ "MENU_QUIT", "退出" },
|
||||||
|
};
|
||||||
|
var en = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "SET_SECTION_AUDIO", "Audio" },
|
||||||
|
{ "SET_MASTER_VOLUME", "Master Volume" },
|
||||||
|
{ "SET_BGM_VOLUME", "Music" },
|
||||||
|
{ "SET_SFX_VOLUME", "Sound Effects" },
|
||||||
|
{ "SET_AMBIENT_VOLUME", "Ambience" },
|
||||||
|
{ "SET_SECTION_DISPLAY", "Display" },
|
||||||
|
{ "SET_VSYNC", "V-Sync" },
|
||||||
|
{ "SET_TARGET_FPS", "Target FPS" },
|
||||||
|
{ "SET_SECTION_ACCESS", "Accessibility" },
|
||||||
|
{ "SET_UI_SCALE", "UI Scale" },
|
||||||
|
{ "SET_COLORBLIND", "Colorblind Mode" },
|
||||||
|
{ "SET_SCREEN_SHAKE", "Screen Shake" },
|
||||||
|
{ "SET_SECTION_LANGUAGE", "Language" },
|
||||||
|
{ "SET_LANGUAGE", "Language" },
|
||||||
|
{ "SET_FPS_UNLIMITED", "Unlimited" },
|
||||||
|
{ "SET_COLORBLIND_0", "Off" },
|
||||||
|
{ "SET_COLORBLIND_1", "Protanopia" },
|
||||||
|
{ "SET_COLORBLIND_2", "Deuteranopia" },
|
||||||
|
{ "SET_COLORBLIND_3", "Tritanopia" },
|
||||||
|
{ "MENU_NEW_GAME", "New Game" },
|
||||||
|
{ "MENU_CONTINUE", "Continue" },
|
||||||
|
{ "MENU_SETTINGS", "Settings" },
|
||||||
|
{ "MENU_CREDITS", "Credits" },
|
||||||
|
{ "MENU_QUIT", "Quit" },
|
||||||
|
};
|
||||||
|
|
||||||
|
int added = MergeWriteUI(Language.ChineseSimplified, zh)
|
||||||
|
+ MergeWriteUI(Language.English, en);
|
||||||
|
Debug.Log($"[UIControlLibrary] 已补充设置/菜单本地化(新增 {added} 条,已存在的不覆盖)。" +
|
||||||
|
"日/韩缺省走英文回退;可用「BaseGames/Localization/表格编辑器」补译。");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>把缺失的 key 合并写入指定语言的 UI 表(已存在的保留,不覆盖)。返回新增数。</summary>
|
||||||
|
private static int MergeWriteUI(Language lang, Dictionary<string, string> kv)
|
||||||
|
{
|
||||||
|
var dict = LocalizationFileIO.Read(lang, LocalizationTable.UI);
|
||||||
|
int added = 0;
|
||||||
|
foreach (var p in kv)
|
||||||
|
if (!dict.ContainsKey(p.Key)) { dict[p.Key] = p.Value; added++; }
|
||||||
|
if (added > 0) LocalizationFileIO.Write(lang, LocalizationTable.UI, dict);
|
||||||
|
return added;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 通用助手 ─────────────────────────────────────────────────────────
|
||||||
|
private static GameObject NewUI(string name, float w, float h)
|
||||||
|
{
|
||||||
|
var go = new GameObject(name, typeof(RectTransform));
|
||||||
|
((RectTransform)go.transform).sizeDelta = new Vector2(w, h);
|
||||||
|
return go;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GameObject NewUIChild(Transform parent, string name, out RectTransform rt)
|
||||||
|
{
|
||||||
|
var go = new GameObject(name, typeof(RectTransform));
|
||||||
|
rt = (RectTransform)go.transform;
|
||||||
|
rt.SetParent(parent, false);
|
||||||
|
return go;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Size(GameObject go, float w, float h)
|
||||||
|
{
|
||||||
|
if (go.transform is RectTransform rt) rt.sizeDelta = new Vector2(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Stretch(RectTransform rt)
|
||||||
|
{
|
||||||
|
rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one;
|
||||||
|
rt.offsetMin = Vector2.zero; rt.offsetMax = Vector2.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static T GetOrAdd<T>(GameObject go) where T : Component
|
||||||
|
=> go.GetComponent<T>() ?? go.AddComponent<T>();
|
||||||
|
|
||||||
|
private static void SetEnum(Component c, string prop, int value)
|
||||||
|
{
|
||||||
|
var so = new SerializedObject(c);
|
||||||
|
var p = so.FindProperty(prop);
|
||||||
|
if (p != null) { p.enumValueIndex = value; so.ApplyModifiedPropertiesWithoutUndo(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AssignRef(Object target, string prop, Object value)
|
||||||
|
{
|
||||||
|
var so = new SerializedObject(target);
|
||||||
|
var p = so.FindProperty(prop);
|
||||||
|
if (p == null) { Debug.LogWarning($"[UIControlLibrary] 未找到属性 {target.GetType().Name}.{prop}"); return; }
|
||||||
|
p.objectReferenceValue = value;
|
||||||
|
so.ApplyModifiedPropertiesWithoutUndo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GameObject SaveAsPrefab(GameObject go, string name, List<string> report)
|
||||||
|
{
|
||||||
|
string path = $"{ControlsDir}/{name}.prefab";
|
||||||
|
var asset = PrefabUtility.SaveAsPrefabAsset(go, path);
|
||||||
|
Object.DestroyImmediate(go);
|
||||||
|
report.Add(path);
|
||||||
|
return asset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnsureFolder(string dir)
|
||||||
|
{
|
||||||
|
string[] parts = dir.Split('/');
|
||||||
|
string cur = parts[0]; // "Assets"
|
||||||
|
for (int i = 1; i < parts.Length; i++)
|
||||||
|
{
|
||||||
|
string next = $"{cur}/{parts[i]}";
|
||||||
|
if (!AssetDatabase.IsValidFolder(next)) AssetDatabase.CreateFolder(cur, parts[i]);
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 内建 UI 资源(默认皮肤 sprite)──────────────────────────────────────
|
||||||
|
private static Sprite Standard() => AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/UISprite.psd");
|
||||||
|
private static Sprite Background() => AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/Background.psd");
|
||||||
|
private static Sprite Knob() => AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/Knob.psd");
|
||||||
|
private static Sprite Checkmark() => AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/Checkmark.psd");
|
||||||
|
private static Sprite DropArrow() => AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/DropdownArrow.psd");
|
||||||
|
private static Sprite Mask() => AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/UIMask.psd");
|
||||||
|
private static Sprite InputBg() => AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/InputFieldBackground.psd");
|
||||||
|
|
||||||
|
private static DefaultControls.Resources UiResources() => new DefaultControls.Resources
|
||||||
|
{
|
||||||
|
standard = Standard(), background = Background(), inputField = InputBg(),
|
||||||
|
knob = Knob(), checkmark = Checkmark(), dropdown = DropArrow(), mask = Mask(),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static TMP_DefaultControls.Resources TmpResources() => new TMP_DefaultControls.Resources
|
||||||
|
{
|
||||||
|
standard = Standard(), background = Background(), inputField = InputBg(),
|
||||||
|
knob = Knob(), checkmark = Checkmark(), dropdown = DropArrow(), mask = Mask(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2c325d7b7aebe0b4c855627035ebcf02
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -2,7 +2,8 @@ namespace BaseGames.Localization
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 游戏支持的语言列表。
|
/// 游戏支持的语言列表。
|
||||||
/// 添加新语言时同步在 Resources/Localization/ 下创建对应子目录和 JSON 表文件。
|
/// 添加新语言时同步在 Assets/_Game/Data/Localization/ 下创建对应子目录和 JSON 表文件
|
||||||
|
/// (推荐用「BaseGames / Localization / 表格编辑器」新建并自动注册 Addressables)。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum Language
|
public enum Language
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Assets/Scripts/Localization/LocalizationManager.cs
|
// Assets/Scripts/Localization/LocalizationManager.cs
|
||||||
// 本地化管理器(运行时 JSON 文件驱动)。
|
// 本地化管理器(运行时 JSON 文件驱动)。
|
||||||
//
|
//
|
||||||
// 数据格式(放在 Resources/Localization/{Language}/{TableName}.json):
|
// 数据格式(放在 Assets/_Game/Data/Localization/{Language}/{TableName}.json):
|
||||||
// {
|
// {
|
||||||
// "entries": [
|
// "entries": [
|
||||||
// { "key": "ui_start", "value": "开始游戏" },
|
// { "key": "ui_start", "value": "开始游戏" },
|
||||||
@@ -317,7 +317,7 @@ namespace BaseGames.Localization
|
|||||||
return cached;
|
return cached;
|
||||||
|
|
||||||
// 编辑器按资产路径读取(与运行时 Addressable 地址对应的物理位置)
|
// 编辑器按资产路径读取(与运行时 Addressable 地址对应的物理位置)
|
||||||
string path = $"Assets/_Game/Data/Localization/{language}/{table}.json";
|
string path = LocalizationPaths.AssetPath(language, table);
|
||||||
var asset = UnityEditor.AssetDatabase.LoadAssetAtPath<TextAsset>(path);
|
var asset = UnityEditor.AssetDatabase.LoadAssetAtPath<TextAsset>(path);
|
||||||
var dict = asset == null ? null : ParseTableText(asset.text);
|
var dict = asset == null ? null : ParseTableText(asset.text);
|
||||||
s_editorPreviewCache[cacheKey] = dict;
|
s_editorPreviewCache[cacheKey] = dict;
|
||||||
@@ -349,7 +349,7 @@ namespace BaseGames.Localization
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private static Dictionary<string, string> LoadTable(Language language, string table)
|
private static Dictionary<string, string> LoadTable(Language language, string table)
|
||||||
{
|
{
|
||||||
string address = $"Localization/{language}/{table}";
|
string address = LocalizationPaths.Address(language, table);
|
||||||
// 统一经 AssetLoader 门面:缺键安全检查 + 同步加载 + 释放
|
// 统一经 AssetLoader 门面:缺键安全检查 + 同步加载 + 释放
|
||||||
if (!AssetLoader.Exists(address, typeof(TextAsset))) return null;
|
if (!AssetLoader.Exists(address, typeof(TextAsset))) return null;
|
||||||
|
|
||||||
@@ -360,21 +360,12 @@ namespace BaseGames.Localization
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 将 JSON 文本解析为 key→value 字典(内部共享解析逻辑)。
|
/// 将 JSON 文本解析为 key→value 字典。
|
||||||
|
/// 委托给 <see cref="LocalizationSerializer.Parse"/>,与编辑器写盘共用同一格式逻辑。
|
||||||
/// 返回 null 表示格式无效。
|
/// 返回 null 表示格式无效。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static Dictionary<string, string> ParseTableText(string jsonText)
|
private static Dictionary<string, string> ParseTableText(string jsonText)
|
||||||
{
|
=> LocalizationSerializer.Parse(jsonText);
|
||||||
var parsed = JsonUtility.FromJson<StringTableJson>(jsonText);
|
|
||||||
if (parsed?.entries == null) return null;
|
|
||||||
|
|
||||||
var dict = new Dictionary<string, string>(parsed.entries.Count, StringComparer.Ordinal);
|
|
||||||
foreach (var entry in parsed.entries)
|
|
||||||
if (!string.IsNullOrEmpty(entry.key))
|
|
||||||
dict[entry.key] = entry.value ?? string.Empty;
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── 缓存键(值类型,消除字符串插值 GC)──────────────────────────────
|
// ── 缓存键(值类型,消除字符串插值 GC)──────────────────────────────
|
||||||
private readonly struct CacheKey : IEquatable<CacheKey>
|
private readonly struct CacheKey : IEquatable<CacheKey>
|
||||||
@@ -398,20 +389,5 @@ namespace BaseGames.Localization
|
|||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
=> HashCode.Combine((int)_language, _table);
|
=> HashCode.Combine((int)_language, _table);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── 序列化辅助类型 ────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
private class StringTableJson
|
|
||||||
{
|
|
||||||
public List<StringEntry> entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
private class StringEntry
|
|
||||||
{
|
|
||||||
public string key;
|
|
||||||
public string value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
40
Assets/_Game/Scripts/Localization/LocalizationPaths.cs
Normal file
40
Assets/_Game/Scripts/Localization/LocalizationPaths.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
namespace BaseGames.Localization
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 本地化资源路径 / Addressable 地址的唯一真相源。
|
||||||
|
///
|
||||||
|
/// 运行时与编辑器工具的所有路径、地址都必须经此类构造,禁止再硬编码
|
||||||
|
/// "Assets/_Game/Data/Localization" 或 "Localization/{lang}/{table}" 字符串。
|
||||||
|
///
|
||||||
|
/// 设计要点:
|
||||||
|
/// - 纯静态、无 UnityEditor 依赖,放运行时 asmdef(<c>BaseGames.Localization</c>),
|
||||||
|
/// 使运行时加载(<see cref="LocalizationManager"/>)与编辑器工具共用同一套路径逻辑。
|
||||||
|
/// - 物理 JSON 路径(<see cref="AssetPath"/>)供编辑器直读 / 写盘;
|
||||||
|
/// Addressable 地址(<see cref="Address"/>)供运行时 <c>AssetLoader</c> 加载。
|
||||||
|
/// </summary>
|
||||||
|
public static class LocalizationPaths
|
||||||
|
{
|
||||||
|
/// <summary>本地化 JSON 数据根目录(项目资产相对路径)。</summary>
|
||||||
|
public const string DataRoot = "Assets/_Game/Data/Localization";
|
||||||
|
|
||||||
|
/// <summary>CSV 导入导出目录(供 Excel 往返)。</summary>
|
||||||
|
public const string ExportRoot = "Assets/_Game/Localization/Export";
|
||||||
|
|
||||||
|
/// <summary>指定语言的子目录,如 <c>Assets/_Game/Data/Localization/English</c>。</summary>
|
||||||
|
public static string LanguageFolder(Language language) => $"{DataRoot}/{language}";
|
||||||
|
|
||||||
|
/// <summary>指定语言 + 表的 JSON 资产路径。</summary>
|
||||||
|
public static string AssetPath(Language language, string table)
|
||||||
|
=> $"{DataRoot}/{language}/{table}.json";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 指定语言 + 表的 Addressable 地址(运行时加载用)。
|
||||||
|
/// 必须与 <see cref="AssetPath"/> 指向的文件注册的地址一致。
|
||||||
|
/// </summary>
|
||||||
|
public static string Address(Language language, string table)
|
||||||
|
=> $"Localization/{language}/{table}";
|
||||||
|
|
||||||
|
/// <summary>指定表的 CSV 导出路径。</summary>
|
||||||
|
public static string CsvPath(string table) => $"{ExportRoot}/{table}.csv";
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/_Game/Scripts/Localization/LocalizationPaths.cs.meta
Normal file
11
Assets/_Game/Scripts/Localization/LocalizationPaths.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b557437701451774a81e3932e3486ff8
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
79
Assets/_Game/Scripts/Localization/LocalizationSerializer.cs
Normal file
79
Assets/_Game/Scripts/Localization/LocalizationSerializer.cs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace BaseGames.Localization
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 本地化表 JSON 的对称解析 / 序列化(唯一格式真相源)。
|
||||||
|
///
|
||||||
|
/// 表格式:<c>{ "entries": [ { "key": "...", "value": "..." } ] }</c>
|
||||||
|
///
|
||||||
|
/// 运行时加载(<see cref="LocalizationManager"/>)与编辑器写盘(<c>LocalizationFileIO</c>)
|
||||||
|
/// 都经此类,确保读写格式永远一致,杜绝"格式漂移"。
|
||||||
|
/// </summary>
|
||||||
|
public static class LocalizationSerializer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 将表 JSON 文本解析为 key→value 字典。
|
||||||
|
/// 返回 null 表示格式无效(entries 缺失)。空 key 条目被跳过。
|
||||||
|
/// </summary>
|
||||||
|
public static Dictionary<string, string> Parse(string jsonText)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(jsonText)) return null;
|
||||||
|
|
||||||
|
StringTableJson parsed;
|
||||||
|
try { parsed = JsonUtility.FromJson<StringTableJson>(jsonText); }
|
||||||
|
catch { return null; }
|
||||||
|
|
||||||
|
if (parsed?.entries == null) return null;
|
||||||
|
|
||||||
|
var dict = new Dictionary<string, string>(parsed.entries.Count, StringComparer.Ordinal);
|
||||||
|
foreach (var entry in parsed.entries)
|
||||||
|
if (!string.IsNullOrEmpty(entry.key))
|
||||||
|
dict[entry.key] = entry.value ?? string.Empty;
|
||||||
|
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 key→value 字典序列化为表 JSON 文本(<c>{entries:[…]}</c> 格式,pretty print)。
|
||||||
|
/// 该输出可被 <see cref="Parse"/> 与运行时加载器无损还原。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dict">要序列化的字典。</param>
|
||||||
|
/// <param name="sortKeys">是否按 key 的序数顺序排序(默认 true,减少版本控制 diff 噪声)。</param>
|
||||||
|
public static string Serialize(IReadOnlyDictionary<string, string> dict, bool sortKeys = true)
|
||||||
|
{
|
||||||
|
var table = new StringTableJson { entries = new List<StringEntry>(dict?.Count ?? 0) };
|
||||||
|
if (dict != null)
|
||||||
|
{
|
||||||
|
IEnumerable<string> keys = dict.Keys;
|
||||||
|
if (sortKeys)
|
||||||
|
{
|
||||||
|
var sorted = new List<string>(dict.Keys);
|
||||||
|
sorted.Sort(StringComparer.Ordinal);
|
||||||
|
keys = sorted;
|
||||||
|
}
|
||||||
|
foreach (var key in keys)
|
||||||
|
table.entries.Add(new StringEntry { key = key, value = dict[key] ?? string.Empty });
|
||||||
|
}
|
||||||
|
|
||||||
|
// JsonUtility 正确转义引号/反斜杠/换行,且保留中日韩字符原文(不转 \uXXXX)。
|
||||||
|
return JsonUtility.ToJson(table, prettyPrint: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 序列化辅助类型(运行时与编辑器共用)────────────────────────────────
|
||||||
|
[Serializable]
|
||||||
|
internal class StringTableJson
|
||||||
|
{
|
||||||
|
public List<StringEntry> entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
internal class StringEntry
|
||||||
|
{
|
||||||
|
public string key;
|
||||||
|
public string value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 501e8b363022d9e4d8a69b399e6cdeb3
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -5,7 +5,8 @@ namespace BaseGames.Localization
|
|||||||
/// 所有调用 <see cref="ILocalizationService.Get"/> 或 <see cref="LocalizationManager.Get"/> 时
|
/// 所有调用 <see cref="ILocalizationService.Get"/> 或 <see cref="LocalizationManager.Get"/> 时
|
||||||
/// 必须引用此类的常量,禁止直接硬编码表名字符串。
|
/// 必须引用此类的常量,禁止直接硬编码表名字符串。
|
||||||
///
|
///
|
||||||
/// 新增表时:在此追加常量,并在 Resources/Localization/{Language}/ 下创建同名 JSON 文件。
|
/// 新增表时:在此追加常量,并用「BaseGames / Localization / 表格编辑器」新建同名表
|
||||||
|
/// (自动在 Assets/_Game/Data/Localization/{Language}/ 下创建 JSON 并注册 Addressables)。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class LocalizationTable
|
public static class LocalizationTable
|
||||||
{
|
{
|
||||||
|
|||||||
8
Assets/_Game/Scripts/UI/Base.meta
Normal file
8
Assets/_Game/Scripts/UI/Base.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e8cff642fe44f954694ab825135c02f5
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
91
Assets/_Game/Scripts/UI/Base/UIPanelBase.cs
Normal file
91
Assets/_Game/Scripts/UI/Base/UIPanelBase.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using BaseGames.Core;
|
||||||
|
using BaseGames.Core.Events;
|
||||||
|
|
||||||
|
namespace BaseGames.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// UI 面板基类:统一面板生命周期、焦点恢复、进场淡入与事件订阅清理。
|
||||||
|
///
|
||||||
|
/// 消除各面板控制器(PauseMenu / Settings / InventoryHub 等)重复的样板:
|
||||||
|
/// - OnEnable:取服务 / 订阅 / 设默认选中 / 播淡入
|
||||||
|
/// - OnDisable:清理订阅(<see cref="_subs"/>)/ 停动画
|
||||||
|
/// - <see cref="IFocusable.OnFocusRestored"/>:关闭子面板回到栈顶时聚焦首项
|
||||||
|
///
|
||||||
|
/// 与 <see cref="UIManager"/> 面板栈完全兼容:UIManager 仍以 SetActive 驱动开关,
|
||||||
|
/// 本基类只在 OnEnable/OnDisable 加钩子,不改变栈语义。
|
||||||
|
///
|
||||||
|
/// 子类用法:重写 <see cref="OnPanelOpen"/>(订阅/刷新)与可选 <see cref="OnPanelClose"/>;
|
||||||
|
/// 在 Inspector 指定 <see cref="_firstSelected"/>(手柄/键盘默认焦点);可选挂 CanvasGroup 做淡入。
|
||||||
|
/// </summary>
|
||||||
|
[DisallowMultipleComponent]
|
||||||
|
public abstract class UIPanelBase : MonoBehaviour, IFocusable
|
||||||
|
{
|
||||||
|
[Header("Panel Base")]
|
||||||
|
[Tooltip("打开 / 焦点恢复时默认选中的控件(手柄/键盘导航起点)。可空。")]
|
||||||
|
[SerializeField] protected Selectable _firstSelected;
|
||||||
|
|
||||||
|
[Tooltip("进场淡入用的 CanvasGroup(可空;为空则不淡入)。")]
|
||||||
|
[SerializeField] protected CanvasGroup _canvasGroup;
|
||||||
|
|
||||||
|
[Tooltip("进场淡入时长(秒)。0 表示无淡入。")]
|
||||||
|
[SerializeField] protected float _fadeInDuration = 0.15f;
|
||||||
|
|
||||||
|
[Tooltip("打开时是否自动把焦点设到首项。")]
|
||||||
|
[SerializeField] protected bool _selectFirstOnEnable = true;
|
||||||
|
|
||||||
|
/// <summary>事件订阅容器,OnDisable 自动清理。子类订阅用 <c>channel.Subscribe(..).AddTo(_subs)</c>。</summary>
|
||||||
|
protected readonly CompositeDisposable _subs = new();
|
||||||
|
|
||||||
|
private Coroutine _fadeRoutine;
|
||||||
|
|
||||||
|
// ── 生命周期 ──────────────────────────────────────────────────────────
|
||||||
|
protected virtual void OnEnable()
|
||||||
|
{
|
||||||
|
OnPanelOpen();
|
||||||
|
if (_canvasGroup != null && _fadeInDuration > 0f) PlayFadeIn();
|
||||||
|
if (_selectFirstOnEnable) FocusFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnDisable()
|
||||||
|
{
|
||||||
|
_subs.Clear();
|
||||||
|
if (_fadeRoutine != null) { StopCoroutine(_fadeRoutine); _fadeRoutine = null; }
|
||||||
|
OnPanelClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>面板打开时调用(OnEnable)。子类在此取服务、订阅事件、刷新内容。</summary>
|
||||||
|
protected virtual void OnPanelOpen() { }
|
||||||
|
|
||||||
|
/// <summary>面板关闭时调用(OnDisable,_subs 已清理之后)。子类在此释放非 _subs 资源。</summary>
|
||||||
|
protected virtual void OnPanelClose() { }
|
||||||
|
|
||||||
|
// ── 焦点 ──────────────────────────────────────────────────────────────
|
||||||
|
/// <summary>关闭子面板、本面板恢复为栈顶时调用(<see cref="IUIManager.CloseTopPanel"/> 触发)。</summary>
|
||||||
|
public virtual void OnFocusRestored() => FocusFirst();
|
||||||
|
|
||||||
|
/// <summary>将 EventSystem 焦点设到首项(优先 <see cref="_firstSelected"/>,否则 <see cref="ResolveFirstSelected"/>)。</summary>
|
||||||
|
protected void FocusFirst()
|
||||||
|
{
|
||||||
|
var go = _firstSelected != null ? _firstSelected.gameObject : ResolveFirstSelected();
|
||||||
|
if (go != null && EventSystem.current != null)
|
||||||
|
EventSystem.current.SetSelectedGameObject(go);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>子类可重写:动态决定首个选中项(如列表第一行),当 <see cref="_firstSelected"/> 未指定时使用。</summary>
|
||||||
|
protected virtual GameObject ResolveFirstSelected() => null;
|
||||||
|
|
||||||
|
// ── 工具 ──────────────────────────────────────────────────────────────
|
||||||
|
/// <summary>从 ServiceLocator 取服务(未注册返回 null)。</summary>
|
||||||
|
protected static T GetService<T>() where T : class => ServiceLocator.GetOrDefault<T>();
|
||||||
|
|
||||||
|
private void PlayFadeIn()
|
||||||
|
{
|
||||||
|
if (_fadeRoutine != null) StopCoroutine(_fadeRoutine);
|
||||||
|
_canvasGroup.alpha = 0f;
|
||||||
|
_fadeRoutine = StartCoroutine(UITween.FadeCanvasGroup(_canvasGroup, 1f, _fadeInDuration));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/_Game/Scripts/UI/Base/UIPanelBase.cs.meta
Normal file
11
Assets/_Game/Scripts/UI/Base/UIPanelBase.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b0b3d5f5b7a324d47930ee0ccd5c6ae3
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
11
Assets/_Game/Scripts/UI/Base/UISimplePanel.cs
Normal file
11
Assets/_Game/Scripts/UI/Base/UISimplePanel.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace BaseGames.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 通用面板:<see cref="UIPanelBase"/> 的最简具体实现,无额外逻辑。
|
||||||
|
/// 用作脚手架生成的 themed 面板根(带 CanvasGroup 淡入 + 默认焦点 + 订阅清理),
|
||||||
|
/// 适合不需要自定义控制器的简单弹窗 / 容器。需要业务逻辑时改挂自定义 <see cref="UIPanelBase"/> 子类。
|
||||||
|
/// </summary>
|
||||||
|
public sealed class UISimplePanel : UIPanelBase
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/_Game/Scripts/UI/Base/UISimplePanel.cs.meta
Normal file
11
Assets/_Game/Scripts/UI/Base/UISimplePanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c6fa4cf81d2fd2e46b0d922f7b55097c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/_Game/Scripts/UI/Controls.meta
Normal file
8
Assets/_Game/Scripts/UI/Controls.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 986c5f0b71c98d74c9082fb0c5236b1c
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
96
Assets/_Game/Scripts/UI/Controls/PooledListView.cs
Normal file
96
Assets/_Game/Scripts/UI/Controls/PooledListView.cs
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace BaseGames.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 简单数据绑定列表项接口。视图实现后,<see cref="PooledListView{TData,TView}"/>
|
||||||
|
/// 的默认 <c>BindItem</c> 可直接调用,无需子类重写绑定逻辑。
|
||||||
|
/// </summary>
|
||||||
|
public interface IPooledItemView<in TData>
|
||||||
|
{
|
||||||
|
void Bind(TData data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 对象池数据绑定列表基类(统一 ItemInventory / CharmEquip / QuestLog 等处的手写重建模板)。
|
||||||
|
///
|
||||||
|
/// 用法:
|
||||||
|
/// 1. 子类指定 TData(数据)与 TView(继承 <see cref="Component"/> 的列表项视图)。
|
||||||
|
/// 2. 在 Inspector 设置 <see cref="_container"/>(布局父节点)与 <see cref="_template"/>(保持 inactive 的原型)。
|
||||||
|
/// 3. 调用 <see cref="SetItems"/> 以数据集重建;视图通过 <see cref="BindItem"/> 绑定。
|
||||||
|
///
|
||||||
|
/// 默认绑定:TView 实现 <see cref="IPooledItemView{TData}"/> 时无需重写 <see cref="BindItem"/>;
|
||||||
|
/// 需要传回调(如 onSelect)时重写 <see cref="BindItem"/>。
|
||||||
|
///
|
||||||
|
/// 非虚拟化:所有项同时存在(适合数十到上百项);超长列表后续可加虚拟化。
|
||||||
|
/// </summary>
|
||||||
|
public abstract class PooledListView<TData, TView> : MonoBehaviour
|
||||||
|
where TView : Component
|
||||||
|
{
|
||||||
|
[Header("Pooled List")]
|
||||||
|
[Tooltip("列表项的布局父节点(通常挂 Horizontal/VerticalLayoutGroup 或 GridLayoutGroup)。")]
|
||||||
|
[SerializeField] protected Transform _container;
|
||||||
|
|
||||||
|
[Tooltip("列表项原型(保持 inactive,作为对象池模板)。")]
|
||||||
|
[SerializeField] protected TView _template;
|
||||||
|
|
||||||
|
private readonly List<TView> _active = new();
|
||||||
|
private readonly Queue<TView> _pool = new();
|
||||||
|
|
||||||
|
/// <summary>当前激活的列表项视图(只读)。</summary>
|
||||||
|
public IReadOnlyList<TView> Active => _active;
|
||||||
|
|
||||||
|
protected virtual void Awake()
|
||||||
|
{
|
||||||
|
if (_template != null) _template.gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>以数据集重建列表(回收旧项 → 逐项 Spawn + 绑定 → <see cref="OnRebuilt"/>)。</summary>
|
||||||
|
public void SetItems(IEnumerable<TData> items)
|
||||||
|
{
|
||||||
|
RecycleAll();
|
||||||
|
if (_container == null || _template == null || items == null) { OnRebuilt(); return; }
|
||||||
|
|
||||||
|
foreach (var data in items)
|
||||||
|
{
|
||||||
|
var view = Spawn();
|
||||||
|
BindItem(view, data);
|
||||||
|
_active.Add(view);
|
||||||
|
}
|
||||||
|
OnRebuilt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>回收所有激活项到池中(隐藏)。</summary>
|
||||||
|
public void RecycleAll()
|
||||||
|
{
|
||||||
|
foreach (var view in _active)
|
||||||
|
{
|
||||||
|
if (view == null) continue;
|
||||||
|
view.gameObject.SetActive(false);
|
||||||
|
_pool.Enqueue(view);
|
||||||
|
}
|
||||||
|
_active.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 绑定单个视图。默认:TView 实现 <see cref="IPooledItemView{TData}"/> 时直接调用其 Bind。
|
||||||
|
/// 需要额外参数(如选中回调)时子类重写。
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void BindItem(TView view, TData data)
|
||||||
|
{
|
||||||
|
if (view is IPooledItemView<TData> bindable) bindable.Bind(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>重建完成回调(子类可重写:默认选中首项、空态提示等)。</summary>
|
||||||
|
protected virtual void OnRebuilt() { }
|
||||||
|
|
||||||
|
private TView Spawn()
|
||||||
|
{
|
||||||
|
TView view = _pool.Count > 0 ? _pool.Dequeue() : Instantiate(_template, _container);
|
||||||
|
view.transform.SetParent(_container, false);
|
||||||
|
view.gameObject.SetActive(true);
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/_Game/Scripts/UI/Controls/PooledListView.cs.meta
Normal file
11
Assets/_Game/Scripts/UI/Controls/PooledListView.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9c1f8c866c54a9440ba21d3a146de17d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
142
Assets/_Game/Scripts/UI/Controls/UIButton.cs
Normal file
142
Assets/_Game/Scripts/UI/Controls/UIButton.cs
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using BaseGames.Core.Events;
|
||||||
|
using BaseGames.UI.Theme;
|
||||||
|
|
||||||
|
namespace BaseGames.UI
|
||||||
|
{
|
||||||
|
/// <summary>按钮视觉变体(驱动从主题派生的 <see cref="ColorBlock"/>)。</summary>
|
||||||
|
public enum UIButtonVariant { Primary, Secondary, Accent, Danger, Ghost }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主题化按钮变体 + 交互反馈。薄封装在 uGUI <see cref="Button"/> 之上:
|
||||||
|
/// - 按变体从 <see cref="UIThemeSO"/> 取基色,派生 normal/highlighted/pressed/disabled 并写入 Button.colors。
|
||||||
|
/// - 选中/悬停时缩放反馈(走 <see cref="UITween.Scale"/>)。
|
||||||
|
/// - 可选点击/悬停音效(事件频道驱动,不直接耦合 Audio 程序集)。
|
||||||
|
///
|
||||||
|
/// 主题来源:优先 Inspector 直接赋的 <see cref="_theme"/>,否则就近向上找 <see cref="UIThemeApplier"/>。
|
||||||
|
/// </summary>
|
||||||
|
[RequireComponent(typeof(Button))]
|
||||||
|
[DisallowMultipleComponent]
|
||||||
|
public class UIButton : MonoBehaviour,
|
||||||
|
ISelectHandler, IDeselectHandler, IPointerEnterHandler, IPointerExitHandler
|
||||||
|
{
|
||||||
|
[Header("变体")]
|
||||||
|
[SerializeField] private UIButtonVariant _variant = UIButtonVariant.Primary;
|
||||||
|
[Tooltip("主题资产;为空则就近向上查找 UIThemeApplier。")]
|
||||||
|
[SerializeField] private UIThemeSO _theme;
|
||||||
|
|
||||||
|
[Header("反馈")]
|
||||||
|
[Tooltip("选中/悬停时的缩放反馈。")]
|
||||||
|
[SerializeField] private bool _scaleFeedback = true;
|
||||||
|
[SerializeField] private float _selectedScale = 1.06f;
|
||||||
|
[SerializeField] private float _scaleDuration = 0.08f;
|
||||||
|
|
||||||
|
[Header("音效(可选,事件频道驱动)")]
|
||||||
|
[SerializeField] private VoidEventChannelSO _onClickSfx;
|
||||||
|
[SerializeField] private VoidEventChannelSO _onHoverSfx;
|
||||||
|
|
||||||
|
private Button _button;
|
||||||
|
private Coroutine _scaleRoutine;
|
||||||
|
private Vector3 _baseScale = Vector3.one;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
_button = GetComponent<Button>();
|
||||||
|
_baseScale = transform.localScale;
|
||||||
|
_button.onClick.AddListener(RaiseClickSfx);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
ApplyTheme();
|
||||||
|
transform.localScale = _baseScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
if (_scaleRoutine != null) { StopCoroutine(_scaleRoutine); _scaleRoutine = null; }
|
||||||
|
transform.localScale = _baseScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 主题应用 ──────────────────────────────────────────────────────────
|
||||||
|
/// <summary>按当前变体与主题刷新 Button 配色。</summary>
|
||||||
|
public void ApplyTheme()
|
||||||
|
{
|
||||||
|
var theme = ResolveTheme();
|
||||||
|
if (theme == null) return;
|
||||||
|
if (_button == null) _button = GetComponent<Button>();
|
||||||
|
if (_button == null) return;
|
||||||
|
|
||||||
|
Color baseColor = VariantBaseColor(theme, _variant);
|
||||||
|
var cb = _button.colors;
|
||||||
|
cb.colorMultiplier = 1f;
|
||||||
|
cb.fadeDuration = 0.1f;
|
||||||
|
cb.disabledColor = theme.ButtonDisabled;
|
||||||
|
|
||||||
|
if (_variant == UIButtonVariant.Ghost)
|
||||||
|
{
|
||||||
|
cb.normalColor = new Color(baseColor.r, baseColor.g, baseColor.b, 0f);
|
||||||
|
cb.highlightedColor = new Color(baseColor.r, baseColor.g, baseColor.b, 0.25f);
|
||||||
|
cb.pressedColor = new Color(baseColor.r, baseColor.g, baseColor.b, 0.40f);
|
||||||
|
cb.selectedColor = cb.highlightedColor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cb.normalColor = baseColor;
|
||||||
|
cb.highlightedColor = Color.Lerp(baseColor, Color.white, 0.12f);
|
||||||
|
cb.pressedColor = Color.Lerp(baseColor, Color.black, 0.15f);
|
||||||
|
cb.selectedColor = cb.highlightedColor;
|
||||||
|
}
|
||||||
|
_button.colors = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Color VariantBaseColor(UIThemeSO t, UIButtonVariant v) => v switch
|
||||||
|
{
|
||||||
|
UIButtonVariant.Primary => t.Primary,
|
||||||
|
UIButtonVariant.Secondary => t.Secondary,
|
||||||
|
UIButtonVariant.Accent => t.Accent,
|
||||||
|
UIButtonVariant.Danger => t.Danger,
|
||||||
|
UIButtonVariant.Ghost => t.TextPrimary,
|
||||||
|
_ => t.Primary,
|
||||||
|
};
|
||||||
|
|
||||||
|
private UIThemeSO ResolveTheme()
|
||||||
|
{
|
||||||
|
if (_theme != null) return _theme;
|
||||||
|
var applier = GetComponentInParent<UIThemeApplier>(includeInactive: true);
|
||||||
|
return applier != null ? applier.Theme : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 交互反馈 ──────────────────────────────────────────────────────────
|
||||||
|
public void OnSelect(BaseEventData e) { PlayScale(_selectedScale); RaiseHoverSfx(); }
|
||||||
|
public void OnDeselect(BaseEventData e) { PlayScale(1f); }
|
||||||
|
public void OnPointerEnter(PointerEventData e) { PlayScale(_selectedScale); RaiseHoverSfx(); }
|
||||||
|
public void OnPointerExit(PointerEventData e)
|
||||||
|
{
|
||||||
|
// 仍为当前选中项则保持放大
|
||||||
|
if (EventSystem.current != null && EventSystem.current.currentSelectedGameObject == gameObject) return;
|
||||||
|
PlayScale(1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PlayScale(float factor)
|
||||||
|
{
|
||||||
|
if (!_scaleFeedback || !isActiveAndEnabled) return;
|
||||||
|
if (_scaleRoutine != null) StopCoroutine(_scaleRoutine);
|
||||||
|
_scaleRoutine = StartCoroutine(UITween.Scale(transform, _baseScale * factor, _scaleDuration));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RaiseClickSfx() => _onClickSfx?.Raise();
|
||||||
|
private void RaiseHoverSfx() => _onHoverSfx?.Raise();
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
private void OnValidate()
|
||||||
|
{
|
||||||
|
if (Application.isPlaying) return;
|
||||||
|
_button = GetComponent<Button>();
|
||||||
|
ApplyTheme();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/_Game/Scripts/UI/Controls/UIButton.cs.meta
Normal file
11
Assets/_Game/Scripts/UI/Controls/UIButton.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 270b0a121b06dfc4587c060335f18432
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
44
Assets/_Game/Scripts/UI/Controls/UIDropdown.cs
Normal file
44
Assets/_Game/Scripts/UI/Controls/UIDropdown.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Events;
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
namespace BaseGames.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 下拉控件封装:TMP_Dropdown + 一行式 <see cref="Bind"/>(填充选项 / 设当前项 / 接回调),
|
||||||
|
/// 消除设置面板里重复的 ClearOptions/AddOptions/RefreshShownValue 样板。
|
||||||
|
/// 选项文本可由调用方先经本地化(<c>LocalizationManager.Get</c>)解析后传入。
|
||||||
|
/// </summary>
|
||||||
|
[DisallowMultipleComponent]
|
||||||
|
public class UIDropdown : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] private TMP_Dropdown _dropdown;
|
||||||
|
|
||||||
|
public TMP_Dropdown Dropdown => _dropdown;
|
||||||
|
public int Value => _dropdown != null ? _dropdown.value : 0;
|
||||||
|
|
||||||
|
/// <summary>填充选项、设当前选中项并接变更回调。</summary>
|
||||||
|
public void Bind(IEnumerable<string> options, int index, UnityAction<int> onChanged)
|
||||||
|
{
|
||||||
|
if (_dropdown == null) return;
|
||||||
|
_dropdown.onValueChanged.RemoveAllListeners();
|
||||||
|
_dropdown.ClearOptions();
|
||||||
|
|
||||||
|
var list = options as List<string> ?? new List<string>(options);
|
||||||
|
_dropdown.AddOptions(list);
|
||||||
|
_dropdown.value = Mathf.Clamp(index, 0, Mathf.Max(0, list.Count - 1));
|
||||||
|
_dropdown.RefreshShownValue();
|
||||||
|
|
||||||
|
_dropdown.onValueChanged.AddListener(i => onChanged?.Invoke(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>不触发回调地设置当前选中项(用于外部状态同步)。</summary>
|
||||||
|
public void SetIndexSilent(int index)
|
||||||
|
{
|
||||||
|
if (_dropdown == null) return;
|
||||||
|
_dropdown.SetValueWithoutNotify(Mathf.Clamp(index, 0, Mathf.Max(0, _dropdown.options.Count - 1)));
|
||||||
|
_dropdown.RefreshShownValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/_Game/Scripts/UI/Controls/UIDropdown.cs.meta
Normal file
11
Assets/_Game/Scripts/UI/Controls/UIDropdown.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d6a9d49903ac46e4194b22cc1632a790
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
74
Assets/_Game/Scripts/UI/Controls/UISelectableRow.cs
Normal file
74
Assets/_Game/Scripts/UI/Controls/UISelectableRow.cs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
namespace BaseGames.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 通用可选择行:图标 + 标签 + 选中高亮 + 按钮,适用于菜单项、设置行、存档槽、列表项。
|
||||||
|
///
|
||||||
|
/// 配合 <see cref="PooledListView{TData,TView}"/> 作 TView,或在面板里直接布局使用。
|
||||||
|
/// 选中(手柄/键盘导航或鼠标悬停)时自动切换高亮节点。
|
||||||
|
/// </summary>
|
||||||
|
[DisallowMultipleComponent]
|
||||||
|
public class UISelectableRow : MonoBehaviour, ISelectHandler, IDeselectHandler, IPointerEnterHandler
|
||||||
|
{
|
||||||
|
[Header("引用")]
|
||||||
|
[SerializeField] private Button _button;
|
||||||
|
[SerializeField] private TMP_Text _label;
|
||||||
|
[Tooltip("行图标(可空)。")]
|
||||||
|
[SerializeField] private Image _icon;
|
||||||
|
[Tooltip("选中高亮节点(可空,选中时 SetActive(true))。")]
|
||||||
|
[SerializeField] private GameObject _selectedHighlight;
|
||||||
|
|
||||||
|
/// <summary>行被点击(或 Submit)时触发。</summary>
|
||||||
|
public event Action Clicked;
|
||||||
|
|
||||||
|
public Button Button => _button;
|
||||||
|
public Selectable Selectable => _button;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (_selectedHighlight != null) _selectedHighlight.SetActive(false);
|
||||||
|
if (_button != null)
|
||||||
|
_button.onClick.AddListener(() => Clicked?.Invoke());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 数据填充 ──────────────────────────────────────────────────────────
|
||||||
|
public void SetLabel(string text)
|
||||||
|
{
|
||||||
|
if (_label != null) _label.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetIcon(Sprite sprite)
|
||||||
|
{
|
||||||
|
if (_icon == null) return;
|
||||||
|
_icon.sprite = sprite;
|
||||||
|
_icon.enabled = sprite != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSelected(bool selected)
|
||||||
|
{
|
||||||
|
if (_selectedHighlight != null) _selectedHighlight.SetActive(selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>把 EventSystem 焦点设到本行。</summary>
|
||||||
|
public void Focus()
|
||||||
|
{
|
||||||
|
if (_button != null && EventSystem.current != null)
|
||||||
|
EventSystem.current.SetSelectedGameObject(_button.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 选中反馈 ──────────────────────────────────────────────────────────
|
||||||
|
public void OnSelect(BaseEventData e) => SetSelected(true);
|
||||||
|
public void OnDeselect(BaseEventData e) => SetSelected(false);
|
||||||
|
|
||||||
|
public void OnPointerEnter(PointerEventData e)
|
||||||
|
{
|
||||||
|
if (_button != null && _button.interactable && EventSystem.current != null)
|
||||||
|
EventSystem.current.SetSelectedGameObject(_button.gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/_Game/Scripts/UI/Controls/UISelectableRow.cs.meta
Normal file
11
Assets/_Game/Scripts/UI/Controls/UISelectableRow.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 64037ec2ca4c93d40908480eb137ccf3
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
52
Assets/_Game/Scripts/UI/Controls/UISlider.cs
Normal file
52
Assets/_Game/Scripts/UI/Controls/UISlider.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityEngine.Events;
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
namespace BaseGames.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 滑条控件封装:Slider + 实时数值标签 + 一行式 <see cref="Bind"/>,
|
||||||
|
/// 消除 <see cref="SettingsPanelController"/> 里"移除监听→设值→加监听→更新标签"的重复样板。
|
||||||
|
/// </summary>
|
||||||
|
[DisallowMultipleComponent]
|
||||||
|
public class UISlider : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] private Slider _slider;
|
||||||
|
[Tooltip("实时数值标签(可空)。")]
|
||||||
|
[SerializeField] private TMP_Text _valueLabel;
|
||||||
|
[Tooltip("数值标签格式(当未传 fmt 委托时使用)。例:\"{0:0}\"、\"{0:0}%\"。")]
|
||||||
|
[SerializeField] private string _format = "{0:0}";
|
||||||
|
|
||||||
|
private Func<float, string> _fmt;
|
||||||
|
|
||||||
|
public Slider Slider => _slider;
|
||||||
|
public float Value => _slider != null ? _slider.value : 0f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 绑定取值范围、初值与变更回调。<paramref name="fmt"/> 可自定义数值标签文本(优先于 <see cref="_format"/>)。
|
||||||
|
/// </summary>
|
||||||
|
public void Bind(float min, float max, float value, UnityAction<float> onChanged, Func<float, string> fmt = null)
|
||||||
|
{
|
||||||
|
if (_slider == null) return;
|
||||||
|
_slider.onValueChanged.RemoveAllListeners();
|
||||||
|
_slider.minValue = min;
|
||||||
|
_slider.maxValue = max;
|
||||||
|
_slider.value = Mathf.Clamp(value, min, max);
|
||||||
|
_fmt = fmt;
|
||||||
|
UpdateLabel(_slider.value);
|
||||||
|
_slider.onValueChanged.AddListener(v =>
|
||||||
|
{
|
||||||
|
onChanged?.Invoke(v);
|
||||||
|
UpdateLabel(v);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateLabel(float v)
|
||||||
|
{
|
||||||
|
if (_valueLabel == null) return;
|
||||||
|
_valueLabel.text = _fmt != null ? _fmt(v) : string.Format(_format, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/_Game/Scripts/UI/Controls/UISlider.cs.meta
Normal file
11
Assets/_Game/Scripts/UI/Controls/UISlider.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a1743e750e4f79c43b64e07a1c1a7270
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
157
Assets/_Game/Scripts/UI/Controls/UITabGroup.cs
Normal file
157
Assets/_Game/Scripts/UI/Controls/UITabGroup.cs
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using BaseGames.Core.Events;
|
||||||
|
|
||||||
|
namespace BaseGames.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 可复用标签组(从 <see cref="BaseGames.UI.Inventory.InventoryHubPanel"/> 的 Tab 逻辑提取)。
|
||||||
|
///
|
||||||
|
/// 职责:管理一组 Tab(内容根 + 头部按钮 + 高亮),处理 Next/Prev/Select 切换、
|
||||||
|
/// 头部高亮、焦点委托(内容若实现 <see cref="IFocusable"/> 则接管,否则聚焦头部按钮),
|
||||||
|
/// 可选跨重建记忆当前 Tab,并通过 C# 事件 + 可选 SO 频道广播索引。
|
||||||
|
///
|
||||||
|
/// 解耦:不引用任何具体 Tab 类型,只持有 Tab 根 <see cref="GameObject"/>。
|
||||||
|
/// 由宿主面板在 OnEnable 中调用 <see cref="Activate"/>,并把肩键频道接到 <see cref="Next"/>/<see cref="Prev"/>。
|
||||||
|
/// </summary>
|
||||||
|
public class UITabGroup : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public struct Tab
|
||||||
|
{
|
||||||
|
[Tooltip("Tab 内容根节点(激活时 SetActive(true))。")]
|
||||||
|
public GameObject content;
|
||||||
|
[Tooltip("Tab 头部按钮(点击跳转;高亮显示当前选中)。可空。")]
|
||||||
|
public Button headerButton;
|
||||||
|
[Tooltip("Tab 头部高亮节点(选中时 SetActive(true))。可空。")]
|
||||||
|
public GameObject headerHighlight;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Header("Tabs(按显示顺序)")]
|
||||||
|
[SerializeField] private Tab[] _tabs;
|
||||||
|
|
||||||
|
[Tooltip("默认打开的 Tab 索引。")]
|
||||||
|
[SerializeField] private int _defaultIndex = 0;
|
||||||
|
|
||||||
|
[Tooltip("是否记住上次停留的 Tab(跨面板重开)。")]
|
||||||
|
[SerializeField] private bool _rememberLast = true;
|
||||||
|
|
||||||
|
[Tooltip("跨重建记忆用的键;为空则只在本实例存活期间记忆。")]
|
||||||
|
[SerializeField] private string _persistKey = "";
|
||||||
|
|
||||||
|
[Header("Event Channels(可选)")]
|
||||||
|
[Tooltip("当前 Tab 变化时广播索引。可空。")]
|
||||||
|
[SerializeField] private IntEventChannelSO _onTabChanged;
|
||||||
|
|
||||||
|
/// <summary>当前 Tab 变化时触发(参数为新索引)。</summary>
|
||||||
|
public event Action<int> TabChanged;
|
||||||
|
|
||||||
|
public int CurrentIndex { get; private set; } = -1;
|
||||||
|
public int TabCount => _tabs?.Length ?? 0;
|
||||||
|
|
||||||
|
// 跨重建记忆(静态:面板/组件被销毁重建后仍保留)
|
||||||
|
private static readonly Dictionary<string, int> s_persist = new();
|
||||||
|
|
||||||
|
private bool _wired;
|
||||||
|
|
||||||
|
private void Awake() => EnsureWired();
|
||||||
|
|
||||||
|
private void EnsureWired()
|
||||||
|
{
|
||||||
|
if (_wired || _tabs == null) return;
|
||||||
|
for (int i = 0; i < _tabs.Length; i++)
|
||||||
|
{
|
||||||
|
int captured = i;
|
||||||
|
if (_tabs[i].headerButton != null)
|
||||||
|
{
|
||||||
|
_tabs[i].headerButton.onClick.RemoveAllListeners();
|
||||||
|
_tabs[i].headerButton.onClick.AddListener(() => Select(captured));
|
||||||
|
}
|
||||||
|
if (_tabs[i].content != null) _tabs[i].content.SetActive(false);
|
||||||
|
if (_tabs[i].headerHighlight != null) _tabs[i].headerHighlight.SetActive(false);
|
||||||
|
}
|
||||||
|
_wired = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>激活标签组并打开起始 Tab(默认或记忆)。宿主面板在 OnEnable 中调用。</summary>
|
||||||
|
public void Activate()
|
||||||
|
{
|
||||||
|
EnsureWired();
|
||||||
|
if (TabCount == 0) return;
|
||||||
|
int start = _rememberLast && TryGetPersisted(out var p) ? p : _defaultIndex;
|
||||||
|
CurrentIndex = -1; // 强制 Select 执行切换
|
||||||
|
Select(Mathf.Clamp(start, 0, TabCount - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Next() => Step(+1);
|
||||||
|
public void Prev() => Step(-1);
|
||||||
|
|
||||||
|
private void Step(int dir)
|
||||||
|
{
|
||||||
|
if (TabCount == 0) return;
|
||||||
|
int next = CurrentIndex;
|
||||||
|
for (int i = 0; i < _tabs.Length; i++) // 跳过未配置 content 的空槽
|
||||||
|
{
|
||||||
|
next = (next + dir + _tabs.Length) % _tabs.Length;
|
||||||
|
if (_tabs[next].content != null) break;
|
||||||
|
}
|
||||||
|
Select(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>切换到指定 Tab;无效或与当前相同则忽略。</summary>
|
||||||
|
public void Select(int index)
|
||||||
|
{
|
||||||
|
EnsureWired();
|
||||||
|
if (TabCount == 0) return;
|
||||||
|
index = Mathf.Clamp(index, 0, _tabs.Length - 1);
|
||||||
|
if (index == CurrentIndex) return;
|
||||||
|
|
||||||
|
// 关闭旧 Tab
|
||||||
|
if (CurrentIndex >= 0 && CurrentIndex < _tabs.Length)
|
||||||
|
{
|
||||||
|
if (_tabs[CurrentIndex].content != null) _tabs[CurrentIndex].content.SetActive(false);
|
||||||
|
if (_tabs[CurrentIndex].headerHighlight != null) _tabs[CurrentIndex].headerHighlight.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentIndex = index;
|
||||||
|
SetPersisted(index);
|
||||||
|
|
||||||
|
// 打开新 Tab
|
||||||
|
var tab = _tabs[index];
|
||||||
|
if (tab.content != null) tab.content.SetActive(true);
|
||||||
|
if (tab.headerHighlight != null) tab.headerHighlight.SetActive(true);
|
||||||
|
|
||||||
|
FocusCurrent();
|
||||||
|
_onTabChanged?.Raise(index);
|
||||||
|
TabChanged?.Invoke(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>把焦点交给当前 Tab(内容 IFocusable 优先,否则其头部按钮)。供宿主 OnFocusRestored 调用。</summary>
|
||||||
|
public void FocusCurrent()
|
||||||
|
{
|
||||||
|
if (CurrentIndex < 0 || CurrentIndex >= TabCount) return;
|
||||||
|
var tab = _tabs[CurrentIndex];
|
||||||
|
var focusable = tab.content != null ? tab.content.GetComponent<IFocusable>() : null;
|
||||||
|
if (focusable != null) focusable.OnFocusRestored();
|
||||||
|
else if (tab.headerButton != null && EventSystem.current != null)
|
||||||
|
EventSystem.current.SetSelectedGameObject(tab.headerButton.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 记忆 ──────────────────────────────────────────────────────────────
|
||||||
|
private bool TryGetPersisted(out int index)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_persistKey) && s_persist.TryGetValue(_persistKey, out index)) return true;
|
||||||
|
if (CurrentIndex >= 0) { index = CurrentIndex; return true; }
|
||||||
|
index = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetPersisted(int index)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_persistKey)) s_persist[_persistKey] = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/_Game/Scripts/UI/Controls/UITabGroup.cs.meta
Normal file
11
Assets/_Game/Scripts/UI/Controls/UITabGroup.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8cc0a2d3090a75f4c82697a82dd9ec85
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
259
Assets/_Game/Scripts/UI/MainMenu/DataDrivenMainMenuController.cs
Normal file
259
Assets/_Game/Scripts/UI/MainMenu/DataDrivenMainMenuController.cs
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using BaseGames.Core;
|
||||||
|
using BaseGames.Core.Assets;
|
||||||
|
using BaseGames.Core.Events;
|
||||||
|
|
||||||
|
namespace BaseGames.UI.MainMenu
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 数据驱动主菜单控制器(<see cref="MainMenuController"/> 的表驱动版,非破坏性并存)。
|
||||||
|
///
|
||||||
|
/// 按钮列表据 <see cref="MainMenuConfigSO"/> 生成(标签/图标/顺序/动作纯数据,策划改表零代码);
|
||||||
|
/// 子面板开关、存档槽流程、入场动画、状态锁定等编排仍在本控制器(场景耦合,不下放配置表)。
|
||||||
|
/// 动作派发:内置 NewGame/Continue/OpenSettings/OpenCredits/LoadScene/Quit + 事件频道 RaiseEvent。
|
||||||
|
/// </summary>
|
||||||
|
public class DataDrivenMainMenuController : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("数据表 / 按钮列表")]
|
||||||
|
[SerializeField] private MainMenuConfigSO _config;
|
||||||
|
[Tooltip("按钮的父节点(通常挂 VerticalLayoutGroup,即主按钮组)。")]
|
||||||
|
[SerializeField] private Transform _container;
|
||||||
|
[SerializeField] private MainMenuButtonView _buttonPrefab;
|
||||||
|
|
||||||
|
[Header("主按钮组(入场动画)")]
|
||||||
|
[SerializeField] private CanvasGroup _mainButtonsGroup;
|
||||||
|
[SerializeField] private RectTransform _mainButtonsRect;
|
||||||
|
|
||||||
|
[Header("子面板")]
|
||||||
|
[SerializeField] private GameObject _saveSlotPanel;
|
||||||
|
[SerializeField] private BaseGames.UI.Menus.SaveSlotController _saveSlotController;
|
||||||
|
[SerializeField] private GameObject _settingsPanel;
|
||||||
|
[SerializeField] private GameObject _creditsPanel;
|
||||||
|
|
||||||
|
[Header("子面板关闭按钮(可选)")]
|
||||||
|
[SerializeField] private Button _btnCloseSaveSlot;
|
||||||
|
[SerializeField] private Button _btnCloseSettings;
|
||||||
|
[SerializeField] private Button _btnCloseCredits;
|
||||||
|
|
||||||
|
[Header("入场动画")]
|
||||||
|
[SerializeField] private float _entrySlideOffset = 80f;
|
||||||
|
[SerializeField] private float _entryDuration = 0.55f;
|
||||||
|
|
||||||
|
[Header("场景")]
|
||||||
|
[SerializeField] private string _firstGameSceneKey = AddressKeys.SceneGameChapter1;
|
||||||
|
|
||||||
|
[Header("Event Channels - Listen")]
|
||||||
|
[SerializeField] private GameStateEventChannelSO _onGameStateChanged;
|
||||||
|
[SerializeField] private IntEventChannelSO _onSlotConfirmed;
|
||||||
|
|
||||||
|
[Header("Event Channels - Raise")]
|
||||||
|
[SerializeField] private SceneLoadRequestEventChannelSO _onSceneLoadRequest;
|
||||||
|
|
||||||
|
private readonly CompositeDisposable _subs = new();
|
||||||
|
private readonly List<(MainMenuConfigSO.Item item, MainMenuButtonView view)> _buttons = new();
|
||||||
|
private Vector2 _buttonsPanelOriginalPos;
|
||||||
|
private MainMenuButtonView _firstButton;
|
||||||
|
|
||||||
|
// ── 生命周期 ──────────────────────────────────────────────────────────
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (_buttonPrefab != null) _buttonPrefab.gameObject.SetActive(false);
|
||||||
|
|
||||||
|
_btnCloseSaveSlot?.onClick.AddListener(() => CloseSubPanel(_saveSlotPanel));
|
||||||
|
_btnCloseSettings?.onClick.AddListener(() => CloseSubPanel(_settingsPanel));
|
||||||
|
_btnCloseCredits? .onClick.AddListener(() => CloseSubPanel(_creditsPanel));
|
||||||
|
|
||||||
|
if (_mainButtonsRect != null)
|
||||||
|
_buttonsPanelOriginalPos = _mainButtonsRect.anchoredPosition;
|
||||||
|
|
||||||
|
SetPanel(_saveSlotPanel, false);
|
||||||
|
SetPanel(_settingsPanel, false);
|
||||||
|
SetPanel(_creditsPanel, false);
|
||||||
|
SetButtonsGroupVisible(false);
|
||||||
|
|
||||||
|
BuildMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
_onGameStateChanged?.Subscribe(HandleGameStateChanged).AddTo(_subs);
|
||||||
|
_onSlotConfirmed? .Subscribe(HandleSlotConfirmed).AddTo(_subs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisable() => _subs.Clear();
|
||||||
|
|
||||||
|
private void Start() => StartCoroutine(PlayEntryAnimation());
|
||||||
|
|
||||||
|
// ── 据表建菜单 ────────────────────────────────────────────────────────
|
||||||
|
/// <summary>据配置重建主菜单按钮列表(public 以便编辑器/测试验证)。</summary>
|
||||||
|
public void BuildMenu()
|
||||||
|
{
|
||||||
|
foreach (var (_, view) in _buttons) if (view != null) Destroy(view.gameObject);
|
||||||
|
_buttons.Clear();
|
||||||
|
_firstButton = null;
|
||||||
|
|
||||||
|
if (_config == null || _container == null || _buttonPrefab == null) return;
|
||||||
|
|
||||||
|
foreach (var item in _config.Items)
|
||||||
|
{
|
||||||
|
var view = Instantiate(_buttonPrefab, _container);
|
||||||
|
view.gameObject.SetActive(true);
|
||||||
|
var captured = item;
|
||||||
|
view.Bind(item.labelKey, item.icon, () => Dispatch(captured));
|
||||||
|
_buttons.Add((item, view));
|
||||||
|
if (_firstButton == null) _firstButton = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshConditional();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>根据存档存在性刷新 requiresSave 按钮的可用性(如"继续")。</summary>
|
||||||
|
public void RefreshConditional()
|
||||||
|
{
|
||||||
|
bool hasSave = HasAnySave();
|
||||||
|
foreach (var (item, view) in _buttons)
|
||||||
|
if (item.requiresSave && view != null)
|
||||||
|
view.SetInteractable(hasSave);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 动作派发 ──────────────────────────────────────────────────────────
|
||||||
|
private void Dispatch(MainMenuConfigSO.Item item)
|
||||||
|
{
|
||||||
|
switch (item.action)
|
||||||
|
{
|
||||||
|
case MainMenuAction.NewGame:
|
||||||
|
_saveSlotController?.SetMode(BaseGames.UI.Menus.SaveSlotPanelMode.NewGame);
|
||||||
|
OpenSubPanel(_saveSlotPanel);
|
||||||
|
break;
|
||||||
|
case MainMenuAction.Continue:
|
||||||
|
_saveSlotController?.SetMode(BaseGames.UI.Menus.SaveSlotPanelMode.Continue);
|
||||||
|
OpenSubPanel(_saveSlotPanel);
|
||||||
|
break;
|
||||||
|
case MainMenuAction.OpenSettings:
|
||||||
|
OpenSubPanel(_settingsPanel);
|
||||||
|
break;
|
||||||
|
case MainMenuAction.OpenCredits:
|
||||||
|
OpenSubPanel(_creditsPanel);
|
||||||
|
if (_btnCloseCredits != null)
|
||||||
|
EventSystem.current?.SetSelectedGameObject(_btnCloseCredits.gameObject);
|
||||||
|
break;
|
||||||
|
case MainMenuAction.LoadScene:
|
||||||
|
_onSceneLoadRequest?.Raise(new SceneLoadRequest
|
||||||
|
{
|
||||||
|
SceneName = string.IsNullOrEmpty(item.sceneKey) ? _firstGameSceneKey : item.sceneKey,
|
||||||
|
TransitionType = TransitionType.Scene,
|
||||||
|
ShowLoadingScreen = true,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case MainMenuAction.Quit:
|
||||||
|
Application.Quit();
|
||||||
|
break;
|
||||||
|
case MainMenuAction.RaiseEvent:
|
||||||
|
item.eventChannel?.Raise();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 子面板编排 ────────────────────────────────────────────────────────
|
||||||
|
private void OpenSubPanel(GameObject panel)
|
||||||
|
{
|
||||||
|
SetMainButtonsInteractable(false);
|
||||||
|
SetPanel(panel, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CloseSubPanel(GameObject panel)
|
||||||
|
{
|
||||||
|
SetPanel(panel, false);
|
||||||
|
SetMainButtonsInteractable(true);
|
||||||
|
if (_firstButton != null)
|
||||||
|
EventSystem.current?.SetSelectedGameObject(_firstButton.Button.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetMainButtonsInteractable(bool on)
|
||||||
|
{
|
||||||
|
if (_mainButtonsGroup == null) return;
|
||||||
|
_mainButtonsGroup.interactable = on;
|
||||||
|
_mainButtonsGroup.blocksRaycasts = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 存档槽确认(与 MainMenuController 一致)────────────────────────────
|
||||||
|
private void HandleSlotConfirmed(int _)
|
||||||
|
{
|
||||||
|
SetPanel(_saveSlotPanel, false);
|
||||||
|
|
||||||
|
var svc = ServiceLocator.GetOrDefault<ISaveService>();
|
||||||
|
string checkpointScene = svc?.LastCheckpointScene;
|
||||||
|
bool hasCheckpoint = !string.IsNullOrEmpty(checkpointScene);
|
||||||
|
|
||||||
|
_onSceneLoadRequest?.Raise(new SceneLoadRequest
|
||||||
|
{
|
||||||
|
SceneName = hasCheckpoint ? checkpointScene : _firstGameSceneKey,
|
||||||
|
EntryTransitionId = hasCheckpoint ? svc.LastCheckpointSpawnId : null,
|
||||||
|
TransitionType = TransitionType.Scene,
|
||||||
|
ShowLoadingScreen = true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleGameStateChanged(GameStateId state)
|
||||||
|
{
|
||||||
|
bool isMainMenu = state == GameStates.MainMenu;
|
||||||
|
if (_mainButtonsGroup != null)
|
||||||
|
{
|
||||||
|
_mainButtonsGroup.interactable = isMainMenu;
|
||||||
|
_mainButtonsGroup.blocksRaycasts = isMainMenu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 入场动画 ──────────────────────────────────────────────────────────
|
||||||
|
private IEnumerator PlayEntryAnimation()
|
||||||
|
{
|
||||||
|
if (_mainButtonsGroup == null) yield break;
|
||||||
|
|
||||||
|
Vector2 startPos = _buttonsPanelOriginalPos - new Vector2(0f, _entrySlideOffset);
|
||||||
|
if (_mainButtonsRect != null) _mainButtonsRect.anchoredPosition = startPos;
|
||||||
|
|
||||||
|
float elapsed = 0f;
|
||||||
|
while (elapsed < _entryDuration)
|
||||||
|
{
|
||||||
|
float t = Mathf.SmoothStep(0f, 1f, elapsed / _entryDuration);
|
||||||
|
_mainButtonsGroup.alpha = t;
|
||||||
|
if (_mainButtonsRect != null)
|
||||||
|
_mainButtonsRect.anchoredPosition = Vector2.Lerp(startPos, _buttonsPanelOriginalPos, t);
|
||||||
|
elapsed += Time.unscaledDeltaTime;
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_mainButtonsGroup.alpha = 1f;
|
||||||
|
if (_mainButtonsRect != null) _mainButtonsRect.anchoredPosition = _buttonsPanelOriginalPos;
|
||||||
|
_mainButtonsGroup.interactable = true;
|
||||||
|
_mainButtonsGroup.blocksRaycasts = true;
|
||||||
|
|
||||||
|
if (_firstButton != null)
|
||||||
|
EventSystem.current?.SetSelectedGameObject(_firstButton.Button.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 工具 ──────────────────────────────────────────────────────────────
|
||||||
|
private static bool HasAnySave()
|
||||||
|
{
|
||||||
|
var s = ServiceLocator.GetOrDefault<ISaveService>();
|
||||||
|
return s != null && (s.HasSave(0) || s.HasSave(1) || s.HasSave(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetPanel(GameObject panel, bool active)
|
||||||
|
{
|
||||||
|
if (panel != null) panel.SetActive(active);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetButtonsGroupVisible(bool visible)
|
||||||
|
{
|
||||||
|
if (_mainButtonsGroup == null) return;
|
||||||
|
_mainButtonsGroup.alpha = visible ? 1f : 0f;
|
||||||
|
_mainButtonsGroup.interactable = visible;
|
||||||
|
_mainButtonsGroup.blocksRaycasts = visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a38dc36f833bef3438073a0740ece716
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
44
Assets/_Game/Scripts/UI/MainMenu/MainMenuButtonView.cs
Normal file
44
Assets/_Game/Scripts/UI/MainMenu/MainMenuButtonView.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using BaseGames.Localization;
|
||||||
|
|
||||||
|
namespace BaseGames.UI.MainMenu
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主菜单按钮视图(显式序列化绑定,对照 <see cref="BaseGames.UI.Inventory.ItemSlotView"/> 风格)。
|
||||||
|
/// 由 <see cref="DataDrivenMainMenuController"/> 据配置实例化并 <see cref="Bind"/>。
|
||||||
|
/// 标签走 <see cref="LocalizedText"/>,随语言切换自动刷新。
|
||||||
|
/// </summary>
|
||||||
|
[DisallowMultipleComponent]
|
||||||
|
public class MainMenuButtonView : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] private Button _button;
|
||||||
|
[SerializeField] private LocalizedText _label;
|
||||||
|
[Tooltip("按钮图标(可空)。")]
|
||||||
|
[SerializeField] private Image _icon;
|
||||||
|
|
||||||
|
public Button Button => _button;
|
||||||
|
|
||||||
|
/// <summary>绑定标签 Key、图标与点击回调。</summary>
|
||||||
|
public void Bind(string labelKey, Sprite icon, Action onClick)
|
||||||
|
{
|
||||||
|
if (_label != null) _label.SetKey(labelKey);
|
||||||
|
if (_icon != null)
|
||||||
|
{
|
||||||
|
_icon.sprite = icon;
|
||||||
|
_icon.enabled = icon != null;
|
||||||
|
}
|
||||||
|
if (_button != null)
|
||||||
|
{
|
||||||
|
_button.onClick.RemoveAllListeners();
|
||||||
|
if (onClick != null) _button.onClick.AddListener(() => onClick());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetInteractable(bool value)
|
||||||
|
{
|
||||||
|
if (_button != null) _button.interactable = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/_Game/Scripts/UI/MainMenu/MainMenuButtonView.cs.meta
Normal file
11
Assets/_Game/Scripts/UI/MainMenu/MainMenuButtonView.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: aa83d8ead83f78b428cdd2b0d1a89aa7
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
56
Assets/_Game/Scripts/UI/MainMenu/MainMenuConfigSO.cs
Normal file
56
Assets/_Game/Scripts/UI/MainMenu/MainMenuConfigSO.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
using BaseGames.Core.Events;
|
||||||
|
|
||||||
|
namespace BaseGames.UI.MainMenu
|
||||||
|
{
|
||||||
|
/// <summary>主菜单项动作类型。常用动作内置;任意自定义走事件频道。</summary>
|
||||||
|
public enum MainMenuAction
|
||||||
|
{
|
||||||
|
NewGame, // 打开存档槽(新游戏语境)
|
||||||
|
Continue, // 打开存档槽(继续语境)
|
||||||
|
OpenSettings, // 打开设置子面板
|
||||||
|
OpenCredits, // 打开制作团队子面板
|
||||||
|
LoadScene, // 直接发起场景加载(用 sceneKey)
|
||||||
|
Quit, // 退出游戏
|
||||||
|
RaiseEvent, // 触发 eventChannel(万能扩展)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主菜单数据驱动表(策划编辑)。按顺序列出主菜单项;
|
||||||
|
/// <see cref="DataDrivenMainMenuController"/> 据此生成按钮并派发动作。
|
||||||
|
/// 策划可增删 / 重排 / 改标签图标 / 改动作,无需改代码。
|
||||||
|
///
|
||||||
|
/// 派发边界:动作类型固定(含 RaiseEvent 万能扩展);
|
||||||
|
/// 子面板 / 场景 / 存档流的编排在控制器,配置表不引用场景对象。
|
||||||
|
/// </summary>
|
||||||
|
[CreateAssetMenu(menuName = "BaseGames/UI/Main Menu Config", fileName = "UI_MainMenuConfig")]
|
||||||
|
public class MainMenuConfigSO : ScriptableObject
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public struct Item
|
||||||
|
{
|
||||||
|
[Tooltip("按钮标签本地化 Key(UI 表)。")]
|
||||||
|
public string labelKey;
|
||||||
|
|
||||||
|
[Tooltip("按钮图标(可空)。")]
|
||||||
|
public Sprite icon;
|
||||||
|
|
||||||
|
[Tooltip("点击动作。")]
|
||||||
|
public MainMenuAction action;
|
||||||
|
|
||||||
|
[Tooltip("勾选则需要存在有效存档才可用(如\"继续\";无存档时按钮置灰)。")]
|
||||||
|
public bool requiresSave;
|
||||||
|
|
||||||
|
[Tooltip("LoadScene 动作的目标场景 Addressable Key。")]
|
||||||
|
public string sceneKey;
|
||||||
|
|
||||||
|
[Tooltip("RaiseEvent 动作触发的事件频道。")]
|
||||||
|
public VoidEventChannelSO eventChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SerializeField] private Item[] _items;
|
||||||
|
|
||||||
|
public Item[] Items => _items;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/_Game/Scripts/UI/MainMenu/MainMenuConfigSO.cs.meta
Normal file
11
Assets/_Game/Scripts/UI/MainMenu/MainMenuConfigSO.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d78ee6af5c2b0344ea105452f496e85c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -93,9 +93,9 @@ namespace BaseGames.UI.MainMenu
|
|||||||
_btnCredits? .onClick.AddListener(OnCreditsClicked);
|
_btnCredits? .onClick.AddListener(OnCreditsClicked);
|
||||||
_btnQuit? .onClick.AddListener(Application.Quit);
|
_btnQuit? .onClick.AddListener(Application.Quit);
|
||||||
|
|
||||||
_btnCloseSaveSlot?.onClick.AddListener(() => SetPanel(_saveSlotPanel, false));
|
_btnCloseSaveSlot?.onClick.AddListener(() => CloseSubPanel(_saveSlotPanel, _btnNewGame));
|
||||||
_btnCloseSettings?.onClick.AddListener(() => SetPanel(_settingsPanel, false));
|
_btnCloseSettings?.onClick.AddListener(() => CloseSubPanel(_settingsPanel, _btnSettings));
|
||||||
_btnCloseCredits? .onClick.AddListener(() => SetPanel(_creditsPanel, false));
|
_btnCloseCredits? .onClick.AddListener(() => CloseSubPanel(_creditsPanel, _btnCredits));
|
||||||
|
|
||||||
// 记录按钮组原始位置(供动画使用)
|
// 记录按钮组原始位置(供动画使用)
|
||||||
if (_mainButtonsRect != null)
|
if (_mainButtonsRect != null)
|
||||||
@@ -162,15 +162,44 @@ namespace BaseGames.UI.MainMenu
|
|||||||
private void OnNewGameClicked()
|
private void OnNewGameClicked()
|
||||||
{
|
{
|
||||||
_saveSlotController?.SetMode(BaseGames.UI.Menus.SaveSlotPanelMode.NewGame);
|
_saveSlotController?.SetMode(BaseGames.UI.Menus.SaveSlotPanelMode.NewGame);
|
||||||
SetPanel(_saveSlotPanel, true);
|
OpenSubPanel(_saveSlotPanel);
|
||||||
}
|
}
|
||||||
private void OnContinueClicked()
|
private void OnContinueClicked()
|
||||||
{
|
{
|
||||||
_saveSlotController?.SetMode(BaseGames.UI.Menus.SaveSlotPanelMode.Continue);
|
_saveSlotController?.SetMode(BaseGames.UI.Menus.SaveSlotPanelMode.Continue);
|
||||||
SetPanel(_saveSlotPanel, true);
|
OpenSubPanel(_saveSlotPanel);
|
||||||
|
}
|
||||||
|
private void OnSettingsClicked() => OpenSubPanel(_settingsPanel); // SettingsPanelController 自行设焦点
|
||||||
|
private void OnCreditsClicked()
|
||||||
|
{
|
||||||
|
OpenSubPanel(_creditsPanel);
|
||||||
|
// Credits 面板无独立控制器,打开时把焦点交给返回按钮(键盘 / 手柄可直接退出)
|
||||||
|
if (_btnCloseCredits != null)
|
||||||
|
EventSystem.current?.SetSelectedGameObject(_btnCloseCredits.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>打开子面板:禁用主按钮组交互,避免键盘/手柄导航"穿透"到背后的主菜单按钮。</summary>
|
||||||
|
private void OpenSubPanel(GameObject panel)
|
||||||
|
{
|
||||||
|
SetMainButtonsInteractable(false);
|
||||||
|
SetPanel(panel, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>关闭子面板:恢复主按钮组交互,并把焦点恢复到对应主菜单按钮(导航连续性)。</summary>
|
||||||
|
private void CloseSubPanel(GameObject panel, Button focusAfter)
|
||||||
|
{
|
||||||
|
SetPanel(panel, false);
|
||||||
|
SetMainButtonsInteractable(true);
|
||||||
|
if (focusAfter != null)
|
||||||
|
EventSystem.current?.SetSelectedGameObject(focusAfter.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetMainButtonsInteractable(bool on)
|
||||||
|
{
|
||||||
|
if (_mainButtonsGroup == null) return;
|
||||||
|
_mainButtonsGroup.interactable = on;
|
||||||
|
_mainButtonsGroup.blocksRaycasts = on;
|
||||||
}
|
}
|
||||||
private void OnSettingsClicked() => SetPanel(_settingsPanel, true);
|
|
||||||
private void OnCreditsClicked() => SetPanel(_creditsPanel, true);
|
|
||||||
|
|
||||||
// ── 存档槽确认 ───────────────────────────────────────────────────────
|
// ── 存档槽确认 ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityEngine.EventSystems;
|
|
||||||
using BaseGames.Core;
|
|
||||||
using BaseGames.Core.Assets;
|
using BaseGames.Core.Assets;
|
||||||
using BaseGames.Core.Events;
|
using BaseGames.Core.Events;
|
||||||
|
|
||||||
@@ -10,9 +8,9 @@ namespace BaseGames.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 暂停菜单控制器(架构 10_UIModule §5)。
|
/// 暂停菜单控制器(架构 10_UIModule §5)。
|
||||||
/// 挂载在 Canvas_Menu → PauseMenuPanel GameObject 上。
|
/// 挂载在 Canvas_Menu → PauseMenuPanel GameObject 上。
|
||||||
/// 按钮绑定在 Awake 中完成;由 UIManager 负责面板开关。
|
/// 按钮绑定在 Awake 中完成;生命周期 / 焦点由 <see cref="UIPanelBase"/> 统一处理。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PauseMenuController : MonoBehaviour, IFocusable
|
public class PauseMenuController : UIPanelBase
|
||||||
{
|
{
|
||||||
// UIManager 通过 ServiceLocator 解析,开启时自动获取,无需 Inspector 直接绑定具体类型
|
// UIManager 通过 ServiceLocator 解析,开启时自动获取,无需 Inspector 直接绑定具体类型
|
||||||
private IUIManager _uiManager;
|
private IUIManager _uiManager;
|
||||||
@@ -35,18 +33,13 @@ namespace BaseGames.UI
|
|||||||
_btnQuit?.onClick.AddListener(Application.Quit);
|
_btnQuit?.onClick.AddListener(Application.Quit);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEnable()
|
|
||||||
{
|
|
||||||
// 暂停面板由 UIManager 开启,此时 ServiceLocator 已就绪
|
// 暂停面板由 UIManager 开启,此时 ServiceLocator 已就绪
|
||||||
_uiManager = ServiceLocator.GetOrDefault<IUIManager>();
|
protected override void OnPanelOpen() => _uiManager = GetService<IUIManager>();
|
||||||
// 手柄导航:打开时将焦点置于第一个按钮
|
protected override void OnPanelClose() => _uiManager = null;
|
||||||
EventSystem.current?.SetSelectedGameObject(_btnResume?.gameObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDisable()
|
/// <summary>默认焦点 / 焦点恢复回到"继续"按钮(基类 FocusFirst 调用)。</summary>
|
||||||
{
|
protected override GameObject ResolveFirstSelected()
|
||||||
_uiManager = null;
|
=> _btnResume != null ? _btnResume.gameObject : null;
|
||||||
}
|
|
||||||
|
|
||||||
// ── 按钮回调 ──────────────────────────────────────────────────────────
|
// ── 按钮回调 ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -71,11 +64,5 @@ namespace BaseGames.UI
|
|||||||
ShowLoadingScreen = false,
|
ShowLoadingScreen = false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── IFocusable ────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
/// <summary>面板恢复为栈顶时(关闭子面板后)自动移回第一个按鈕。</summary>
|
|
||||||
public void OnFocusRestored()
|
|
||||||
=> EventSystem.current?.SetSelectedGameObject(_btnResume?.gameObject);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,9 @@ namespace BaseGames.UI.Menus
|
|||||||
if (t.IsFaulted && !(t.Exception?.InnerException is OperationCanceledException))
|
if (t.IsFaulted && !(t.Exception?.InnerException is OperationCanceledException))
|
||||||
Debug.LogException(t.Exception?.InnerException ?? t.Exception, this);
|
Debug.LogException(t.Exception?.InnerException ?? t.Exception, this);
|
||||||
}, TaskScheduler.FromCurrentSynchronizationContext());
|
}, TaskScheduler.FromCurrentSynchronizationContext());
|
||||||
|
|
||||||
|
// 面板打开时设置初始焦点(键盘 / 手柄导航入口)
|
||||||
|
StartCoroutine(RestoreFocusNextFrame());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDisable()
|
private void OnDisable()
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityEngine.EventSystems;
|
|
||||||
using BaseGames.Core;
|
using BaseGames.Core;
|
||||||
|
using BaseGames.Localization;
|
||||||
|
|
||||||
namespace BaseGames.UI
|
namespace BaseGames.UI
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置面板控制器(架构 10_UIModule §7)。
|
/// 设置面板控制器(架构 10_UIModule §7)。
|
||||||
/// 驱动 SettingsManager 的音量与画面设置,并从当前配置初始化控件值。
|
/// 驱动 SettingsManager 的音量与画面设置,并从当前配置初始化控件值。
|
||||||
|
/// 生命周期 / 焦点由 <see cref="UIPanelBase"/> 统一处理。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SettingsPanelController : MonoBehaviour, IFocusable
|
public class SettingsPanelController : UIPanelBase
|
||||||
{
|
{
|
||||||
// ISettingsService 通过 ServiceLocator 获取,无需 Inspector 直接注入具体类,
|
// ISettingsService 通过 ServiceLocator 获取,无需 Inspector 直接注入具体类,
|
||||||
// 支持测试场景替换 Mock 实现。
|
// 支持测试场景替换 Mock 实现。
|
||||||
@@ -32,12 +33,19 @@ namespace BaseGames.UI
|
|||||||
[SerializeField] private TMP_Dropdown _colorblindDropdown; // None / Prot / Deut / Trit
|
[SerializeField] private TMP_Dropdown _colorblindDropdown; // None / Prot / Deut / Trit
|
||||||
[SerializeField] private Toggle _screenShakeToggle;
|
[SerializeField] private Toggle _screenShakeToggle;
|
||||||
|
|
||||||
|
[Header("语言")]
|
||||||
|
[SerializeField] private TMP_Dropdown _languageDropdown; // 中文 / English / 日本語 / 한국어
|
||||||
|
|
||||||
[Header("按键重绑定")]
|
[Header("按键重绑定")]
|
||||||
[SerializeField] private GameObject _rebindPanelRoot; // RebindPanel GameObject
|
[SerializeField] private GameObject _rebindPanelRoot; // RebindPanel GameObject
|
||||||
|
|
||||||
private static readonly int[] FpsOptions = { 30, 60, 120, -1 };
|
private static readonly int[] FpsOptions = { 30, 60, 120, -1 };
|
||||||
|
|
||||||
private void OnEnable()
|
// 语言下拉项顺序(与脚手架填充的显示项一一对应)
|
||||||
|
private static readonly Language[] LanguageOptions =
|
||||||
|
{ Language.ChineseSimplified, Language.English, Language.Japanese, Language.Korean };
|
||||||
|
|
||||||
|
protected override void OnPanelOpen()
|
||||||
{
|
{
|
||||||
_settings = ServiceLocator.GetOrDefault<ISettingsService>();
|
_settings = ServiceLocator.GetOrDefault<ISettingsService>();
|
||||||
if (_settings == null) return;
|
if (_settings == null) return;
|
||||||
@@ -95,8 +103,18 @@ namespace BaseGames.UI
|
|||||||
_screenShakeToggle.onValueChanged.AddListener(v => _settings.SetScreenShakeEnabled(v));
|
_screenShakeToggle.onValueChanged.AddListener(v => _settings.SetScreenShakeEnabled(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 手柄导航:打开设置面板时将焦点置于主音量滑条
|
// ── 语言 ──────────────────────────────────────────────────────────
|
||||||
EventSystem.current?.SetSelectedGameObject(_masterVolume?.gameObject);
|
if (_languageDropdown != null)
|
||||||
|
{
|
||||||
|
_languageDropdown.onValueChanged.RemoveAllListeners();
|
||||||
|
var loc = ServiceLocator.GetOrDefault<ILocalizationService>();
|
||||||
|
int idx = loc != null ? System.Array.IndexOf(LanguageOptions, loc.CurrentLanguage) : 0;
|
||||||
|
_languageDropdown.value = idx >= 0 ? idx : 0;
|
||||||
|
_languageDropdown.RefreshShownValue();
|
||||||
|
_languageDropdown.onValueChanged.AddListener(i =>
|
||||||
|
ServiceLocator.GetOrDefault<ILocalizationService>()?
|
||||||
|
.SetLanguage(LanguageOptions[Mathf.Clamp(i, 0, LanguageOptions.Length - 1)]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateUIScaleLabel(float v)
|
private void UpdateUIScaleLabel(float v)
|
||||||
@@ -115,10 +133,10 @@ namespace BaseGames.UI
|
|||||||
slider.onValueChanged.AddListener(onChange);
|
slider.onValueChanged.AddListener(onChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── IFocusable ────────────────────────────────────────────────────────
|
// ── 焦点 ──────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
/// <summary>面板恢复为栈顶时将焦点移回主音量滑条。</summary>
|
/// <summary>默认焦点 / 焦点恢复回到主音量滑条(基类 FocusFirst 调用)。</summary>
|
||||||
public void OnFocusRestored()
|
protected override GameObject ResolveFirstSelected()
|
||||||
=> EventSystem.current?.SetSelectedGameObject(_masterVolume?.gameObject);
|
=> _masterVolume != null ? _masterVolume.gameObject : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
214
Assets/_Game/Scripts/UI/Settings/DataDrivenSettingsPanel.cs
Normal file
214
Assets/_Game/Scripts/UI/Settings/DataDrivenSettingsPanel.cs
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using BaseGames.Core;
|
||||||
|
using BaseGames.Localization;
|
||||||
|
|
||||||
|
namespace BaseGames.UI.Settings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 数据驱动设置面板:据 <see cref="SettingsSchemaSO"/> 生成控件行并绑定 <see cref="ISettingsService"/>。
|
||||||
|
///
|
||||||
|
/// 取代硬编码的 <see cref="BaseGames.UI.SettingsPanelController"/>:策划改表即可增删 / 重排 / 改标签 / 分节,
|
||||||
|
/// 无需改代码。每行据 <see cref="SettingKey"/> 自动选用 Slider / Toggle / Dropdown 行预制件,
|
||||||
|
/// 并复用通用控件 <see cref="UISlider"/> / <see cref="UIDropdown"/>。
|
||||||
|
///
|
||||||
|
/// 控件来源:行预制件由 <c>SettingsPanelScaffold</c> 生成(标签为 <see cref="LocalizedText"/>)。
|
||||||
|
/// </summary>
|
||||||
|
public class DataDrivenSettingsPanel : UIPanelBase
|
||||||
|
{
|
||||||
|
public enum ControlKind { Slider, Toggle, Dropdown }
|
||||||
|
|
||||||
|
[Header("数据表")]
|
||||||
|
[SerializeField] private SettingsSchemaSO _schema;
|
||||||
|
|
||||||
|
[Header("行布局")]
|
||||||
|
[Tooltip("生成的行的父节点(通常挂 VerticalLayoutGroup)。")]
|
||||||
|
[SerializeField] private Transform _container;
|
||||||
|
[SerializeField] private GameObject _headerPrefab;
|
||||||
|
[SerializeField] private GameObject _sliderRowPrefab;
|
||||||
|
[SerializeField] private GameObject _toggleRowPrefab;
|
||||||
|
[SerializeField] private GameObject _dropdownRowPrefab;
|
||||||
|
|
||||||
|
// FPS 下拉的取值集合(与 SettingsPanelController 一致)
|
||||||
|
private static readonly int[] FpsOptions = { 30, 60, 120, -1 };
|
||||||
|
private static readonly Language[] LanguageOptions =
|
||||||
|
{ Language.ChineseSimplified, Language.English, Language.Japanese, Language.Korean };
|
||||||
|
private static readonly string[] LanguageNativeNames =
|
||||||
|
{ "简体中文", "English", "日本語", "한국어" };
|
||||||
|
|
||||||
|
private ISettingsService _settings;
|
||||||
|
private ILocalizationService _loc;
|
||||||
|
private readonly List<GameObject> _spawned = new();
|
||||||
|
|
||||||
|
// ── 生命周期 ──────────────────────────────────────────────────────────
|
||||||
|
protected override void OnPanelOpen()
|
||||||
|
{
|
||||||
|
_settings = GetService<ISettingsService>();
|
||||||
|
_loc = GetService<ILocalizationService>();
|
||||||
|
Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPanelClose() => Clear();
|
||||||
|
|
||||||
|
// ── 构建 ──────────────────────────────────────────────────────────────
|
||||||
|
/// <summary>据 schema 重建所有行。可在无 ISettingsService 时调用(仅生成行 + 标签,不绑定)。</summary>
|
||||||
|
public void Build()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
if (_schema == null || _container == null) return;
|
||||||
|
|
||||||
|
foreach (var item in _schema.Items)
|
||||||
|
{
|
||||||
|
GameObject prefab = item.isHeader ? _headerPrefab : PrefabFor(KindOf(item.key));
|
||||||
|
if (prefab == null) continue;
|
||||||
|
|
||||||
|
var go = Instantiate(prefab, _container);
|
||||||
|
_spawned.Add(go);
|
||||||
|
|
||||||
|
SetLabel(go, item.labelKey);
|
||||||
|
if (!item.isHeader && _settings != null)
|
||||||
|
BindControl(go, item.key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Clear()
|
||||||
|
{
|
||||||
|
foreach (var go in _spawned) if (go != null) Destroy(go);
|
||||||
|
_spawned.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private GameObject PrefabFor(ControlKind kind) => kind switch
|
||||||
|
{
|
||||||
|
ControlKind.Slider => _sliderRowPrefab,
|
||||||
|
ControlKind.Toggle => _toggleRowPrefab,
|
||||||
|
ControlKind.Dropdown => _dropdownRowPrefab,
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
|
|
||||||
|
private static void SetLabel(GameObject row, string labelKey)
|
||||||
|
{
|
||||||
|
var loc = row.GetComponentInChildren<LocalizedText>(true);
|
||||||
|
if (loc != null) loc.SetKey(labelKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 控件类型映射 ──────────────────────────────────────────────────────
|
||||||
|
public static ControlKind KindOf(SettingKey key) => key switch
|
||||||
|
{
|
||||||
|
SettingKey.MasterVolume or SettingKey.BGMVolume or SettingKey.SFXVolume
|
||||||
|
or SettingKey.AmbientVolume or SettingKey.UIScale => ControlKind.Slider,
|
||||||
|
SettingKey.VSync or SettingKey.ScreenShake => ControlKind.Toggle,
|
||||||
|
SettingKey.TargetFPS or SettingKey.ColorblindMode or SettingKey.Language => ControlKind.Dropdown,
|
||||||
|
_ => ControlKind.Slider,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ── 绑定派发 ──────────────────────────────────────────────────────────
|
||||||
|
private void BindControl(GameObject row, SettingKey key)
|
||||||
|
{
|
||||||
|
switch (KindOf(key))
|
||||||
|
{
|
||||||
|
case ControlKind.Slider: BindSlider(row, key); break;
|
||||||
|
case ControlKind.Toggle: BindToggle(row, key); break;
|
||||||
|
case ControlKind.Dropdown: BindDropdown(row, key); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BindSlider(GameObject row, SettingKey key)
|
||||||
|
{
|
||||||
|
var ui = row.GetComponentInChildren<UISlider>(true);
|
||||||
|
if (ui == null) return;
|
||||||
|
var data = _settings.Current;
|
||||||
|
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case SettingKey.MasterVolume:
|
||||||
|
ui.Bind(0f, 1f, data.MasterVolume, v => _settings.SetMasterVolume(v), Percent); break;
|
||||||
|
case SettingKey.BGMVolume:
|
||||||
|
ui.Bind(0f, 1f, data.BGMVolume, v => _settings.SetBGMVolume(v), Percent); break;
|
||||||
|
case SettingKey.SFXVolume:
|
||||||
|
ui.Bind(0f, 1f, data.SFXVolume, v => _settings.SetSFXVolume(v), Percent); break;
|
||||||
|
case SettingKey.AmbientVolume:
|
||||||
|
ui.Bind(0f, 1f, data.AmbientVolume, v => _settings.SetAmbientVolume(v), Percent); break;
|
||||||
|
case SettingKey.UIScale:
|
||||||
|
ui.Bind(0.8f, 1.5f, data.UIScale, v => _settings.SetUIScale(v), Percent); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BindToggle(GameObject row, SettingKey key)
|
||||||
|
{
|
||||||
|
var toggle = row.GetComponentInChildren<Toggle>(true);
|
||||||
|
if (toggle == null) return;
|
||||||
|
var data = _settings.Current;
|
||||||
|
toggle.onValueChanged.RemoveAllListeners();
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case SettingKey.VSync:
|
||||||
|
toggle.isOn = data.VSync;
|
||||||
|
toggle.onValueChanged.AddListener(v => _settings.SetVSync(v));
|
||||||
|
break;
|
||||||
|
case SettingKey.ScreenShake:
|
||||||
|
toggle.isOn = data.ScreenShakeEnabled;
|
||||||
|
toggle.onValueChanged.AddListener(v => _settings.SetScreenShakeEnabled(v));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BindDropdown(GameObject row, SettingKey key)
|
||||||
|
{
|
||||||
|
var ui = row.GetComponentInChildren<UIDropdown>(true);
|
||||||
|
if (ui == null) return;
|
||||||
|
var data = _settings.Current;
|
||||||
|
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case SettingKey.TargetFPS:
|
||||||
|
{
|
||||||
|
var opts = new List<string> { "30", "60", "120", Loc("SET_FPS_UNLIMITED", "无限") };
|
||||||
|
int idx = Array.IndexOf(FpsOptions, data.TargetFPS); if (idx < 0) idx = 1;
|
||||||
|
ui.Bind(opts, idx, i => _settings.SetTargetFrameRate(FpsOptions[Mathf.Clamp(i, 0, FpsOptions.Length - 1)]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SettingKey.ColorblindMode:
|
||||||
|
{
|
||||||
|
int count = Enum.GetValues(typeof(ColorblindMode)).Length;
|
||||||
|
var opts = new List<string>(count);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
opts.Add(Loc($"SET_COLORBLIND_{i}", ((ColorblindMode)i).ToString()));
|
||||||
|
ui.Bind(opts, (int)data.ColorblindMode,
|
||||||
|
i => _settings.SetColorblindMode((ColorblindMode)Mathf.Clamp(i, 0, count - 1)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SettingKey.Language:
|
||||||
|
{
|
||||||
|
var opts = new List<string>(LanguageNativeNames);
|
||||||
|
int idx = _loc != null ? Array.IndexOf(LanguageOptions, _loc.CurrentLanguage) : 0;
|
||||||
|
if (idx < 0) idx = 0;
|
||||||
|
ui.Bind(opts, idx, i =>
|
||||||
|
GetService<ILocalizationService>()?.SetLanguage(LanguageOptions[Mathf.Clamp(i, 0, LanguageOptions.Length - 1)]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 工具 ──────────────────────────────────────────────────────────────
|
||||||
|
private static string Percent(float v) => Mathf.RoundToInt(v * 100f) + "%";
|
||||||
|
|
||||||
|
private string Loc(string key, string fallback)
|
||||||
|
{
|
||||||
|
if (_loc != null && _loc.TryGet(key, out var v, LocalizationTable.UI)) return v;
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override GameObject ResolveFirstSelected()
|
||||||
|
{
|
||||||
|
foreach (var go in _spawned)
|
||||||
|
{
|
||||||
|
if (go == null) continue;
|
||||||
|
var sel = go.GetComponentInChildren<Selectable>(true);
|
||||||
|
if (sel != null) return sel.gameObject;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a7cf26a2f7cc5bb49b573bbe9f5614b5
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user