ステージ自動生成対応

This commit is contained in:
kimura 2022-07-25 10:57:04 +09:00
parent f1f0df1a95
commit 3c03aa99e9
1 changed files with 87 additions and 27 deletions

View File

@ -6,54 +6,114 @@ namespace MyGame.Scenes.MiniGame.Scripts
{ {
public class StageManager : MonoBehaviour public class StageManager : MonoBehaviour
{ {
[SerializeField] private BackGround[] backGrounds;
[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 int generateStageCount;
[SerializeField] private float beginStageOffset;
[SerializeField] private float partsToPartsOffset;
private Transform[] stagePrefabs;
private Transform[] stages; private Transform[] stages;
private float stageEndXPos;
private float cacheTargetXPos;
public IObservable<float> OnFence => fenceSubject; public IObservable<float> OnFence => fenceSubject;
private readonly Subject<float> fenceSubject = new(); private readonly Subject<float> fenceSubject = new();
public IReadOnlyReactiveProperty<ScrollGameDifficulty> Difficulty => difficulty;
private readonly ReactiveProperty<ScrollGameDifficulty> difficulty = new();
private IDisposable timerDisposable;
private void Start() private void Start()
{ {
fenceSubject.AddTo(this); fenceSubject.AddTo(this);
difficulty.AddTo(this);
} }
public void SetBeginStages(Transform[] newStages) public void SetBeginStages(Transform[] newStages)
{ {
difficulty.SetValueAndForceNotify(ScrollGameDifficulty.Easy);
stagePrefabs = newStages;
stageTarget.DestroyAllChildrens(); stageTarget.DestroyAllChildrens();
stages = new Transform[newStages.Length]; stageEndXPos = stageTarget.position.x + beginStageOffset;
var selectIndex = UnityEngine.Random.Range(0, stages.Length); cacheTargetXPos = stageEndXPos;
for (var i = 0; i < newStages.Length; i++) GenerateStage();
}
private void GenerateStage()
{
var selectIndex = UnityEngine.Random.Range(0, stagePrefabs.Length);
for (var i = 0; i < generateStageCount; i++)
{ {
stages[i] = Instantiate(newStages[i], stageTarget.position, Quaternion.identity, stageTarget); var stage = Instantiate(stagePrefabs[selectIndex], stageTarget.position + Vector3.left * 100f, Quaternion.identity, stageTarget);
stages[i].gameObject.SetActive(i == selectIndex); var minPos = float.MaxValue;
} var maxPos = float.MinValue;
stages[0].FindAllChildrensComponent<StageItem>(x => var holePos = float.MinValue;
{ stage.FindAllChildrensComponent<StageItem>(x =>
if (x.ItemType != StageItem.Type.Hole)
{ {
return; var xPos = x.transform.position.x;
minPos = Mathf.Min(minPos, xPos);
maxPos = Mathf.Max(maxPos, xPos);
// 落とし穴があった場合通知
if (x.ItemType != StageItem.Type.Hole)
{
return;
}
holePos = xPos;
});
var xPos = stage.position.x;
var minDiff = minPos - xPos;
var maxDiff = maxPos - xPos;
stage.SetPositionX(stageEndXPos - minDiff);
// endPos更新
stageEndXPos = stage.position.x + maxDiff + partsToPartsOffset;
// ステージの破棄
Observable.Interval(TimeSpan.FromSeconds(.5f))
.Where(_ => stageEndXPos < cacheTargetXPos)
.Subscribe(_ =>
{
Destroy(stage.gameObject);
}).AddTo(this);
if (holePos > float.MinValue)
{
Observable.NextFrame().Subscribe(_ => fenceSubject.OnNext(stage.position.x + holePos - xPos)).AddTo(this);
} }
Observable.NextFrame().Subscribe(_ => fenceSubject.OnNext(x.transform.position.x)).AddTo(this);
});
}
public void SetSky(ScrollGameDifficulty difficulty)
{
foreach (var backGround in backGrounds)
{
backGround.SetSky(difficulty);
} }
} }
public void GenerateStage()
{
}
public void UpdatePos(float targetXPos) public void UpdatePos(float targetXPos)
{ {
cacheTargetXPos = targetXPos;
if (stageEndXPos - targetXPos <= stageGenerateDistance)
{
GenerateStage();
}
}
public void StartTimer()
{
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();
} }
} }
} }