From a835e8321b25b78009eb4be75629f7221b602251 Mon Sep 17 00:00:00 2001 From: TRADER_FOER Date: Fri, 10 Jul 2026 14:05:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9track=E5=A4=8D=E5=88=B6?= =?UTF-8?q?=E6=AD=A5=E8=BF=9B=E5=92=8C=E6=92=A4=E9=94=80=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: TRADER_FOER --- Assets/FR2_Cache.asset | 386 +++++----- .../Scripts/CommandSystem/CommandManager.cs | 14 +- .../GameElementStructuralCommands.cs | 245 +++++++ .../GameElementStructuralCommands.cs.meta | 2 + .../DynamicUI/Core/InspectorBuilder.cs | 29 +- .../Scripts/DynamicUI/Hierarchy/Hierarchy.cs | 6 +- .../DynamicUI/MainUI/ToolBar/ToolBar.cs | 38 +- .../DisplacementTracker_Editor.cs | 5 +- .../EditorAnimations/ScaleTracker_Editor.cs | 5 +- .../EditorAnimations/SwirlTracker_Editor.cs | 5 +- .../Transform/Displacement_Editor.cs | 5 +- .../Transform/Scale_Editor.cs | 5 +- .../Transform/Swirl_Editor.cs | 5 +- .../EnvironmentObject_Editor.cs | 25 +- .../Essential/ElementFolder_Editor.cs | 27 +- .../Essential/GameCamera_Editor.cs | 9 +- .../Essential/TemporaryObject_Editor.cs | 2 +- .../GlobalElements/BackgroundSetter_Editor.cs | 5 +- .../Notes/NoteObjects/NoteBase_Editor.cs | 3 +- .../Track/PathNode_Editor.cs | 5 +- .../TrackPoints/CrossTrackPoint_Editor.cs | 17 +- .../TrackPoints/TrackHeadPoint_Editor.cs | 13 +- .../TrackPoints/TrackPercentPoint_Editor.cs | 13 +- .../TrackPathSubmodule_Editor.cs | 3 +- .../Track/TrackTools_Editor.cs | 16 +- .../GameElements_Editor/Track/Track_Editor.cs | 85 ++- Assets/Scripts/Manager/OperationManager.cs | 106 ++- Assets/Scripts/Manager/ProjectManager.cs | 90 ++- Assets/StreamingAssets/Clips/p5.json | 692 ++++++++++++++++++ Assets/StreamingAssets/Clips/p5.json.meta | 7 + 30 files changed, 1501 insertions(+), 367 deletions(-) create mode 100644 Assets/Scripts/CommandSystem/GameElementStructuralCommands.cs create mode 100644 Assets/Scripts/CommandSystem/GameElementStructuralCommands.cs.meta create mode 100644 Assets/StreamingAssets/Clips/p5.json create mode 100644 Assets/StreamingAssets/Clips/p5.json.meta diff --git a/Assets/FR2_Cache.asset b/Assets/FR2_Cache.asset index dbd1e29b..c8473768 100644 --- a/Assets/FR2_Cache.asset +++ b/Assets/FR2_Cache.asset @@ -49,10 +49,10 @@ MonoBehaviour: m_addressable: m_atlas: m_fileSize: 28008 - m_assetChangeTS: 1783188822 - m_fileInfoReadTS: 1783188909 - m_fileWriteTS: 1783188822 - m_cachefileWriteTS: 1783188822 + m_assetChangeTS: 1783610837 + m_fileInfoReadTS: 1783610909 + m_fileWriteTS: 1783610837 + m_cachefileWriteTS: 1783610837 refreshStamp: 2 UseGUIDsList: - guid: cd62869af1bc6534d83427c72b66bb9f @@ -193,10 +193,10 @@ MonoBehaviour: m_addressable: m_atlas: m_fileSize: 2641 - m_assetChangeTS: 1783188822 - m_fileInfoReadTS: 1783188909 - m_fileWriteTS: 1783188822 - m_cachefileWriteTS: 1783188822 + m_assetChangeTS: 1783610837 + m_fileInfoReadTS: 1783610909 + m_fileWriteTS: 1783610837 + m_cachefileWriteTS: 1783610837 refreshStamp: 2 UseGUIDsList: - guid: 0000000000000000f000000000000000 @@ -5699,15 +5699,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 5037ef52545d81a4db6b8f6787fb1d06 type: 2 - m_fileInfoHash: 1557.cs + m_fileInfoHash: 1622.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 1557 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088720 - m_fileWriteTS: 1780686680 - m_cachefileWriteTS: 1780686680 + m_fileSize: 1622 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: 5057a30c9a654e0bb16bd234bf770359 @@ -13299,10 +13299,10 @@ MonoBehaviour: m_addressable: m_atlas: m_fileSize: 4590 - m_assetChangeTS: 1783609901 - m_fileInfoReadTS: 1783609902 - m_fileWriteTS: 1783609901 - m_cachefileWriteTS: 1783609901 + m_assetChangeTS: 1783610836 + m_fileInfoReadTS: 1783610909 + m_fileWriteTS: 1783610836 + m_cachefileWriteTS: 1783610836 refreshStamp: 2 UseGUIDsList: - guid: bf2edee5c58d82540a51f03df9d42094 @@ -28229,15 +28229,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 914dd73ddae7943148ea71537167542b type: 2 - m_fileInfoHash: 15588.cs + m_fileInfoHash: 15838.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 15588 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088713 - m_fileWriteTS: 1781390586 - m_cachefileWriteTS: 1781390586 + m_fileSize: 15838 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783655016 + m_cachefileWriteTS: 1783655016 refreshStamp: 2 UseGUIDsList: [] - guid: 919d97c1a707113409177d498d31cf51 @@ -32588,10 +32588,10 @@ MonoBehaviour: m_addressable: m_atlas: m_fileSize: 4587 - m_assetChangeTS: 1783397504 - m_fileInfoReadTS: 1783397511 - m_fileWriteTS: 1783397504 - m_cachefileWriteTS: 1783397504 + m_assetChangeTS: 1783610836 + m_fileInfoReadTS: 1783610909 + m_fileWriteTS: 1783610836 + m_cachefileWriteTS: 1783610836 refreshStamp: 2 UseGUIDsList: - guid: bf2edee5c58d82540a51f03df9d42094 @@ -50724,15 +50724,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 13a766a7f5125104cbf4967ec56b300e type: 2 - m_fileInfoHash: 3754.cs + m_fileInfoHash: 3999.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 3754 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088707 - m_fileWriteTS: 1780689737 - m_cachefileWriteTS: 1780689737 + m_fileSize: 3999 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: 13b75c95f34a00d4e8c04f76b73312e6 @@ -54927,15 +54927,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 53e4a3f4417b16c4a8371fed037c2962 type: 2 - m_fileInfoHash: 1871.cs + m_fileInfoHash: 1936.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 1871 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088705 - m_fileWriteTS: 1780689513 - m_cachefileWriteTS: 1780689513 + m_fileSize: 1936 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: 5315c047999aa4d869298f6988dfeb30 @@ -66633,15 +66633,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 14f2bbe520e9b084dbbcd01854f179ea type: 2 - m_fileInfoHash: 1890.cs + m_fileInfoHash: 1893.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 1890 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088699 - m_fileWriteTS: 1780689896 - m_cachefileWriteTS: 1780689896 + m_fileSize: 1893 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: 14f21d7a1e53a8c4e87b25526a7eb63c @@ -67362,15 +67362,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 14aeb2826cddec04094e132d9ad2d320 type: 2 - m_fileInfoHash: 2664.cs + m_fileInfoHash: 2657.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 2664 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088699 - m_fileWriteTS: 1780682031 - m_cachefileWriteTS: 1780682031 + m_fileSize: 2657 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: 14dea3cd6f9354539a93235fc98c74bb @@ -70879,15 +70879,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 54748045ed19d4ea6889de9b617f6f8b type: 2 - m_fileInfoHash: 8287.cs + m_fileInfoHash: 8376.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 8287 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088697 - m_fileWriteTS: 1779543480 - m_cachefileWriteTS: 1779543480 + m_fileSize: 8376 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: 5474f72bf7b54b743bbc3868e205ef2d @@ -75824,15 +75824,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: a464b4e255d397d4180d3bacf74dcc5c type: 2 - m_fileInfoHash: 6872.cs + m_fileInfoHash: 7412.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 6872 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088696 - m_fileWriteTS: 1772539206 - m_cachefileWriteTS: 1772539206 + m_fileSize: 7412 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: a48458ea708872f44bf79d4c9e33ff07 @@ -80879,15 +80879,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: f497f16c91f01db48ab2e21dc67a0f3b type: 2 - m_fileInfoHash: 52154.cs + m_fileInfoHash: 52435.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 52154 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088695 - m_fileWriteTS: 1780690576 - m_cachefileWriteTS: 1780690576 + m_fileSize: 52435 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: f4c78ca7f2e9828499e1861881e6e143 @@ -100893,15 +100893,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 166bf8a5ee9f19e4d9ddecfab43469ce type: 2 - m_fileInfoHash: 15285.cs + m_fileInfoHash: 16916.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 15285 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088690 - m_fileWriteTS: 1780689815 - m_cachefileWriteTS: 1780689815 + m_fileSize: 16916 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: 168b55aaa8b259147b4b5ce9d360e311 @@ -101718,15 +101718,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 26ca158aed8cec04d8455a7119eae07b type: 2 - m_fileInfoHash: 4535.cs + m_fileInfoHash: 4600.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 4535 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088689 - m_fileWriteTS: 1780689689 - m_cachefileWriteTS: 1780689689 + m_fileSize: 4600 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: 260b531edc40677429c0198d6961e448 @@ -101882,15 +101882,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 26ed323898e48044589649bfb4c62083 type: 2 - m_fileInfoHash: 1685.cs + m_fileInfoHash: 1985.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 1685 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088689 - m_fileWriteTS: 1774190667 - m_cachefileWriteTS: 1774190667 + m_fileSize: 1985 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662487 + m_cachefileWriteTS: 1783662487 refreshStamp: 2 UseGUIDsList: [] - guid: 260e630c5c1b1af42991291f6de23ede @@ -110161,15 +110161,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: b616c828cf8808147907365ad776142d type: 2 - m_fileInfoHash: 1871.cs + m_fileInfoHash: 1936.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 1871 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088687 - m_fileWriteTS: 1780689509 - m_cachefileWriteTS: 1780689509 + m_fileSize: 1936 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: b63607ddb964c4897880a99d41c70efd @@ -123123,15 +123123,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 773c77098921d4c1a87dc6068b5253e8 type: 2 - m_fileInfoHash: 8041.cs + m_fileInfoHash: 9599.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 8041 - m_assetChangeTS: 1783609273 - m_fileInfoReadTS: 1783609282 - m_fileWriteTS: 1783609146 - m_cachefileWriteTS: 1783609146 + m_fileSize: 9599 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662268 + m_cachefileWriteTS: 1783662268 refreshStamp: 2 UseGUIDsList: [] - guid: 774c00e683b6094459a1ed557b35694b @@ -133489,10 +133489,10 @@ MonoBehaviour: m_addressable: m_atlas: m_fileSize: 23881 - m_assetChangeTS: 1783188822 - m_fileInfoReadTS: 1783188909 - m_fileWriteTS: 1783188822 - m_cachefileWriteTS: 1783188822 + m_assetChangeTS: 1783610837 + m_fileInfoReadTS: 1783610909 + m_fileWriteTS: 1783610837 + m_cachefileWriteTS: 1783610837 refreshStamp: 2 UseGUIDsList: - guid: 2ec995e51a6e251468d2a3fd8a686257 @@ -139124,15 +139124,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 78139f91998ceef4dbcba970e25e9066 type: 2 - m_fileInfoHash: 4414.cs + m_fileInfoHash: 4587.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 4414 - m_assetChangeTS: 1783609273 - m_fileInfoReadTS: 1783609282 - m_fileWriteTS: 1783609115 - m_cachefileWriteTS: 1783609115 + m_fileSize: 4587 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662117 + m_cachefileWriteTS: 1783662117 refreshStamp: 2 UseGUIDsList: [] - guid: 7883cd788d83a71478342eef943e8150 @@ -142193,15 +142193,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: a8b322c654c10e14cb10f8a02c9411dc type: 2 - m_fileInfoHash: 2122.cs + m_fileInfoHash: 2259.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 2122 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088661 - m_fileWriteTS: 1780688070 - m_cachefileWriteTS: 1780688070 + m_fileSize: 2259 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: a834bac5135fab746bc234ec665972de @@ -143206,15 +143206,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: b8b3a4599898ef24aa9b77020f5f6a5a type: 2 - m_fileInfoHash: 2562.cs + m_fileInfoHash: 2627.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 2562 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088661 - m_fileWriteTS: 1780690469 - m_cachefileWriteTS: 1780690469 + m_fileSize: 2627 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: b8b3da1ab40a53c49a3de1e3fe357ad2 @@ -156106,15 +156106,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 8902bbaa297d89248bbb17ee0564edd0 type: 2 - m_fileInfoHash: 1491.cs + m_fileInfoHash: 1556.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 1491 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088657 - m_fileWriteTS: 1780686683 - m_cachefileWriteTS: 1780686683 + m_fileSize: 1556 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: 896223e567b01c747b4726ef429e31ea @@ -163167,15 +163167,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: e9538206e110cae4bb725767761790a9 type: 2 - m_fileInfoHash: 1518.cs + m_fileInfoHash: 1583.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 1518 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088654 - m_fileWriteTS: 1780686675 - m_cachefileWriteTS: 1780686675 + m_fileSize: 1583 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: e963dcd72924ca1448e01147b483fb05 @@ -180641,15 +180641,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: eaac9d0bf222646fc89d03493f9fca69 type: 2 - m_fileInfoHash: 22664.cs + m_fileInfoHash: 25140.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 22664 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088634 - m_fileWriteTS: 1782718823 - m_cachefileWriteTS: 1782718823 + m_fileSize: 25140 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783655016 + m_cachefileWriteTS: 1783655016 refreshStamp: 2 UseGUIDsList: [] - guid: eacc8c07331ade049a6102ca81caa612 @@ -189735,10 +189735,10 @@ MonoBehaviour: m_addressable: m_atlas: m_fileSize: 4597 - m_assetChangeTS: 1783397504 - m_fileInfoReadTS: 1783397511 - m_fileWriteTS: 1783397504 - m_cachefileWriteTS: 1783397504 + m_assetChangeTS: 1783610836 + m_fileInfoReadTS: 1783610909 + m_fileWriteTS: 1783610836 + m_cachefileWriteTS: 1783610836 refreshStamp: 2 UseGUIDsList: - guid: bf2edee5c58d82540a51f03df9d42094 @@ -207554,15 +207554,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 7c39beb8ca959c747820aa38886ed3a2 type: 2 - m_fileInfoHash: 1943.cs + m_fileInfoHash: 2008.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 1943 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088627 - m_fileWriteTS: 1780689505 - m_cachefileWriteTS: 1780689505 + m_fileSize: 2008 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: 7c499715fdb4d7c479dcd3fd13abe0d0 @@ -208563,15 +208563,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 8c3c6c8aa2d7f5d48aee5ced0ffe9bb8 type: 2 - m_fileInfoHash: 9537.cs + m_fileInfoHash: 9769.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 9537 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088627 - m_fileWriteTS: 1780689785 - m_cachefileWriteTS: 1780689785 + m_fileSize: 9769 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: 8c7c7e69d9574cd6994b42e64fb32db2 @@ -234740,15 +234740,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 2e498d1c8094910479dc3e1b768306a4 type: 5 - m_fileInfoHash: 604828.asset + m_fileInfoHash: 604949.asset m_assetbundle: m_addressable: m_atlas: - m_fileSize: 604828 - m_assetChangeTS: 1783609901 - m_fileInfoReadTS: 1783609902 - m_fileWriteTS: 1783609901 - m_cachefileWriteTS: 1783609901 + m_fileSize: 604949 + m_assetChangeTS: 1783654224 + m_fileInfoReadTS: 1783654225 + m_fileWriteTS: 1783654224 + m_cachefileWriteTS: 1783654224 refreshStamp: 2 UseGUIDsList: - guid: fe393ace9b354375a9cb14cdbbc28be4 @@ -248849,15 +248849,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: 1f2679cb25973a04299c960841e384a5 type: 2 - m_fileInfoHash: 3279.cs + m_fileInfoHash: 3259.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 3279 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088608 - m_fileWriteTS: 1780682017 - m_cachefileWriteTS: 1780682017 + m_fileSize: 3259 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: 1f262e722aecf4d02a1103c1e8a96c3f @@ -257740,15 +257740,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: aff80908d5bdc8e438b6d006be38d4b3 type: 2 - m_fileInfoHash: 1818.cs + m_fileInfoHash: 1919.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 1818 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088606 - m_fileWriteTS: 1780689763 - m_cachefileWriteTS: 1780689763 + m_fileSize: 1919 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: af19581c6078849139e0671f575e4b7c @@ -262813,15 +262813,15 @@ MonoBehaviour: UseGUIDsList: [] - guid: ff4f07b63a568fc4a86f757969b47fce type: 2 - m_fileInfoHash: 2057.cs + m_fileInfoHash: 2194.cs m_assetbundle: m_addressable: m_atlas: - m_fileSize: 2057 - m_assetChangeTS: 0 - m_fileInfoReadTS: 1783088605 - m_fileWriteTS: 1780688065 - m_cachefileWriteTS: 1780688065 + m_fileSize: 2194 + m_assetChangeTS: 1783662864 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662667 + m_cachefileWriteTS: 1783662667 refreshStamp: 2 UseGUIDsList: [] - guid: ff5f5220af00e574287547dab664b9ab @@ -263360,6 +263360,32 @@ MonoBehaviour: m_cachefileWriteTS: 1783563309 refreshStamp: 2 UseGUIDsList: [] + - guid: f743f8f91400ea04097346d48e479fd8 + type: 9 + m_fileInfoHash: 17887.json + m_assetbundle: + m_addressable: + m_atlas: + m_fileSize: 17887 + m_assetChangeTS: 0 + m_fileInfoReadTS: 1783662889 + m_fileWriteTS: 1783662864 + m_cachefileWriteTS: 1783662864 + refreshStamp: 2 + UseGUIDsList: [] + - guid: 96273157236b1a54fbf492d88d4c540f + type: 2 + m_fileInfoHash: 7703.cs + m_assetbundle: + m_addressable: + m_atlas: + m_fileSize: 7703 + m_assetChangeTS: 1783663381 + m_fileInfoReadTS: 1783663388 + m_fileWriteTS: 1783663346 + m_cachefileWriteTS: 1783663346 + refreshStamp: 2 + UseGUIDsList: [] setting: alternateColor: 1 excludeTypes: 0 diff --git a/Assets/Scripts/CommandSystem/CommandManager.cs b/Assets/Scripts/CommandSystem/CommandManager.cs index 0c2457f4..337c23d0 100644 --- a/Assets/Scripts/CommandSystem/CommandManager.cs +++ b/Assets/Scripts/CommandSystem/CommandManager.cs @@ -1,5 +1,6 @@ -using System.Collections; +using System; using System.Collections.Generic; +using Ichni.RhythmGame; using UnityEngine; namespace Ichni.Editor.Commands @@ -14,6 +15,8 @@ namespace Ichni.Editor.Commands /// public static void ExecuteCommand(ICommand command) { + if (command == null) return; + if (undoStack.Count > 0) { var topCommand = undoStack.Peek(); @@ -28,7 +31,14 @@ namespace Ichni.Editor.Commands // 新操作彻底切断原本可能存在的重做未来 command.Execute(); undoStack.Push(command); - redoStack.Clear(); + redoStack.Clear(); + } + + public static GameElement ExecuteCreate(Func createAction) + { + var command = new CreateElementCommand(createAction); + ExecuteCommand(command); + return command.CreatedElement; } public static void Undo() diff --git a/Assets/Scripts/CommandSystem/GameElementStructuralCommands.cs b/Assets/Scripts/CommandSystem/GameElementStructuralCommands.cs new file mode 100644 index 00000000..1e94a6c9 --- /dev/null +++ b/Assets/Scripts/CommandSystem/GameElementStructuralCommands.cs @@ -0,0 +1,245 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Ichni.RhythmGame; +using Ichni.RhythmGame.Beatmap; +using UnityEngine; + +namespace Ichni.Editor.Commands +{ + internal sealed class ElementTreeSnapshot + { + private readonly List elements = new List(); + private readonly Guid rootGuid; + private readonly Guid parentGuid; + private readonly int parentChildIndex; + + private ElementTreeSnapshot(GameElement root) + { + rootGuid = root.elementGuid; + parentGuid = root.parentElement?.elementGuid ?? Guid.Empty; + parentChildIndex = root.parentElement != null + ? root.parentElement.childElementList.IndexOf(root) + : -1; + + RegisterExistingAncestorChain(root.parentElement); + + foreach (GameElement element in root.GetAllGameElementsFromThis()) + { + if (element == null) continue; + element.SaveBM(); + if (element.matchedBM != null) + elements.Add(element.matchedBM); + + element.submoduleList.RemoveAll(submodule => submodule == null); + foreach (SubmoduleBase submodule in element.submoduleList) + { + submodule.SaveBM(); + if (submodule.matchedBM != null) + elements.Add(submodule.matchedBM); + } + } + } + + public static ElementTreeSnapshot Capture(GameElement root) + { + return root == null ? null : new ElementTreeSnapshot(root); + } + + public GameElement Restore() + { + if (elements.Count == 0) return null; + + GameElement parent = parentGuid == Guid.Empty ? null : FindExistingElement(parentGuid); + RegisterExistingAncestorChain(parent); + RepairRootAttachment(); + + foreach (GameElement_BM gameElementBM in elements.OfType()) + { + GameElement_BM.identifier[gameElementBM.elementGuid] = gameElementBM; + } + + foreach (BaseElement_BM elementBM in elements) + { + elementBM.ExecuteBM(); + } + + EditorManager.instance.beatmapContainer.ExecuteLowPriorityActions(); + + GameElement root = GameElement_BM.GetElement(rootGuid); + if (root == null) return null; + + RestoreParentOrder(root, parent); + + foreach (GameElement element in root.GetAllGameElementsFromThis()) + { + if (element == null) continue; + element.AfterInitialize(); + element.Refresh(); + } + + EditorManager.instance.uiManager.hierarchy.FindTab(root); + return root; + } + + private GameElement FindExistingElement(Guid elementGuid) + { + GameElement element = GameElement_BM.GetElement(elementGuid); + if (element != null) return element; + + return EditorManager.instance.beatmapContainer.gameElementList + .FirstOrDefault(gameElement => gameElement != null && gameElement.elementGuid == elementGuid); + } + + private void RepairRootAttachment() + { + if (parentGuid == Guid.Empty) return; + + GameElement_BM rootBM = elements + .OfType() + .FirstOrDefault(gameElementBM => gameElementBM.elementGuid == rootGuid); + + if (rootBM != null) + { + rootBM.attachedElementGuid = parentGuid; + } + } + + private void RegisterExistingAncestorChain(GameElement parent) + { + if (parent == null) return; + + List ancestors = new List(); + for (GameElement current = parent; current != null; current = current.parentElement) + { + ancestors.Add(current); + } + + ancestors.Reverse(); + foreach (GameElement ancestor in ancestors) + { + ancestor.SaveBM(); + if (ancestor.matchedBM is not GameElement_BM ancestorBM) continue; + + GameElement_BM.identifier[ancestor.elementGuid] = ancestorBM; + ancestorBM.matchedElement = ancestor; + } + } + + private void RestoreParentOrder(GameElement root, GameElement parent) + { + if (parent == null || parentChildIndex < 0) return; + + parent.childElementList.Remove(root); + int insertIndex = Mathf.Clamp(parentChildIndex, 0, parent.childElementList.Count); + parent.childElementList.Insert(insertIndex, root); + root.transform.SetSiblingIndex(insertIndex); + parent.Refresh(); + } + } + + public sealed class DeleteElementCommand : ICommand + { + private readonly ElementTreeSnapshot snapshot; + private GameElement target; + + public DeleteElementCommand(GameElement target) + { + this.target = target; + snapshot = ElementTreeSnapshot.Capture(target); + } + + public void Execute() + { + DeleteCurrentTarget(); + } + + public void Undo() + { + target = snapshot?.Restore(); + } + + public void Redo() + { + DeleteCurrentTarget(); + } + + public bool TryMerge(ICommand other) => false; + + private void DeleteCurrentTarget() + { + if (target == null) return; + EditorManager.instance.operationManager.CopyPasteDeleteModule.DeleteElementRaw(target); + target = null; + } + } + + public sealed class PasteElementCommand : ICommand + { + private readonly CopyPasteDeleteModule module; + private readonly GameElement source; + private readonly GameElement parent; + private ElementTreeSnapshot snapshot; + private GameElement pastedRoot; + + public PasteElementCommand(CopyPasteDeleteModule module, GameElement source, GameElement parent) + { + this.module = module; + this.source = source; + this.parent = parent; + } + + public void Execute() + { + pastedRoot = module.PasteElementRaw(source, parent); + snapshot ??= ElementTreeSnapshot.Capture(pastedRoot); + } + + public void Undo() + { + if (pastedRoot == null) return; + module.DeleteElementRaw(pastedRoot, false); + pastedRoot = null; + } + + public void Redo() + { + pastedRoot = snapshot?.Restore(); + } + + public bool TryMerge(ICommand other) => false; + } + + public sealed class CreateElementCommand : ICommand + { + private readonly Func createAction; + private ElementTreeSnapshot snapshot; + + public GameElement CreatedElement { get; private set; } + + public CreateElementCommand(Func createAction) + { + this.createAction = createAction; + } + + public void Execute() + { + CreatedElement = createAction?.Invoke(); + snapshot ??= ElementTreeSnapshot.Capture(CreatedElement); + } + + public void Undo() + { + if (CreatedElement == null) return; + EditorManager.instance.operationManager.CopyPasteDeleteModule.DeleteElementRaw(CreatedElement, false); + CreatedElement = null; + } + + public void Redo() + { + CreatedElement = snapshot?.Restore(); + } + + public bool TryMerge(ICommand other) => false; + } +} diff --git a/Assets/Scripts/CommandSystem/GameElementStructuralCommands.cs.meta b/Assets/Scripts/CommandSystem/GameElementStructuralCommands.cs.meta new file mode 100644 index 00000000..753cc702 --- /dev/null +++ b/Assets/Scripts/CommandSystem/GameElementStructuralCommands.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 96273157236b1a54fbf492d88d4c540f \ No newline at end of file diff --git a/Assets/Scripts/DynamicUI/Core/InspectorBuilder.cs b/Assets/Scripts/DynamicUI/Core/InspectorBuilder.cs index 744a9b93..cd904de2 100644 --- a/Assets/Scripts/DynamicUI/Core/InspectorBuilder.cs +++ b/Assets/Scripts/DynamicUI/Core/InspectorBuilder.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using Ichni.Editor.Commands; using Ichni.RhythmGame; using Lean.Pool; using UnityEngine; @@ -784,29 +785,29 @@ namespace Ichni.Editor builder .Button("Displacement", () => - Displacement.GenerateElement("New Displacement", Guid.NewGuid(), + CommandManager.ExecuteCreate(() => Displacement.GenerateElement("New Displacement", Guid.NewGuid(), new List(), true, gameElement, - new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true))) + new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true)))) .Button("Swirl", () => - Swirl.GenerateElement("New Swirl", Guid.NewGuid(), + CommandManager.ExecuteCreate(() => Swirl.GenerateElement("New Swirl", Guid.NewGuid(), new List(), true, gameElement, - new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true))) + new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true)))) .Button("Scale", () => - Scale.GenerateElement("New Scale", Guid.NewGuid(), + CommandManager.ExecuteCreate(() => Scale.GenerateElement("New Scale", Guid.NewGuid(), new List(), true, gameElement, - new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true))) + new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true)))) .Button("Look At", () => - LookAt.GenerateElement("New Look At", Guid.NewGuid(), - new List(), true, gameElement, null, new FlexibleBool())) + CommandManager.ExecuteCreate(() => LookAt.GenerateElement("New Look At", Guid.NewGuid(), + new List(), true, gameElement, null, new FlexibleBool()))) .Button("Displacement Tracker", () => - DisplacementTracker.GenerateElement("New Displacement Tracker", Guid.NewGuid(), - new List(), true, gameElement, null, 0f)) + CommandManager.ExecuteCreate(() => DisplacementTracker.GenerateElement("New Displacement Tracker", Guid.NewGuid(), + new List(), true, gameElement, null, 0f))) .Button("Swirl Tracker", () => - SwirlTracker.GenerateElement("New Swirl Tracker", Guid.NewGuid(), - new List(), true, gameElement, null, 0f)) + CommandManager.ExecuteCreate(() => SwirlTracker.GenerateElement("New Swirl Tracker", Guid.NewGuid(), + new List(), true, gameElement, null, 0f))) .Button("Scale Tracker", () => - ScaleTracker.GenerateElement("New Scale Tracker", Guid.NewGuid(), - new List(), true, gameElement, null, 0f)); + CommandManager.ExecuteCreate(() => ScaleTracker.GenerateElement("New Scale Tracker", Guid.NewGuid(), + new List(), true, gameElement, null, 0f))); } // ════════════════════════════════════════════════════════ diff --git a/Assets/Scripts/DynamicUI/Hierarchy/Hierarchy.cs b/Assets/Scripts/DynamicUI/Hierarchy/Hierarchy.cs index e51c29c3..3b5e8c9f 100644 --- a/Assets/Scripts/DynamicUI/Hierarchy/Hierarchy.cs +++ b/Assets/Scripts/DynamicUI/Hierarchy/Hierarchy.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using DG.Tweening; using Lean.Pool; +using Ichni.Editor.Commands; using Ichni.RhythmGame; using Unity.VisualScripting; using UnityEngine; @@ -24,7 +25,8 @@ namespace Ichni.Editor tabList = new List(); addFolderButton.onClick.AddListener(() => { - ElementFolder.GenerateElement("New Folder", Guid.NewGuid(), new List(), true, null); + CommandManager.ExecuteCreate(() => + ElementFolder.GenerateElement("New Folder", Guid.NewGuid(), new List(), true, null)); }); expandButtom.onClick.AddListener(Expand); rectTransform = this.GetComponent(); @@ -201,4 +203,4 @@ namespace Ichni.Editor upLoadElement = null; } } -} \ No newline at end of file +} diff --git a/Assets/Scripts/DynamicUI/MainUI/ToolBar/ToolBar.cs b/Assets/Scripts/DynamicUI/MainUI/ToolBar/ToolBar.cs index f93e032a..1eea6f1c 100644 --- a/Assets/Scripts/DynamicUI/MainUI/ToolBar/ToolBar.cs +++ b/Assets/Scripts/DynamicUI/MainUI/ToolBar/ToolBar.cs @@ -176,13 +176,7 @@ namespace Ichni.Editor private void GenerateSaveClipWindow() { - GameElement currentElement = EditorManager.instance.operationManager.currentSelectedElements[0]; - - if (currentElement == null) - { - LogWindow.Log("No Game Element selected.", Color.red); - return; - } + if (!TryGetSingleSelectedElementForClip(out GameElement currentElement)) return; if (clipManagementWindow != null) { @@ -208,15 +202,7 @@ namespace Ichni.Editor private void GenerateLoadClipWindow() { - GameElement currentElement = EditorManager.instance.operationManager.currentSelectedElements[0]; - - if (currentElement == null) - { - LogWindow.Log("No Game Element selected.", Color.red); - return; - } - - GameElement loadTarget = currentElement == EditorManager.instance ? null : currentElement.parentElement; + if (!TryGetSingleSelectedElementForClip(out GameElement currentElement)) return; if (clipManagementWindow != null) { @@ -240,6 +226,26 @@ namespace Ichni.Editor }); } + private bool TryGetSingleSelectedElementForClip(out GameElement currentElement) + { + currentElement = null; + var selectedElements = EditorManager.instance.operationManager.currentSelectedElements; + if (selectedElements == null || selectedElements.Count != 1) + { + LogWindow.Log("Please select only one Game Element for clip operation.", Color.red); + return false; + } + + currentElement = selectedElements[0]; + if (currentElement == null) + { + LogWindow.Log("No Game Element selected.", Color.red); + return false; + } + + return true; + } + private void GenerateMergeWindow() { GeneralSecondaryWindow mergeWindow = Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow, diff --git a/Assets/Scripts/Game/EditorCore/Animations_Editor/EditorAnimations/DisplacementTracker_Editor.cs b/Assets/Scripts/Game/EditorCore/Animations_Editor/EditorAnimations/DisplacementTracker_Editor.cs index aaa6547e..7b12c449 100644 --- a/Assets/Scripts/Game/EditorCore/Animations_Editor/EditorAnimations/DisplacementTracker_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/Animations_Editor/EditorAnimations/DisplacementTracker_Editor.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using Ichni.Editor; +using Ichni.Editor.Commands; using UnityEngine; namespace Ichni.RhythmGame @@ -37,8 +38,8 @@ namespace Ichni.RhythmGame .InputField(nameof(TimeOffset), "Offset") .Button("Interferometer", () => { - Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(), - new List(), true, this, InterferomType.Additive, Vector3.zero); + CommandManager.ExecuteCreate(() => Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(), + new List(), true, this, InterferomType.Additive, Vector3.zero)); }) .Build(); } diff --git a/Assets/Scripts/Game/EditorCore/Animations_Editor/EditorAnimations/ScaleTracker_Editor.cs b/Assets/Scripts/Game/EditorCore/Animations_Editor/EditorAnimations/ScaleTracker_Editor.cs index 36552c7e..a158b5c2 100644 --- a/Assets/Scripts/Game/EditorCore/Animations_Editor/EditorAnimations/ScaleTracker_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/Animations_Editor/EditorAnimations/ScaleTracker_Editor.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using Ichni.Editor; +using Ichni.Editor.Commands; using UnityEngine; namespace Ichni.RhythmGame @@ -37,8 +38,8 @@ namespace Ichni.RhythmGame .InputField(nameof(TimeOffset), "Offset") .Button("Interferometer", () => { - Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(), - new List(), true, this, InterferomType.Additive, Vector3.zero); + CommandManager.ExecuteCreate(() => Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(), + new List(), true, this, InterferomType.Additive, Vector3.zero)); }) .Build(); } diff --git a/Assets/Scripts/Game/EditorCore/Animations_Editor/EditorAnimations/SwirlTracker_Editor.cs b/Assets/Scripts/Game/EditorCore/Animations_Editor/EditorAnimations/SwirlTracker_Editor.cs index 75d6d7d6..129fd710 100644 --- a/Assets/Scripts/Game/EditorCore/Animations_Editor/EditorAnimations/SwirlTracker_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/Animations_Editor/EditorAnimations/SwirlTracker_Editor.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using Ichni.Editor; +using Ichni.Editor.Commands; using UnityEngine; namespace Ichni.RhythmGame @@ -37,8 +38,8 @@ namespace Ichni.RhythmGame .InputField(nameof(TimeOffset), "Offset") .Button("Interferometer", () => { - Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(), - new List(), true, this, InterferomType.Additive, Vector3.zero); + CommandManager.ExecuteCreate(() => Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(), + new List(), true, this, InterferomType.Additive, Vector3.zero)); }) .Build(); } diff --git a/Assets/Scripts/Game/EditorCore/Animations_Editor/Transform/Displacement_Editor.cs b/Assets/Scripts/Game/EditorCore/Animations_Editor/Transform/Displacement_Editor.cs index e7445d0d..8dd98fa2 100644 --- a/Assets/Scripts/Game/EditorCore/Animations_Editor/Transform/Displacement_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/Animations_Editor/Transform/Displacement_Editor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Ichni.Editor; +using Ichni.Editor.Commands; using UnityEngine; namespace Ichni.RhythmGame @@ -21,8 +22,8 @@ namespace Ichni.RhythmGame new FlexibleFloat[] { positionX, positionY, positionZ }, new string[] { "PosX", "PosY", "PosZ" })) .ParameterText(nameof(PreviewValue), "value:", autoUpdate: true) .Span(3) - .Button("Interferometer", () => Vector3Interferometer.GenerateElement("New Vector3 Interferometer", - Guid.NewGuid(), new List(), true, this, InterferomType.Additive, Vector3.zero)) + .Button("Interferometer", () => CommandManager.ExecuteCreate(() => Vector3Interferometer.GenerateElement("New Vector3 Interferometer", + Guid.NewGuid(), new List(), true, this, InterferomType.Additive, Vector3.zero))) .Span(3) .Build(); } diff --git a/Assets/Scripts/Game/EditorCore/Animations_Editor/Transform/Scale_Editor.cs b/Assets/Scripts/Game/EditorCore/Animations_Editor/Transform/Scale_Editor.cs index 55ee07a1..a54cd67d 100644 --- a/Assets/Scripts/Game/EditorCore/Animations_Editor/Transform/Scale_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/Animations_Editor/Transform/Scale_Editor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Ichni.Editor; +using Ichni.Editor.Commands; using UnityEngine; namespace Ichni.RhythmGame @@ -22,8 +23,8 @@ namespace Ichni.RhythmGame new string[] { "ScaleX", "ScaleY", "ScaleZ" })) .ParameterText(nameof(PreviewValue), "value:", autoUpdate: true) .Span(3) - .Button("Interferometer", () => Vector3Interferometer.GenerateElement("New Vector3 Interferometer", - Guid.NewGuid(), new List(), true, this, InterferomType.Additive, Vector3.zero)) + .Button("Interferometer", () => CommandManager.ExecuteCreate(() => Vector3Interferometer.GenerateElement("New Vector3 Interferometer", + Guid.NewGuid(), new List(), true, this, InterferomType.Additive, Vector3.zero))) .Span(3) .Build(); } diff --git a/Assets/Scripts/Game/EditorCore/Animations_Editor/Transform/Swirl_Editor.cs b/Assets/Scripts/Game/EditorCore/Animations_Editor/Transform/Swirl_Editor.cs index 8c01819b..ebc75b12 100644 --- a/Assets/Scripts/Game/EditorCore/Animations_Editor/Transform/Swirl_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/Animations_Editor/Transform/Swirl_Editor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Ichni.Editor; +using Ichni.Editor.Commands; using UnityEngine; namespace Ichni.RhythmGame @@ -22,8 +23,8 @@ namespace Ichni.RhythmGame new string[] { "EulerX", "EulerY", "EulerZ" })) .ParameterText(nameof(PreviewValue), "value:", autoUpdate: true) .Span(3) - .Button("Interferometer", () => Vector3Interferometer.GenerateElement("New Vector3 Interferometer", - Guid.NewGuid(), new List(), true, this, InterferomType.Additive, Vector3.zero)) + .Button("Interferometer", () => CommandManager.ExecuteCreate(() => Vector3Interferometer.GenerateElement("New Vector3 Interferometer", + Guid.NewGuid(), new List(), true, this, InterferomType.Additive, Vector3.zero))) .Span(3) .Build(); } diff --git a/Assets/Scripts/Game/EditorCore/GameElements_Editor/EnvironmentObjects/EnvironmentObject_Editor.cs b/Assets/Scripts/Game/EditorCore/GameElements_Editor/EnvironmentObjects/EnvironmentObject_Editor.cs index a937d4c8..3fd07fea 100644 --- a/Assets/Scripts/Game/EditorCore/GameElements_Editor/EnvironmentObjects/EnvironmentObject_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/GameElements_Editor/EnvironmentObjects/EnvironmentObject_Editor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Ichni.Editor; +using Ichni.Editor.Commands; using Ichni.RhythmGame.Beatmap; namespace Ichni.RhythmGame @@ -23,41 +24,41 @@ namespace Ichni.RhythmGame var builder = InspectorBuilder.For(this) .Section("Generate") .Button("Environment Object", () => - TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), - new List(), true, this)) + CommandManager.ExecuteCreate(() => TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), + new List(), true, this))) .Toggle(nameof(isStatic), "Is Static") .OnChanged(() => gameObject.isStatic = isStatic) .Preset(InspectorBuilder.TransformPreset) .Section("Generate Animations") .Button("Base Color Change", () => - BaseColorChange.GenerateElement("New Base Color Change", Guid.NewGuid(), new List(), true, + CommandManager.ExecuteCreate(() => BaseColorChange.GenerateElement("New Base Color Change", Guid.NewGuid(), new List(), true, this, new FlexibleFloat(new List { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.r, colorSubmodule.originalBaseColor.r, animationCurveType: AnimationCurveType.Linear) }), new FlexibleFloat(new List { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.g, colorSubmodule.originalBaseColor.g, animationCurveType: AnimationCurveType.Linear) }), new FlexibleFloat(new List { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.b, colorSubmodule.originalBaseColor.b, animationCurveType: AnimationCurveType.Linear) }), new FlexibleFloat(new List { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.a, colorSubmodule.originalBaseColor.a, animationCurveType: AnimationCurveType.Linear) }) - )); + ))); if (haveEmissionColor) { builder.Button("Emission Color Change", () => - EmissionColorChange.GenerateElement("New Emission Color Change", Guid.NewGuid(), + CommandManager.ExecuteCreate(() => EmissionColorChange.GenerateElement("New Emission Color Change", Guid.NewGuid(), new List(), true, this, - new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat())); + new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat()))); } builder .Button("Property Animation Color", () => - PropertyAnimationColor.GenerateElement("New Property Animation Color", Guid.NewGuid(), + CommandManager.ExecuteCreate(() => PropertyAnimationColor.GenerateElement("New Property Animation Color", Guid.NewGuid(), new List(), true, this, GetType().FullName, "", - new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat())) + new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat()))) .Button("Property Animation Float", () => - PropertyAnimationFloat.GenerateElement("New Property Animation Float", Guid.NewGuid(), - new List(), true, this, GetType().FullName, "", new FlexibleFloat())) + CommandManager.ExecuteCreate(() => PropertyAnimationFloat.GenerateElement("New Property Animation Float", Guid.NewGuid(), + new List(), true, this, GetType().FullName, "", new FlexibleFloat()))) .Button("Property Animation Vector3", () => - PropertyAnimationVector3.GenerateElement("New Property Animation Vector3", Guid.NewGuid(), + CommandManager.ExecuteCreate(() => PropertyAnimationVector3.GenerateElement("New Property Animation Vector3", Guid.NewGuid(), new List(), true, this, GetType().FullName, "", - new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat())) + new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat()))) .Build(); } #endregion diff --git a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Essential/ElementFolder_Editor.cs b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Essential/ElementFolder_Editor.cs index d5695862..f64c6407 100644 --- a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Essential/ElementFolder_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Essential/ElementFolder_Editor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Ichni.Editor; +using Ichni.Editor.Commands; using Ichni.RhythmGame.Beatmap; using Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse; using Sirenix.OdinInspector; @@ -26,29 +27,29 @@ namespace Ichni.RhythmGame InspectorBuilder.For(this) .Section("Generate", sectionOrder: 10) - .Button("Folder", () => ElementFolder.GenerateElement("New Folder", Guid.NewGuid(), new List(), true, this)) - .Button("Track", () => Track.GenerateElement("New Track", Guid.NewGuid(), new List(), true, this)) - .Button("Camera", () => GameCamera.GenerateElement("New Camera", Guid.NewGuid(), new List(), true, this, GameCamera.CameraViewType.Perspective, 60, 10)) - .Button("Cross Track Point", () => CrossTrackPoint.GenerateElement("New Cross Track Point", Guid.NewGuid(), new List(), true, this, new FlexibleInt(), new FlexibleFloat())) + .Button("Folder", () => CommandManager.ExecuteCreate(() => ElementFolder.GenerateElement("New Folder", Guid.NewGuid(), new List(), true, this))) + .Button("Track", () => CommandManager.ExecuteCreate(() => Track.GenerateElement("New Track", Guid.NewGuid(), new List(), true, this))) + .Button("Camera", () => CommandManager.ExecuteCreate(() => GameCamera.GenerateElement("New Camera", Guid.NewGuid(), new List(), true, this, GameCamera.CameraViewType.Perspective, 60, 10))) + .Button("Cross Track Point", () => CommandManager.ExecuteCreate(() => CrossTrackPoint.GenerateElement("New Cross Track Point", Guid.NewGuid(), new List(), true, this, new FlexibleInt(), new FlexibleFloat()))) .Build(); InspectorBuilder.For(this) .Section("Generate Elements", sectionOrder: 15) .Preset(InspectorBuilder.TransformPreset) .Section("Generate Notes", sectionOrder: 20) - .Button("Tap", () => Tap.GenerateElement("New Tap", Guid.NewGuid(), new List(), true, this, 0f)) - .Button("Stay", () => Stay.GenerateElement("New Stay", Guid.NewGuid(), new List(), true, this, 0f)) - .Button("Hold", () => Hold.GenerateElement("New Hold", Guid.NewGuid(), new List(), true, this, 0f, 1f)) - .Button("Flick", () => Flick.GenerateElement("New Flick", Guid.NewGuid(), new List(), true, this, 0f, new List())) + .Button("Tap", () => CommandManager.ExecuteCreate(() => Tap.GenerateElement("New Tap", Guid.NewGuid(), new List(), true, this, 0f))) + .Button("Stay", () => CommandManager.ExecuteCreate(() => Stay.GenerateElement("New Stay", Guid.NewGuid(), new List(), true, this, 0f))) + .Button("Hold", () => CommandManager.ExecuteCreate(() => Hold.GenerateElement("New Hold", Guid.NewGuid(), new List(), true, this, 0f, 1f))) + .Button("Flick", () => CommandManager.ExecuteCreate(() => Flick.GenerateElement("New Flick", Guid.NewGuid(), new List(), true, this, 0f, new List()))) .Section("Generate Environment", sectionOrder: 30) - .Button("Environment Object", () => TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List(), true, this)) - .Button("Time Effects Collection", () => TimeEffectsCollection.GenerateElement("New Time Effects Collection", Guid.NewGuid(), - new List(), true, this, 0)) + .Button("Environment Object", () => CommandManager.ExecuteCreate(() => TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List(), true, this))) + .Button("Time Effects Collection", () => CommandManager.ExecuteCreate(() => TimeEffectsCollection.GenerateElement("New Time Effects Collection", Guid.NewGuid(), + new List(), true, this, 0))) .Button("Particle Emitter", () => { - ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List(), true, + CommandManager.ExecuteCreate(() => ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List(), true, this, "", "", false, 0, 1, ParticleSystemSimulationSpace.World, - 10, 5, 1, 1, true, Vector3.zero); + 10, 5, 1, 1, true, Vector3.zero)); }) .Section("Tools", sectionOrder: 40) diff --git a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Essential/GameCamera_Editor.cs b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Essential/GameCamera_Editor.cs index 524072f4..47bc6165 100644 --- a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Essential/GameCamera_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Essential/GameCamera_Editor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Ichni.Editor; +using Ichni.Editor.Commands; using Ichni.RhythmGame.Beatmap; namespace Ichni.RhythmGame @@ -25,14 +26,14 @@ namespace Ichni.RhythmGame .Preset(InspectorBuilder.TransformPreset) .Section("Generate") .Button("Field of View", () => - CameraFieldOfView.GenerateElement("New Field of View", Guid.NewGuid(), + CommandManager.ExecuteCreate(() => CameraFieldOfView.GenerateElement("New Field of View", Guid.NewGuid(), new List(), true, this, new FlexibleFloat(new List { new AnimatedFloat(0f, 1f, 60f, 60f, AnimationCurveType.Linear) - }))) + })))) .Button("Extension", () => - GameCameraExtension.GenerateElement("New Extension", Guid.NewGuid(), - new List(), true, this, 1000f)) + CommandManager.ExecuteCreate(() => GameCameraExtension.GenerateElement("New Extension", Guid.NewGuid(), + new List(), true, this, 1000f))) .Build(); } #endregion diff --git a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Essential/TemporaryObject_Editor.cs b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Essential/TemporaryObject_Editor.cs index 2207c6a1..c6a27bff 100644 --- a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Essential/TemporaryObject_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Essential/TemporaryObject_Editor.cs @@ -30,7 +30,7 @@ namespace Ichni.RhythmGame .OnChanged(() => inspectorMain.SetInspector(this)) .Button("Generate", () => { - EditorManager.instance.operationManager.CopyPasteDeleteModule.DeleteElement(this); + EditorManager.instance.operationManager.CopyPasteDeleteModule.DeleteElementRaw(this); inspectorMain.ClearInspector(); SubstantialObject.GenerateElement(elementName, elementGuid, tags, true, themeBundleName, objectName, parentElement); diff --git a/Assets/Scripts/Game/EditorCore/GameElements_Editor/GlobalElements/BackgroundSetter_Editor.cs b/Assets/Scripts/Game/EditorCore/GameElements_Editor/GlobalElements/BackgroundSetter_Editor.cs index bbfbfbbb..acf9e7c6 100644 --- a/Assets/Scripts/Game/EditorCore/GameElements_Editor/GlobalElements/BackgroundSetter_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/GameElements_Editor/GlobalElements/BackgroundSetter_Editor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Ichni.Editor; +using Ichni.Editor.Commands; using Ichni.RhythmGame.Beatmap; using UnityEngine; @@ -84,9 +85,9 @@ namespace Ichni.RhythmGame { if (skyboxSubsetter == null) { - SkyboxSubsetter.GenerateElement("New Skybox Subsetter", Guid.NewGuid(), + CommandManager.ExecuteCreate(() => SkyboxSubsetter.GenerateElement("New Skybox Subsetter", Guid.NewGuid(), new List(), true, this, - new List(), new List(), new List(), new List()); + new List(), new List(), new List(), new List())); } else { diff --git a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Notes/NoteObjects/NoteBase_Editor.cs b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Notes/NoteObjects/NoteBase_Editor.cs index 843a1a0e..4351e13f 100644 --- a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Notes/NoteObjects/NoteBase_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Notes/NoteObjects/NoteBase_Editor.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using Ichni.Editor; +using Ichni.Editor.Commands; using Ichni.RhythmGame.Beatmap; namespace Ichni.RhythmGame @@ -75,7 +76,7 @@ namespace Ichni.RhythmGame .Section("Note Visual") .Button("Generate Note Visual", () => { - TemporaryObject.GenerateElement("New Note Visual", Guid.NewGuid(), new List(), true, this); + CommandManager.ExecuteCreate(() => TemporaryObject.GenerateElement("New Note Visual", Guid.NewGuid(), new List(), true, this)); }) .EnabledIf(() => noteVisual == null) .Build(); diff --git a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/PathNode_Editor.cs b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/PathNode_Editor.cs index a38458f9..fb81cc83 100644 --- a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/PathNode_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/PathNode_Editor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Ichni.Editor; +using Ichni.Editor.Commands; using Ichni.RhythmGame.Beatmap; namespace Ichni.RhythmGame @@ -38,13 +39,13 @@ namespace Ichni.RhythmGame public void GenerateBaseColorChange() { - BaseColorChange.GenerateElement("New Base Color Change", Guid.NewGuid(), new List(), true, + CommandManager.ExecuteCreate(() => BaseColorChange.GenerateElement("New Base Color Change", Guid.NewGuid(), new List(), true, this, new FlexibleFloat(new List { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.r, colorSubmodule.originalBaseColor.r, animationCurveType: AnimationCurveType.Linear) }), new FlexibleFloat(new List { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.g, colorSubmodule.originalBaseColor.g, animationCurveType: AnimationCurveType.Linear) }), new FlexibleFloat(new List { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.b, colorSubmodule.originalBaseColor.b, animationCurveType: AnimationCurveType.Linear) }), new FlexibleFloat(new List { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.a, colorSubmodule.originalBaseColor.a, animationCurveType: AnimationCurveType.Linear) }) - ); + )); } #endregion diff --git a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackPoints/CrossTrackPoint_Editor.cs b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackPoints/CrossTrackPoint_Editor.cs index 9d218231..20d3a035 100644 --- a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackPoints/CrossTrackPoint_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackPoints/CrossTrackPoint_Editor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Ichni.Editor; +using Ichni.Editor.Commands; using Ichni.RhythmGame.Beatmap; using UnityEngine; @@ -36,19 +37,19 @@ namespace Ichni.RhythmGame .Toggle(nameof(MotionAngles), "Motion With Angles") .Section("Generate") .Button("Game Camera", () => - GameCamera.GenerateElement("New Game Camera", Guid.NewGuid(), new List(), - true, this, GameCamera.CameraViewType.Perspective, 60, 10)) + CommandManager.ExecuteCreate(() => GameCamera.GenerateElement("New Game Camera", Guid.NewGuid(), new List(), + true, this, GameCamera.CameraViewType.Perspective, 60, 10))) .Button("Trail", () => - Trail.GenerateElement("New Trail", Guid.NewGuid(), new List(), + CommandManager.ExecuteCreate(() => Trail.GenerateElement("New Trail", Guid.NewGuid(), new List(), true, this, 1, true, 1, - AnimationCurve.Constant(0, 1, 1), ColorExtensions.DefaultGradient(), "", "")) + AnimationCurve.Constant(0, 1, 1), ColorExtensions.DefaultGradient(), "", ""))) .Button("Environment Object", () => - TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List(), - true, this)) + CommandManager.ExecuteCreate(() => TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List(), + true, this))) .Button("Generate Particle Emitter", () => - ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List(), true, + CommandManager.ExecuteCreate(() => ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List(), true, this, "", "", false, 0, 1, ParticleSystemSimulationSpace.World, - 10, 5, 1, 1, true, Vector3.zero)) + 10, 5, 1, 1, true, Vector3.zero))) .Build(); } #endregion diff --git a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackPoints/TrackHeadPoint_Editor.cs b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackPoints/TrackHeadPoint_Editor.cs index 514cf5b4..12ed2aaa 100644 --- a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackPoints/TrackHeadPoint_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackPoints/TrackHeadPoint_Editor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Ichni.Editor; +using Ichni.Editor.Commands; using Ichni.RhythmGame.Beatmap; using UnityEngine; @@ -29,16 +30,16 @@ namespace Ichni.RhythmGame .OnChanged(() => trackPositioner.motion.rotationOffset = motionEulerAngles) .Section("Generate") .Button("Generate Trail", () => - Trail.GenerateElement("New Trail", Guid.NewGuid(), new List(), true, + CommandManager.ExecuteCreate(() => Trail.GenerateElement("New Trail", Guid.NewGuid(), new List(), true, this, 1, true, 1, - AnimationCurve.Constant(0, 1, 1), ColorExtensions.DefaultGradient(), "", "")) + AnimationCurve.Constant(0, 1, 1), ColorExtensions.DefaultGradient(), "", ""))) .Button("Environment Object", () => - TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List(), - true, this)) + CommandManager.ExecuteCreate(() => TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List(), + true, this))) .Button("Generate Particle Emitter", () => - ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List(), true, + CommandManager.ExecuteCreate(() => ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List(), true, this, "", "", false, 0, 1, ParticleSystemSimulationSpace.World, - 10, 5, 1, 1, true, Vector3.zero)) + 10, 5, 1, 1, true, Vector3.zero))) .Build(); } #endregion diff --git a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackPoints/TrackPercentPoint_Editor.cs b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackPoints/TrackPercentPoint_Editor.cs index d42df296..ad70a9f8 100644 --- a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackPoints/TrackPercentPoint_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackPoints/TrackPercentPoint_Editor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Ichni.Editor; +using Ichni.Editor.Commands; using Ichni.RhythmGame.Beatmap; using UnityEngine; @@ -33,16 +34,16 @@ namespace Ichni.RhythmGame .Toggle(nameof(MotionAngles), "Motion With Angles") .Section("Generate") .Button("Generate Trail", () => - Trail.GenerateElement("New Trail", Guid.NewGuid(), new List(), true, + CommandManager.ExecuteCreate(() => Trail.GenerateElement("New Trail", Guid.NewGuid(), new List(), true, this, 1, true, 1, - AnimationCurve.Constant(0, 1, 1), ColorExtensions.DefaultGradient(), "", "")) + AnimationCurve.Constant(0, 1, 1), ColorExtensions.DefaultGradient(), "", ""))) .Button("Environment Object", () => - TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List(), - true, this)) + CommandManager.ExecuteCreate(() => TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List(), + true, this))) .Button("Generate Particle Emitter", () => - ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List(), true, + CommandManager.ExecuteCreate(() => ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List(), true, this, "", "", false, 0, 1, ParticleSystemSimulationSpace.World, - 10, 5, 1, 1, true, Vector3.zero)) + 10, 5, 1, 1, true, Vector3.zero))) .Build(); } #endregion diff --git a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackSubmodules/TrackPathSubmodule_Editor.cs b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackSubmodules/TrackPathSubmodule_Editor.cs index ea5acac6..3f1c7a6f 100644 --- a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackSubmodules/TrackPathSubmodule_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackSubmodules/TrackPathSubmodule_Editor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Ichni.Editor; +using Ichni.Editor.Commands; using Ichni.RhythmGame.Beatmap; namespace Ichni.RhythmGame @@ -27,7 +28,7 @@ namespace Ichni.RhythmGame .OnChanged(ClosePath) .Button("Generate Path Node", () => { - PathNode.GenerateElement("New Path Node", Guid.NewGuid(), new List(), true, track, true); + CommandManager.ExecuteCreate(() => PathNode.GenerateElement("New Path Node", Guid.NewGuid(), new List(), true, track, true)); }) .Toggle(nameof(isShowingDisplay), "Show Display") .OnChanged(() => SetDisplay(isShowingDisplay)) diff --git a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackTools_Editor.cs b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackTools_Editor.cs index fbab2b3a..1b6d5b4f 100644 --- a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackTools_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/TrackTools_Editor.cs @@ -14,8 +14,10 @@ namespace Ichni.RhythmGame /// /// 单位位置整体偏移 /// 单位时间偏移 + /// 单位旋转偏移(欧拉角) + /// 单位缩放偏移 /// 迭代次数,即产生几个粘贴的Track - private void QuickCopy(Vector3 unitPositionOffset, float unitTimeOffset, bool includeAnimations = true, int iteration = 1, bool MovingTrack = false) + private void QuickCopy(Vector3 unitPositionOffset, float unitTimeOffset, bool includeAnimations = true, int iteration = 1, bool MovingTrack = false, Vector3 unitRotationOffset = default, Vector3 unitScaleOffset = default) { if (iteration <= 0) return; @@ -23,23 +25,29 @@ namespace Ichni.RhythmGame cpd.CopyElement(this); for (int i = 1; i <= iteration; i++) { - cpd.PasteElement(parentElement); + cpd.PasteElementRaw(this, parentElement); Track newTrack = cpd.pastedElementList[0] as Track; Vector3 positionOffset = unitPositionOffset * i; float timeOffset = unitTimeOffset * i; + Vector3 rotationOffset = unitRotationOffset * i; + Vector3 scaleOffset = unitScaleOffset * i; //以下:对Track的所有有效的Submodule和子GameElement进行偏移 TODO: 需要思考是否有统一时间偏移的方法? if (MovingTrack) { newTrack.transformSubmodule.originalPosition += positionOffset; + newTrack.transformSubmodule.originalEulerAngles += rotationOffset; + newTrack.transformSubmodule.originalScale += scaleOffset; newTrack.transformSubmodule.Refresh(); } else { - //PathNode,位置偏移 + //PathNode,位置/旋转/缩放偏移 newTrack.trackPathSubmodule.pathNodeList.ForEach(pn => { pn.transformSubmodule.originalPosition += positionOffset; + pn.transformSubmodule.originalEulerAngles += rotationOffset; + pn.transformSubmodule.originalScale += scaleOffset; pn.transformSubmodule.Refresh(); }); } @@ -161,4 +169,4 @@ namespace Ichni.RhythmGame trackPathSubmodule.pathNodeList.ForEach(pn => pn.SetPathNodeSphere(isShowing)); } } -} \ No newline at end of file +} diff --git a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/Track_Editor.cs b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/Track_Editor.cs index c64479a2..cf95deb4 100644 --- a/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/Track_Editor.cs +++ b/Assets/Scripts/Game/EditorCore/GameElements_Editor/Track/Track_Editor.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using ichni.RhythmGame; using Ichni.Editor; +using Ichni.Editor.Commands; using Ichni.RhythmGame.Beatmap; using Sirenix.OdinInspector; using UnityEngine; @@ -79,41 +80,45 @@ namespace Ichni.RhythmGame .Section("Generate Elements", sectionOrder: 20) .Button("Path Node", () => { - PathNode.GenerateElement("New Path Node", Guid.NewGuid(), new List(), true, this, true); + CommandManager.ExecuteCreate(() => PathNode.GenerateElement("New Path Node", Guid.NewGuid(), new List(), true, this, true)); }) .EnabledIf(() => trackPathSubmodule != null) .Button("Track Percent Point", () => { - var a = TrackPercentPoint.GenerateElement("New Track Percent Point", Guid.NewGuid(), new List(), true, this, new FlexibleFloat()); - if (trackTimeSubmodule != null && trackTimeSubmodule is TrackTimeSubmoduleMovable trackTimeSubmoduleMovable) - a.trackPercent.Add( - new AnimatedFloat(trackTimeSubmoduleMovable.trackStartTime, trackTimeSubmoduleMovable.trackEndTime, 0, 1, AnimationCurveType.Linear)); + CommandManager.ExecuteCreate(() => + { + var a = TrackPercentPoint.GenerateElement("New Track Percent Point", Guid.NewGuid(), new List(), true, this, new FlexibleFloat()); + if (trackTimeSubmodule != null && trackTimeSubmodule is TrackTimeSubmoduleMovable trackTimeSubmoduleMovable) + a.trackPercent.Add( + new AnimatedFloat(trackTimeSubmoduleMovable.trackStartTime, trackTimeSubmoduleMovable.trackEndTime, 0, 1, AnimationCurveType.Linear)); + return a; + }); }) .Button("Track Head Point", () => { - TrackHeadPoint.GenerateElement("New Track Head Point", Guid.NewGuid(), new List(), true, this, false, Vector3.zero); + CommandManager.ExecuteCreate(() => TrackHeadPoint.GenerateElement("New Track Head Point", Guid.NewGuid(), new List(), true, this, false, Vector3.zero)); }) .EnabledIf(() => trackTimeSubmodule is TrackTimeSubmoduleMovable) - .Button("Tap", () => Tap.GenerateElement("New Tap", Guid.NewGuid(), new List(), true, this, 0f)) - .Button("Stay", () => Stay.GenerateElement("New Stay", Guid.NewGuid(), new List(), true, this, 0f)) - .Button("Hold", () => Hold.GenerateElement("New Hold", Guid.NewGuid(), new List(), true, this, 0f, 1f)) - .Button("Flick", () => Flick.GenerateElement("New Flick", Guid.NewGuid(), new List(), true, this, 0f, new List())) + .Button("Tap", () => CommandManager.ExecuteCreate(() => Tap.GenerateElement("New Tap", Guid.NewGuid(), new List(), true, this, 0f))) + .Button("Stay", () => CommandManager.ExecuteCreate(() => Stay.GenerateElement("New Stay", Guid.NewGuid(), new List(), true, this, 0f))) + .Button("Hold", () => CommandManager.ExecuteCreate(() => Hold.GenerateElement("New Hold", Guid.NewGuid(), new List(), true, this, 0f, 1f))) + .Button("Flick", () => CommandManager.ExecuteCreate(() => Flick.GenerateElement("New Flick", Guid.NewGuid(), new List(), true, this, 0f, new List()))) .Button("Particle Tracker", () => { - ParticleTracker.GenerateElement("New Particle Tracker", Guid.NewGuid(), new List(), true, this, - string.Empty, string.Empty, false, 0, 1, false, 10, Vector3.right, 10, 5, true, Vector3.zero); + CommandManager.ExecuteCreate(() => ParticleTracker.GenerateElement("New Particle Tracker", Guid.NewGuid(), new List(), true, this, + string.Empty, string.Empty, false, 0, 1, false, 10, Vector3.right, 10, 5, true, Vector3.zero)); }) .Button("Object Tracker", () => { - ObjectTracker.GenerateElement("New Object Tracker", Guid.NewGuid(), new List(), true, this, + CommandManager.ExecuteCreate(() => ObjectTracker.GenerateElement("New Object Tracker", Guid.NewGuid(), new List(), true, this, string.Empty, string.Empty, 10, Vector2.zero, Vector2.zero, string.Empty, false, Vector3.zero, Vector3.zero, string.Empty, - false, Vector3.zero, Vector3.zero, string.Empty); + false, Vector3.zero, Vector3.zero, string.Empty)); }) .Button("Track Global Color Change", () => { - TrackGlobalColorChange.GenerateElement("New Track Global Color Change", Guid.NewGuid(), new List(), true, this, - new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true)); + CommandManager.ExecuteCreate(() => TrackGlobalColorChange.GenerateElement("New Track Global Color Change", Guid.NewGuid(), new List(), true, this, + new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true))); }) .Build(); @@ -126,22 +131,44 @@ namespace Ichni.RhythmGame { IHaveInspection qcWindow = inspectorMain.GenerateSecondaryWindow(this, elementName + "'s Quick Copy"); var qcContainer = qcWindow.GenerateContainer(); - var qcSubcontainer = qcContainer.GenerateSubcontainer(3); - var xField = qcWindow.GenerateInputField(qcSubcontainer, "X offset", "0"); - var yField = qcWindow.GenerateInputField(qcSubcontainer, "Y offset", "0"); - var zField = qcWindow.GenerateInputField(qcSubcontainer, "Z offset", "0"); - var timeField = qcWindow.GenerateInputField(qcSubcontainer, "Time offset", "0"); - var iterationField = qcWindow.GenerateInputField(qcSubcontainer, "Iteration", "0"); - var includeAnimationToggle = qcWindow.GenerateToggle(null, qcSubcontainer, "Include Animation", string.Empty); - var movingTrackToggle = qcWindow.GenerateToggle(null, qcSubcontainer, "Moving Track or PathNode", string.Empty); - qcWindow.GenerateButton(this, qcSubcontainer, "Copy", () => + + // 位置偏移 + var posSub = qcContainer.GenerateSubcontainer(3); + var xField = qcWindow.GenerateInputField(posSub, "X offset", "0"); + var yField = qcWindow.GenerateInputField(posSub, "Y offset", "0"); + var zField = qcWindow.GenerateInputField(posSub, "Z offset", "0"); + + // 旋转偏移(欧拉角) + var rotSub = qcContainer.GenerateSubcontainer(3); + var rotXField = qcWindow.GenerateInputField(rotSub, "Rot X", "0"); + var rotYField = qcWindow.GenerateInputField(rotSub, "Rot Y", "0"); + var rotZField = qcWindow.GenerateInputField(rotSub, "Rot Z", "0"); + + // 缩放偏移 + var scaleSub = qcContainer.GenerateSubcontainer(3); + var scaleXField = qcWindow.GenerateInputField(scaleSub, "Scale X", "0"); + var scaleYField = qcWindow.GenerateInputField(scaleSub, "Scale Y", "0"); + var scaleZField = qcWindow.GenerateInputField(scaleSub, "Scale Z", "0"); + + // 时间 & 迭代 + var timeSub = qcContainer.GenerateSubcontainer(3); + var timeField = qcWindow.GenerateInputField(timeSub, "Time offset", "0"); + var iterationField = qcWindow.GenerateInputField(timeSub, "Iteration", "1"); + + // 选项 & 按钮 + var toggleSub = qcContainer.GenerateSubcontainer(3); + var includeAnimationToggle = qcWindow.GenerateToggle(null, toggleSub, "Include Animation", string.Empty); + var movingTrackToggle = qcWindow.GenerateToggle(null, toggleSub, "Move Track", string.Empty); + qcWindow.GenerateButton(this, toggleSub, "Copy", () => { Vector3 positionOffset = new Vector3(xField.GetValue(), yField.GetValue(), zField.GetValue()); + Vector3 rotationOffset = new Vector3(rotXField.GetValue(), rotYField.GetValue(), rotZField.GetValue()); + Vector3 scaleOffset = new Vector3(scaleXField.GetValue(), scaleYField.GetValue(), scaleZField.GetValue()); float timeOffset = timeField.GetValue(); int iteration = iterationField.GetValue(); bool includeAnimation = includeAnimationToggle.toggle.isOn; bool movingTrack = movingTrackToggle.toggle.isOn; - this.QuickCopy(positionOffset, timeOffset, includeAnimation, iteration, movingTrack); + this.QuickCopy(positionOffset, timeOffset, includeAnimation, iteration, movingTrack, rotationOffset, scaleOffset); }); }) .Button("Whole Track Move", () => @@ -198,7 +225,7 @@ namespace Ichni.RhythmGame .Span(3) .Button("Fast Note Tracker", () => { - FastNoteTracker.GenerateElement("Fast Note Tracker", Guid.NewGuid(), new List(), true, this); + CommandManager.ExecuteCreate(() => FastNoteTracker.GenerateElement("Fast Note Tracker", Guid.NewGuid(), new List(), true, this)); }) .Span(3) .Build(); @@ -225,7 +252,7 @@ namespace Ichni.RhythmGame return notes; } - + [Button("Check Notes")] public void checkNotes() { @@ -252,7 +279,7 @@ namespace Ichni.RhythmGame } } } - + [Button("Rebuild")] public void Rebuild() { diff --git a/Assets/Scripts/Manager/OperationManager.cs b/Assets/Scripts/Manager/OperationManager.cs index 9b78fece..b07e6e59 100644 --- a/Assets/Scripts/Manager/OperationManager.cs +++ b/Assets/Scripts/Manager/OperationManager.cs @@ -1,8 +1,9 @@ using System.Collections; -using System.Collections.Generic; -using System.Linq; -using Ichni.RhythmGame; -using Ichni.RhythmGame.Beatmap; +using System.Collections.Generic; +using System.Linq; +using Ichni.Editor.Commands; +using Ichni.RhythmGame; +using Ichni.RhythmGame.Beatmap; using UnityEngine; using UnityEngine.InputSystem; @@ -126,9 +127,9 @@ namespace Ichni.Editor copiedElement = gameElement; } - public void PasteElement(GameElement parentElement) - { - if (parentElement == null) + public void PasteElement(GameElement parentElement) + { + if (parentElement == null) { LogWindow.Log("No parent element selected to paste.", Color.red); return; @@ -137,44 +138,73 @@ namespace Ichni.Editor if (copiedElement == null) { LogWindow.Log("No element copied."); - return; - } - - LogWindow.Log("Pasted element: " + copiedElement.elementName + " to " + parentElement.elementName); - pastedElementList = new List(); - AffiliatedPaste(copiedElement, parentElement); - - // 粘贴完成后,对所有新生成的元素执行 AfterInitialize 和 Refresh, - // 与 EditorManager.LoadProject 的加载后流程对齐,确保 Manager 注册等关键步骤不遗漏。 + return; + } + + CommandManager.ExecuteCommand(new PasteElementCommand(this, copiedElement, parentElement)); + } + + public GameElement PasteElementRaw(GameElement sourceElement, GameElement parentElement) + { + if (sourceElement == null || parentElement == null) return null; + + LogWindow.Log("Pasted element: " + sourceElement.elementName + " to " + parentElement.elementName); + pastedElementList = new List(); + AffiliatedPaste(sourceElement, parentElement); + + // 粘贴完成后,对所有新生成的元素执行 AfterInitialize 和 Refresh, + // 与 EditorManager.LoadProject 的加载后流程对齐,确保 Manager 注册等关键步骤不遗漏。 foreach (GameElement pasted in pastedElementList) { if (pasted == null) continue; - pasted.AfterInitialize(); - pasted.Refresh(); - } - } - - public void DeleteElement(GameElement gameElement) + pasted.AfterInitialize(); + pasted.Refresh(); + } + + return pastedElementList.FirstOrDefault(); + } + + public void DeleteElement(GameElement gameElement) { if (gameElement == null) { LogWindow.Log("No element selected to delete.", Color.red); - return; - } - - LogWindow.Log("Deleted element: " + gameElement.elementName + " and all its children."); - - if (gameElement.parentElement != null) - { - gameElement.parentElement.childElementList.Remove(gameElement); //从父物体的子物体列表中移除,避免报null - gameElement.parentElement.connectedTab.childTabList.Remove(gameElement.connectedTab); - gameElement.parentElement.connectedTab.SetStatus(); - } - - EditorManager.instance.operationManager.RemoveSelectElement(gameElement); - gameElement.Delete(); - EditorManager.instance.uiManager.inspector.ClearInspector(); - } + return; + } + + CommandManager.ExecuteCommand(new DeleteElementCommand(gameElement)); + } + + public void DeleteElementRaw(GameElement gameElement, bool writeLog = true) + { + if (gameElement == null) return; + + var deletedElements = gameElement.GetAllGameElementsFromThis(); + var deletedGuids = deletedElements.Select(element => element.elementGuid).ToList(); + var deletedTabs = deletedElements + .Select(element => element.connectedTab) + .Where(tab => tab != null) + .ToList(); + + if (writeLog) + LogWindow.Log("Deleted element: " + gameElement.elementName + " and all its children."); + + if (gameElement.parentElement != null) + { + gameElement.parentElement.childElementList.Remove(gameElement); //从父物体的子物体列表中移除,避免报null + if (gameElement.parentElement.connectedTab != null) + { + gameElement.parentElement.connectedTab.childTabList.Remove(gameElement.connectedTab); + gameElement.parentElement.connectedTab.SetStatus(); + } + } + + EditorManager.instance.operationManager.RemoveSelectElement(gameElement); + gameElement.Delete(); + deletedGuids.ForEach(guid => GameElement_BM.identifier.Remove(guid)); + deletedTabs.ForEach(tab => EditorManager.instance.uiManager.hierarchy.tabList.Remove(tab)); + EditorManager.instance.uiManager.inspector.ClearInspector(); + } /// /// 使用递归的方式复制粘贴物体及其所有子物体 diff --git a/Assets/Scripts/Manager/ProjectManager.cs b/Assets/Scripts/Manager/ProjectManager.cs index 2a5e2e00..eff1284f 100644 --- a/Assets/Scripts/Manager/ProjectManager.cs +++ b/Assets/Scripts/Manager/ProjectManager.cs @@ -230,9 +230,15 @@ namespace Ichni public class BeatmapClipManager { + private string clipFolder => Application.streamingAssetsPath + "/Clips"; + private string GetClipPath(string clipName) => clipFolder + "/" + clipName + ".json"; + public void SaveClip(string clipName) { LogWindow.Log("Start Saving Clip..."); + clipName = clipName?.Trim(); + + if (!ValidateClipName(clipName)) return; if (EditorManager.instance.operationManager.currentSelectedElements.Count != 1) // TODO: 后续适应多选 { @@ -256,8 +262,11 @@ namespace Ichni public void LoadClip(string clipName) { LogWindow.Log("Start Loading Clip..."); + clipName = clipName?.Trim(); - if (!ES3.FileExists(Application.streamingAssetsPath + "/Clips/" + clipName + ".json")) + if (!ValidateClipName(clipName)) return; + + if (!ES3.FileExists(GetClipPath(clipName))) { LogWindow.Log("Clip not found", Color.red); return; @@ -278,9 +287,10 @@ namespace Ichni } Debug.Log(selectedElement.elementName + " " + selectedElement.elementGuid); - _LoadClip(selectedElement, clipName); - - LogWindow.Log("Load Clip Complete", Color.green); + if (_LoadClip(selectedElement, clipName)) + { + LogWindow.Log("Load Clip Complete", Color.green); + } } private void _SaveClip(GameElement element, string clipName) @@ -290,7 +300,8 @@ namespace Ichni element.GetAllGameElementsFromThis().ForEach(e => { e.SaveBM(); - clip.Add(e.matchedBM); + if (e.matchedBM != null) + clip.Add(e.matchedBM); e.submoduleList.ForEach(s => { s.SaveBM(); @@ -299,47 +310,59 @@ namespace Ichni }); }); - string filePath = Application.streamingAssetsPath + "/Clips/" + clipName + ".json"; + Directory.CreateDirectory(clipFolder); + string filePath = GetClipPath(clipName); ES3.Save("Clip", clip, filePath, ProjectManager.SaveSettings); } - private void _LoadClip(GameElement target, string clipName) + private bool _LoadClip(GameElement target, string clipName) { try { - string filePath = Application.streamingAssetsPath + "/Clips/" + clipName + ".json"; + string filePath = GetClipPath(clipName); List clip = ES3.Load>("Clip", filePath, ProjectManager.SaveSettings); if (clip == null || clip.Count == 0) { Debug.LogError("Clip is empty or null"); - return; + LogWindow.Log("Clip is empty or null", Color.red); + return false; } // 验证第一个元素 if (!(clip[0] is GameElement_BM first)) { Debug.LogError("First element is not a GameElement_BM"); - return; + LogWindow.Log("First element is not a GameElement_BM", Color.red); + return false; } // 处理目标对象 - 添加清理机制 target.SaveBM(); + if (target.matchedBM is not GameElement_BM targetBM) + { + LogWindow.Log("Load Clip failed: target did not create a valid BM.", Color.red); + return false; + } + bool targetAdded = GameElement_BM.identifier.TryAdd(target.elementGuid, target.matchedBM as GameElement_BM); if (!targetAdded) { Debug.LogWarning("Target element already exists in identifier dictionary"); } + targetBM.matchedElement = target; + + List loadedElements = new List(); // 处理第一个元素及其附加元素 - ProcessGameElement(first, clip, target.elementGuid); + if (!ProcessGameElement(first, clip, target.elementGuid, loadedElements)) return false; // 处理后续元素 for (var index = 1; index < clip.Count; index++) { if (clip[index] is GameElement_BM gameElement) { - ProcessGameElement(gameElement, clip, null); + if (!ProcessGameElement(gameElement, clip, null, loadedElements)) return false; } else { @@ -348,14 +371,28 @@ namespace Ichni } } + EditorManager.instance.beatmapContainer.ExecuteLowPriorityActions(); + loadedElements.ForEach(element => + { + if (element == null) return; + element.AfterInitialize(); + element.Refresh(); + }); + return true; } catch (Exception ex) { Debug.LogError($"Failed to load clip: {ex.Message}"); + LogWindow.Log("Failed to load clip: " + ex.Message, Color.red); + return false; } } - private void ProcessGameElement(GameElement_BM gameElement, List clip, Guid? attachToGuid) + private bool ProcessGameElement( + GameElement_BM gameElement, + List clip, + Guid? attachToGuid, + List loadedElements) { List attachedElements = GameElement_BM.GetAllAttachedBaseElements(gameElement, clip); @@ -365,7 +402,8 @@ namespace Ichni if (!elementAdded) { Debug.LogError($"Failed to add element with GUID: {gameElement.elementGuid}"); - return; + LogWindow.Log("Failed to add clip element: " + gameElement.elementName, Color.red); + return false; } // 更新附加元素 @@ -381,7 +419,31 @@ namespace Ichni } gameElement.ExecuteBM(); + if (gameElement.matchedElement == null) + { + LogWindow.Log("Failed to generate clip element: " + gameElement.elementName, Color.red); + return false; + } + loadedElements.Add(gameElement.matchedElement); + return true; + } + + private bool ValidateClipName(string clipName) + { + if (string.IsNullOrWhiteSpace(clipName)) + { + LogWindow.Log("Clip name cannot be empty.", Color.red); + return false; + } + + if (clipName.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0) + { + LogWindow.Log("Clip name contains invalid characters.", Color.red); + return false; + } + + return true; } } diff --git a/Assets/StreamingAssets/Clips/p5.json b/Assets/StreamingAssets/Clips/p5.json new file mode 100644 index 00000000..b38c041f --- /dev/null +++ b/Assets/StreamingAssets/Clips/p5.json @@ -0,0 +1,692 @@ +{ + "Clip" : { + "__type" : "System.Collections.Generic.List`1[[Ichni.RhythmGame.Beatmap.BaseElement_BM, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]],mscorlib", + "value" : [ + { + "__type" : "Ichni.RhythmGame.Beatmap.ElementFolder_BM,Assembly-CSharp", + "elementName" : "p5", + "tags" : [ + + ], + "elementGuid" : { + "value" : "a9b243b4-13cb-45eb-842b-b523ee1f97f7" + }, + "attachedElementGuid" : { + "value" : "00000000-0000-0000-0000-000000000000" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TransformSubmodule_BM,Assembly-CSharp", + "originalPosition" : { + "x" : 100, + "y" : 24, + "z" : 6592.9 + }, + "originalEulerAngles" : { + "x" : 27.9, + "y" : 25, + "z" : 0 + }, + "originalScale" : { + "x" : 1, + "y" : 1, + "z" : 1 + }, + "attachedElementGuid" : { + "value" : "a9b243b4-13cb-45eb-842b-b523ee1f97f7" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TimeDurationSubmodule_BM,Assembly-CSharp", + "isOverridingDuration" : false, + "startTime" : -32767, + "endTime" : 32767, + "attachedElementGuid" : { + "value" : "a9b243b4-13cb-45eb-842b-b523ee1f97f7" + } + },{ + "__type" : "Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap.DTMCircleSpinTrails_BM,Assembly-CSharp", + "particleCount" : 12, + "particleLifetime" : 7, + "colorGradient" : { + "colorKeys" : [ + { + "color" : { + "r" : 0.4, + "g" : 0, + "b" : 1, + "a" : 1 + }, + "time" : 1 + },{ + "color" : { + "r" : 0, + "g" : 0, + "b" : 1, + "a" : 1 + }, + "time" : 1 + } + ], + "alphaKeys" : [ + { + "alpha" : 1, + "time" : 0 + },{ + "alpha" : 1, + "time" : 1 + } + ], + "mode" : 0 + }, + "orbitalZSpeed" : 0, + "emissionIntensity" : -10, + "isStatic" : false, + "themeBundleName" : "departure_to_multiverse", + "objectName" : "DTM_CircleSpinTrails", + "elementName" : "New Environment Object", + "tags" : [ + + ], + "elementGuid" : { + "value" : "dca41628-256f-48b8-afae-d337c7f9fa4a" + }, + "attachedElementGuid" : { + "value" : "a9b243b4-13cb-45eb-842b-b523ee1f97f7" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TransformSubmodule_BM,Assembly-CSharp", + "originalPosition" : { + "x" : 0, + "y" : 120, + "z" : 0 + }, + "originalEulerAngles" : { + "x" : 0, + "y" : 0, + "z" : 0 + }, + "originalScale" : { + "x" : 100, + "y" : 100, + "z" : 1 + }, + "attachedElementGuid" : { + "value" : "dca41628-256f-48b8-afae-d337c7f9fa4a" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TimeDurationSubmodule_BM,Assembly-CSharp", + "isOverridingDuration" : false, + "startTime" : -32767, + "endTime" : 32767, + "attachedElementGuid" : { + "value" : "dca41628-256f-48b8-afae-d337c7f9fa4a" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.ColorSubmodule_BM,Assembly-CSharp", + "originalBaseColor" : { + "r" : 1, + "g" : 1, + "b" : 1, + "a" : 1 + }, + "emissionEnabled" : false, + "originalEmissionColor" : { + "r" : 0, + "g" : 0, + "b" : 0, + "a" : 1 + }, + "originalEmissionIntensity" : 0, + "attachedElementGuid" : { + "value" : "dca41628-256f-48b8-afae-d337c7f9fa4a" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.PropertyAnimationFloat_BM,Assembly-CSharp", + "componentName" : "Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.DTMCircleSpinTrails", + "propertyName" : "particleLifetime", + "propertyValue" : { + "animatedFloatList" : [ + { + "startValue" : 7, + "endValue" : 7, + "startTime" : 0, + "endTime" : 0.3300003, + "animationCurveType" : 0 + },{ + "startValue" : 7, + "endValue" : 7, + "startTime" : 95.7001, + "endTime" : 96.03009, + "animationCurveType" : 0 + } + ] + }, + "elementName" : "New Property Animation Float", + "tags" : [ + + ], + "elementGuid" : { + "value" : "dcfa7e41-d664-4c12-964d-6b9e6fe3ffa3" + }, + "attachedElementGuid" : { + "value" : "dca41628-256f-48b8-afae-d337c7f9fa4a" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TimeDurationSubmodule_BM,Assembly-CSharp", + "isOverridingDuration" : false, + "startTime" : -32767, + "endTime" : 32767, + "attachedElementGuid" : { + "value" : "dcfa7e41-d664-4c12-964d-6b9e6fe3ffa3" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.PropertyAnimationFloat_BM,Assembly-CSharp", + "componentName" : "Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.DTMCircleSpinTrails", + "propertyName" : "orbitalZSpeed", + "propertyValue" : { + "animatedFloatList" : [ + { + "startValue" : 0, + "endValue" : 0, + "startTime" : 0, + "endTime" : 1, + "animationCurveType" : 0 + },{ + "startValue" : 5, + "endValue" : 0, + "startTime" : 95.3701, + "endTime" : 96.0301, + "animationCurveType" : 0 + },{ + "startValue" : 5, + "endValue" : 0, + "startTime" : 96.3601, + "endTime" : 97.0200958, + "animationCurveType" : 0 + },{ + "startValue" : 5, + "endValue" : 0, + "startTime" : 97.3501, + "endTime" : 98.01009, + "animationCurveType" : 0 + },{ + "startValue" : 0, + "endValue" : 2, + "startTime" : 98.3401, + "endTime" : 99.3301, + "animationCurveType" : 0 + } + ] + }, + "elementName" : "New Property Animation Float", + "tags" : [ + + ], + "elementGuid" : { + "value" : "b8444120-d9a1-43bf-8956-d4f4f495ede7" + }, + "attachedElementGuid" : { + "value" : "dca41628-256f-48b8-afae-d337c7f9fa4a" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TimeDurationSubmodule_BM,Assembly-CSharp", + "isOverridingDuration" : false, + "startTime" : -32767, + "endTime" : 32767, + "attachedElementGuid" : { + "value" : "b8444120-d9a1-43bf-8956-d4f4f495ede7" + } + },{ + "__type" : "Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap.DTMCircleSpinTrails_BM,Assembly-CSharp", + "particleCount" : 12, + "particleLifetime" : 7, + "colorGradient" : { + "colorKeys" : [ + { + "color" : { + "r" : 0, + "g" : 1, + "b" : 1, + "a" : 1 + }, + "time" : 1 + },{ + "color" : { + "r" : 0, + "g" : 1, + "b" : 1, + "a" : 1 + }, + "time" : 1 + } + ], + "alphaKeys" : [ + { + "alpha" : 1, + "time" : 0 + },{ + "alpha" : 1, + "time" : 1 + } + ], + "mode" : 0 + }, + "orbitalZSpeed" : 0, + "emissionIntensity" : -100, + "isStatic" : false, + "themeBundleName" : "departure_to_multiverse", + "objectName" : "DTM_CircleSpinTrails", + "elementName" : "New Environment Object", + "tags" : [ + + ], + "elementGuid" : { + "value" : "87c781ae-eb58-413c-82aa-b203b783eb80" + }, + "attachedElementGuid" : { + "value" : "a9b243b4-13cb-45eb-842b-b523ee1f97f7" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TransformSubmodule_BM,Assembly-CSharp", + "originalPosition" : { + "x" : 0, + "y" : 120, + "z" : 0 + }, + "originalEulerAngles" : { + "x" : 0, + "y" : 0, + "z" : 0 + }, + "originalScale" : { + "x" : 100, + "y" : 100, + "z" : 1 + }, + "attachedElementGuid" : { + "value" : "87c781ae-eb58-413c-82aa-b203b783eb80" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TimeDurationSubmodule_BM,Assembly-CSharp", + "isOverridingDuration" : false, + "startTime" : -32767, + "endTime" : 32767, + "attachedElementGuid" : { + "value" : "87c781ae-eb58-413c-82aa-b203b783eb80" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.ColorSubmodule_BM,Assembly-CSharp", + "originalBaseColor" : { + "r" : 1, + "g" : 1, + "b" : 1, + "a" : 1 + }, + "emissionEnabled" : false, + "originalEmissionColor" : { + "r" : 0, + "g" : 0, + "b" : 0, + "a" : 1 + }, + "originalEmissionIntensity" : 0, + "attachedElementGuid" : { + "value" : "87c781ae-eb58-413c-82aa-b203b783eb80" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.PropertyAnimationFloat_BM,Assembly-CSharp", + "componentName" : "Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.DTMCircleSpinTrails", + "propertyName" : "particleLifetime", + "propertyValue" : { + "animatedFloatList" : [ + { + "startValue" : 7, + "endValue" : 7, + "startTime" : 0, + "endTime" : 0.3300003, + "animationCurveType" : 0 + },{ + "startValue" : 7, + "endValue" : 7, + "startTime" : 95.7001, + "endTime" : 96.03009, + "animationCurveType" : 0 + } + ] + }, + "elementName" : "New Property Animation Float", + "tags" : [ + + ], + "elementGuid" : { + "value" : "ccd883ad-d1e1-4f11-bbca-3cc87fabb994" + }, + "attachedElementGuid" : { + "value" : "87c781ae-eb58-413c-82aa-b203b783eb80" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TimeDurationSubmodule_BM,Assembly-CSharp", + "isOverridingDuration" : false, + "startTime" : -32767, + "endTime" : 32767, + "attachedElementGuid" : { + "value" : "ccd883ad-d1e1-4f11-bbca-3cc87fabb994" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.PropertyAnimationFloat_BM,Assembly-CSharp", + "componentName" : "Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.DTMCircleSpinTrails", + "propertyName" : "orbitalZSpeed", + "propertyValue" : { + "animatedFloatList" : [ + { + "startValue" : 0, + "endValue" : 0, + "startTime" : 0, + "endTime" : 1, + "animationCurveType" : 0 + },{ + "startValue" : 5, + "endValue" : 0, + "startTime" : 95.3701, + "endTime" : 96.0301, + "animationCurveType" : 0 + },{ + "startValue" : 5, + "endValue" : 0, + "startTime" : 96.3601, + "endTime" : 97.0201, + "animationCurveType" : 0 + },{ + "startValue" : 5, + "endValue" : 0, + "startTime" : 97.3501, + "endTime" : 98.01009, + "animationCurveType" : 0 + },{ + "startValue" : 0, + "endValue" : 1.5, + "startTime" : 98.3401, + "endTime" : 99.3301, + "animationCurveType" : 0 + } + ] + }, + "elementName" : "New Property Animation Float", + "tags" : [ + + ], + "elementGuid" : { + "value" : "33182b59-d291-4b17-9eda-b1f26557812c" + }, + "attachedElementGuid" : { + "value" : "87c781ae-eb58-413c-82aa-b203b783eb80" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TimeDurationSubmodule_BM,Assembly-CSharp", + "isOverridingDuration" : false, + "startTime" : -32767, + "endTime" : 32767, + "attachedElementGuid" : { + "value" : "33182b59-d291-4b17-9eda-b1f26557812c" + } + },{ + "__type" : "Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap.DTMCircleSpinTrails_BM,Assembly-CSharp", + "particleCount" : 45, + "particleLifetime" : 7, + "colorGradient" : { + "colorKeys" : [ + { + "color" : { + "r" : 1, + "g" : 1, + "b" : 1, + "a" : 1 + }, + "time" : 1 + },{ + "color" : { + "r" : 1, + "g" : 1, + "b" : 1, + "a" : 1 + }, + "time" : 1 + } + ], + "alphaKeys" : [ + { + "alpha" : 1, + "time" : 0 + },{ + "alpha" : 1, + "time" : 1 + } + ], + "mode" : 0 + }, + "orbitalZSpeed" : 0, + "emissionIntensity" : -94.8275452, + "isStatic" : false, + "themeBundleName" : "departure_to_multiverse", + "objectName" : "DTM_CircleSpinTrails", + "elementName" : "New Environment Object", + "tags" : [ + + ], + "elementGuid" : { + "value" : "a831833a-becc-495e-876a-2c3d22154de6" + }, + "attachedElementGuid" : { + "value" : "a9b243b4-13cb-45eb-842b-b523ee1f97f7" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TransformSubmodule_BM,Assembly-CSharp", + "originalPosition" : { + "x" : 0, + "y" : 120, + "z" : 0 + }, + "originalEulerAngles" : { + "x" : 0, + "y" : 0, + "z" : 0 + }, + "originalScale" : { + "x" : 500, + "y" : 500, + "z" : 1 + }, + "attachedElementGuid" : { + "value" : "a831833a-becc-495e-876a-2c3d22154de6" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TimeDurationSubmodule_BM,Assembly-CSharp", + "isOverridingDuration" : false, + "startTime" : -32767, + "endTime" : 32767, + "attachedElementGuid" : { + "value" : "a831833a-becc-495e-876a-2c3d22154de6" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.ColorSubmodule_BM,Assembly-CSharp", + "originalBaseColor" : { + "r" : 1, + "g" : 1, + "b" : 1, + "a" : 1 + }, + "emissionEnabled" : false, + "originalEmissionColor" : { + "r" : 0, + "g" : 0, + "b" : 0, + "a" : 1 + }, + "originalEmissionIntensity" : 0, + "attachedElementGuid" : { + "value" : "a831833a-becc-495e-876a-2c3d22154de6" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.PropertyAnimationFloat_BM,Assembly-CSharp", + "componentName" : "Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.DTMCircleSpinTrails", + "propertyName" : "particleLifetime", + "propertyValue" : { + "animatedFloatList" : [ + { + "startValue" : 7, + "endValue" : 7, + "startTime" : 0, + "endTime" : 0.3300003, + "animationCurveType" : 0 + },{ + "startValue" : 7, + "endValue" : 7, + "startTime" : 95.7001, + "endTime" : 96.03009, + "animationCurveType" : 0 + } + ] + }, + "elementName" : "New Property Animation Float", + "tags" : [ + + ], + "elementGuid" : { + "value" : "ce56385d-2285-4507-a467-94ee7ad5a3c5" + }, + "attachedElementGuid" : { + "value" : "a831833a-becc-495e-876a-2c3d22154de6" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TimeDurationSubmodule_BM,Assembly-CSharp", + "isOverridingDuration" : false, + "startTime" : -32767, + "endTime" : 32767, + "attachedElementGuid" : { + "value" : "ce56385d-2285-4507-a467-94ee7ad5a3c5" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.PropertyAnimationFloat_BM,Assembly-CSharp", + "componentName" : "Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.DTMCircleSpinTrails", + "propertyName" : "orbitalZSpeed", + "propertyValue" : { + "animatedFloatList" : [ + { + "startValue" : 0, + "endValue" : 0, + "startTime" : 0, + "endTime" : 1, + "animationCurveType" : 0 + },{ + "startValue" : 5, + "endValue" : 0, + "startTime" : 95.3701, + "endTime" : 96.0301, + "animationCurveType" : 0 + },{ + "startValue" : 5, + "endValue" : 0, + "startTime" : 96.3601, + "endTime" : 97.0201, + "animationCurveType" : 0 + },{ + "startValue" : 5, + "endValue" : 0, + "startTime" : 97.3501, + "endTime" : 98.01009, + "animationCurveType" : 0 + },{ + "startValue" : 0, + "endValue" : 0.5, + "startTime" : 98.3401, + "endTime" : 99.3301, + "animationCurveType" : 0 + } + ] + }, + "elementName" : "New Property Animation Float", + "tags" : [ + + ], + "elementGuid" : { + "value" : "6b8b26d0-4f89-4164-b5f8-26cfd8a5c822" + }, + "attachedElementGuid" : { + "value" : "a831833a-becc-495e-876a-2c3d22154de6" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TimeDurationSubmodule_BM,Assembly-CSharp", + "isOverridingDuration" : false, + "startTime" : -32767, + "endTime" : 32767, + "attachedElementGuid" : { + "value" : "6b8b26d0-4f89-4164-b5f8-26cfd8a5c822" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.Displacement_BM,Assembly-CSharp", + "positionX" : { + "animatedFloatList" : [ + { + "startValue" : 0, + "endValue" : 0, + "startTime" : 0, + "endTime" : 1, + "animationCurveType" : 0 + } + ] + }, + "positionY" : { + "animatedFloatList" : [ + { + "startValue" : 0, + "endValue" : 0, + "startTime" : 0, + "endTime" : 1, + "animationCurveType" : 0 + } + ] + }, + "positionZ" : { + "animatedFloatList" : [ + { + "startValue" : 0, + "endValue" : 0, + "startTime" : 0, + "endTime" : 1, + "animationCurveType" : 0 + },{ + "startValue" : 0, + "endValue" : 290, + "startTime" : 98.3401, + "endTime" : 99.33, + "animationCurveType" : 0 + },{ + "startValue" : 290, + "endValue" : 2315, + "startTime" : 99.33, + "endTime" : 131.01, + "animationCurveType" : 0 + } + ] + }, + "elementName" : "New Displacement", + "tags" : [ + + ], + "elementGuid" : { + "value" : "3130f797-6121-4900-9d5c-cb2f71dc2943" + }, + "attachedElementGuid" : { + "value" : "a9b243b4-13cb-45eb-842b-b523ee1f97f7" + } + },{ + "__type" : "Ichni.RhythmGame.Beatmap.TimeDurationSubmodule_BM,Assembly-CSharp", + "isOverridingDuration" : false, + "startTime" : -32767, + "endTime" : 32767, + "attachedElementGuid" : { + "value" : "3130f797-6121-4900-9d5c-cb2f71dc2943" + } + } + ] + } +} \ No newline at end of file diff --git a/Assets/StreamingAssets/Clips/p5.json.meta b/Assets/StreamingAssets/Clips/p5.json.meta new file mode 100644 index 00000000..e845d074 --- /dev/null +++ b/Assets/StreamingAssets/Clips/p5.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f743f8f91400ea04097346d48e479fd8 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: