using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Runtime.InteropServices; using DG.Tweening; using Ichni.RhythmGame.Beatmap; using TMPro; using UniRx; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; using UnityEngine.UI; namespace Ichni.StartMenu { public partial class CreateEmptyProjectPage : StartMenuPage { public TMP_InputField projectNameInputField, creatorNameInputField, bpmInputField, songLocationInputField, delayInputField; public Button selectSongButton, autoFillSongPathButton; public Button createEmptyProjectButton; private OpenFileName songFile; public string songName; public ThemeBundleSelector themeBundleSelector; public AsyncOperation loadEditor; private void Start() { loadEditor = SceneManager.LoadSceneAsync("EditorScene"); loadEditor.allowSceneActivation = false; } private void Update() { if (canvasGroup.interactable && Keyboard.current.escapeKey.wasPressedThisFrame) { fadeOut.Restart(); } } private void CreateEmptyProject() { string projectPath = Application.streamingAssetsPath + "/Projects/" + projectNameInputField.text; //Create project folder if (!Directory.Exists(projectPath)) { Directory.CreateDirectory(projectPath); } InformationTransistor.instance.projectInfo_BM = new ProjectInformation_BM( projectNameInputField.text, creatorNameInputField.text, "0.1.0", DateTime.Now.ToString(CultureInfo.CurrentCulture), DateTime.Now.ToString(CultureInfo.CurrentCulture), themeBundleSelector.GetSelectedThemeBundleList()); File.Copy(songLocationInputField.text, Application.streamingAssetsPath + "/Projects/" + projectNameInputField.text + "/" + songName, true); InformationTransistor.instance.songInfo_BM = new SongInformation_BM( songName, float.Parse(bpmInputField.text), float.Parse(delayInputField.text), 0 ); InformationTransistor.instance.isLoadedProject = false; //Load ThemeBundles, then go to EditorScene ThemeBundleManager.instance.LoadThemeBundles(InformationTransistor.instance.projectInfo_BM.selectedThemeBundleList); ThemeBundleManager.instance.waitingBundleAmount .Where(amount => amount == 0) // 当 waitingAmount 变为 0 时触发 .First() .Subscribe(_ => { Debug.Log("All AssetBundles are loaded. Switching scene."); loadEditor.allowSceneActivation = true; }).AddTo(this); } } public partial class CreateEmptyProjectPage { protected override void InitializeAnimations() { fadeIn = DOTween.Sequence(); fadeOut = DOTween.Sequence(); fadeIn.Join(canvasGroup.DOFade(1f, 0.5f)) .SetEase(Ease.InOutQuad) .SetAutoKill(false) .OnComplete(() => { canvasGroup.interactable = true; canvasGroup.blocksRaycasts = true; }).Pause(); fadeOut.Join(canvasGroup.DOFade(0f, 0.5f)) .SetEase(Ease.InOutQuad) .SetAutoKill(false) .OnPlay(() => { canvasGroup.interactable = false; canvasGroup.blocksRaycasts = false; }) .OnComplete(() => { StartMenuManager.instance.startPage.fadeIn.Restart(); }) .Pause(); } protected override void InitializeUI() { songLocationInputField.onEndEdit.AddListener((str) => { string fullPath = Path.GetFullPath(str); songName = Path.GetFileName(fullPath); }); selectSongButton.onClick.AddListener(SelectSong); autoFillSongPathButton.onClick.AddListener(AutoFillSongPath); createEmptyProjectButton.onClick.AddListener(CreateEmptyProject); } private void AutoFillSongPath() { string path = Application.streamingAssetsPath + "/Songs/"; songLocationInputField.text = path; } private void SelectSong() { songFile = new OpenFileName(); songFile.structSize = Marshal.SizeOf(songFile); songFile.filter = "Music Files (*.wav;*.mp3;*.ogg)\0*.wav;*.mp3;*.ogg\0\0"; songFile.file = new string(new char[256]); songFile.maxFile = songFile.file.Length; songFile.fileTitle = new string(new char[64]); songFile.maxFileTitle = songFile.fileTitle.Length; songFile.initialDir = Application.streamingAssetsPath.Replace('/', '\\');//默认路径 songFile.title = "Select A Song"; songFile.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000008; if (LocalDialog.GetOpenFileName(songFile) && songFile.file != "") { songName = Path.GetFileName(songFile.file); songLocationInputField.text = Path.GetFullPath(songFile.file); } } } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public class OpenFileName { public int structSize = 0; public IntPtr dlgOwner = IntPtr.Zero; public IntPtr instance = IntPtr.Zero; public string filter = null; public string customFilter = null; public int maxCustFilter = 0; public int filterIndex = 0; public string file = null; public int maxFile = 0; public string fileTitle = null; public int maxFileTitle = 0; public string initialDir = null; public string title = null; public int flags = 0; public short fileOffset = 0; public short fileExtension = 0; public string defExt = null; public IntPtr custData = IntPtr.Zero; public IntPtr hook = IntPtr.Zero; public string templateName = null; public IntPtr reservedPtr = IntPtr.Zero; public int reservedInt = 0; public int flagsEx = 0; } public static class LocalDialog { [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)] public static extern bool GetOpenFileName([In, Out] OpenFileName ofn); public static bool GetOFN([In, Out] OpenFileName ofn) { return GetOpenFileName(ofn); } [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)] public static extern bool GetSaveFileName([In, Out] OpenFileName ofn); public static bool GetSFN([In, Out] OpenFileName ofn) { return GetSaveFileName(ofn); } } }