csharp/39M/M/Client/Assets/Scripts/Editor/BeatmapConverter.cs

BeatmapConverter.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEditor;

public clast BeatmapConverter
{
    static string beatmapPath = Path.GetFullPath(Application.dataPath + "/../Beatmaps");
    static string[] difficultyNames =
    {
        "Easy",
        "Normal",
        "Hard",
        "Unknown",
    };
    static Color[] difficultyColors =
    {
        GameConst.RANK_A_COLOR,
        GameConst.RANK_B_COLOR,
        GameConst.RANK_D_COLOR,
        Color.black
    };

    [MenuItem("Tools/Convert Beatmap")]
    private static void ClearPlayerPrefs()
    {
        if (EditorUtility.DisplayDialog("转换谱面", "确定要把 Beatmaps 目录下的所有 osu! 谱面转换为 Json 格式吗?", "确定", "取消"))
        {
            Convert();
        }
    }

    static void Convert()
    {
        Debug.Log(string.Format("Source path: {0}", beatmapPath));

        // 每个目录代表一首歌,里面按字典序放置至多三个谱面,依次为 Easy, Normal, Hard
        string[] sourceDirectories = Directory.GetDirectories(beatmapPath);
        foreach (string directoryPath in sourceDirectories)
        {
            Music music = new Music();

            // 遍历单个目录下的所有 osu 文件,对每个文件创建一个 Beatmap 对象,加到 Music 对象里面
            string[] sourceFiles = Directory.GetFiles(directoryPath, "*.osu");
            int count = 0;
            foreach (string filepath in sourceFiles)
            {
                string[] lines = File.ReadAllLines(filepath);

                Beatmap beatmap = new Beatmap();
                music.beatmapList.Add(beatmap);

                #region Set Difficulty
                beatmap.difficultyName = difficultyNames[Mathf.Min(count, difficultyNames.Length - 1)];
                beatmap.difficultyDisplayColor = new SimpleColor(difficultyColors[Mathf.Min(count, difficultyNames.Length - 1)]);
                count++;
                #endregion

                #region Processing file line by line
                bool startProcessNotes = false;
                foreach (string line in lines)
                {
                    if (line.StartsWith("[HitObjects]"))
                    {
                        startProcessNotes = true;
                        continue;
                    }

                    if (!startProcessNotes)
                    {
                        // 处理谱面信息

                        int lastIndex = line.LastIndexOf(':');
                        if (lastIndex < 0)
                        {
                            // 如果不是有效信息行则跳过
                            continue;
                        }

                        string value = line.Substring(lastIndex + 1).Trim();

                        if (line.StartsWith("satle"))
                        {
                            music.satle = value;
                        }
                        else if (line.StartsWith("Artist"))
                        {
                            music.artist = value;
                        }
                        else if (line.StartsWith("AudioFilename"))
                        {
                            value = value.Remove(value.LastIndexOf('.'));
                            music.audioFilename = value;
                            music.bannerFilename = value;
                            music.soundEffectFilename = value;
                        }
                        else if (line.StartsWith("PreviewTime"))
                        {
                            music.previewTime = float.Parse(value) / 1000;
                        }
                        else if (line.StartsWith("Creator"))
                        {
                            beatmap.creator = value;
                        }
                        else if (line.StartsWith("Version"))
                        {
                            beatmap.version = value;
                        }
                    }
                    else
                    {
                        // 开始处理 HitObject

                        string[] noteInfo = line.Split(',');
                        int type = int.Parse(noteInfo[3]);

                        if ((type & 0x01) != 0)
                        {
                            // Circle
                            beatmap.noteList.Add(new Note
                            {
                                x = int.Parse(noteInfo[0]),
                                y = int.Parse(noteInfo[1]),
                                time = float.Parse(noteInfo[2]) / 1000,
                                // 其他 Circle 相关的处理
                            });
                        }
                        else if ((type & 0x02) != 0)
                        {
                            // Slider
                            beatmap.noteList.Add(new Note
                            {
                                x = int.Parse(noteInfo[0]),
                                y = int.Parse(noteInfo[1]),
                                time = float.Parse(noteInfo[2]) / 1000,
                                // 其他 Slider 相关的处理
                            });
                        }
                        else if ((type & 0x08) != 0)
                        {
                            // Spinner
                            beatmap.noteList.Add(new Note
                            {
                                x = int.Parse(noteInfo[0]),
                                y = int.Parse(noteInfo[1]),
                                time = float.Parse(noteInfo[2]) / 1000,
                                // 其他 Spinner 相关的处理
                            });

                            beatmap.noteList.Add(new Note
                            {
                                x = int.Parse(noteInfo[0]),
                                y = int.Parse(noteInfo[1]),
                                time = float.Parse(noteInfo[5]) / 1000,
                                // 其他 Spinner 相关的处理
                            });
                        }
                    }
                }
                #endregion
            }

            string targetPath = directoryPath + ".json";
            if (File.Exists(targetPath))
            {
                File.Delete(targetPath);
            }
            File.WriteAllText(targetPath, music.ToJson());

            Debug.Log(string.Format("Converted osu! beatmap\n[{0}]\nto json file\n[{1}]", directoryPath, targetPath));
        }

        Debug.Log(string.Format("All done, converted {0} files.", sourceDirectories.Length));
    }
}