【Unity】一週間ゲームジャム「あつい」でUniRXを使ってTurboSobaを作ってみました。
今回の一週間ゲームジャムのテーマは「あつい」なので、熱い蕎麦を配達するゲーム「TurboSoba」を作ってみました。
- テーマについて
- TurboSobaのタイトルの由来
- ゲームのコンセプト
- 開発の工夫
- レベルデザイン
- 音楽について
- アイテムアイコンなどの素材について
- 今後のブラッシュアップについて
- ゲームジャムに参加してみて
テーマについて
冒頭でも書きましたが、テーマがあついなので、熱き蕎麦を配達するゲームを作ってみようと思いました。
TurboSobaのタイトルの由来
以前PlayStatoinのゲームでJet Motoというゲームがあり、そのCMでJet Sobaという人物が登場していました。このCMではあくまでネタとしてのキャラクターでしたが、このJet Sobaがやけに印象に残っていて、このキャラクターを主役にしたゲームを作ってみたいという気持ちがあり、今回のゲームジャムで作ってみることにしました。(ただJet Motoは実は遊んだことがありません。。)
Jet Sobaのような名前で勢いのある単語として、TurboSobaとネーミングしてみました。
ゲームのコンセプト
今回タイトルは決まっていたので、タイトルを元にゲームの内容を決めることにしました。タイトルにターボとついているので、加速要素を取り入れ、蕎麦を使ったゲームということで配達がよぎったので、加速しながら配達していくゲームを作ってみることにしました。ただ実際に配達になると、蕎麦屋と出前先を往復したりするのはゲームとして億劫になってしまいそうなのと、ルールの簡略化を図るために、蕎麦を集めるゲームにしてみました。
開発の工夫
今回各コンポーネントとの連携でUniRXを使いたいと考えていたので、各機能ごとにclassを分割し、UniRXによって各機能を連携させるようにしてみました。
例えば音楽の再生などはプレイヤーがターボ状態の時や残り時間が少なくなってきた時に、専用の音楽を再生したかったので、音楽再生用のClassで BoolReactivePropertyなどを使い、状態の変化に応じて再生する音楽を変更するようにしてみました。
SoundController.cs
音楽専用のClass、プレイヤーとタイマー管理を監視して、フラグが更新されたら専用の音楽を再生するようにしてみました。
SoundController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UniRx;
using UniRx.Triggers;
using TurboSoba.Scripts.Player;
using TurboSoba.Scripts.Timecontroller;
// 音楽管理
namespace TurboSoba.Scripts.Sound
{
public class SoundController : MonoBehaviour
{
[SerializeField]
private AudioClip StageNormal;
[SerializeField]
private AudioClip StageHurry;
[SerializeField]
private AudioClip StageTurbo;
private AudioSource audioSource;
void Start()
{
var player = GameObject.Find("Player");
var playerCore = player.GetComponent<PlayerCore>();
var timeController = GetComponent<TimeController>();
audioSource = GetComponent<AudioSource>();
playerCore.isPlayerTurbo.Subscribe(x =>
{
if (x)
{
Play(StageTurbo);
}
else
{
if (timeController.isTimeHurry.Value)
{
Play(StageHurry);
}
else
{
Play(StageNormal);
}
}
});
timeController.isTimeHurry.Subscribe(x =>
{
if (x)
{
Play(StageHurry);
}
else
{
Play(StageNormal);
}
});
}
void Play(AudioClip audio)
{
audioSource.clip = audio;
audioSource.Play();
}
}
}
PlayerCore.cs
プレイヤーの状態管理用Class。ターボ状態のフラグなどをUniRX化しておき他のClassと連携できるようにしてみました。(ターボはコルーチンを併用して、一定時間が経つと更新されるようになります。ただ追加でターボを取得した時に時間が上書きされないので、少し見直そうと考えています。)
PlayerCore.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UniRx;
using UniRx.Triggers;
using TurboSoba.Scripts.Item;
// プレイヤー状態管理
namespace TurboSoba.Scripts.Player
{
public class PlayerCore : MonoBehaviour
{
// ターボ継続時間
[SerializeField]
private int turboTime;
public bool isPlayerStan { get; set; }
/// ターボフラグ
public BoolReactiveProperty isPlayerTurbo = new BoolReactiveProperty();
void Start()
{
isPlayerStan = false;
isPlayerTurbo.Value = false;
}
// 外部から呼び出されるターボ切り替えメソッド
public void Turbo()
{
StartCoroutine(TurboCoroutine());
}
/// ターボ中に実行されるコルーチン
private IEnumerator TurboCoroutine()
{
//ターボフラグON
isPlayerTurbo.Value = true;
//待機
yield return new WaitForSeconds(turboTime);
//ターボフラグOFF
isPlayerTurbo.Value = false;
}
}
}
TimeController.cs
時間管理用Class。時間の表示と時間フラグ(ハリー状態、タイムオーバー状態)をUniRX化して、他のClassと連携できるようにしてみました。
(Viewの部分は別Classに分離した方がよいので、こちらも見直そうと思います。)
TimeController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UniRx;
using UniRx.Triggers;
// ゲーム時間管理
namespace TurboSoba.Scripts.Timecontroller
{
public class TimeController : MonoBehaviour
{
public Text scoreText;
public float GameTime;
public int HurryTime;
public int RecoverTime;
private int currentTime;
// ハリーフラグ
public BoolReactiveProperty isTimeHurry = new BoolReactiveProperty();
// タイムオーバーフラグ
public BoolReactiveProperty isTimeOver = new BoolReactiveProperty();
void Start()
{
isTimeHurry.Value = false;
}
// Update is called once per frame
void FixedUpdate()
{
GameTime -= Time.deltaTime;
currentTime = (int)GameTime;
scoreText.text = "Time " + currentTime.ToString();
TimeCheck();
}
public void TimeCheck()
{
// timeover
if (currentTime < 1)
{
isTimeOver.Value = true;
}
// hurryup
if (currentTime == HurryTime)
{
isTimeHurry.Value = true;
}
else if (currentTime > HurryTime && isTimeHurry.Value)
{
isTimeHurry.Value = false;
}
}
public void PickupTime()
{
GameTime += RecoverTime;
}
}
}
レベルデザイン
最終日まで開発をしていたので、あまりゲームステージのレベルデザインには時間をかけられませんでしたが、ProGridsを使うことで障害物やアイテムなどの設置が比較的容易に行うことができました。ただそんなに素材が用意ができなかったので、改良の際はより街並みを再現できるようにしていければと思います。ローポリなどの技術も磨いたり、普段から素材をある程度作っておく必要があると実感しました。
バイクの素材としてBikers、ビルの素材として、Block Building Packを使ってみました。
音楽について
今回音楽作成ではiOSアプリのPlayGroundというアプリを使ってみました。画面をタップするなどするだけで音楽が簡単に作れるので、今回のゲーム作曲でかなり便利でした。(1時間くらいで今回のゲーム用音楽を作曲できました。)
テンポの調整などもできるのでターボ時や残り時間が少ない時の音楽なども比較的作りやすかったです。
アイテムアイコンなどの素材について
蕎麦のアイテムアイコンなどの素材を以下のサイトから使わせていただきました。ありがとうございます!
地面の素材は私の別のブログで以前作ったものを適用してみました。
今後のブラッシュアップについて
登場人物など設定がけっこう浮かんできたので、今回その一部を元に3Dモデリングなどもしてみようかなと思ったのですが、限られた期間内ではなかなか難しかったため、こちらは今後アップデートしていく際に作っていければと思います。登場人物の設定などをしていくにあたりストーリーなども色々浮かんできたので、もう少し作り込んだらスマートフォンアプリ化してみるのもよいかなと思いました。
ゲームジャムに参加してみて
前回参加した時も感じましたが、やはり完成させるということが大事だと思います。
アウトプットして初めて自分の力になっていくことが実感します。今後もゲームジャムに限らず短いスパンでいくつかゲームを作ってみる習慣を作っていければと思います。