ステージ切り替え方式変更
This commit is contained in:
parent
59bc6367fc
commit
bdcd475ff6
|
|
@ -1942,7 +1942,7 @@ MonoBehaviour:
|
||||||
stageGenerateDistance: 15
|
stageGenerateDistance: 15
|
||||||
generateStageCount: 1
|
generateStageCount: 1
|
||||||
beginStageOffset: 0.5
|
beginStageOffset: 0.5
|
||||||
partsToPartsOffset: 3
|
partsToPartsOffset: 0
|
||||||
--- !u!114 &1932485204
|
--- !u!114 &1932485204
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
||||||
var levelPlaceList = placeList.Where(data => data.placeId == placeId).ToArray();
|
var levelPlaceList = placeList.Where(data => data.placeId == placeId).ToArray();
|
||||||
var levelStageList = stageList.Where(data => data.placeId == placeId).ToArray();
|
var levelStageList = stageList.Where(data => data.placeId == placeId).ToArray();
|
||||||
|
|
||||||
|
// スコア保存に1つ目のstageDataIdを使用
|
||||||
var stageData = levelStageList[0];
|
var stageData = levelStageList[0];
|
||||||
var scoreUpdate = new Subject<Unit>().AddTo(this);
|
var scoreUpdate = new Subject<Unit>().AddTo(this);
|
||||||
stageSelectView.SetPlaceData(levelPlaceList);
|
stageSelectView.SetPlaceData(levelPlaceList);
|
||||||
|
|
@ -92,20 +93,14 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
||||||
{
|
{
|
||||||
if (gameData.ScrollGameTodayPlayCount == 0)
|
if (gameData.ScrollGameTodayPlayCount == 0)
|
||||||
{
|
{
|
||||||
gameData.ScrollGameLastPlayTime = DateTime.UtcNow.ToBinary();
|
ResetGameWithCount(levelPlaceList, levelStageList);
|
||||||
gameData.ScrollGameTodayPlayCount++;
|
|
||||||
ResetGame(levelPlaceList, stageData);
|
|
||||||
menuState.Value = MenuState.Game;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ポップアップ ビデオ視聴表示
|
// ポップアップ ビデオ視聴表示
|
||||||
ScrollGameWatchVideoDialog.ShowDialog(() =>
|
ScrollGameWatchVideoDialog.ShowDialog(() =>
|
||||||
{
|
{
|
||||||
gameData.ScrollGameLastPlayTime = DateTime.UtcNow.ToBinary();
|
ResetGameWithCount(levelPlaceList, levelStageList);
|
||||||
gameData.ScrollGameTodayPlayCount++;
|
|
||||||
ResetGame(levelPlaceList, stageData);
|
|
||||||
menuState.Value = MenuState.Game;
|
|
||||||
});
|
});
|
||||||
}).AddTo(this);
|
}).AddTo(this);
|
||||||
scoreUpdate.OnNext(Unit.Default);
|
scoreUpdate.OnNext(Unit.Default);
|
||||||
|
|
@ -162,7 +157,6 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
||||||
break;
|
break;
|
||||||
case GameState.Play:
|
case GameState.Play:
|
||||||
SoundManager.Instance.PlaySE("se_minigame_Start");
|
SoundManager.Instance.PlaySE("se_minigame_Start");
|
||||||
stageManager.StartTimer();
|
|
||||||
break;
|
break;
|
||||||
case GameState.Success:
|
case GameState.Success:
|
||||||
SoundManager.Instance.PlaySE("se_minigame_End");
|
SoundManager.Instance.PlaySE("se_minigame_End");
|
||||||
|
|
@ -200,7 +194,10 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
||||||
// カメラ移動
|
// カメラ移動
|
||||||
cameraTransform.position = playerPosX * Vector3.right + cameraOffset;
|
cameraTransform.position = playerPosX * Vector3.right + cameraOffset;
|
||||||
bgManager.UpdatePos(playerPosX);
|
bgManager.UpdatePos(playerPosX);
|
||||||
stageManager.UpdatePos(playerPosX);
|
if (!player.IsHit)
|
||||||
|
{
|
||||||
|
stageManager.UpdatePos(playerPosX);
|
||||||
|
}
|
||||||
}).AddTo(this);
|
}).AddTo(this);
|
||||||
|
|
||||||
stageManager.OnFence.Subscribe(x =>
|
stageManager.OnFence.Subscribe(x =>
|
||||||
|
|
@ -274,7 +271,6 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
||||||
switch (item.ItemType)
|
switch (item.ItemType)
|
||||||
{
|
{
|
||||||
case StageItem.Type.Obstacle:
|
case StageItem.Type.Obstacle:
|
||||||
stageManager.StopTimer();
|
|
||||||
player.Hit(closestPoint);
|
player.Hit(closestPoint);
|
||||||
break;
|
break;
|
||||||
case StageItem.Type.Item1:
|
case StageItem.Type.Item1:
|
||||||
|
|
@ -290,12 +286,21 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
||||||
}
|
}
|
||||||
}).AddTo(this);
|
}).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);
|
SoundManager.Instance.ChangeVolumeUniqueBGM(1f);
|
||||||
// ステージ読み込み
|
// ステージ読み込み
|
||||||
stageManager.SetBeginStages(stageData.GetBeginStagePrefabs());
|
stageManager.SetBeginStages();
|
||||||
player.transform.position = characterBeginPos;
|
player.transform.position = characterBeginPos;
|
||||||
player.ResetPlayer();
|
player.ResetPlayer();
|
||||||
scoreCount.Value = 0;
|
scoreCount.Value = 0;
|
||||||
|
|
@ -306,7 +311,7 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
||||||
.SelectMany(Observable.Timer(TimeSpan.FromSeconds(resultWaitTime)))
|
.SelectMany(Observable.Timer(TimeSpan.FromSeconds(resultWaitTime)))
|
||||||
.Subscribe(x =>
|
.Subscribe(x =>
|
||||||
{
|
{
|
||||||
resultManager.ShowResult(scoreCount.Value, placeList, stageData);
|
resultManager.ShowResult(scoreCount.Value, placeList, stageDataList[0]);
|
||||||
SoundManager.Instance.ChangePitchBGM(1f);
|
SoundManager.Instance.ChangePitchBGM(1f);
|
||||||
}).AddTo(gameCompositeDisposable);
|
}).AddTo(gameCompositeDisposable);
|
||||||
|
|
||||||
|
|
@ -314,10 +319,7 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
||||||
{
|
{
|
||||||
ScrollGameWatchVideoDialog.ShowDialog(() =>
|
ScrollGameWatchVideoDialog.ShowDialog(() =>
|
||||||
{
|
{
|
||||||
GameDataManager.GameData.ScrollGameLastPlayTime = DateTime.UtcNow.ToBinary();
|
ResetGameWithCount(placeList, stageDataList);
|
||||||
GameDataManager.GameData.ScrollGameTodayPlayCount++;
|
|
||||||
// ステージ読み込み
|
|
||||||
ResetGame(placeList, stageData);
|
|
||||||
});
|
});
|
||||||
}).AddTo(gameCompositeDisposable);
|
}).AddTo(gameCompositeDisposable);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using UniRx;
|
using UniRx;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
@ -8,77 +9,143 @@ namespace MyGame.Scenes.MiniGame.Scripts
|
||||||
public class StageManager : MonoBehaviour
|
public class StageManager : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private Transform stageTarget;
|
[SerializeField] private Transform stageTarget;
|
||||||
[SerializeField] private float normalTime;
|
|
||||||
[SerializeField] private float hardTime;
|
|
||||||
[SerializeField] private float extraTime;
|
|
||||||
[SerializeField] private float stageGenerateDistance;
|
[SerializeField] private float stageGenerateDistance;
|
||||||
[SerializeField] private int generateStageCount;
|
[SerializeField] private int generateStageCount;
|
||||||
[SerializeField] private float beginStageOffset;
|
[SerializeField] private float beginStageOffset;
|
||||||
[SerializeField] private float partsToPartsOffset;
|
[SerializeField] private float partsToPartsOffset;
|
||||||
private Transform[] stagePrefabs;
|
private float normalTime;
|
||||||
private Transform[] stages;
|
private float hardTime;
|
||||||
|
private float extraTime;
|
||||||
|
private Transform[] stageBeginPrefabList;
|
||||||
|
private Transform[] stageRandomPrefabList;
|
||||||
|
private int beginIndex;
|
||||||
|
private int lengthIndex;
|
||||||
private float stageEndXPos;
|
private float stageEndXPos;
|
||||||
private float cacheTargetXPos;
|
private float cacheTargetXPos;
|
||||||
public IObservable<float> OnFence => fenceSubject;
|
public IObservable<float> OnFence => fenceSubject.DelayFrame(1); // 1フレーム送らせて通知
|
||||||
private readonly Subject<float> fenceSubject = new();
|
private readonly Subject<float> fenceSubject = new();
|
||||||
public IReadOnlyReactiveProperty<ScrollGameDifficulty> Difficulty => difficulty;
|
public IReadOnlyReactiveProperty<ScrollGameDifficulty> Difficulty => difficulty;
|
||||||
private readonly ReactiveProperty<ScrollGameDifficulty> difficulty = new();
|
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()
|
private void Start()
|
||||||
{
|
{
|
||||||
fenceSubject.AddTo(this);
|
fenceSubject.AddTo(this);
|
||||||
difficulty.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);
|
difficulty.SetValueAndForceNotify(ScrollGameDifficulty.Easy);
|
||||||
stagePrefabs = newStages;
|
|
||||||
stageTarget.DestroyAllChildrens();
|
stageTarget.DestroyAllChildrens();
|
||||||
stageEndXPos = stageTarget.position.x + beginStageOffset;
|
stageEndXPos = stageTarget.position.x + beginStageOffset;
|
||||||
cacheTargetXPos = stageEndXPos;
|
cacheTargetXPos = stageEndXPos;
|
||||||
|
lengthIndex = 0;
|
||||||
|
beginIndex = 0;
|
||||||
|
generateStageDifficulty = difficulty.Value;
|
||||||
GenerateStage();
|
GenerateStage();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void 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);
|
stageCount = generateStageCount;
|
||||||
var minPos = float.MaxValue;
|
}
|
||||||
var maxPos = float.MinValue;
|
|
||||||
var holePosList = new List<float>();
|
// beginPrefabsの使用が終わったらrandomに切り替え
|
||||||
stage.FindAllChildrensComponent<StageItem>(x =>
|
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;
|
var count = Mathf.Min(randomStageCount, prefabs.Length);
|
||||||
minPos = Mathf.Min(minPos, xPos);
|
stagePrefabs = stagePrefabs.Concat(prefabs.RandomChoose(count)).ToArray();
|
||||||
maxPos = Mathf.Max(maxPos, xPos);
|
randomStageCount -= count;
|
||||||
if (x.ItemType == StageItem.Type.Hole)
|
}
|
||||||
{
|
}
|
||||||
holePosList.Add(xPos);
|
|
||||||
}
|
lengthIndex += stagePrefabs.Length;
|
||||||
});
|
|
||||||
var xPos = stage.position.x;
|
foreach (var stagePrefab in stagePrefabs)
|
||||||
var minDiff = minPos - xPos;
|
{
|
||||||
var maxDiff = maxPos - xPos;
|
var stage = Instantiate(stagePrefab, stageTarget.position + Vector3.left * 100f, Quaternion.identity, stageTarget).GetComponent<Stage>();
|
||||||
stage.SetPositionX(stageEndXPos - minDiff);
|
stage.transform.SetPositionX(stageEndXPos + stage.transform.position.x - stage.StartXPos);
|
||||||
// endPos更新
|
// endPos更新
|
||||||
stageEndXPos = stage.position.x + maxDiff + partsToPartsOffset;
|
stageEndXPos = stage.EndPos + partsToPartsOffset;
|
||||||
var cacheStageEndPos = stageEndXPos;
|
|
||||||
// ステージの破棄
|
// ステージの破棄
|
||||||
|
var cacheStageEndPos = stageEndXPos;
|
||||||
Observable.Interval(TimeSpan.FromSeconds(.5f))
|
Observable.Interval(TimeSpan.FromSeconds(.5f))
|
||||||
.First(_ => cacheStageEndPos < cacheTargetXPos)
|
.First(_ => cacheStageEndPos < cacheTargetXPos)
|
||||||
.Subscribe(_ => { }, () =>
|
.Subscribe(_ => { }, () =>
|
||||||
{
|
{
|
||||||
Destroy(stage.gameObject);
|
Destroy(stage.gameObject, 5f);
|
||||||
}).AddTo(stage.gameObject);
|
}).AddTo(stage.gameObject);
|
||||||
|
|
||||||
// 落とし穴があった場合通知
|
// 落とし穴があった場合通知
|
||||||
holePosList.ToObservable().DelayFrame(1).Subscribe(x =>
|
stage.transform.FindAllChildrensComponent<StageItem>(x =>
|
||||||
{
|
{
|
||||||
fenceSubject.OnNext(stage.position.x + x - xPos);
|
if (x.ItemType != StageItem.Type.Hole)
|
||||||
}).AddTo(this);
|
{
|
||||||
|
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();
|
return value switch
|
||||||
timerDisposable = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1))
|
{
|
||||||
.Subscribe(x =>
|
ScrollGameDifficulty.Easy => ScrollGameDifficulty.Normal,
|
||||||
{
|
ScrollGameDifficulty.Normal => ScrollGameDifficulty.Hard,
|
||||||
if (x >= extraTime)
|
ScrollGameDifficulty.Hard => ScrollGameDifficulty.Extra,
|
||||||
{
|
ScrollGameDifficulty.Extra => ScrollGameDifficulty.Extra,
|
||||||
difficulty.Value = ScrollGameDifficulty.Extra;
|
_ => throw new ArgumentOutOfRangeException(nameof(value), value, null)
|
||||||
}
|
};
|
||||||
else if (x >= hardTime)
|
|
||||||
{
|
|
||||||
difficulty.Value = ScrollGameDifficulty.Hard;
|
|
||||||
}
|
|
||||||
else if (x >= normalTime)
|
|
||||||
{
|
|
||||||
difficulty.Value = ScrollGameDifficulty.Normal;
|
|
||||||
}
|
|
||||||
}).AddTo(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StopTimer()
|
|
||||||
{
|
|
||||||
timerDisposable?.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue