예제 #1
0
        protected virtual TChartEntity Convert(ChartJsonData chartJsonData, TChartEntity chart)
        {
            chart.AudioSource = chartJsonData.AudioSource.Split('.')[0];
            chart.StartTime   = chartJsonData.StartTime;
            chart.Difficulty  = (TChartDifficulty)Enum.ToObject(typeof(TChartDifficulty), chartJsonData.Difficulty);

            // bpm changes
            var bpmChanges = new List <(float bpm, float position)>();

            bpmChanges.AddRange(chartJsonData.Timeline.OtherObjects.Where(o => o.type == (int)OtherObjectType.Bpm)
                                .Select(bpmChangeJsonData => (float.Parse(bpmChangeJsonData.value),
                                                              position: bpmChangeJsonData.measureIndex + bpmChangeJsonData.measurePosition.To01())));

            // speed changes
            chart.SpeedChanges = new List <SpeedChangeEntity>();
            foreach (var speedChange in chartJsonData.Timeline.OtherObjects.Where(o =>
                                                                                  o.type == (int)OtherObjectType.Speed))
            {
                chart.SpeedChanges.Add(new SpeedChangeEntity(speedChange));
            }

            // カスタムオブジェクト
            chart.OtherObjects = new List <OtherObjectEntity>();
            foreach (var jsonData in chartJsonData.Timeline.OtherObjects.Where(
                         o => o.type >= (int)OtherObjectType.Other))
            {
                chart.OtherObjects.Add(new OtherObjectEntity(jsonData));
            }

            chart.BpmChanges = new List <BpmChangeEntity>();

            var sortedBpmChanges = bpmChanges.OrderBy(bpmChange => bpmChange.position).ToList();

            // 最終 BPM を譜面の最後に配置する
            sortedBpmChanges.Add((sortedBpmChanges.Last().bpm, position: 1000f));

            // BPM の区間を計算する
            var beginTime = 0f;

            for (var i = 0; i < sortedBpmChanges.Count - 1; i++)
            {
                var begin = sortedBpmChanges[i];
                var end   = sortedBpmChanges[i + 1];

                // 1 小節の時間
                var unitTime = (60f / begin.bpm) * 4;

                var beginMeasureIndex = Mathf.FloorToInt(begin.position);
                var endMeasureIndex   = Mathf.FloorToInt(end.position);

                for (var measureIndex = beginMeasureIndex; measureIndex < endMeasureIndex; measureIndex++)
                {
                    var tempo = 1f;

                    if (chartJsonData.Timeline.Measures != null)
                    {
                        var tempoJsonData =
                            chartJsonData.Timeline.Measures.FirstOrDefault(a => a.index == measureIndex);

                        tempo = tempoJsonData == null ? 1f : tempoJsonData.beat.To01();
                    }

                    // 区間の秒数
                    var time = unitTime * tempo;

                    chart.BpmChanges.Add(new BpmChangeEntity
                    {
                        BeginPosition = measureIndex,
                        EndPosition   = measureIndex + 1,
                        BeginTime     = beginTime,
                        Duration      = time
                    });

                    beginTime += time;
                }
            }

            var noteGuidMap = new Dictionary <Guid, TNoteEntity>();

            // ノートを生成する
            chart.Notes = new List <TNoteEntity>();
            foreach (var noteJsonData in chartJsonData.Timeline.Notes)
            {
                // ノートの小節位置
                var noteMeasurePosition = noteJsonData.measureIndex + noteJsonData.measurePosition.To01();

                // 判定時間を取得する
                var judgeTime = chart.BpmChanges.Find(bpmRange => bpmRange.Between(noteMeasurePosition))
                                .GetJudgeTime(noteMeasurePosition);

                var note = ScriptableObject.CreateInstance <TNoteEntity>();
                note.Initialize(noteJsonData, judgeTime);
                note.name = $"note_{noteJsonData.guid}";

                noteGuidMap[noteJsonData.guid] = note;

                chart.Notes.Add(note);
            }

            // ノートラインを生成する
            chart.NoteLines = new List <TNoteLineEntity>();
            foreach (var noteLineJsonData in chartJsonData.Timeline.NoteLines)
            {
                var headNote = noteGuidMap[noteLineJsonData.head];
                var tailNote = noteGuidMap[noteLineJsonData.tail];

                // 横に繋がっているロングは除外する
                if (Mathf.Approximately(headNote.JudgeTime, tailNote.JudgeTime))
                {
                    continue;
                }

                var noteLine = ScriptableObject.CreateInstance <TNoteLineEntity>();
                noteLine.Initialize(noteLineJsonData, headNote, tailNote);
                chart.NoteLines.Add(noteLine);
            }

            chart.Measures = new List <MeasureEntity>();

            if (chartJsonData.Timeline.Measures != null)
            {
                // 小節を生成する
                foreach (var measureJsonData in chartJsonData.Timeline.Measures)
                {
                    try
                    {
                        // 判定時間を取得する
                        var judgeTime = chart.BpmChanges.Find(bpmRange => bpmRange.Between(measureJsonData.index))
                                        .GetJudgeTime(measureJsonData.index);

                        var measure = new MeasureEntity(measureJsonData, judgeTime);
                        chart.Measures.Add(measure);
                    }
                    catch (NullReferenceException e)
                    {
                        Debug.LogError(measureJsonData.index + " / " + e.Message);
                    }
                }
            }

            chart.Notes = chart.Notes.OrderBy(note => note.JudgeTime).ToList();

            return(chart);
        }
예제 #2
0
        public TChartEntity Convert(ChartJsonData chartJsonData)
        {
            var chart = ScriptableObject.CreateInstance <TChartEntity>();

            return(Convert(chartJsonData, chart));
        }