From bdcd475ff6de78d7af6c24b5a8b98a5b159f1376 Mon Sep 17 00:00:00 2001 From: kimura Date: Thu, 28 Jul 2022 12:49:07 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=B9=E3=83=86=E3=83=BC=E3=82=B8=E5=88=87?= =?UTF-8?q?=E3=82=8A=E6=9B=BF=E3=81=88=E6=96=B9=E5=BC=8F=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MyGame/Scenes/MiniGame/MiniGame.unity | 2 +- .../Scenes/MiniGame/Scripts/GameManager.cs | 38 ++-- .../Scenes/MiniGame/Scripts/StageManager.cs | 167 ++++++++++++------ 3 files changed, 131 insertions(+), 76 deletions(-) diff --git a/popcorn/Assets/MyGame/Scenes/MiniGame/MiniGame.unity b/popcorn/Assets/MyGame/Scenes/MiniGame/MiniGame.unity index 0ebcfd37..90fd1a96 100644 --- a/popcorn/Assets/MyGame/Scenes/MiniGame/MiniGame.unity +++ b/popcorn/Assets/MyGame/Scenes/MiniGame/MiniGame.unity @@ -1942,7 +1942,7 @@ MonoBehaviour: stageGenerateDistance: 15 generateStageCount: 1 beginStageOffset: 0.5 - partsToPartsOffset: 3 + partsToPartsOffset: 0 --- !u!114 &1932485204 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/popcorn/Assets/MyGame/Scenes/MiniGame/Scripts/GameManager.cs b/popcorn/Assets/MyGame/Scenes/MiniGame/Scripts/GameManager.cs index 60347f8e..d2c0ea82 100644 --- a/popcorn/Assets/MyGame/Scenes/MiniGame/Scripts/GameManager.cs +++ b/popcorn/Assets/MyGame/Scenes/MiniGame/Scripts/GameManager.cs @@ -76,6 +76,7 @@ namespace MyGame.Scenes.MiniGame.Scripts var levelPlaceList = placeList.Where(data => data.placeId == placeId).ToArray(); var levelStageList = stageList.Where(data => data.placeId == placeId).ToArray(); + // スコア保存に1つ目のstageDataIdを使用 var stageData = levelStageList[0]; var scoreUpdate = new Subject().AddTo(this); stageSelectView.SetPlaceData(levelPlaceList); @@ -92,20 +93,14 @@ namespace MyGame.Scenes.MiniGame.Scripts { if (gameData.ScrollGameTodayPlayCount == 0) { - gameData.ScrollGameLastPlayTime = DateTime.UtcNow.ToBinary(); - gameData.ScrollGameTodayPlayCount++; - ResetGame(levelPlaceList, stageData); - menuState.Value = MenuState.Game; + ResetGameWithCount(levelPlaceList, levelStageList); return; } // ポップアップ ビデオ視聴表示 ScrollGameWatchVideoDialog.ShowDialog(() => { - gameData.ScrollGameLastPlayTime = DateTime.UtcNow.ToBinary(); - gameData.ScrollGameTodayPlayCount++; - ResetGame(levelPlaceList, stageData); - menuState.Value = MenuState.Game; + ResetGameWithCount(levelPlaceList, levelStageList); }); }).AddTo(this); scoreUpdate.OnNext(Unit.Default); @@ -162,7 +157,6 @@ namespace MyGame.Scenes.MiniGame.Scripts break; case GameState.Play: SoundManager.Instance.PlaySE("se_minigame_Start"); - stageManager.StartTimer(); break; case GameState.Success: SoundManager.Instance.PlaySE("se_minigame_End"); @@ -200,7 +194,10 @@ namespace MyGame.Scenes.MiniGame.Scripts // カメラ移動 cameraTransform.position = playerPosX * Vector3.right + cameraOffset; bgManager.UpdatePos(playerPosX); - stageManager.UpdatePos(playerPosX); + if (!player.IsHit) + { + stageManager.UpdatePos(playerPosX); + } }).AddTo(this); stageManager.OnFence.Subscribe(x => @@ -274,7 +271,6 @@ namespace MyGame.Scenes.MiniGame.Scripts switch (item.ItemType) { case StageItem.Type.Obstacle: - stageManager.StopTimer(); player.Hit(closestPoint); break; case StageItem.Type.Item1: @@ -290,12 +286,21 @@ namespace MyGame.Scenes.MiniGame.Scripts } }).AddTo(this); } + + private void ResetGameWithCount (ScrollGamePlaceData[] levelPlaceList, ScrollGameStageData[] levelStageList) + { + GameDataManager.GameData.ScrollGameLastPlayTime = DateTime.UtcNow.ToBinary(); + GameDataManager.GameData.ScrollGameTodayPlayCount++; + stageManager.SetStageList(levelStageList); + ResetGame(levelPlaceList, levelStageList); + menuState.Value = MenuState.Game; + } - private void ResetGame(ScrollGamePlaceData[] placeList, ScrollGameStageData stageData) + private void ResetGame(ScrollGamePlaceData[] placeList, ScrollGameStageData[] stageDataList) { SoundManager.Instance.ChangeVolumeUniqueBGM(1f); // ステージ読み込み - stageManager.SetBeginStages(stageData.GetBeginStagePrefabs()); + stageManager.SetBeginStages(); player.transform.position = characterBeginPos; player.ResetPlayer(); scoreCount.Value = 0; @@ -306,7 +311,7 @@ namespace MyGame.Scenes.MiniGame.Scripts .SelectMany(Observable.Timer(TimeSpan.FromSeconds(resultWaitTime))) .Subscribe(x => { - resultManager.ShowResult(scoreCount.Value, placeList, stageData); + resultManager.ShowResult(scoreCount.Value, placeList, stageDataList[0]); SoundManager.Instance.ChangePitchBGM(1f); }).AddTo(gameCompositeDisposable); @@ -314,10 +319,7 @@ namespace MyGame.Scenes.MiniGame.Scripts { ScrollGameWatchVideoDialog.ShowDialog(() => { - GameDataManager.GameData.ScrollGameLastPlayTime = DateTime.UtcNow.ToBinary(); - GameDataManager.GameData.ScrollGameTodayPlayCount++; - // ステージ読み込み - ResetGame(placeList, stageData); + ResetGameWithCount(placeList, stageDataList); }); }).AddTo(gameCompositeDisposable); diff --git a/popcorn/Assets/MyGame/Scenes/MiniGame/Scripts/StageManager.cs b/popcorn/Assets/MyGame/Scenes/MiniGame/Scripts/StageManager.cs index 3fc76284..30ec79bf 100644 --- a/popcorn/Assets/MyGame/Scenes/MiniGame/Scripts/StageManager.cs +++ b/popcorn/Assets/MyGame/Scenes/MiniGame/Scripts/StageManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using UniRx; using UnityEngine; @@ -8,77 +9,143 @@ namespace MyGame.Scenes.MiniGame.Scripts public class StageManager : MonoBehaviour { [SerializeField] private Transform stageTarget; - [SerializeField] private float normalTime; - [SerializeField] private float hardTime; - [SerializeField] private float extraTime; [SerializeField] private float stageGenerateDistance; [SerializeField] private int generateStageCount; [SerializeField] private float beginStageOffset; [SerializeField] private float partsToPartsOffset; - private Transform[] stagePrefabs; - private Transform[] stages; + private float normalTime; + private float hardTime; + private float extraTime; + private Transform[] stageBeginPrefabList; + private Transform[] stageRandomPrefabList; + private int beginIndex; + private int lengthIndex; private float stageEndXPos; private float cacheTargetXPos; - public IObservable OnFence => fenceSubject; + public IObservable OnFence => fenceSubject.DelayFrame(1); // 1フレーム送らせて通知 private readonly Subject fenceSubject = new(); public IReadOnlyReactiveProperty Difficulty => difficulty; private readonly ReactiveProperty difficulty = new(); - private IDisposable timerDisposable; + private ScrollGameDifficulty generateStageDifficulty; + private IDisposable timerDisposable; + private readonly Dictionary stageDataDict = new(); private void Start() { fenceSubject.AddTo(this); difficulty.AddTo(this); + difficulty.SkipLatestValueOnSubscribe().Subscribe(_ => + { + // 難易度変更時にリソース開放 + Resources.UnloadUnusedAssets(); + Debug.Log($"change difficulty ({difficulty.Value}) and unload resources"); + }).AddTo(this); } - public void SetBeginStages(Transform[] newStages) + + public void SetStageList(ScrollGameStageData[] stageDataList) + { + // ステージリストを取り込み + stageDataDict.Clear(); + foreach (var stageData in stageDataList) + { + if (stageDataDict.ContainsKey(stageData.Difficulty)) + { + continue; + } + stageDataDict.Add(stageData.Difficulty, stageData); + } + } + + public void SetBeginStages() { difficulty.SetValueAndForceNotify(ScrollGameDifficulty.Easy); - stagePrefabs = newStages; stageTarget.DestroyAllChildrens(); stageEndXPos = stageTarget.position.x + beginStageOffset; cacheTargetXPos = stageEndXPos; + lengthIndex = 0; + beginIndex = 0; + generateStageDifficulty = difficulty.Value; GenerateStage(); } private void GenerateStage() { - var selectIndex = UnityEngine.Random.Range(0, stagePrefabs.Length); - for (var i = 0; i < generateStageCount; i++) + // リソース読み込み + stageBeginPrefabList = stageDataDict[generateStageDifficulty].GetBeginStagePrefabs(); + stageRandomPrefabList = stageDataDict[generateStageDifficulty].GetRandomStagePrefabs(); + var stagePrefabs = Array.Empty(); + + var stageCount = stageDataDict[generateStageDifficulty].length; + if (stageCount == 0) { - var stage = Instantiate(stagePrefabs[selectIndex], stageTarget.position + Vector3.left * 100f, Quaternion.identity, stageTarget); - var minPos = float.MaxValue; - var maxPos = float.MinValue; - var holePosList = new List(); - stage.FindAllChildrensComponent(x => + stageCount = generateStageCount; + } + + // beginPrefabsの使用が終わったらrandomに切り替え + if (stageBeginPrefabList.Length > beginIndex) + { + var rangeEnd = Mathf.Min(beginIndex + stageCount, stageBeginPrefabList.Length); + stagePrefabs = stageBeginPrefabList[beginIndex..rangeEnd]; + beginIndex += stagePrefabs.Length; + } + var randomStageCount = stageCount - stagePrefabs.Length; + if (randomStageCount > 0) + { + var prefabs = (stageRandomPrefabList?.Length ?? 0) > 0 ? stageRandomPrefabList : stageBeginPrefabList; + while (randomStageCount > 0) { - var xPos = x.transform.position.x; - minPos = Mathf.Min(minPos, xPos); - maxPos = Mathf.Max(maxPos, xPos); - if (x.ItemType == StageItem.Type.Hole) - { - holePosList.Add(xPos); - } - }); - var xPos = stage.position.x; - var minDiff = minPos - xPos; - var maxDiff = maxPos - xPos; - stage.SetPositionX(stageEndXPos - minDiff); + var count = Mathf.Min(randomStageCount, prefabs.Length); + stagePrefabs = stagePrefabs.Concat(prefabs.RandomChoose(count)).ToArray(); + randomStageCount -= count; + } + } + + lengthIndex += stagePrefabs.Length; + + foreach (var stagePrefab in stagePrefabs) + { + var stage = Instantiate(stagePrefab, stageTarget.position + Vector3.left * 100f, Quaternion.identity, stageTarget).GetComponent(); + stage.transform.SetPositionX(stageEndXPos + stage.transform.position.x - stage.StartXPos); // endPos更新 - stageEndXPos = stage.position.x + maxDiff + partsToPartsOffset; - var cacheStageEndPos = stageEndXPos; + stageEndXPos = stage.EndPos + partsToPartsOffset; + // ステージの破棄 + var cacheStageEndPos = stageEndXPos; Observable.Interval(TimeSpan.FromSeconds(.5f)) .First(_ => cacheStageEndPos < cacheTargetXPos) .Subscribe(_ => { }, () => { - Destroy(stage.gameObject); + Destroy(stage.gameObject, 5f); }).AddTo(stage.gameObject); + // 落とし穴があった場合通知 - holePosList.ToObservable().DelayFrame(1).Subscribe(x => + stage.transform.FindAllChildrensComponent(x => { - fenceSubject.OnNext(stage.position.x + x - xPos); - }).AddTo(this); + if (x.ItemType != StageItem.Type.Hole) + { + return; + } + fenceSubject.OnNext(x.transform.position.x); + }); + } + + // 指定の長さ生成を終えた場合 + if (lengthIndex >= stageDataDict[generateStageDifficulty].length) + { + // 次回ステージ生成の難易度を変更 + generateStageDifficulty = NextDifficulty(generateStageDifficulty); + lengthIndex = 0; + beginIndex = 0; + + // ステージを完走すると難易度変更 + var cacheStageEndPos = stageEndXPos; + Observable.Interval(TimeSpan.FromSeconds(.5f)) + .First(_ => cacheStageEndPos < cacheTargetXPos) + .Subscribe(_ => { }, () => + { + difficulty.Value = NextDifficulty(difficulty.Value); + }).AddTo(this); } } @@ -91,30 +158,16 @@ namespace MyGame.Scenes.MiniGame.Scripts } } - public void StartTimer() + private static ScrollGameDifficulty NextDifficulty(ScrollGameDifficulty value) { - StopTimer(); - timerDisposable = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1)) - .Subscribe(x => - { - if (x >= extraTime) - { - difficulty.Value = ScrollGameDifficulty.Extra; - } - else if (x >= hardTime) - { - difficulty.Value = ScrollGameDifficulty.Hard; - } - else if (x >= normalTime) - { - difficulty.Value = ScrollGameDifficulty.Normal; - } - }).AddTo(this); - } - - public void StopTimer() - { - timerDisposable?.Dispose(); + return value switch + { + ScrollGameDifficulty.Easy => ScrollGameDifficulty.Normal, + ScrollGameDifficulty.Normal => ScrollGameDifficulty.Hard, + ScrollGameDifficulty.Hard => ScrollGameDifficulty.Extra, + ScrollGameDifficulty.Extra => ScrollGameDifficulty.Extra, + _ => throw new ArgumentOutOfRangeException(nameof(value), value, null) + }; } } } \ No newline at end of file