From 93012f5f7ce270f27f2172ae5623c6f0e480d6af Mon Sep 17 00:00:00 2001 From: Ding Yuntian <1491671119@qq.com> Date: Sat, 25 Apr 2026 20:13:29 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat(chapter):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E7=AB=A0=E8=8A=82=E7=B3=BB=E7=BB=9F=E4=B8=BA=E5=A4=9A=E5=87=BA?= =?UTF-8?q?=E5=8F=A3=E5=9B=BE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TalkSceneSO 引入 SceneExit 多出口列表与 displayOrder 排序 - GameManager.NextSceneSo 与 Yarn NextYarn 支持 exitName 跳转 - ChapterController 改用 GameManager 全局 SceneSO 列表 - SceneSO 资源迁移至 Archive/Demo/Fiction/Test 子目录 --- .../{HuoshanDay1.asset.meta => Archive.meta} | 6 +-- .../SceneSO/{ => Archive}/Day3_mid.asset | 8 +++- .../SceneSO/{ => Archive}/Day3_mid.asset.meta | 0 .../SceneSO/{ => Archive}/Day3_night.asset | 14 ++++-- .../{ => Archive}/Day3_night.asset.meta | 0 .../SceneSO/{ => Archive}/Day4_mid.asset | 14 ++++-- .../SceneSO/{ => Archive}/Day4_mid.asset.meta | 0 .../SceneSO/{ => Archive}/FP_HuoShan.asset | 8 +++- .../{ => Archive}/FP_HuoShan.asset.meta | 0 .../SceneSO/{ => Archive}/Gts1.asset | 8 +++- .../SceneSO/{ => Archive}/Gts1.asset.meta | 0 .../SceneSO/{ => Archive}/PeipeiDay1.asset | 8 +++- .../{ => Archive}/PeipeiDay1.asset.meta | 0 .../SceneSO/{ => Archive}/PeipeiDay2.asset | 8 +++- .../{ => Archive}/PeipeiDay2.asset.meta | 0 .../SceneSO/{ => Archive}/PeipeiDay3.asset | 14 ++++-- .../{ => Archive}/PeipeiDay3.asset.meta | 0 .../{ => Archive}/Prologue_begin.asset | 14 ++++-- .../{ => Archive}/Prologue_begin.asset.meta | 0 .../SceneSO/{ => Archive}/StoneDay2.asset | 14 ++++-- .../{ => Archive}/StoneDay2.asset.meta | 0 .../SceneSO/{ => Archive}/YingliDay1.asset | 14 ++++-- .../{ => Archive}/YingliDay1.asset.meta | 0 .../{StoneDay1.asset.meta => Demo.meta} | 6 +-- .../SceneSO/{ => Demo}/Day0_Prologue.asset | 7 ++- .../{ => Demo}/Day0_Prologue.asset.meta | 0 .../SceneSO/{ => Demo}/Day1_FIRST_PP1.asset | 7 ++- .../{ => Demo}/Day1_FIRST_PP1.asset.meta | 0 .../SceneSO/{ => Demo}/Day1_begin.asset | 7 ++- .../SceneSO/{ => Demo}/Day1_begin.asset.meta | 0 .../SceneSO/{ => Demo}/Day1_mid.asset | 7 ++- .../SceneSO/{ => Demo}/Day1_mid.asset.meta | 0 .../SceneSO/{ => Demo}/Day1_night.asset | 7 ++- .../SceneSO/{ => Demo}/Day1_night.asset.meta | 0 .../SceneSO/{ => Demo}/Day1_sleep.asset | 7 ++- .../SceneSO/{ => Demo}/Day1_sleep.asset.meta | 0 .../SceneSO/{ => Demo}/Day2_FIRST_HS1.asset | 7 ++- .../{ => Demo}/Day2_FIRST_HS1.asset.meta | 0 .../SceneSO/{ => Demo}/Day2_NEXT_PP2.asset | 7 ++- .../{ => Demo}/Day2_NEXT_PP2.asset.meta | 0 .../SceneSO/{ => Demo}/Day2_begin.asset | 7 ++- .../SceneSO/{ => Demo}/Day2_begin.asset.meta | 0 .../SceneSO/{ => Demo}/Day2_mid.asset | 7 ++- .../SceneSO/{ => Demo}/Day2_mid.asset.meta | 0 .../SceneSO/{ => Demo}/Day2_night.asset | 7 ++- .../SceneSO/{ => Demo}/Day2_night.asset.meta | 0 .../SceneSO/{ => Demo}/Day2_sleep.asset | 7 ++- .../SceneSO/{ => Demo}/Day2_sleep.asset.meta | 0 .../SceneSO/{ => Demo}/GeneralEnd.asset | 5 ++- .../SceneSO/{ => Demo}/GeneralEnd.asset.meta | 0 Assets/ScriptableObjects/SceneSO/Fiction.meta | 8 ++++ .../SceneSO/{ => Fiction}/Day1_NEXT_ST1.asset | 14 ++++-- .../{ => Fiction}/Day1_NEXT_ST1.asset.meta | 0 .../SceneSO/HuoshanDay1.asset | 19 -------- .../ScriptableObjects/SceneSO/StoneDay1.asset | 19 -------- Assets/ScriptableObjects/SceneSO/Test.meta | 8 ++++ .../SceneSO/{ => Test}/TestSO.asset | 8 +++- .../SceneSO/{ => Test}/TestSO.asset.meta | 0 .../SceneSO/{ => Test}/Test_Shitou.asset | 4 ++ .../SceneSO/{ => Test}/Test_Shitou.asset.meta | 0 .../Scripts/Dialog System/BaseYarnCommand.cs | 4 +- Assets/Scripts/Game Loop/ChapterController.cs | 29 +++++++++---- Assets/Scripts/Game Loop/GameManager.cs | 11 +++-- Assets/Scripts/Game Loop/TalkSceneSO.cs | 43 +++++++++++++++++-- 64 files changed, 291 insertions(+), 101 deletions(-) rename Assets/ScriptableObjects/SceneSO/{HuoshanDay1.asset.meta => Archive.meta} (52%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/Day3_mid.asset (71%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/Day3_mid.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/Day3_night.asset (63%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/Day3_night.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/Day4_mid.asset (63%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/Day4_mid.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/FP_HuoShan.asset (71%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/FP_HuoShan.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/Gts1.asset (75%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/Gts1.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/PeipeiDay1.asset (75%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/PeipeiDay1.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/PeipeiDay2.asset (71%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/PeipeiDay2.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/PeipeiDay3.asset (63%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/PeipeiDay3.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/Prologue_begin.asset (64%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/Prologue_begin.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/StoneDay2.asset (63%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/StoneDay2.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/YingliDay1.asset (63%) rename Assets/ScriptableObjects/SceneSO/{ => Archive}/YingliDay1.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{StoneDay1.asset.meta => Demo.meta} (52%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day0_Prologue.asset (76%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day0_Prologue.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day1_FIRST_PP1.asset (77%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day1_FIRST_PP1.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day1_begin.asset (77%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day1_begin.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day1_mid.asset (76%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day1_mid.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day1_night.asset (77%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day1_night.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day1_sleep.asset (78%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day1_sleep.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day2_FIRST_HS1.asset (77%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day2_FIRST_HS1.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day2_NEXT_PP2.asset (77%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day2_NEXT_PP2.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day2_begin.asset (76%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day2_begin.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day2_mid.asset (77%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day2_mid.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day2_night.asset (76%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day2_night.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day2_sleep.asset (77%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/Day2_sleep.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/GeneralEnd.asset (86%) rename Assets/ScriptableObjects/SceneSO/{ => Demo}/GeneralEnd.asset.meta (100%) create mode 100644 Assets/ScriptableObjects/SceneSO/Fiction.meta rename Assets/ScriptableObjects/SceneSO/{ => Fiction}/Day1_NEXT_ST1.asset (64%) rename Assets/ScriptableObjects/SceneSO/{ => Fiction}/Day1_NEXT_ST1.asset.meta (100%) delete mode 100644 Assets/ScriptableObjects/SceneSO/HuoshanDay1.asset delete mode 100644 Assets/ScriptableObjects/SceneSO/StoneDay1.asset create mode 100644 Assets/ScriptableObjects/SceneSO/Test.meta rename Assets/ScriptableObjects/SceneSO/{ => Test}/TestSO.asset (71%) rename Assets/ScriptableObjects/SceneSO/{ => Test}/TestSO.asset.meta (100%) rename Assets/ScriptableObjects/SceneSO/{ => Test}/Test_Shitou.asset (85%) rename Assets/ScriptableObjects/SceneSO/{ => Test}/Test_Shitou.asset.meta (100%) diff --git a/Assets/ScriptableObjects/SceneSO/HuoshanDay1.asset.meta b/Assets/ScriptableObjects/SceneSO/Archive.meta similarity index 52% rename from Assets/ScriptableObjects/SceneSO/HuoshanDay1.asset.meta rename to Assets/ScriptableObjects/SceneSO/Archive.meta index c8e4fd24c..8a7bf59c3 100644 --- a/Assets/ScriptableObjects/SceneSO/HuoshanDay1.asset.meta +++ b/Assets/ScriptableObjects/SceneSO/Archive.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: f9314e7bc5b932c41b8cd00507d7ac19 -NativeFormatImporter: +guid: b69b73da769b9f74e8d1da23717b76bf +folderAsset: yes +DefaultImporter: externalObjects: {} - mainObjectFileID: 11400000 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/ScriptableObjects/SceneSO/Day3_mid.asset b/Assets/ScriptableObjects/SceneSO/Archive/Day3_mid.asset similarity index 71% rename from Assets/ScriptableObjects/SceneSO/Day3_mid.asset rename to Assets/ScriptableObjects/SceneSO/Archive/Day3_mid.asset index 8b464bc31..c449f5e05 100644 --- a/Assets/ScriptableObjects/SceneSO/Day3_mid.asset +++ b/Assets/ScriptableObjects/SceneSO/Archive/Day3_mid.asset @@ -12,10 +12,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day3_mid m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: aaef579ad8bdda542b503b40ce6773a8, type: 2} + nextScene: {fileID: 0} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: aaef579ad8bdda542b503b40ce6773a8, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 640f90d7758f6524f8735352da531604, type: 3} firstSceneName: Scene/ClinicOut title: description: coverPic: {fileID: 0} chapter: "\u96EAxue" + graphPosition: {x: 420, y: 110} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day3_mid.asset.meta b/Assets/ScriptableObjects/SceneSO/Archive/Day3_mid.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day3_mid.asset.meta rename to Assets/ScriptableObjects/SceneSO/Archive/Day3_mid.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Day3_night.asset b/Assets/ScriptableObjects/SceneSO/Archive/Day3_night.asset similarity index 63% rename from Assets/ScriptableObjects/SceneSO/Day3_night.asset rename to Assets/ScriptableObjects/SceneSO/Archive/Day3_night.asset index 44b0dfbbc..2d694b596 100644 --- a/Assets/ScriptableObjects/SceneSO/Day3_night.asset +++ b/Assets/ScriptableObjects/SceneSO/Archive/Day3_night.asset @@ -12,8 +12,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day3_night m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: ff82a99e791be3e41acf40232f908eb3, type: 2} + nextScene: {fileID: 0} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: ff82a99e791be3e41acf40232f908eb3, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 640f90d7758f6524f8735352da531604, type: 3} firstSceneName: Scene/ClinicOut - isEndOfDay: 1 - nameToPlayer: "\u7B2C\u4E09\u5929\u4E2D\u5348\u4F11\u606F" + title: + description: + coverPic: {fileID: 0} + chapter: + graphPosition: {x: 0, y: -990} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day3_night.asset.meta b/Assets/ScriptableObjects/SceneSO/Archive/Day3_night.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day3_night.asset.meta rename to Assets/ScriptableObjects/SceneSO/Archive/Day3_night.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Day4_mid.asset b/Assets/ScriptableObjects/SceneSO/Archive/Day4_mid.asset similarity index 63% rename from Assets/ScriptableObjects/SceneSO/Day4_mid.asset rename to Assets/ScriptableObjects/SceneSO/Archive/Day4_mid.asset index a6d00fc5f..07abae7fe 100644 --- a/Assets/ScriptableObjects/SceneSO/Day4_mid.asset +++ b/Assets/ScriptableObjects/SceneSO/Archive/Day4_mid.asset @@ -12,8 +12,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day4_mid m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: 362a7dfb573114247a33c0e290b698eb, type: 2} + nextScene: {fileID: 0} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: 362a7dfb573114247a33c0e290b698eb, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: fceb65c69f946c740992b742bc01a6a2, type: 3} firstSceneName: Scene/ClinicOut - isEndOfDay: 0 - nameToPlayer: "\u7B2C\u56DB\u5929\u4E2D\u5348\u4F11\u606F" + title: + description: + coverPic: {fileID: 0} + chapter: + graphPosition: {x: 0, y: -770} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day4_mid.asset.meta b/Assets/ScriptableObjects/SceneSO/Archive/Day4_mid.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day4_mid.asset.meta rename to Assets/ScriptableObjects/SceneSO/Archive/Day4_mid.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/FP_HuoShan.asset b/Assets/ScriptableObjects/SceneSO/Archive/FP_HuoShan.asset similarity index 71% rename from Assets/ScriptableObjects/SceneSO/FP_HuoShan.asset rename to Assets/ScriptableObjects/SceneSO/Archive/FP_HuoShan.asset index c87f7eea8..249aed938 100644 --- a/Assets/ScriptableObjects/SceneSO/FP_HuoShan.asset +++ b/Assets/ScriptableObjects/SceneSO/Archive/FP_HuoShan.asset @@ -12,10 +12,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: FP_HuoShan m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: 8d8b11f0c2fbc4d4cb8c2857d98383c9, type: 2} + nextScene: {fileID: 0} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: 8d8b11f0c2fbc4d4cb8c2857d98383c9, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: dc075ea1c729cec4484634a00ebb03a4, type: 3} firstSceneName: Scene/HuoShanFixScene title: description: coverPic: {fileID: 0} chapter: + graphPosition: {x: 0, y: -550} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/FP_HuoShan.asset.meta b/Assets/ScriptableObjects/SceneSO/Archive/FP_HuoShan.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/FP_HuoShan.asset.meta rename to Assets/ScriptableObjects/SceneSO/Archive/FP_HuoShan.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Gts1.asset b/Assets/ScriptableObjects/SceneSO/Archive/Gts1.asset similarity index 75% rename from Assets/ScriptableObjects/SceneSO/Gts1.asset rename to Assets/ScriptableObjects/SceneSO/Archive/Gts1.asset index 6b2a0dd3e..b95ec74a3 100644 --- a/Assets/ScriptableObjects/SceneSO/Gts1.asset +++ b/Assets/ScriptableObjects/SceneSO/Archive/Gts1.asset @@ -12,10 +12,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Gts1 m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: 172e1298764e87a4b9ed51264b908ba9, type: 2} + nextScene: {fileID: 0} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: 172e1298764e87a4b9ed51264b908ba9, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 31109973cccc10642a3bc09bc70f47d3, type: 3} firstSceneName: Scene/PeipeiFixScene title: "10\u5E74\u524D" description: "\u201C\u4E8B\u6545\u201D" coverPic: {fileID: -3514371587045790464, guid: fd04c28739017964789d58d573f9fabb, type: 3} chapter: "\u201C\u4E8B\u6545\u201D" + graphPosition: {x: 0, y: -330} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Gts1.asset.meta b/Assets/ScriptableObjects/SceneSO/Archive/Gts1.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Gts1.asset.meta rename to Assets/ScriptableObjects/SceneSO/Archive/Gts1.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/PeipeiDay1.asset b/Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay1.asset similarity index 75% rename from Assets/ScriptableObjects/SceneSO/PeipeiDay1.asset rename to Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay1.asset index ef01c0b3f..e698f1886 100644 --- a/Assets/ScriptableObjects/SceneSO/PeipeiDay1.asset +++ b/Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay1.asset @@ -12,10 +12,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: PeipeiDay1 m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: 68a9c1b8c5230454bb9498fd2ab5714b, type: 2} + nextScene: {fileID: 0} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: 68a9c1b8c5230454bb9498fd2ab5714b, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 26fc6619bbcda734a81361b8bb615f04, type: 3} firstSceneName: Scene/PeipeiFixScene title: "\u4F69\u4F69" description: "\u7B2C\u4E00\u4F4D\u75C5\u4EBA" coverPic: {fileID: 21300000, guid: ef7ba7c21d2aea048abe5729d7da2eee, type: 3} chapter: "\u7B2C\u4E00\u4F4D\u75C5\u4EBA" + graphPosition: {x: 0, y: 110} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/PeipeiDay1.asset.meta b/Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay1.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/PeipeiDay1.asset.meta rename to Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay1.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/PeipeiDay2.asset b/Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay2.asset similarity index 71% rename from Assets/ScriptableObjects/SceneSO/PeipeiDay2.asset rename to Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay2.asset index 0ed99c3a1..b0f3ad756 100644 --- a/Assets/ScriptableObjects/SceneSO/PeipeiDay2.asset +++ b/Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay2.asset @@ -12,10 +12,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: PeipeiDay2 m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: afc5b01ef301cc74db7cae741acad427, type: 2} + nextScene: {fileID: 0} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: afc5b01ef301cc74db7cae741acad427, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 247e2ccd847942843bb87841bb9888c5, type: 3} firstSceneName: Scene/PeipeiFixScene title: description: coverPic: {fileID: 0} chapter: + graphPosition: {x: 420, y: -110} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/PeipeiDay2.asset.meta b/Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay2.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/PeipeiDay2.asset.meta rename to Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay2.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/PeipeiDay3.asset b/Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay3.asset similarity index 63% rename from Assets/ScriptableObjects/SceneSO/PeipeiDay3.asset rename to Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay3.asset index 3181e282a..a62ecb0e4 100644 --- a/Assets/ScriptableObjects/SceneSO/PeipeiDay3.asset +++ b/Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay3.asset @@ -12,8 +12,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: PeipeiDay3 m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: e749fe0f9aa32f44097e037f52a5bfe0, type: 2} + nextScene: {fileID: 0} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: e749fe0f9aa32f44097e037f52a5bfe0, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 05ccf66391562af43835d718ca36f508, type: 3} firstSceneName: Scene/PeipeiFixScene - isEndOfDay: 1 - nameToPlayer: "\u7B2C\u56DB\u5929\u4E0A\u5348\u4F69\u4F69" + title: + description: + coverPic: {fileID: 0} + chapter: + graphPosition: {x: 0, y: 330} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/PeipeiDay3.asset.meta b/Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay3.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/PeipeiDay3.asset.meta rename to Assets/ScriptableObjects/SceneSO/Archive/PeipeiDay3.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Prologue_begin.asset b/Assets/ScriptableObjects/SceneSO/Archive/Prologue_begin.asset similarity index 64% rename from Assets/ScriptableObjects/SceneSO/Prologue_begin.asset rename to Assets/ScriptableObjects/SceneSO/Archive/Prologue_begin.asset index 6e7708021..9eea46e7c 100644 --- a/Assets/ScriptableObjects/SceneSO/Prologue_begin.asset +++ b/Assets/ScriptableObjects/SceneSO/Archive/Prologue_begin.asset @@ -12,8 +12,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Prologue_begin m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: 2f763a2c04ecafb4981379b7363f9791, type: 2} + nextScene: {fileID: 0} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: 2f763a2c04ecafb4981379b7363f9791, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: ab71ff7b298372f48a262ad5b949c395, type: 3} firstSceneName: Scene/OpenFixScene - isEndOfDay: 0 - nameToPlayer: "\u5E8F\u7AE0" + title: + description: + coverPic: {fileID: 0} + chapter: + graphPosition: {x: 0, y: 550} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Prologue_begin.asset.meta b/Assets/ScriptableObjects/SceneSO/Archive/Prologue_begin.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Prologue_begin.asset.meta rename to Assets/ScriptableObjects/SceneSO/Archive/Prologue_begin.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/StoneDay2.asset b/Assets/ScriptableObjects/SceneSO/Archive/StoneDay2.asset similarity index 63% rename from Assets/ScriptableObjects/SceneSO/StoneDay2.asset rename to Assets/ScriptableObjects/SceneSO/Archive/StoneDay2.asset index d53e3bda4..a70b28ab2 100644 --- a/Assets/ScriptableObjects/SceneSO/StoneDay2.asset +++ b/Assets/ScriptableObjects/SceneSO/Archive/StoneDay2.asset @@ -12,8 +12,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: StoneDay2 m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: afc5b01ef301cc74db7cae741acad427, type: 2} + nextScene: {fileID: 0} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: afc5b01ef301cc74db7cae741acad427, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: fa8082420f7bb5b4a8ab33a59c70bcc9, type: 3} firstSceneName: Scene/ExpressFixScene - isEndOfDay: 0 - nameToPlayer: "\u77F3\u5934\u590D\u8BCA" + title: + description: + coverPic: {fileID: 0} + chapter: + graphPosition: {x: 0, y: 770} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/StoneDay2.asset.meta b/Assets/ScriptableObjects/SceneSO/Archive/StoneDay2.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/StoneDay2.asset.meta rename to Assets/ScriptableObjects/SceneSO/Archive/StoneDay2.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/YingliDay1.asset b/Assets/ScriptableObjects/SceneSO/Archive/YingliDay1.asset similarity index 63% rename from Assets/ScriptableObjects/SceneSO/YingliDay1.asset rename to Assets/ScriptableObjects/SceneSO/Archive/YingliDay1.asset index 1d2e8e575..a2cbf3522 100644 --- a/Assets/ScriptableObjects/SceneSO/YingliDay1.asset +++ b/Assets/ScriptableObjects/SceneSO/Archive/YingliDay1.asset @@ -12,8 +12,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: YingliDay1 m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: e749fe0f9aa32f44097e037f52a5bfe0, type: 2} + nextScene: {fileID: 0} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: e749fe0f9aa32f44097e037f52a5bfe0, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 3bb399faf6caadd4c89f85b7aa83c388, type: 3} firstSceneName: Scene/YingliFixScene - isEndOfDay: 0 - nameToPlayer: "\u82F1\u7406\u521D\u8BCA" + title: + description: + coverPic: {fileID: 0} + chapter: + graphPosition: {x: 0, y: 990} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/YingliDay1.asset.meta b/Assets/ScriptableObjects/SceneSO/Archive/YingliDay1.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/YingliDay1.asset.meta rename to Assets/ScriptableObjects/SceneSO/Archive/YingliDay1.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/StoneDay1.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo.meta similarity index 52% rename from Assets/ScriptableObjects/SceneSO/StoneDay1.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo.meta index 525fd3fd8..882e2f65e 100644 --- a/Assets/ScriptableObjects/SceneSO/StoneDay1.asset.meta +++ b/Assets/ScriptableObjects/SceneSO/Demo.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: 6d49b124127007b48b6881ce33350263 -NativeFormatImporter: +guid: d9ce4de6ffe606743a73b423d93578c5 +folderAsset: yes +DefaultImporter: externalObjects: {} - mainObjectFileID: 11400000 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/ScriptableObjects/SceneSO/Day0_Prologue.asset b/Assets/ScriptableObjects/SceneSO/Demo/Day0_Prologue.asset similarity index 76% rename from Assets/ScriptableObjects/SceneSO/Day0_Prologue.asset rename to Assets/ScriptableObjects/SceneSO/Demo/Day0_Prologue.asset index ccea86df1..4b6337272 100644 --- a/Assets/ScriptableObjects/SceneSO/Day0_Prologue.asset +++ b/Assets/ScriptableObjects/SceneSO/Demo/Day0_Prologue.asset @@ -12,10 +12,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day0_Prologue m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: ac5ca9a66ff22ab4b9cd5adbdade6b8c, type: 2} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: ac5ca9a66ff22ab4b9cd5adbdade6b8c, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 2fa76ffaa57f62244b77be9b25ca14c2, type: 3} firstSceneName: Scene/OpenFixScene title: "\u68A6" description: "\u6D77\u6D6A\u4E0E\u75C5\u75DB" coverPic: {fileID: 21300000, guid: c66b2b5ca74393c45a0d281a6662aa54, type: 3} chapter: "\u6D77\u6D6A\u4E0E\u75C5\u75DB" + graphPosition: {x: -8.666687, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day0_Prologue.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo/Day0_Prologue.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day0_Prologue.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo/Day0_Prologue.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Day1_FIRST_PP1.asset b/Assets/ScriptableObjects/SceneSO/Demo/Day1_FIRST_PP1.asset similarity index 77% rename from Assets/ScriptableObjects/SceneSO/Day1_FIRST_PP1.asset rename to Assets/ScriptableObjects/SceneSO/Demo/Day1_FIRST_PP1.asset index 9bad0e3f6..59f54161c 100644 --- a/Assets/ScriptableObjects/SceneSO/Day1_FIRST_PP1.asset +++ b/Assets/ScriptableObjects/SceneSO/Demo/Day1_FIRST_PP1.asset @@ -12,10 +12,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day1_FIRST_PP1 m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: 68a9c1b8c5230454bb9498fd2ab5714b, type: 2} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: 68a9c1b8c5230454bb9498fd2ab5714b, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 26fc6619bbcda734a81361b8bb615f04, type: 3} firstSceneName: Scene/PeipeiFixScene title: "\u4F69\u4F69" description: "\u7B2C\u4E00\u4F4D\u75C5\u4EBA" coverPic: {fileID: 21300000, guid: ef7ba7c21d2aea048abe5729d7da2eee, type: 3} chapter: "\u7B2C\u4E00\u4F4D\u75C5\u4EBA" + graphPosition: {x: 640, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day1_FIRST_PP1.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo/Day1_FIRST_PP1.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day1_FIRST_PP1.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo/Day1_FIRST_PP1.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Day1_begin.asset b/Assets/ScriptableObjects/SceneSO/Demo/Day1_begin.asset similarity index 77% rename from Assets/ScriptableObjects/SceneSO/Day1_begin.asset rename to Assets/ScriptableObjects/SceneSO/Demo/Day1_begin.asset index f81fbaeb7..a68de8f08 100644 --- a/Assets/ScriptableObjects/SceneSO/Day1_begin.asset +++ b/Assets/ScriptableObjects/SceneSO/Demo/Day1_begin.asset @@ -12,10 +12,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day1_begin m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: dadf07a02eb4b8d4c8bdf1739a10c9c5, type: 2} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: dadf07a02eb4b8d4c8bdf1739a10c9c5, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 533dc422c8871c143a551bd5d446b439, type: 3} firstSceneName: Scene/SubWay title: "\u5730\u94C1\u4E0A" description: "\u8BB0\u5F97\u6253\u5361" coverPic: {fileID: 21300000, guid: f78e34492dd89b341928553dd1dfcbdb, type: 3} chapter: "\u8BB0\u5F97\u6253\u5361" + graphPosition: {x: 320, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day1_begin.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo/Day1_begin.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day1_begin.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo/Day1_begin.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Day1_mid.asset b/Assets/ScriptableObjects/SceneSO/Demo/Day1_mid.asset similarity index 76% rename from Assets/ScriptableObjects/SceneSO/Day1_mid.asset rename to Assets/ScriptableObjects/SceneSO/Demo/Day1_mid.asset index ef8dcba94..2b313e794 100644 --- a/Assets/ScriptableObjects/SceneSO/Day1_mid.asset +++ b/Assets/ScriptableObjects/SceneSO/Demo/Day1_mid.asset @@ -12,10 +12,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day1_mid m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: ada4bdc2db5594e4f860c90b3a4b9da8, type: 2} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: ada4bdc2db5594e4f860c90b3a4b9da8, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 293561ce52efc594399242651d44b366, type: 3} firstSceneName: Scene/ClinicOut title: "\u5348\u4F11" description: "\u51AC\u5929\u5230\u4E86" coverPic: {fileID: 21300000, guid: 7715c89797cc6ca4e914b85f5524e9fd, type: 3} chapter: "\u51AC\u5929\u5230\u4E86" + graphPosition: {x: 960, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day1_mid.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo/Day1_mid.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day1_mid.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo/Day1_mid.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Day1_night.asset b/Assets/ScriptableObjects/SceneSO/Demo/Day1_night.asset similarity index 77% rename from Assets/ScriptableObjects/SceneSO/Day1_night.asset rename to Assets/ScriptableObjects/SceneSO/Demo/Day1_night.asset index 6579177fb..3411417c5 100644 --- a/Assets/ScriptableObjects/SceneSO/Day1_night.asset +++ b/Assets/ScriptableObjects/SceneSO/Demo/Day1_night.asset @@ -12,10 +12,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day1_night m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: 653fbfbb55fef7740a2360590e29d552, type: 2} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: 653fbfbb55fef7740a2360590e29d552, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 29ebe788cfe2c084e88ffdd8e2f93378, type: 3} firstSceneName: Scene/ClinicOut title: "\u9152\u676F\u548C\u724C" description: "\u9152\u676F\u548C\u724C" coverPic: {fileID: 21300000, guid: df86302e77350e34ea422cd24043dd93, type: 3} chapter: "\u9152\u676F\u548C\u724C" + graphPosition: {x: 1280, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day1_night.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo/Day1_night.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day1_night.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo/Day1_night.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Day1_sleep.asset b/Assets/ScriptableObjects/SceneSO/Demo/Day1_sleep.asset similarity index 78% rename from Assets/ScriptableObjects/SceneSO/Day1_sleep.asset rename to Assets/ScriptableObjects/SceneSO/Demo/Day1_sleep.asset index 81317ba8f..932db9b6c 100644 --- a/Assets/ScriptableObjects/SceneSO/Day1_sleep.asset +++ b/Assets/ScriptableObjects/SceneSO/Demo/Day1_sleep.asset @@ -12,10 +12,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day1_sleep m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: 172e1298764e87a4b9ed51264b908ba9, type: 2} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: 172e1298764e87a4b9ed51264b908ba9, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: beb6e77de3427b04dae210b2c9ca29a1, type: 3} firstSceneName: "Scene/\u68A6\u5883" title: "\u542F\u793A" description: "\u627E\u5230\u5929\u6587\u53F0\u7684\u5165\u53E3" coverPic: {fileID: 21300000, guid: 20296b9c29cb10f4a97913165e98fb62, type: 3} chapter: "\u627E\u5230\u5929\u6587\u53F0\u7684\u5165\u53E3" + graphPosition: {x: 1600, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day1_sleep.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo/Day1_sleep.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day1_sleep.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo/Day1_sleep.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Day2_FIRST_HS1.asset b/Assets/ScriptableObjects/SceneSO/Demo/Day2_FIRST_HS1.asset similarity index 77% rename from Assets/ScriptableObjects/SceneSO/Day2_FIRST_HS1.asset rename to Assets/ScriptableObjects/SceneSO/Demo/Day2_FIRST_HS1.asset index e1c740e10..42cc6841d 100644 --- a/Assets/ScriptableObjects/SceneSO/Day2_FIRST_HS1.asset +++ b/Assets/ScriptableObjects/SceneSO/Demo/Day2_FIRST_HS1.asset @@ -12,10 +12,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day2_FIRST_HS1 m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: 8d8b11f0c2fbc4d4cb8c2857d98383c9, type: 2} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: 8d8b11f0c2fbc4d4cb8c2857d98383c9, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: dc075ea1c729cec4484634a00ebb03a4, type: 3} firstSceneName: Scene/HuoShanFixScene title: "\u706B\u5C71" description: "\u6211\u7684\u7535\u89C6\u5934\u670B\u53CB" coverPic: {fileID: 21300000, guid: 77af8281471ddab42993b4b7795f2f57, type: 3} chapter: "\u6211\u7684\u7535\u89C6\u5934\u670B\u53CB" + graphPosition: {x: 2240, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day2_FIRST_HS1.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo/Day2_FIRST_HS1.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day2_FIRST_HS1.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo/Day2_FIRST_HS1.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Day2_NEXT_PP2.asset b/Assets/ScriptableObjects/SceneSO/Demo/Day2_NEXT_PP2.asset similarity index 77% rename from Assets/ScriptableObjects/SceneSO/Day2_NEXT_PP2.asset rename to Assets/ScriptableObjects/SceneSO/Demo/Day2_NEXT_PP2.asset index 5a9615eb2..56dd46678 100644 --- a/Assets/ScriptableObjects/SceneSO/Day2_NEXT_PP2.asset +++ b/Assets/ScriptableObjects/SceneSO/Demo/Day2_NEXT_PP2.asset @@ -12,10 +12,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day2_NEXT_PP2 m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: afc5b01ef301cc74db7cae741acad427, type: 2} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: afc5b01ef301cc74db7cae741acad427, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 247e2ccd847942843bb87841bb9888c5, type: 3} firstSceneName: Scene/PeipeiFixScene title: "\u505C\u6B62\u60F3\u8C61" description: "\u505C\u6B62\u60F3\u8C61" coverPic: {fileID: 21300000, guid: ef7ba7c21d2aea048abe5729d7da2eee, type: 3} chapter: "\u505C\u6B62\u60F3\u8C61" + graphPosition: {x: 2880, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day2_NEXT_PP2.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo/Day2_NEXT_PP2.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day2_NEXT_PP2.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo/Day2_NEXT_PP2.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Day2_begin.asset b/Assets/ScriptableObjects/SceneSO/Demo/Day2_begin.asset similarity index 76% rename from Assets/ScriptableObjects/SceneSO/Day2_begin.asset rename to Assets/ScriptableObjects/SceneSO/Demo/Day2_begin.asset index abff4dc6c..dc0a5ce2f 100644 --- a/Assets/ScriptableObjects/SceneSO/Day2_begin.asset +++ b/Assets/ScriptableObjects/SceneSO/Demo/Day2_begin.asset @@ -12,10 +12,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day2_begin m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: 0bdbd8e46fa688e49a5a670b78b6f956, type: 2} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: 0bdbd8e46fa688e49a5a670b78b6f956, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 6ecfe80fd0370554db9a7ec3a173f7e3, type: 3} firstSceneName: Scene/SubWay title: "\u5730\u94C1\u4E0A" description: "\u5BBF\u9189" coverPic: {fileID: 21300000, guid: 922da7b13a1cf2747a43933c2afea754, type: 3} chapter: "\u5BBF\u9189" + graphPosition: {x: 1920, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day2_begin.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo/Day2_begin.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day2_begin.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo/Day2_begin.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Day2_mid.asset b/Assets/ScriptableObjects/SceneSO/Demo/Day2_mid.asset similarity index 77% rename from Assets/ScriptableObjects/SceneSO/Day2_mid.asset rename to Assets/ScriptableObjects/SceneSO/Demo/Day2_mid.asset index 7326e49ed..27bad24b8 100644 --- a/Assets/ScriptableObjects/SceneSO/Day2_mid.asset +++ b/Assets/ScriptableObjects/SceneSO/Demo/Day2_mid.asset @@ -12,10 +12,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day2_mid m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: a4dba2e2976607d45a28d4c8cade6b0a, type: 2} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: a4dba2e2976607d45a28d4c8cade6b0a, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 25f49957c68bca34bb1aeafec7feca8b, type: 3} firstSceneName: Scene/ClinicOut title: "\u7B2C\u4E8C\u5929\u4E2D\u5348" description: "\u7B2C\u4E8C\u5929\u4E2D\u5348" coverPic: {fileID: 21300000, guid: 7715c89797cc6ca4e914b85f5524e9fd, type: 3} chapter: "\u7B2C\u4E8C\u5929\u4E2D\u5348" + graphPosition: {x: 2560, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day2_mid.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo/Day2_mid.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day2_mid.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo/Day2_mid.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Day2_night.asset b/Assets/ScriptableObjects/SceneSO/Demo/Day2_night.asset similarity index 76% rename from Assets/ScriptableObjects/SceneSO/Day2_night.asset rename to Assets/ScriptableObjects/SceneSO/Demo/Day2_night.asset index f9e9c4152..8b9bbc649 100644 --- a/Assets/ScriptableObjects/SceneSO/Day2_night.asset +++ b/Assets/ScriptableObjects/SceneSO/Demo/Day2_night.asset @@ -12,10 +12,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day2_night m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: aaef579ad8bdda542b503b40ce6773a8, type: 2} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: aaef579ad8bdda542b503b40ce6773a8, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: ec06c945cb99fb544b1dd9a2a6ea9a7b, type: 3} firstSceneName: Scene/ClinicOut title: "\u5915\u9633" description: "\u5915\u9633" coverPic: {fileID: 21300000, guid: dc09bd90b2ce79249ac504f07b98944f, type: 3} chapter: "\u5915\u9633" + graphPosition: {x: 3200, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day2_night.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo/Day2_night.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day2_night.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo/Day2_night.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Day2_sleep.asset b/Assets/ScriptableObjects/SceneSO/Demo/Day2_sleep.asset similarity index 77% rename from Assets/ScriptableObjects/SceneSO/Day2_sleep.asset rename to Assets/ScriptableObjects/SceneSO/Demo/Day2_sleep.asset index 5373be1a4..f2310665b 100644 --- a/Assets/ScriptableObjects/SceneSO/Day2_sleep.asset +++ b/Assets/ScriptableObjects/SceneSO/Demo/Day2_sleep.asset @@ -12,10 +12,15 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day2_sleep m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: 362a7dfb573114247a33c0e290b698eb, type: 2} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: 362a7dfb573114247a33c0e290b698eb, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 62f2a99a47fc652449b846035a739529, type: 3} firstSceneName: "Scene/\u68A6\u5883" title: "\u542F\u793A" description: "\u6D77\u662F\u5B58\u5728\u7684\u5417\uFF1F" coverPic: {fileID: 21300000, guid: 2796d4ad771bcde488978d1c1e67ed8f, type: 3} chapter: "\u6D77\u662F\u5B58\u5728\u7684\u5417\uFF1F" + graphPosition: {x: 3520, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day2_sleep.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo/Day2_sleep.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day2_sleep.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo/Day2_sleep.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/GeneralEnd.asset b/Assets/ScriptableObjects/SceneSO/Demo/GeneralEnd.asset similarity index 86% rename from Assets/ScriptableObjects/SceneSO/GeneralEnd.asset rename to Assets/ScriptableObjects/SceneSO/Demo/GeneralEnd.asset index 0d291c779..116766009 100644 --- a/Assets/ScriptableObjects/SceneSO/GeneralEnd.asset +++ b/Assets/ScriptableObjects/SceneSO/Demo/GeneralEnd.asset @@ -12,10 +12,13 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: GeneralEnd m_EditorClassIdentifier: - nextScene: {fileID: 0} + exits: [] + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: e6bac2644a8a04b4899ce2fe8ae1f4fc, type: 3} firstSceneName: Scene/Bridge title: "\u7ED3\u675F" description: "\u7ED3\u675F" coverPic: {fileID: 21300000, guid: 8344881c78a9845499555d573e34e362, type: 3} chapter: "\u7ED3\u675F" + graphPosition: {x: 3840, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/GeneralEnd.asset.meta b/Assets/ScriptableObjects/SceneSO/Demo/GeneralEnd.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/GeneralEnd.asset.meta rename to Assets/ScriptableObjects/SceneSO/Demo/GeneralEnd.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Fiction.meta b/Assets/ScriptableObjects/SceneSO/Fiction.meta new file mode 100644 index 000000000..6e33c16de --- /dev/null +++ b/Assets/ScriptableObjects/SceneSO/Fiction.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: df234a5ef69dc6d468e8accd8fe47fbe +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ScriptableObjects/SceneSO/Day1_NEXT_ST1.asset b/Assets/ScriptableObjects/SceneSO/Fiction/Day1_NEXT_ST1.asset similarity index 64% rename from Assets/ScriptableObjects/SceneSO/Day1_NEXT_ST1.asset rename to Assets/ScriptableObjects/SceneSO/Fiction/Day1_NEXT_ST1.asset index 3666aea88..9a337f4cd 100644 --- a/Assets/ScriptableObjects/SceneSO/Day1_NEXT_ST1.asset +++ b/Assets/ScriptableObjects/SceneSO/Fiction/Day1_NEXT_ST1.asset @@ -12,8 +12,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: Day1_NEXT_ST1 m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: ada4bdc2db5594e4f860c90b3a4b9da8, type: 2} + nextScene: {fileID: 0} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: ada4bdc2db5594e4f860c90b3a4b9da8, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: 9c6e0818864e6964d83f946e81e32916, type: 3} firstSceneName: Scene/ExpressFixScene - isEndOfDay: 0 - nameToPlayer: "\u77F3\u5934\u521D\u8BCA" + title: + description: + coverPic: {fileID: 0} + chapter: + graphPosition: {x: 0, y: 0} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Day1_NEXT_ST1.asset.meta b/Assets/ScriptableObjects/SceneSO/Fiction/Day1_NEXT_ST1.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Day1_NEXT_ST1.asset.meta rename to Assets/ScriptableObjects/SceneSO/Fiction/Day1_NEXT_ST1.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/HuoshanDay1.asset b/Assets/ScriptableObjects/SceneSO/HuoshanDay1.asset deleted file mode 100644 index 18ee3944c..000000000 --- a/Assets/ScriptableObjects/SceneSO/HuoshanDay1.asset +++ /dev/null @@ -1,19 +0,0 @@ -%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: 157431981b8a721458e6706c374a3867, type: 3} - m_Name: HuoshanDay1 - m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: 8d8b11f0c2fbc4d4cb8c2857d98383c9, type: 2} - yarnProject: {fileID: 7545569452688597077, guid: 5b30d815fe3ef1d4aa1af835b6801fd4, type: 3} - firstSceneName: Scene/HuoShanFixScene - isEndOfDay: 0 - nameToPlayer: "\u706B\u5C71\u521D\u8BCA" diff --git a/Assets/ScriptableObjects/SceneSO/StoneDay1.asset b/Assets/ScriptableObjects/SceneSO/StoneDay1.asset deleted file mode 100644 index ba00b0816..000000000 --- a/Assets/ScriptableObjects/SceneSO/StoneDay1.asset +++ /dev/null @@ -1,19 +0,0 @@ -%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: 157431981b8a721458e6706c374a3867, type: 3} - m_Name: StoneDay1 - m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: ada4bdc2db5594e4f860c90b3a4b9da8, type: 2} - yarnProject: {fileID: 7545569452688597077, guid: 9c6e0818864e6964d83f946e81e32916, type: 3} - firstSceneName: Scene/ExpressFixScene - isEndOfDay: 0 - nameToPlayer: "\u77F3\u5934\u521D\u8BCA" diff --git a/Assets/ScriptableObjects/SceneSO/Test.meta b/Assets/ScriptableObjects/SceneSO/Test.meta new file mode 100644 index 000000000..55f062237 --- /dev/null +++ b/Assets/ScriptableObjects/SceneSO/Test.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f47b16116007f004580e98b8f50d35ac +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ScriptableObjects/SceneSO/TestSO.asset b/Assets/ScriptableObjects/SceneSO/Test/TestSO.asset similarity index 71% rename from Assets/ScriptableObjects/SceneSO/TestSO.asset rename to Assets/ScriptableObjects/SceneSO/Test/TestSO.asset index a4734462b..bc634c7f4 100644 --- a/Assets/ScriptableObjects/SceneSO/TestSO.asset +++ b/Assets/ScriptableObjects/SceneSO/Test/TestSO.asset @@ -12,10 +12,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 157431981b8a721458e6706c374a3867, type: 3} m_Name: TestSO m_EditorClassIdentifier: - nextScene: {fileID: 11400000, guid: 10601ce26230723479d875a630f15732, type: 2} + nextScene: {fileID: 0} + exits: + - exitName: default + targetScene: {fileID: 11400000, guid: 10601ce26230723479d875a630f15732, type: 2} + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: b81ce7d02242fc74daf531067098286f, type: 3} firstSceneName: Scene/ExpressFixScene title: description: coverPic: {fileID: 0} chapter: + graphPosition: {x: 0, y: 640} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/TestSO.asset.meta b/Assets/ScriptableObjects/SceneSO/Test/TestSO.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/TestSO.asset.meta rename to Assets/ScriptableObjects/SceneSO/Test/TestSO.asset.meta diff --git a/Assets/ScriptableObjects/SceneSO/Test_Shitou.asset b/Assets/ScriptableObjects/SceneSO/Test/Test_Shitou.asset similarity index 85% rename from Assets/ScriptableObjects/SceneSO/Test_Shitou.asset rename to Assets/ScriptableObjects/SceneSO/Test/Test_Shitou.asset index 588b096e5..a5173d0fa 100644 --- a/Assets/ScriptableObjects/SceneSO/Test_Shitou.asset +++ b/Assets/ScriptableObjects/SceneSO/Test/Test_Shitou.asset @@ -13,9 +13,13 @@ MonoBehaviour: m_Name: Test_Shitou m_EditorClassIdentifier: nextScene: {fileID: 0} + exits: [] + displayOrder: 0 yarnProject: {fileID: 7545569452688597077, guid: a2b0fa96399ebca4c9c61e346f95b037, type: 3} firstSceneName: Scene/Scene/ExpressFixScene title: "\u77F3\u5934\u7684\u5FC3" description: coverPic: {fileID: 0} chapter: + graphPosition: {x: 0, y: 480} + nodeColor: {r: 0.85, g: 0.45, b: 0.45, a: 1} diff --git a/Assets/ScriptableObjects/SceneSO/Test_Shitou.asset.meta b/Assets/ScriptableObjects/SceneSO/Test/Test_Shitou.asset.meta similarity index 100% rename from Assets/ScriptableObjects/SceneSO/Test_Shitou.asset.meta rename to Assets/ScriptableObjects/SceneSO/Test/Test_Shitou.asset.meta diff --git a/Assets/Scripts/Dialog System/BaseYarnCommand.cs b/Assets/Scripts/Dialog System/BaseYarnCommand.cs index 66b8ebb29..efd9e26d8 100644 --- a/Assets/Scripts/Dialog System/BaseYarnCommand.cs +++ b/Assets/Scripts/Dialog System/BaseYarnCommand.cs @@ -12,11 +12,11 @@ namespace AibisDream #region 命令名 [YarnCommand("NextYarn")] - public static void NextYarn() + public static void NextYarn(string exitName = null) { EnumEventSystem.Global.Send(EventEnum.NextYarn); StorageSystem.Instance.ClearLocal(); - DialogController.Instance.StartCoroutine(GameManager.Instance.NextSceneSo()); + DialogController.Instance.StartCoroutine(GameManager.Instance.NextSceneSo(exitName)); } [YarnCommand("OpenEndMenu")] diff --git a/Assets/Scripts/Game Loop/ChapterController.cs b/Assets/Scripts/Game Loop/ChapterController.cs index a78b2d401..ce524be1a 100644 --- a/Assets/Scripts/Game Loop/ChapterController.cs +++ b/Assets/Scripts/Game Loop/ChapterController.cs @@ -24,9 +24,14 @@ namespace AibisDream cacheChapter = ParseChapterTitle(saveFilePath); } + // 优先从 GameManager 获取全量章节并按 displayOrder 排序 + var allChapters = GameManager.Instance?.GetAllSceneSos(); + var sourceList = allChapters != null + ? allChapters.OrderBy(so => so.displayOrder).ToList() + : ChapterData.chapterList; // 拼接章节列表 - var chapterList = ChapterData.chapterList + var chapterList = sourceList .Where(item => ChapterData.unlockedChapterList.Contains(item.name)) .Select(chapterSo => new ChapterVo { @@ -98,14 +103,22 @@ namespace AibisDream private void LoadChapterList() { - chapterList = new List(); - var curChapter = firstChapter; - - do + var all = GameManager.Instance?.GetAllSceneSos(); + if (all != null) { - chapterList.Add(curChapter); - curChapter = curChapter.nextScene; - } while (curChapter != null && !chapterList.Contains(curChapter)); + chapterList = all.OrderBy(so => so.displayOrder).ToList(); + } + else + { + chapterList = new List(); + var curChapter = firstChapter; + + do + { + chapterList.Add(curChapter); + curChapter = curChapter.GetNextScene(); + } while (curChapter != null && !chapterList.Contains(curChapter)); + } } private void LoadUnlockChapters() diff --git a/Assets/Scripts/Game Loop/GameManager.cs b/Assets/Scripts/Game Loop/GameManager.cs index 98dfcc640..7d9fb2c39 100644 --- a/Assets/Scripts/Game Loop/GameManager.cs +++ b/Assets/Scripts/Game Loop/GameManager.cs @@ -236,11 +236,12 @@ namespace AibisDream #endregion - public IEnumerator NextSceneSo() + public IEnumerator NextSceneSo(string exitName = null) { - if (_currentTalkSceneSo.Value && _currentTalkSceneSo.Value.nextScene) + var next = _currentTalkSceneSo.Value?.GetNextScene(exitName); + if (next != null) { - _currentTalkSceneSo.Value = _currentTalkSceneSo.Value.nextScene; + _currentTalkSceneSo.Value = next; ChapterController.Instance.UnlockChapter(_currentTalkSceneSo.Value); yield return UIManager.Instance.GetPanel().FadeInAsync(); yield return SceneLoader.Instance.LoadSceneAsync(_currentTalkSceneSo.Value.firstSceneName); @@ -248,11 +249,13 @@ namespace AibisDream } else { + Debug.Log($"没有下个场景了 (exitName: {exitName})"); yield return null; - Debug.Log("没有下个场景了"); } } + public TalkSceneSO[] GetAllSceneSos() => _totalSceneSos; + public void SetSceneSoByName(string soName) { _currentTalkSceneSo.Value = Array.Find(_totalSceneSos, so => so.name == soName); diff --git a/Assets/Scripts/Game Loop/TalkSceneSO.cs b/Assets/Scripts/Game Loop/TalkSceneSO.cs index 3899202f1..73d249e50 100644 --- a/Assets/Scripts/Game Loop/TalkSceneSO.cs +++ b/Assets/Scripts/Game Loop/TalkSceneSO.cs @@ -1,15 +1,29 @@ +using System; +using System.Collections.Generic; using UnityEngine; using Yarn.Unity; namespace AibisDream { + [Serializable] + public class SceneExit + { + [Tooltip("出口名称,用于Yarn命令指定跳转目标,如 good_end / bad_end / default")] + public string exitName; + + public TalkSceneSO targetScene; + } + /// /// 章节类型数据 /// [CreateAssetMenu(menuName = "Game Scene/TalkSceneSO")] public class TalkSceneSO : ScriptableObject - { - public TalkSceneSO nextScene; + { + private const string DEFAULT_EXIT_NAME = "default"; + + public List exits = new(); + public int displayOrder; public YarnProject yarnProject; @@ -23,6 +37,29 @@ namespace AibisDream public string chapter; #endregion + + #region 仅编辑器使用 + + [HideInInspector] public Vector2 graphPosition; + public Color nodeColor = new(0.85f, 0.45f, 0.45f); + + #endregion + + public TalkSceneSO GetNextScene(string exitName = null) + { + if (exits == null || exits.Count == 0) + return null; + + if (string.IsNullOrEmpty(exitName)) + exitName = DEFAULT_EXIT_NAME; + + foreach (var exit in exits) + { + if (exit.exitName == exitName) + return exit.targetScene; + } + + return null; + } } } - From 94d89330dc091ecb3e9320bb921e6540dedd7660 Mon Sep 17 00:00:00 2001 From: Ding Yuntian <1491671119@qq.com> Date: Sat, 25 Apr 2026 20:13:55 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat(chapter):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=AB=A0=E8=8A=82=E5=9B=BE=E5=8F=AF=E8=A7=86=E5=8C=96=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 基于 UIToolkit 实现 ChapterGraph 编辑器窗口,可视化查看 和编辑 TalkSceneSO 之间的多出口连接关系。 --- Assets/Editor/ChapterGraph.meta | 8 + .../ChapterGraph/ChapterGraphEditorWindow.cs | 267 ++++++++++ .../ChapterGraphEditorWindow.cs.meta | 11 + .../ChapterGraph/ChapterGraphInspector.cs | 70 +++ .../ChapterGraphInspector.cs.meta | 11 + .../Editor/ChapterGraph/ChapterGraphView.cs | 503 ++++++++++++++++++ .../ChapterGraph/ChapterGraphView.cs.meta | 11 + Assets/Editor/ChapterGraph/ChapterNode.cs | 282 ++++++++++ .../Editor/ChapterGraph/ChapterNode.cs.meta | 11 + .../Editor/ChapterGraph/TalkSceneSOEditor.cs | 32 ++ .../ChapterGraph/TalkSceneSOEditor.cs.meta | 11 + 11 files changed, 1217 insertions(+) create mode 100644 Assets/Editor/ChapterGraph.meta create mode 100644 Assets/Editor/ChapterGraph/ChapterGraphEditorWindow.cs create mode 100644 Assets/Editor/ChapterGraph/ChapterGraphEditorWindow.cs.meta create mode 100644 Assets/Editor/ChapterGraph/ChapterGraphInspector.cs create mode 100644 Assets/Editor/ChapterGraph/ChapterGraphInspector.cs.meta create mode 100644 Assets/Editor/ChapterGraph/ChapterGraphView.cs create mode 100644 Assets/Editor/ChapterGraph/ChapterGraphView.cs.meta create mode 100644 Assets/Editor/ChapterGraph/ChapterNode.cs create mode 100644 Assets/Editor/ChapterGraph/ChapterNode.cs.meta create mode 100644 Assets/Editor/ChapterGraph/TalkSceneSOEditor.cs create mode 100644 Assets/Editor/ChapterGraph/TalkSceneSOEditor.cs.meta diff --git a/Assets/Editor/ChapterGraph.meta b/Assets/Editor/ChapterGraph.meta new file mode 100644 index 000000000..bb3d1e74e --- /dev/null +++ b/Assets/Editor/ChapterGraph.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 09d2581fcb827614bba6bf5c3279358e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/ChapterGraph/ChapterGraphEditorWindow.cs b/Assets/Editor/ChapterGraph/ChapterGraphEditorWindow.cs new file mode 100644 index 000000000..c265e4f6c --- /dev/null +++ b/Assets/Editor/ChapterGraph/ChapterGraphEditorWindow.cs @@ -0,0 +1,267 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using AibisDream; +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine; +using UnityEngine.UIElements; + +namespace AibisDream.SystemEditor +{ + public class ChapterGraphEditorWindow : EditorWindow + { + private ChapterGraphView _graphView; + private ChapterGraphInspector _inspector; + private IMGUIContainer _inspectorContainer; + + private const string RootFolderPrefKey = "AibisDream.ChapterGraph.RootFolder"; + private const string CurrentFolderPrefKey = "AibisDream.ChapterGraph.CurrentFolder"; + private string _rootFolder; + private string _currentFolder; + private DropdownField _folderDropdown; + private readonly Dictionary _displayToPath = new(); + + [MenuItem("Window/Chapter Graph Editor")] + public static void ShowWindow() + { + var window = GetWindow("Chapter Graph Editor"); + window.minSize = new Vector2(800, 600); + } + + private void OnEnable() + { + if (_graphView == null) return; + _graphView.LoadGraph(_currentFolder); + } + + private void OnDisable() + { + if (_graphView != null) + { + _graphView.OnNodeDeleted -= OnNodeDeleted; + } + if (_inspector != null) + { + _inspector.OnColorChanged -= OnNodeColorChanged; + _inspector.Destroy(); + } + } + + private void CreateGUI() + { + // 根容器:纵向排列 + var root = rootVisualElement; + root.style.flexDirection = FlexDirection.Column; + + // 顶部工具栏 + var toolbar = new Toolbar(); + toolbar.Add(CreateToolbarButton("Save", OnSaveClicked)); + toolbar.Add(CreateToolbarButton("Auto Layout", OnAutoLayoutClicked)); + toolbar.Add(CreateToolbarButton("Validate", OnValidateClicked)); + + _rootFolder = EditorPrefs.GetString(RootFolderPrefKey, "Assets/ScriptableObjects/SceneSO"); + + _folderDropdown = new DropdownField("路径"); + _folderDropdown.style.width = 160; + _folderDropdown.style.marginLeft = 8; + _folderDropdown.style.marginRight = 4; + RefreshFolderChoices(); + _folderDropdown.RegisterValueChangedCallback(OnFolderChanged); + toolbar.Add(_folderDropdown); + + var setRootBtn = new Button(OnSetRootFolderClicked) { text = "..." }; + setRootBtn.style.width = 28; + toolbar.Add(setRootBtn); + + toolbar.Add(new ToolbarSpacer() { style = { flexGrow = 1 } }); + toolbar.Add(CreateToolbarButton("Create Chapter", OnCreateChapterClicked)); + root.Add(toolbar); + + // 主内容区:横向分栏 + var mainContainer = new VisualElement(); + mainContainer.style.flexGrow = 1; + mainContainer.style.flexDirection = FlexDirection.Row; + mainContainer.style.overflow = Overflow.Hidden; + + // 左侧 Inspector 面板 + var leftPanel = new VisualElement(); + leftPanel.style.width = 320; + leftPanel.style.minWidth = 200; + leftPanel.style.maxWidth = 500; + leftPanel.style.flexShrink = 0; + leftPanel.style.flexDirection = FlexDirection.Column; + leftPanel.style.borderRightWidth = 1; + leftPanel.style.borderRightColor = new StyleColor(new Color(0.15f, 0.15f, 0.15f)); + + // Inspector 标题 + var header = new Label("章节属性") + { + style = + { + unityFontStyleAndWeight = FontStyle.Bold, + fontSize = 14, + paddingTop = 8, + paddingBottom = 8, + paddingLeft = 12, + paddingRight = 12, + borderBottomWidth = 1, + borderBottomColor = new StyleColor(new Color(0.15f, 0.15f, 0.15f)) + } + }; + leftPanel.Add(header); + + // IMGUI Inspector + _inspector = new ChapterGraphInspector(); + _inspectorContainer = new IMGUIContainer(() => _inspector.OnGUI()); + _inspectorContainer.style.flexGrow = 1; + leftPanel.Add(_inspectorContainer); + + mainContainer.Add(leftPanel); + + // 拖拽条 + var resizer = new VisualElement(); + resizer.style.width = 5; + resizer.style.backgroundColor = new StyleColor(new Color(0.15f, 0.15f, 0.15f)); + mainContainer.Add(resizer); + + float startWidth = 0; + float startMouseX = 0; + resizer.RegisterCallback(evt => + { + startWidth = leftPanel.resolvedStyle.width; + startMouseX = evt.mousePosition.x; + resizer.CaptureMouse(); + evt.StopPropagation(); + }); + resizer.RegisterCallback(evt => + { + if (!resizer.HasMouseCapture()) return; + var delta = evt.mousePosition.x - startMouseX; + var newWidth = Mathf.Clamp(startWidth + delta, 200, 600); + leftPanel.style.width = newWidth; + }); + resizer.RegisterCallback(evt => + { + if (resizer.HasMouseCapture()) + resizer.ReleaseMouse(); + }); + + // 右侧 GraphView + _graphView = new ChapterGraphView(); + _graphView.style.flexGrow = 1; + mainContainer.Add(_graphView); + + root.Add(mainContainer); + + // 加载图数据 + _graphView.LoadGraph(_currentFolder); + + // 选中节点同步到 Inspector + _graphView.OnNodeSelected += OnNodeSelected; + _graphView.OnNodeDeleted += OnNodeDeleted; + _inspector.OnColorChanged += OnNodeColorChanged; + } + + private void OnNodeDeleted(TalkSceneSO so) + { + _inspector?.SetTarget(null); + _inspectorContainer?.MarkDirtyRepaint(); + } + + private void OnNodeColorChanged(TalkSceneSO so) + { + _graphView?.UpdateNodeColor(so); + } + + private Button CreateToolbarButton(string text, System.Action onClick) + { + var btn = new Button(onClick) { text = text }; + return btn; + } + + private void OnSaveClicked() + { + AssetDatabase.SaveAssets(); + EditorUtility.DisplayDialog("保存", "所有资源已保存。", "确定"); + } + + private void OnAutoLayoutClicked() + { + _graphView?.AutoLayout(); + } + + private void OnValidateClicked() + { + _graphView?.ValidateGraph(); + } + + private void OnCreateChapterClicked() + { + var center = new Vector2(position.width / 2f, position.height / 2f); + var localPos = _graphView.contentViewContainer.WorldToLocal(center); + var defaultFolder = _currentFolder ?? EditorPrefs.GetString(ChapterGraphView.DefaultFolderPrefKey, _rootFolder); + _graphView?.CreateChapterNodeAt(localPos, defaultFolder); + } + + private void OnNodeSelected(TalkSceneSO so) + { + _inspector?.SetTarget(so); + _inspectorContainer?.MarkDirtyRepaint(); + } + + private void RefreshFolderChoices() + { + _displayToPath.Clear(); + _displayToPath["All"] = null; + + var subFolders = AssetDatabase.GetSubFolders(_rootFolder); + foreach (var folder in subFolders) + { + var name = Path.GetFileName(folder); + _displayToPath[name] = folder; + } + + var rootHasSO = AssetDatabase.FindAssets("t:TalkSceneSO", new[] { _rootFolder }) + .Select(g => AssetDatabase.GUIDToAssetPath(g)) + .Any(path => Path.GetDirectoryName(path)?.Replace('\\', '/') == _rootFolder); + + if (rootHasSO) + { + _displayToPath["(Root)"] = _rootFolder; + } + + _folderDropdown.choices = _displayToPath.Keys.ToList(); + + var saved = EditorPrefs.GetString(CurrentFolderPrefKey, "All"); + _folderDropdown.value = _displayToPath.ContainsKey(saved) ? saved : "All"; + _currentFolder = _displayToPath.TryGetValue(_folderDropdown.value, out var path) ? path : null; + } + + private void OnFolderChanged(ChangeEvent evt) + { + _currentFolder = _displayToPath.TryGetValue(evt.newValue, out var path) ? path : null; + EditorPrefs.SetString(CurrentFolderPrefKey, evt.newValue); + _graphView?.LoadGraph(_currentFolder); + } + + private void OnSetRootFolderClicked() + { + var path = EditorUtility.OpenFolderPanel("选择章节根目录", _rootFolder, ""); + if (string.IsNullOrEmpty(path)) return; + + var absoluteRoot = Application.dataPath.Replace('\\', '/'); + var selected = path.Replace('\\', '/'); + if (!selected.StartsWith(absoluteRoot)) + { + EditorUtility.DisplayDialog("错误", "请选择项目 Assets 目录内的文件夹。", "确定"); + return; + } + + _rootFolder = "Assets" + selected.Substring(absoluteRoot.Length); + EditorPrefs.SetString(RootFolderPrefKey, _rootFolder); + RefreshFolderChoices(); + _graphView?.LoadGraph(_currentFolder); + } + } +} diff --git a/Assets/Editor/ChapterGraph/ChapterGraphEditorWindow.cs.meta b/Assets/Editor/ChapterGraph/ChapterGraphEditorWindow.cs.meta new file mode 100644 index 000000000..a13fed005 --- /dev/null +++ b/Assets/Editor/ChapterGraph/ChapterGraphEditorWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c30bb2152169f544cb672c29ac8cb5d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/ChapterGraph/ChapterGraphInspector.cs b/Assets/Editor/ChapterGraph/ChapterGraphInspector.cs new file mode 100644 index 000000000..1f609b90f --- /dev/null +++ b/Assets/Editor/ChapterGraph/ChapterGraphInspector.cs @@ -0,0 +1,70 @@ +using AibisDream; +using UnityEditor; +using UnityEngine; + +namespace AibisDream.SystemEditor +{ + public class ChapterGraphInspector + { + private Editor _editor; + private TalkSceneSO _target; + private Vector2 _scrollPosition; + + public event System.Action OnColorChanged; + + public void SetTarget(TalkSceneSO so) + { + // 不能用 ==,Unity 重载了 ==,已销毁的对象 == null 为 true + if (ReferenceEquals(_target, so)) return; + + _target = so; + if (_editor != null) + { + Object.DestroyImmediate(_editor); + _editor = null; + } + + if (so != null) + { + _editor = Editor.CreateEditor(so); + } + } + + public void OnGUI() + { + if (_editor == null) + { + EditorGUILayout.HelpBox("请在图中选中一个章节节点以编辑属性", MessageType.Info); + return; + } + + _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition); + + EditorGUI.BeginChangeCheck(); + var newColor = EditorGUILayout.ColorField("节点颜色", _target.nodeColor); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(_target, "Change Node Color"); + _target.nodeColor = newColor; + EditorUtility.SetDirty(_target); + OnColorChanged?.Invoke(_target); + } + + EditorGUILayout.Space(6); + + _editor.OnInspectorGUI(); + EditorGUILayout.EndScrollView(); + } + + public void Destroy() + { + if (_editor != null) + { + Object.DestroyImmediate(_editor); + _editor = null; + } + + _target = null; + } + } +} diff --git a/Assets/Editor/ChapterGraph/ChapterGraphInspector.cs.meta b/Assets/Editor/ChapterGraph/ChapterGraphInspector.cs.meta new file mode 100644 index 000000000..0e5592c47 --- /dev/null +++ b/Assets/Editor/ChapterGraph/ChapterGraphInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9b122b6f926732f46b067d9b26eb191b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/ChapterGraph/ChapterGraphView.cs b/Assets/Editor/ChapterGraph/ChapterGraphView.cs new file mode 100644 index 000000000..ea2297b9e --- /dev/null +++ b/Assets/Editor/ChapterGraph/ChapterGraphView.cs @@ -0,0 +1,503 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using AibisDream; +using UnityEditor; +using UnityEditor.Experimental.GraphView; +using UnityEngine; +using UnityEngine.UIElements; + +namespace AibisDream.SystemEditor +{ + public class ChapterGraphView : GraphView + { + public event Action OnNodeSelected; + public event Action OnNodeDeleted; + + private const float HorizontalSpacing = 420f; + private const float VerticalSpacing = 220f; + public const string DefaultFolderPrefKey = "AibisDream.ChapterGraph.DefaultFolder"; + public const string DefaultFolder = "Assets/ScriptableObjects/SceneSO"; + + public ChapterGraphView() + { + style.flexGrow = 1; + + SetupZoom(ContentZoomer.DefaultMinScale, ContentZoomer.DefaultMaxScale); + this.AddManipulator(new ContentDragger()); + this.AddManipulator(new SelectionDragger()); + this.AddManipulator(new RectangleSelector()); + + var grid = new GridBackground(); + Insert(0, grid); + grid.StretchToParentSize(); + + graphViewChanged += OnGraphViewChanged; + } + + public void UpdateNodeColor(TalkSceneSO so) + { + foreach (var node in graphElements.OfType()) + { + if (node.SceneSo == so) + { + node.UpdateColor(); + break; + } + } + } + + public void LoadGraph(string folderPath = null) + { + ClearGraph(); + + var guids = AssetDatabase.FindAssets("t:TalkSceneSO", folderPath != null ? new[] { folderPath } : null); + var allSos = guids.Select(g => AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(g))).Where(so => so != null).ToList(); + var nodeMap = new Dictionary(); + + // 创建节点 + foreach (var so in allSos) + { + var node = new ChapterNode(so); + AddElement(node); + nodeMap[so] = node; + } + + // 创建连线 + foreach (var so in allSos) + { + if (so.exits == null) continue; + if (!nodeMap.TryGetValue(so, out var sourceNode)) continue; + + for (int i = 0; i < so.exits.Count; i++) + { + var exit = so.exits[i]; + if (exit == null || exit.targetScene == null) continue; + if (!nodeMap.TryGetValue(exit.targetScene, out var targetNode)) continue; + + var outputPort = sourceNode.GetOutputPort(i); + var inputPort = targetNode.InputPort; + if (outputPort == null || inputPort == null) continue; + + var edge = new Edge + { + output = outputPort, + input = inputPort + }; + edge.output.Connect(edge); + edge.input.Connect(edge); + AddElement(edge); + } + } + } + + public void ClearGraph() + { + // 清除所有元素 + var elementsToRemove = graphElements.ToList(); + foreach (var element in elementsToRemove) + { + RemoveElement(element); + } + } + + public override void BuildContextualMenu(ContextualMenuPopulateEvent evt) + { + base.BuildContextualMenu(evt); + + if (evt.target is GraphView) + { + var mousePosition = contentViewContainer.WorldToLocal(evt.mousePosition); + evt.menu.AppendAction("添加章节节点", (_) => CreateChapterNodeAt(mousePosition)); + } + } + + public override List GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter) + { + var compatiblePorts = new List(); + var startNode = startPort.node as ChapterNode; + if (startNode == null) return compatiblePorts; + + ports.ForEach(port => + { + var targetNode = port.node as ChapterNode; + if (targetNode == null) return; + if (targetNode == startNode) return; + if (startPort.direction == port.direction) return; + if (startPort.node == port.node) return; + + compatiblePorts.Add(port); + }); + + return compatiblePorts; + } + + private GraphViewChange OnGraphViewChanged(GraphViewChange change) + { + // 先处理节点删除确认:用户取消则从移除列表中剔除 + if (change.elementsToRemove != null) + { + var nodesToRemove = change.elementsToRemove.OfType().ToList(); + foreach (var node in nodesToRemove) + { + if (!ConfirmRemoveNode(node)) + { + change.elementsToRemove.Remove(node); + // 同时保留与该节点相连的边,避免边被单独删掉 + var edgesToKeep = change.elementsToRemove.OfType() + .Where(e => e.output?.node == node || e.input?.node == node) + .ToList(); + foreach (var edge in edgesToKeep) + { + change.elementsToRemove.Remove(edge); + } + } + } + } + + // 处理 Edge 删除 + if (change.elementsToRemove != null) + { + foreach (var edge in change.elementsToRemove.OfType()) + { + HandleEdgeRemoved(edge); + } + + foreach (var node in change.elementsToRemove.OfType()) + { + HandleNodeRemoved(node); + } + } + + // 处理 Edge 创建 + if (change.edgesToCreate != null) + { + foreach (var edge in change.edgesToCreate) + { + HandleEdgeCreated(edge); + } + } + + // 处理节点移动 + if (change.movedElements != null) + { + foreach (var element in change.movedElements) + { + if (element is ChapterNode node) + { + node.SyncPositionToSo(); + } + } + } + + return change; + } + + private void HandleEdgeCreated(Edge edge) + { + if (!(edge.output?.node is ChapterNode sourceNode)) return; + if (!(edge.input?.node is ChapterNode targetNode)) return; + + var sourceSo = sourceNode.SceneSo; + var targetSo = targetNode.SceneSo; + if (sourceSo == null || targetSo == null) return; + + int exitIndex = edge.output.userData is int idx ? idx : -1; + if (exitIndex < 0 || exitIndex >= sourceSo.exits.Count) return; + + Undo.RecordObject(sourceSo, "Connect Chapter"); + sourceSo.exits[exitIndex].targetScene = targetSo; + EditorUtility.SetDirty(sourceSo); + } + + private void HandleEdgeRemoved(Edge edge) + { + if (!(edge.output?.node is ChapterNode sourceNode)) return; + + var sourceSo = sourceNode.SceneSo; + if (sourceSo == null) return; + + int exitIndex = edge.output.userData is int idx ? idx : -1; + if (exitIndex < 0 || exitIndex >= sourceSo.exits.Count) return; + + Undo.RecordObject(sourceSo, "Disconnect Chapter"); + sourceSo.exits[exitIndex].targetScene = null; + EditorUtility.SetDirty(sourceSo); + } + + private bool ConfirmRemoveNode(ChapterNode node) + { + var so = node.SceneSo; + if (so == null) return true; + + var referrers = new List(); + foreach (var other in graphElements.OfType()) + { + if (other == node) continue; + if (other.SceneSo == null || other.SceneSo.exits == null) continue; + foreach (var exit in other.SceneSo.exits) + { + if (exit.targetScene == so) + { + referrers.Add(string.IsNullOrEmpty(other.SceneSo.title) ? other.SceneSo.name : other.SceneSo.title); + break; + } + } + } + + var name = string.IsNullOrEmpty(so.title) ? so.name : so.title; + var msg = $"确定要删除章节节点 \"{name}\" 吗?"; + if (referrers.Count > 0) + { + msg += $"\n\n以下节点仍引用该节点:\n• {string.Join("\n• ", referrers)}"; + } + + return EditorUtility.DisplayDialog("删除确认", msg, "删除", "取消"); + } + + private void HandleNodeRemoved(ChapterNode node) + { + var so = node.SceneSo; + if (so == null) return; + + var path = AssetDatabase.GetAssetPath(so); + if (!string.IsNullOrEmpty(path)) + { + AssetDatabase.DeleteAsset(path); + } + + OnNodeDeleted?.Invoke(so); + } + + public override void AddToSelection(ISelectable selectable) + { + base.AddToSelection(selectable); + NotifySelectionChanged(); + } + + public override void RemoveFromSelection(ISelectable selectable) + { + base.RemoveFromSelection(selectable); + NotifySelectionChanged(); + } + + public override void ClearSelection() + { + base.ClearSelection(); + NotifySelectionChanged(); + } + + private void NotifySelectionChanged() + { + var selectedNode = selection.OfType().FirstOrDefault(); + OnNodeSelected?.Invoke(selectedNode?.SceneSo); + } + + public void CreateChapterNodeAt(Vector2 position, string defaultFolder = null) + { + var folder = defaultFolder ?? EditorPrefs.GetString(DefaultFolderPrefKey, DefaultFolder); + var path = EditorUtility.SaveFilePanelInProject("新建章节", "NewChapter", "asset", "选择新章节的保存位置", folder); + if (string.IsNullOrEmpty(path)) return; + + var so = ScriptableObject.CreateInstance(); + so.name = System.IO.Path.GetFileNameWithoutExtension(path); + so.title = "新章节"; + so.nodeColor = new Color(0.85f, 0.45f, 0.45f); + so.graphPosition = position; + so.exits = new System.Collections.Generic.List(); + + AssetDatabase.CreateAsset(so, path); + EditorUtility.SetDirty(so); + AssetDatabase.SaveAssets(); + + // 记住文件夹 + var savedFolder = System.IO.Path.GetDirectoryName(path)?.Replace('\\', '/'); + if (!string.IsNullOrEmpty(savedFolder)) + { + EditorPrefs.SetString(DefaultFolderPrefKey, savedFolder); + } + + var node = new ChapterNode(so); + AddElement(node); + } + + public void AutoLayout() + { + var nodes = graphElements.OfType().ToList(); + if (nodes.Count == 0) return; + + // 计算入度 + var inDegree = nodes.ToDictionary(n => n, _ => 0); + var edges = graphElements.OfType().ToList(); + foreach (var edge in edges) + { + if (edge.input?.node is ChapterNode target && inDegree.ContainsKey(target)) + { + inDegree[target]++; + } + } + + // 分层 BFS + var layer = new Dictionary(); + var queue = new Queue(); + + // 入度为 0 的节点作为起点 + foreach (var node in nodes) + { + if (inDegree[node] == 0) + { + layer[node] = 0; + queue.Enqueue(node); + } + } + + // 如果没有入度为 0 的节点(纯循环),任选一个作为起点 + if (queue.Count == 0) + { + layer[nodes[0]] = 0; + queue.Enqueue(nodes[0]); + } + + while (queue.Count > 0) + { + var current = queue.Dequeue(); + var currentLayer = layer[current]; + + foreach (var edge in edges) + { + if (edge.output?.node == current && edge.input?.node is ChapterNode next) + { + if (!layer.ContainsKey(next)) + { + layer[next] = currentLayer + 1; + queue.Enqueue(next); + } + else + { + layer[next] = Math.Max(layer[next], currentLayer + 1); + } + } + } + } + + // 为未分配层级的节点(孤立或不连通部分)分配层级 + foreach (var node in nodes) + { + if (!layer.ContainsKey(node)) + { + layer[node] = 0; + } + } + + // 按层级分组并计算位置 + var groups = layer.GroupBy(kvp => kvp.Value).OrderBy(g => g.Key).ToList(); + Undo.RecordObjects(nodes.Select(n => n.SceneSo).ToArray(), "Auto Layout"); + + for (int i = 0; i < groups.Count; i++) + { + var group = groups[i]; + var groupNodes = group.ToList(); + float x = group.Key * HorizontalSpacing; + float startY = -(groupNodes.Count - 1) * VerticalSpacing / 2f; + + for (int j = 0; j < groupNodes.Count; j++) + { + var node = groupNodes[j].Key; + var y = startY + j * VerticalSpacing; + var newPos = new Vector2(x, y); + node.SetPosition(new Rect(newPos, Vector2.zero)); + node.SceneSo.graphPosition = newPos; + EditorUtility.SetDirty(node.SceneSo); + } + } + } + + public void ValidateGraph() + { + var nodes = graphElements.OfType().ToList(); + var issues = new List(); + var soSet = new HashSet(nodes.Select(n => n.SceneSo)); + + // 孤立节点 + foreach (var node in nodes) + { + var so = node.SceneSo; + bool hasIncoming = graphElements.OfType().Any(e => e.input?.node == node); + bool hasOutgoing = so.exits != null && so.exits.Any(e => e.targetScene != null); + + if (!hasIncoming && !hasOutgoing) + { + issues.Add($"孤立节点: {so.name} (没有入边也没有出边)"); + } + } + + // 循环引用 (DFS) + var visited = new HashSet(); + var visiting = new HashSet(); + + foreach (var so in soSet) + { + if (!visited.Contains(so)) + { + CheckCycle(so, visited, visiting, soSet, issues); + } + } + + // 空 exitName + foreach (var node in nodes) + { + var so = node.SceneSo; + if (so.exits == null) continue; + for (int i = 0; i < so.exits.Count; i++) + { + if (string.IsNullOrEmpty(so.exits[i].exitName)) + { + issues.Add($"空 exitName: {so.name} 的第 {i + 1} 个出口"); + } + } + } + + if (issues.Count == 0) + { + EditorUtility.DisplayDialog("验证结果", "图表验证通过,未发现问题。", "确定"); + } + else + { + var msg = string.Join("\n", issues.Take(20)); + if (issues.Count > 20) + { + msg += $"\n... 还有 {issues.Count - 20} 个问题"; + } + EditorUtility.DisplayDialog($"验证发现 {issues.Count} 个问题", msg, "确定"); + } + } + + private void CheckCycle(TalkSceneSO current, HashSet visited, HashSet visiting, HashSet soSet, List issues) + { + visited.Add(current); + visiting.Add(current); + + if (current.exits != null) + { + foreach (var exit in current.exits) + { + var next = exit.targetScene; + if (next == null || !soSet.Contains(next)) continue; + + if (visiting.Contains(next)) + { + issues.Add($"循环引用: {current.name} -> {next.name}"); + continue; + } + + if (!visited.Contains(next)) + { + CheckCycle(next, visited, visiting, soSet, issues); + } + } + } + + visiting.Remove(current); + } + } +} diff --git a/Assets/Editor/ChapterGraph/ChapterGraphView.cs.meta b/Assets/Editor/ChapterGraph/ChapterGraphView.cs.meta new file mode 100644 index 000000000..eeb632c81 --- /dev/null +++ b/Assets/Editor/ChapterGraph/ChapterGraphView.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 913b090485a3d844fab3e436e7bf4f57 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/ChapterGraph/ChapterNode.cs b/Assets/Editor/ChapterGraph/ChapterNode.cs new file mode 100644 index 000000000..cfe5a5d49 --- /dev/null +++ b/Assets/Editor/ChapterGraph/ChapterNode.cs @@ -0,0 +1,282 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using AibisDream; +using UnityEditor; +using UnityEditor.Experimental.GraphView; +using UnityEngine; +using UnityEngine.UIElements; + +namespace AibisDream.SystemEditor +{ + public class ChapterNode : Node + { + public TalkSceneSO SceneSo { get; } + public Port InputPort { get; private set; } + + private const float PortLabelMaxWidth = 120f; + + public ChapterNode(TalkSceneSO so) + { + SceneSo = so ?? throw new ArgumentNullException(nameof(so)); + + // 节点整体放大 + style.minWidth = 240; + style.paddingTop = 8; + style.paddingBottom = 8; + style.paddingLeft = 10; + style.paddingRight = 10; + + UpdateTitle(); + UpdateColor(); + BuildInputPort(); + BuildOutputPorts(); + BuildSubtitle(); + BuildAddExitButton(); + SetPosition(new Rect(so.graphPosition, Vector2.zero)); + + // 放大标题 + var titleLabel = this.Q