예제 #1
0
    public void ReloadStoryboard()
    {
        if (Storyboard == null)
        {
            return;
        }

        Storyboard.Dispose();
        Storyboard.Renderer.Dispose();

        foreach (var(id, note) in Chart.Model.note_map.Select(it => (it.Key, it.Value)))
        {
            note.PasteFrom(originalChartModel.note_map[id]);
        }

        Storyboard = new Cytoid.Storyboard.Storyboard(this, File.ReadAllText(StoryboardPath));
        Storyboard.Parse();
        Storyboard.Initialize();
    }
예제 #2
0
    public async UniTask Initialize(bool startAutomatically = true)
    {
        ObjectPool = new ObjectPool(this);

        // Decide game mode
        var mode = Context.SelectedGameMode;

        if (mode == GameMode.Unspecified)
        {
            if (EditorGameMode != GameMode.Unspecified)
            {
                mode = EditorGameMode;
            }
            else
            {
                throw new Exception("Game mode not specified");
            }
        }

        if (mode == GameMode.Tier)
        {
            var tierState = Context.TierState;
            if (tierState == null)
            {
                await Context.LevelManager.LoadLevelsOfType(LevelType.Tier);

                tierState         = new TierState(MockData.Season.tiers[0]);
                Context.TierState = tierState;
            }

            if (tierState.IsFailed || tierState.IsCompleted)
            {
                // Reset tier state
                tierState         = new TierState(tierState.Tier);
                Context.TierState = tierState;
            }

            tierState.CurrentStageIndex++;

            Level      = tierState.Tier.Meta.stages[Context.TierState.CurrentStageIndex].ToLevel(LevelType.Tier);
            Difficulty = Difficulty.Parse(Level.Meta.charts.Last().type);
        }
        else if (mode == GameMode.GlobalCalibration)
        {
            // Load global calibration level
            Level = await Context.LevelManager.LoadOrInstallBuiltInLevel(BuiltInData.GlobalCalibrationModeLevelId,
                                                                         LevelType.Temp);

            Difficulty = Level.Meta.GetEasiestDifficulty();

            // Initialize global calibrator
            globalCalibrator = new GlobalCalibrator(this);
        }
        else
        {
            if (Context.SelectedLevel == null && Application.isEditor)
            {
                // Load test level
                await Context.LevelManager.LoadFromMetadataFiles(LevelType.User, new List <string>
                {
                    $"{Context.UserDataPath}/{EditorDefaultLevelDirectory}/level.json"
                });

                Context.SelectedLevel      = Context.LevelManager.LoadedLocalLevels.Values.First();
                Context.SelectedDifficulty = Context.SelectedLevel.Meta.GetHardestDifficulty();
            }

            Level      = Context.SelectedLevel;
            Difficulty = Context.SelectedDifficulty;
        }

        onGameReadyToLoad.Invoke(this);

        await Resources.UnloadUnusedAssets();

        // Load chart
        print("Loading chart");
        var    chartMeta = Level.Meta.GetChartSection(Difficulty.Id);
        var    chartPath = "file://" + Level.Path + chartMeta.path;
        string chartText;

        using (var request = UnityWebRequest.Get(chartPath))
        {
            await request.SendWebRequest();

            if (request.isNetworkError || request.isHttpError)
            {
                Debug.LogError(request.error);
                throw new Exception($"Failed to download chart from {chartPath}");
            }

            chartText = Encoding.UTF8.GetString(request.downloadHandler.data);
        }

        var mods = new HashSet <Mod>(Context.SelectedMods);

        if (Application.isEditor && EditorForceAutoMod)
        {
            mods.Add(Mod.Auto);
        }

        Chart = new Chart(
            chartText,
            mods.Contains(Mod.FlipX) || mods.Contains(Mod.FlipAll),
            mods.Contains(Mod.FlipY) || mods.Contains(Mod.FlipAll),
            true,
            Context.Player.Settings.UseExperimentalNoteAr,
            mods.Contains(Mod.Fast) ? 1.5f : (mods.Contains(Mod.Slow) ? 0.75f : 1),
            camera.orthographicSize
            );
        ChartLength = Chart.Model.note_list.Max(it => it.end_time);
        foreach (var type in (NoteType[])Enum.GetValues(typeof(NoteType)))
        {
            ObjectPool.UpdateNoteObjectCount(type, Chart.MaxSamePageNoteCountByType[type] * 3);
        }

        // Load audio
        print("Loading audio");
        AudioListener.pause = false;

        if (Context.AudioManager == null)
        {
            await UniTask.WaitUntil(() => Context.AudioManager != null);
        }
        Context.AudioManager.Initialize();
        var audioPath = "file://" + Level.Path + Level.Meta.GetMusicPath(Difficulty.Id);
        var loader    = new AudioClipLoader(audioPath);
        await loader.Load();

        if (loader.Error != null)
        {
            Debug.LogError(loader.Error);
            throw new Exception($"Failed to download audio from {audioPath}");
        }

        Music       = Context.AudioManager.Load("Level", loader.AudioClip, false, false, true);
        MusicLength = Music.Length;

        // Load storyboard
        StoryboardPath =
            Level.Path + (chartMeta.storyboard != null ? chartMeta.storyboard.path : "storyboard.json");

        if (File.Exists(StoryboardPath))
        {
            // Initialize storyboard
            // TODO: Why File.ReadAllText() works but not UnityWebRequest?
            // (UnityWebRequest downloaded text could not be parsed by Newtonsoft.Json)
            try
            {
                var storyboardText = File.ReadAllText(StoryboardPath);
                Storyboard = new Cytoid.Storyboard.Storyboard(this, storyboardText);
                Storyboard.Parse();
                await Storyboard.Initialize();

                print($"Loaded storyboard from {StoryboardPath}");
            }
            catch (Exception e)
            {
                Debug.LogError(e);
                Debug.LogError("Could not load storyboard.");
            }
        }

        // Load hit sound
        if (Context.Player.Settings.HitSound != "none")
        {
            var resource = await Resources.LoadAsync <AudioClip>("Audio/HitSounds/" + Context.Player.Settings.HitSound);

            Context.AudioManager.Load("HitSound", resource as AudioClip, isResource: true);
        }

        // State & config
        State             = new GameState(this, mode, mods);
        Context.GameState = State;

        if (Application.isEditor)
        {
            Debug.Log("Chart checksum: " + State.ChartChecksum);
        }

        Config = new GameConfig(this);

        // Touch handlers
        if (mode != GameMode.GlobalCalibration && !State.Mods.Contains(Mod.Auto))
        {
            inputController.EnableInput();
        }

        // System config
        Application.targetFrameRate = 120;
        Context.SetAutoRotation(false);

        // Update last played time
        Level.Record.LastPlayedDate = DateTimeOffset.UtcNow;
        Level.SaveRecord();

        // Initialize note pool
        ObjectPool.Initialize();

        IsLoaded = true;
        if (mode != GameMode.GlobalCalibration)
        {
            Context.ScreenManager.ChangeScreen(OverlayScreen.Id, ScreenTransition.None);
        }

        onGameLoaded.Invoke(this);

        levelInfoParent.transform.RebuildLayout();

        if (startAutomatically)
        {
            StartGame();
        }
    }