ステージ生成方法変更, 難易度切り替えとステージ生成を独立
This commit is contained in:
parent
8be964e884
commit
144c4a2eb0
|
|
@ -1886,6 +1886,7 @@ MonoBehaviour:
|
|||
footerManager: {fileID: 4559813503860727170}
|
||||
stageManager: {fileID: 1870432536}
|
||||
bgManager: {fileID: 1471947212}
|
||||
difficultyChanger: {fileID: 1870432537}
|
||||
resultManager: {fileID: 5034752974072861423}
|
||||
readyObject: {fileID: 978217474}
|
||||
tutorialPopupObject: {fileID: 7325523898178317160}
|
||||
|
|
@ -1941,6 +1942,7 @@ MonoBehaviour:
|
|||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
stageTarget: {fileID: 1450368326}
|
||||
elapsedTimeOffset: 3
|
||||
stageGenerateDistance: 15
|
||||
generateStageCount: 1
|
||||
beginStageOffset: 0.5
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
[SerializeField] private FooterManager footerManager;
|
||||
[SerializeField] private StageManager stageManager;
|
||||
[SerializeField] private BGManager bgManager;
|
||||
[SerializeField] private DifficultyChanger difficultyChanger;
|
||||
[SerializeField] private ResultManager resultManager;
|
||||
[SerializeField] private GameObject readyObject;
|
||||
[SerializeField] private GameObject tutorialPopupObject;
|
||||
|
|
@ -44,8 +45,10 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
private readonly ReactiveProperty<MenuState> menuState = new ReactiveProperty<MenuState>();
|
||||
private readonly ReactiveProperty<GameState> state = new ReactiveProperty<GameState>();
|
||||
private readonly ReactiveProperty<int> scoreCount = new ReactiveProperty<int>();
|
||||
private readonly CompositeDisposable gameCompositeDisposable = new CompositeDisposable();
|
||||
private readonly ReactiveProperty<float> elapsedTime = new ReactiveProperty<float>();
|
||||
private readonly CompositeDisposable stageCompositeDisposable = new CompositeDisposable();
|
||||
private Vector3 characterBeginPos;
|
||||
private IDisposable timerDisposable;
|
||||
|
||||
// Start is called before the first frame update
|
||||
private void Start()
|
||||
|
|
@ -53,7 +56,8 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
menuState.AddTo(this);
|
||||
state.AddTo(this);
|
||||
scoreCount.AddTo(this);
|
||||
gameCompositeDisposable.AddTo(this);
|
||||
elapsedTime.AddTo(this);
|
||||
stageCompositeDisposable.AddTo(this);
|
||||
menuState.Value = MenuState.StageSelect;
|
||||
state.Value = GameState.Ready;
|
||||
|
||||
|
|
@ -74,11 +78,27 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
|
||||
var placeList = SpreadsheetDataManager.Instance.GetBaseDataList<ScrollGamePlaceData>(Const.ScrollGamePlaceDataSheet);
|
||||
var stageList = SpreadsheetDataManager.Instance.GetBaseDataList<ScrollGameStageData>(Const.ScrollGameStageDataSheet);
|
||||
// var difficultyList = SpreadsheetDataManager.Instance.GetBaseDataList<ScrollGameStageDifficultyData>(Const.ScrollGameStageDifficultyDataSheet);
|
||||
|
||||
//ステージ読み込み
|
||||
var placeId = 1;
|
||||
var levelPlaceList = placeList.Where(data => data.placeId == placeId).ToArray();
|
||||
var levelStageList = stageList.Where(data => data.placeId == placeId).ToArray();
|
||||
// var levelDifficulty = difficultyList.First(data => data.placeId == placeId);
|
||||
|
||||
// 仮データ
|
||||
for (var i = 0; i < levelStageList.Length; i++)
|
||||
{
|
||||
levelStageList[i].time = i * 30;
|
||||
}
|
||||
var levelDifficulty = new ScrollGameStageDifficultyData
|
||||
{
|
||||
id = 1,
|
||||
placeId = 1,
|
||||
normalTime = 30,
|
||||
hardTime = 60,
|
||||
extraTime = 90
|
||||
};
|
||||
|
||||
// スコア保存に1つ目のstageDataIdを使用
|
||||
var stageData = levelStageList[0];
|
||||
|
|
@ -95,17 +115,28 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
}).AddTo(this);
|
||||
stageSelectView.OnClick.ThrottleFirst(TimeSpan.FromSeconds(.3f)).Subscribe(_ =>
|
||||
{
|
||||
// ステージ設定読み込み
|
||||
difficultyChanger.SetData(levelDifficulty);
|
||||
stageManager.SetStageList(levelStageList);
|
||||
stageCompositeDisposable.Clear();
|
||||
state.SkipLatestValueOnSubscribe()
|
||||
.Where(x => x == GameState.Success)
|
||||
.SelectMany(Observable.Timer(TimeSpan.FromSeconds(resultWaitTime)))
|
||||
.Subscribe(_ =>
|
||||
{
|
||||
resultManager.ShowResult(scoreCount.Value, levelPlaceList, stageData);
|
||||
SoundManager.Instance.ChangePitchBGM(1f);
|
||||
}).AddTo(stageCompositeDisposable);
|
||||
|
||||
if (gameData.ScrollGameTodayPlayCount == 0)
|
||||
{
|
||||
ResetGameWithCount(levelPlaceList, levelStageList);
|
||||
ResetGameWithCount();
|
||||
return;
|
||||
}
|
||||
|
||||
// ポップアップ ビデオ視聴表示
|
||||
ScrollGameWatchVideoDialog.ShowDialog(() =>
|
||||
{
|
||||
ResetGameWithCount(levelPlaceList, levelStageList);
|
||||
});
|
||||
ScrollGameWatchVideoDialog.ShowDialog(ResetGameWithCount);
|
||||
|
||||
}).AddTo(this);
|
||||
scoreUpdate.OnNext(Unit.Default);
|
||||
|
||||
|
|
@ -134,6 +165,11 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
headerView.ChangeItemCount(x);
|
||||
}).AddTo(this);
|
||||
|
||||
resultManager.OnRetry.ThrottleFirst(TimeSpan.FromSeconds(.2f)).Subscribe(_ =>
|
||||
{
|
||||
ScrollGameWatchVideoDialog.ShowDialog(ResetGameWithCount);
|
||||
}).AddTo(this);
|
||||
|
||||
resultManager.OnClose.ThrottleFirst(TimeSpan.FromMilliseconds(.2f)).Subscribe(_ =>
|
||||
{
|
||||
SoundManager.Instance.ChangeVolumeUniqueBGM(1f);
|
||||
|
|
@ -161,6 +197,7 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
break;
|
||||
case GameState.Play:
|
||||
SoundManager.Instance.PlaySE("se_minigame_Start");
|
||||
StartTimer();
|
||||
break;
|
||||
case GameState.Success:
|
||||
SoundManager.Instance.PlaySE("se_minigame_End", () =>
|
||||
|
|
@ -207,13 +244,19 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
}
|
||||
}).AddTo(this);
|
||||
|
||||
elapsedTime.SkipLatestValueOnSubscribe().Subscribe(x =>
|
||||
{
|
||||
stageManager.UpdateTime(x);
|
||||
difficultyChanger.UpdateTime(x);
|
||||
}).AddTo(this);
|
||||
|
||||
stageManager.OnFence.Subscribe(x =>
|
||||
{
|
||||
bgManager.SetFenceXPos(x);
|
||||
}).AddTo(this);
|
||||
|
||||
// コース難易度変更
|
||||
stageManager.Difficulty.SkipLatestValueOnSubscribe().Subscribe(x =>
|
||||
difficultyChanger.Difficulty.SkipLatestValueOnSubscribe().Subscribe(x =>
|
||||
{
|
||||
bgManager.SetSky(x);
|
||||
player.SetSpeed(x);
|
||||
|
|
@ -284,6 +327,7 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
switch (item.ItemType)
|
||||
{
|
||||
case StageItem.Type.Obstacle:
|
||||
StopTimer();
|
||||
player.Hit(closestPoint);
|
||||
SoundManager.Instance.ChangePitchBGM(0f);
|
||||
break;
|
||||
|
|
@ -301,42 +345,24 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
}).AddTo(this);
|
||||
}
|
||||
|
||||
private void ResetGameWithCount (ScrollGamePlaceData[] levelPlaceList, ScrollGameStageData[] levelStageList)
|
||||
private void ResetGameWithCount ()
|
||||
{
|
||||
GameDataManager.GameData.ScrollGameLastPlayTime = DateTime.UtcNow.ToBinary();
|
||||
GameDataManager.GameData.ScrollGameTodayPlayCount++;
|
||||
stageManager.SetStageList(levelStageList);
|
||||
ResetGame(levelPlaceList, levelStageList);
|
||||
ResetGame();
|
||||
menuState.Value = MenuState.Game;
|
||||
}
|
||||
|
||||
private void ResetGame(ScrollGamePlaceData[] placeList, ScrollGameStageData[] stageDataList)
|
||||
private void ResetGame()
|
||||
{
|
||||
SoundManager.Instance.ChangeVolumeUniqueBGM(1f);
|
||||
ResetTimer();
|
||||
// ステージ読み込み
|
||||
stageManager.SetBeginStages();
|
||||
player.transform.position = characterBeginPos;
|
||||
player.ResetPlayer();
|
||||
scoreCount.Value = 0;
|
||||
resultManager.Reset();
|
||||
gameCompositeDisposable.Clear();
|
||||
state.SkipLatestValueOnSubscribe()
|
||||
.FirstOrDefault(x => x == GameState.Success)
|
||||
.SelectMany(Observable.Timer(TimeSpan.FromSeconds(resultWaitTime)))
|
||||
.Subscribe(x =>
|
||||
{
|
||||
resultManager.ShowResult(scoreCount.Value, placeList, stageDataList[0]);
|
||||
SoundManager.Instance.ChangePitchBGM(1f);
|
||||
}).AddTo(gameCompositeDisposable);
|
||||
|
||||
resultManager.OnRetry.ThrottleFirst(TimeSpan.FromSeconds(.2f)).Subscribe(_ =>
|
||||
{
|
||||
ScrollGameWatchVideoDialog.ShowDialog(() =>
|
||||
{
|
||||
ResetGameWithCount(placeList, stageDataList);
|
||||
});
|
||||
}).AddTo(gameCompositeDisposable);
|
||||
|
||||
state.Value = GameState.Ready;
|
||||
}
|
||||
|
||||
|
|
@ -348,5 +374,26 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
GameDataManager.GameData.ScrollGameTodayPlayCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetTimer()
|
||||
{
|
||||
timerDisposable?.Dispose();
|
||||
elapsedTime.SetValueAndForceNotify(0f);
|
||||
}
|
||||
|
||||
private void StartTimer()
|
||||
{
|
||||
timerDisposable?.Dispose();
|
||||
timerDisposable = Observable.Interval(TimeSpan.FromSeconds(1f))
|
||||
.Subscribe(x =>
|
||||
{
|
||||
elapsedTime.Value = x;
|
||||
}).AddTo(this);
|
||||
}
|
||||
|
||||
private void StopTimer()
|
||||
{
|
||||
timerDisposable?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,32 +9,27 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
public class StageManager : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Transform stageTarget;
|
||||
[SerializeField] private float elapsedTimeOffset;
|
||||
[SerializeField] private float stageGenerateDistance;
|
||||
[SerializeField] private int generateStageCount;
|
||||
[SerializeField] private float beginStageOffset;
|
||||
[SerializeField] private float partsToPartsOffset;
|
||||
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;
|
||||
private float cacheElapsedTime;
|
||||
private ScrollGameStageData currentStageData;
|
||||
private ScrollGameStageData nextStageData;
|
||||
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 ScrollGameDifficulty generateStageDifficulty;
|
||||
private readonly CompositeDisposable changeDifficultyDisposable = new();
|
||||
private readonly Dictionary<ScrollGameDifficulty, ScrollGameStageData> stageDataDict = new();
|
||||
private readonly CompositeDisposable stageDisposable = new();
|
||||
private readonly Dictionary<int, ScrollGameStageData> stageDataDict = new();
|
||||
|
||||
private void Start()
|
||||
{
|
||||
fenceSubject.AddTo(this);
|
||||
difficulty.AddTo(this);
|
||||
changeDifficultyDisposable.AddTo(this);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -42,50 +37,47 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
{
|
||||
// ステージリストを取り込み
|
||||
stageDataDict.Clear();
|
||||
foreach (var stageData in stageDataList)
|
||||
foreach (var stageData in stageDataList.OrderBy(data => data.time))
|
||||
{
|
||||
if (stageDataDict.ContainsKey(stageData.Difficulty))
|
||||
if (stageDataDict.ContainsKey(stageData.time))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
stageDataDict.Add(stageData.Difficulty, stageData);
|
||||
stageDataDict.Add(stageData.time, stageData);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBeginStages()
|
||||
{
|
||||
difficulty.SetValueAndForceNotify(ScrollGameDifficulty.Easy);
|
||||
stageTarget.DestroyAllChildrens();
|
||||
stageEndXPos = stageTarget.position.x + beginStageOffset;
|
||||
cacheTargetXPos = stageEndXPos;
|
||||
lengthIndex = 0;
|
||||
beginIndex = 0;
|
||||
generateStageDifficulty = difficulty.Value;
|
||||
changeDifficultyDisposable.Clear();
|
||||
cacheElapsedTime = 0f;
|
||||
currentStageData = GetCurrentStage(cacheElapsedTime);
|
||||
nextStageData = GetNextStage(cacheElapsedTime);
|
||||
stageDisposable.Clear();
|
||||
GenerateStage();
|
||||
}
|
||||
|
||||
private void GenerateStage()
|
||||
{
|
||||
/*
|
||||
* 生成はLength基準でまず
|
||||
* 拡張するならLenghtIndexをつくって更に小さい単位GenerateCountに対応できるようにする
|
||||
* 一気に読み込むのはしんどい
|
||||
* prefabも1つづつ読み込んだほうがいいっぽい
|
||||
* 次の難易度のリソースを1つづつ読み込むなどする
|
||||
* 読み込みリソースのオブジェクト数を減らす
|
||||
*/
|
||||
// リソース読み込み
|
||||
stageBeginPrefabList = stageDataDict[generateStageDifficulty].GetBeginStagePrefabs();
|
||||
stageRandomPrefabList = stageDataDict[generateStageDifficulty].GetRandomStagePrefabs();
|
||||
var stagePrefabs = Array.Empty<Transform>();
|
||||
|
||||
var stageCount = stageDataDict[generateStageDifficulty].length;
|
||||
if (stageCount == 0)
|
||||
// ステージデータ更新確認
|
||||
var time = cacheElapsedTime + elapsedTimeOffset;
|
||||
if (nextStageData != null && nextStageData.time <= time)
|
||||
{
|
||||
stageCount = generateStageCount;
|
||||
beginIndex = 0;
|
||||
currentStageData = GetCurrentStage(time);
|
||||
nextStageData = GetNextStage(time);
|
||||
}
|
||||
|
||||
// リソース読み込み
|
||||
stageBeginPrefabList = currentStageData.GetBeginStagePrefabs();
|
||||
stageRandomPrefabList = currentStageData.GetRandomStagePrefabs();
|
||||
|
||||
var stagePrefabs = Array.Empty<Transform>();
|
||||
var stageCount = generateStageCount;
|
||||
|
||||
// beginPrefabsの使用が終わったらrandomに切り替え
|
||||
if (stageBeginPrefabList.Length > beginIndex)
|
||||
{
|
||||
|
|
@ -94,7 +86,6 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
beginIndex += stagePrefabs.Length;
|
||||
}
|
||||
|
||||
Debug.Log($"stage {generateStageDifficulty} use begin {stagePrefabs.Length}");
|
||||
var randomStageCount = stageCount - stagePrefabs.Length;
|
||||
if (randomStageCount > 0)
|
||||
{
|
||||
|
|
@ -106,9 +97,6 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
randomStageCount -= count;
|
||||
}
|
||||
}
|
||||
Debug.Log($"stage {generateStageDifficulty} use begin + random {stagePrefabs.Length}");
|
||||
|
||||
lengthIndex += stagePrefabs.Length;
|
||||
|
||||
foreach (var stagePrefab in stagePrefabs)
|
||||
{
|
||||
|
|
@ -136,24 +124,11 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
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(changeDifficultyDisposable);
|
||||
}
|
||||
public void UpdateTime(float elapsed)
|
||||
{
|
||||
cacheElapsedTime = elapsed;
|
||||
}
|
||||
|
||||
public void UpdatePos(float targetXPos)
|
||||
|
|
@ -165,16 +140,14 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
}
|
||||
}
|
||||
|
||||
private static ScrollGameDifficulty NextDifficulty(ScrollGameDifficulty value)
|
||||
private ScrollGameStageData GetCurrentStage(float time)
|
||||
{
|
||||
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)
|
||||
};
|
||||
return stageDataDict.Last(pair => pair.Key <= time).Value;
|
||||
}
|
||||
|
||||
private ScrollGameStageData GetNextStage(float time)
|
||||
{
|
||||
return stageDataDict.FirstOrDefault(pair => pair.Key > time).Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -28,24 +28,6 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
|||
|
||||
public IObservable<Unit> OnClick => button.OnClickAsObservable().TakeUntilDestroy(this);
|
||||
|
||||
public void SetPrevStageData(ScrollGameStageData stageData)
|
||||
{
|
||||
switch (stageData.Difficulty)
|
||||
{
|
||||
case ScrollGameDifficulty.Easy:
|
||||
// lockText.text = string.Format(LocalizationManager.GetTranslation("UI/ScrollGameStageLockNormal"), stageData.needScore);
|
||||
break;
|
||||
case ScrollGameDifficulty.Normal:
|
||||
// lockText.text = string.Format(LocalizationManager.GetTranslation("UI/ScrollGameStageLockHard"), stageData.needScore);
|
||||
break;
|
||||
case ScrollGameDifficulty.Hard:
|
||||
lockText.text = string.Empty;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetData(ScrollGameStageData stageData)
|
||||
{
|
||||
// stageName.text = stageData.id.ToString();
|
||||
|
|
|
|||
|
|
@ -556,11 +556,9 @@ public sealed class ScrollGameStageData
|
|||
{
|
||||
public int id;
|
||||
public int placeId;
|
||||
public int difficulty;
|
||||
public int time;
|
||||
public string beginPrefabName;
|
||||
public string randomPrefabName;
|
||||
public int length;
|
||||
public ScrollGameDifficulty Difficulty => (ScrollGameDifficulty)difficulty;
|
||||
|
||||
private string[] BeginPrefabName => beginPrefabName?.Split(',') ?? Array.Empty<string>();
|
||||
private string[] RandomPrefabName => randomPrefabName?.Split(',') ?? Array.Empty<string>();
|
||||
|
|
|
|||
Loading…
Reference in New Issue