競えて楽しいミニゲーム作ってみた
前書き
otasuketaiはいつも楽しいことを考えている。ユニークなことをたくさん行っているのだ。その中でwebで遊べる簡単なゲームを作ってみてほしいという依頼が私のもとに届いた。様々な議論を重ねた中で、スコアを増やす型の簡単なゲームを作ることにした。よくある、3列のステージを進んでいくゲームだ。
著者:Arata
開発要件
Unity 2021.3.8f1
完成物
ゲームタイトルは、
"Don't Stop VS Don't Worry" - ドン・ストップ VS ドンウォーリー
上記のURLから遊んでみてほしい。ランキング機能もあるので、ぜひ競い合ってみてほしい。
ゲームの概要
3列のレーンがあるステージを障害物をよけて進み続けるゲーム。
進めば進むほどスピードが上がり、生存によるスコア獲得、また寿司を獲得することによるスコア獲得の量が増えていく。
寿司を獲得することによりスコアを増やすことができるし、100個貯めると無敵時間を作ることができる。
ピザを手に入れることによりシールドを纏うことができ、次の衝突を防ぐことができる。プレイヤーの操作は横移動とジャンプのみで、これらを活用して生存を目指す。
寿司とピザはユニバの恒例行事「スピ会(寿司ピザ会)」から着想を得た。
WEBゲームを作るエンジンを考える
webゲームを作るツールというのはかなりある。中心にあるのは、JavaScriptを用いたものである。主なものはPhaseやPlayCanvasである。しっかり作りたいというのであれば、こちらを使ってほしい。しかし、今回は私の興味も込めた意味でUnityのWebGLを用いた開発を行うことにした。こちらならiOSへの移行もできますし。
ゲーム機能の実装方法について解説
プレイヤーの動き
このゲームのプレイヤーは動いていない。逆に、ステージのほうが動く仕組みになっている。そのため、プレイヤーの動きはジャンプと横移動だけである。こちらはシンプルで、UnityのCoroutineを用いてそれぞれ行っている。物理的なところは用いず、単純な座標移動だ。以下はジャンプのCoroutine。座標を少しずつ何度も時間を少しおいて移動させている。iをもちいて重力加速度がかかったようなジャンプを実現する。
IEnumerator Jump()
{
for(int i=1; i<50; i++)
{
transform.Translate(0, 0.1f-i*0.004f, 0);
if (!(i==39))
{
yield return new WaitForFixedUpdate();
}
}
inJump = false;
canMove = false;
}
ステージの動き(床)
床の動きだが、こちらは配列を用いた処理を行っている。床を隙間ないようにスポーンさせ、それを配列に代入。配列の要素ごとに移動の処理を行い、プレイヤーの後ろに移動すると、一番後ろの列に戻されるといったような処理である。
void Start()
{
timerScript = timerObject.GetComponent<StartTimer>();
for (int i = 0; i < step.Length; i++)
{
step[i] = Instantiate(stage[i], new Vector3(5 * i, 0, 0), Quaternion.Euler(0, 90, 0));
}
}
void FixedUpdate()
{
if (timerScript.totalTime<=0.5)
{
for (int i = 0; i < step.Length; i++)
{
step[i].gameObject.transform.position -= new Vector3(speed * Time.deltaTime, 0, 0);
if (step[i].gameObject.transform.position.x < disappear)
{
step[i].gameObject.transform.position = new Vector3(respawn, 0, 0);
}
}
}
}
ステージの動き(障害物)
床と同じような仕組みで作っている。ただ違うのは、毎回プレイヤーを通り過ぎたのちにその障害物をランダムに変更しているということだ。30種類近くの障害物があり、それらをランダムに入れ替えながら障害物のランダム感を作っている。(最初からステージを作るというほうが楽かもしれないが限界が来るので)
for (int i = 0; i < 5; i++)
{
step[i].gameObject.transform.position -= new Vector3(speed * Time.deltaTime, 0, 0);
if (step[i].gameObject.transform.position.x < disappear && count<=20)
{
Destroy(step[i]);
step[i] = Instantiate(enemy[Random.Range(0,24)], new Vector3(90 , -6, 4.7f), Quaternion.Euler(0, 90, 0));
count += 1;
}
スピードの変遷
ゲームが退屈にならぬように、ゲームのスピードが時間がたつほど上がるようになっている。こちら最初はステージ自体のスピードを上げていたのだが、これではジャンプのスピードが追い付かず限界が来てしまうため、ゲーム自体を早送りするようにした。
ランキングシステム
ランキングシステムはこちらのサイトを参考にして行った。非常に簡単にできるようなプラグインを作成してくださっており、何の障害もなく簡単に取り付けることができた。
寿司パワーゲージ
これがたまると無敵時間を作り出せるような設定になっている。ゲージは寿司をとるほど増えるようになっており、この値とスクリプト内で計算している寿司の数は別で管理している。たまるとReadyという文字が点滅するようになっている。Readyの文字は最初透明になっている。Lerp関数を用いて緩やかな移動を可能にした
if(sushi >= 100)
{
ready.color = Color.Lerp(startColor, endColor, Mathf.PingPong(Time.time / duration, 1.0f));
}else
{
ready.color = new Color32(255, 255, 255, 0);
}
これからの課題
・難易度によるスコア獲得調整---スコアの稼ぎやすい難易度とそうでないものがある。今のままだとHardが最も稼ぎやすいかもしれない。しかしこれは調整が難しく、個人の得手不得手にもよるので難しいところだ
・難易度---今のままだと簡単すぎる可能性がある。無限に進み続けることができるというところがある。これだと時間をかければいいということになる。より難易度を大きく上げる仕組みにするか。調整が難しい。
・より多くの機能---今のままだと機能が少ない。アイテムも2種類しかないので、奥深さがなく、退屈である。
まとめ
今回はotasuketaiの業務で私が作成したスコアを競えるゲームについて解説してきた。UnityのWebGLで開発をおこなったけれども、特に障害というものは感じなかった。それ以外のエンジンを試してみる必要があるけれども、Unityでもいいように感じた。技術的なところはシンプルなので、より複雑にするためにもアイテムの追加を考えてもよいかもしれない。
Otasuketaiについてはこちら
Otasuketaiが所属するユニバ株式会社についてはこちらをご覧ください