ステージ切り替え方式変更
This commit is contained in:
parent
59bc6367fc
commit
bdcd475ff6
|
|
@ -1942,7 +1942,7 @@ MonoBehaviour:
|
|||
stageGenerateDistance: 15
|
||||
generateStageCount: 1
|
||||
beginStageOffset: 0.5
|
||||
partsToPartsOffset: 3
|
||||
partsToPartsOffset: 0
|
||||
--- !u!114 &1932485204
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
|
|||
|
|
@ -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<Unit>().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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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<float> OnFence => fenceSubject;
|
||||
public IObservable<float> OnFence => fenceSubject.DelayFrame(1); // 1フレーム送らせて通知
|
||||
private readonly Subject<float> fenceSubject = new();
|
||||
public IReadOnlyReactiveProperty<ScrollGameDifficulty> Difficulty => difficulty;
|
||||
private readonly ReactiveProperty<ScrollGameDifficulty> difficulty = new();
|
||||
private IDisposable timerDisposable;
|
||||
private ScrollGameDifficulty generateStageDifficulty;
|
||||
private IDisposable timerDisposable;
|
||||
private readonly Dictionary<ScrollGameDifficulty, ScrollGameStageData> 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<Transform>();
|
||||
|
||||
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<float>();
|
||||
stage.FindAllChildrensComponent<StageItem>(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>();
|
||||
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<StageItem>(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)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue