見出し画像

【Unity】Unity1Week【Re】に参加!【備忘録】

しょう@ゆっくり学ぶチャンネルです。
今回もunityroom主催のゲームジャム、unity1weekに参加しました。
自分は3回目の参加です。今回のお題は【Re】でした。

自分はフラッピーバード風のトナカイを題材にしたゲームを投稿しました。
トナカイは英語で「Reindeer」なので、お題のReを無理やり達成したことにしました。

フラッパーバード風のゲームはUdemyの以下の講座を参考にしました。

講座のゲームから変えたところは以下の点です。

  1. 画像、UIの差し替え

  2. スプラッシュスクリーンの差し替え

  3. 自分のTwitterアカウントとWebページへのリンクボタンの導入

  4. BGM、SEの導入

  5. 雪を表現するためのパーティクルの導入

  6. 音量調節機能の導入

  7. チュートリアル画面の導入

  8. 多重背景スクロールの導入

  9. オンラインランキングの導入

  10. 結果ツイート機能の導入

いずれも過去に入れたことがある機能なので、目新しいことはしていませんが、新しい気づきもありましたので、記述していこうと思います。
なお、今回のゲームジャムで自分は2回挫折(失敗)しました。

第一の失敗・使ったことがないアセットを使おうとした

少し前に凝りもせずにまたアセットを購入しました。どうせ使いこなせませんが、もう若手Unityクリエイターやアセット作家への寄付だと思って買ってます。

↓こんなんとか

↓こんなんとか

使うだけで見た目が豪華になるので、作った街の中を走るだけで目を引くゲームになりそうじゃないかなと思ったのですが、開くのクッソ重い…。
URP対応のユニティちゃんを走らせようと思ったのですが、これもクッソ重い…。
ゲームができたとしても、もしかしたらWebGL環境では開かないと思い、諦めました。
ちなみにURP対応のユニティちゃんですが、通常バージョンのユニティちゃんと違い、パッケージ化されていないので、アセットとして使うには、一度プロジェクトとして開いて、自分でパッケージ化する必要があります。
詳しくは以下の記事を参照して下さい。

↓参考にしようと思ったゲーム。お題のReと結びつけることができなかった。

第二の失敗・音楽の知識がない上に、興味がないのに音ゲーを作ろうとした

お題のReですが、ドレミファソラシドのレとも読めます。
じゃあ、レが異常に高得点な音ゲーでも作ればいいのではと思い、以下の記事を参考に音ゲーを作りました。

この講座を受講すると、確かに奥側から手前側にノーツが向かってくるタイプの音ゲーが作れます。
でも譜面の作り方が力業なんですよね。C#スクリプト上で「何秒にノーツ発生」みたいなコードを一つ一つ打っていくので、膨大に時間がかかる恐れがあり、他のノーツ生成の方法を調べました。すると以下の動画を発見しました。

MIDIデータを再生すると、音が鳴るタイミングでノーツが生成されるという凄い仕組みを使っているので「これだ!」と思いましたが…MIDIデータの扱い方がわかりませんでした…。
フリーのMIDIデータを使ったり、MP3音源をMIDIデータに変換してみたりしたのですが、動画中で使用しているMIDIデータみたいにノーツが生成されないんですよね…。
でもこの動画で初めて「タイムライン」という機能を知り、使ってみたのは勉強になりましたね。

ここで木曜日終了。あと金、土、日しかなく、日曜日の20:00がデッドラインです。

そして、簡単に作れるゲームをまず作って、そのクオリティを上げようという考えにシフトし、できたのが「走れ!トナカイ!」というわけです。以下作業備忘録となります。

走れ!トナカイ!の作業リスト

画像、UIの差し替えについて

いらすとやとOKUMONOを多用しました。特にOKUMONOの背景は使うだけでオシャレになるので、凄くおススメです。

雪を表現するためのパーティクルの導入

以下の記事を参考に色々いじっていたらできます。

今回の作品では「生存期間の外力」を有効にし、X=-10とすることで、雪を横殴りにして、吹雪を表現しています。

パーティクルシステムのインスペクタ(1/2)
パーティクルシステムのインスペクタ(2/2)

スプラッシュスクリーンの差し替え、結果ツイート機能の導入

以下の過去の記事を参照してください。追記はありません。

チュートリアル画面の導入

タイトル画面のスタートボタンを押した時には操作説明を表示してからスタートし、ゲームオーバー後のリトライボタンを押したときには操作説明を表示せずにスタートさせたかったので、変数をどう使おうか考えていましたが、気づいてしまいました。操作説明のためだけのシーンを用意すればいいのだと…。つまり以下のようなシーン遷移の流れとなります。

Titleシーン→スタートボタン押す→Tutorialシーン→OKボタン押す→Mainシーン→リトライボタン押す→Mainシーン→タイトルボタン押す→Titleシーン

自分のTwitterアカウントとWebページへのリンクボタンの導入、BGM、SEの導入

省略。

多重背景スクロールの導入

なんか毎回悩んでいる気がします…。
今回は以下の通りで右から左に背景が流れるコードを書きました。

using UnityEngine;

public class ScrollBack : MonoBehaviour {
    public float speed;
    [Header("デッドライン")] public float deadLine;
    [Header("リスポーンライン")] public float respawnLine;
    public float posY;//画像のY座標

    void Update() {
        //左方向にスクロール
        transform.position -= new Vector3(Time.deltaTime * speed,0,0);

        //XがDeadLineまで来れば、RespawnLineまで移動する
        if (transform.position.x < deadLine) {
            transform.position = new Vector3(respawnLine,posY,0);
        }
    }
}

背景画像を画面内(少し左にはみ出させる)、画面左、画面右、さらにその右に配置します。
そして一番右の背景画像以外にスクリプトをアタッチします。
デッドラインを画面左に置いた背景画像のX座標、リスポーンラインを一番右の背景画像のX座標とし、一番右の背景画像は削除します。
今作はこれを三列行い、列ごとにspeedを変えることで遠近感を表現しています。

オンラインランキングの導入

初めて参加したゲームジャムでも導入しました。

今作はゲームオーバー時に以下のようなコードを読み込んでいます。

 // Type == Number の場合
 naichilab.RankingLoader.Instance.SendScoreAndShowRanking(score);

あと今回はランキング画面のフォントや画像を差し替えています。
以下の場所にあるRankingシーン(ビルドに含まれるシーンに追加するシーン)を開いて、差し替えるだけなので簡単です。

【重要】音量調節機能の導入

以下の記事で導入した際の手順を書いたのですが、今回それを見ても、しばらく意味が解らなかったので、あらためて記述します。
なおサウンドマネージャーを導入していることが前提です。サウンドマネージャーの作り方も以下の記事内に記述しています。

1.以下の記事を参考に、Sliderを準備するところまで進める。

2.以下のコードを空のオブジェクトなどにアタッチし、AudioVolumeのPrefabを作ります。
データのロード、セーブにはEasySaveを使用していますが、floatなのでplayerprefsでも問題ありません。

using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.UI;

public class AudioVolume : MonoBehaviour {
    public AudioMixer audioMixer;//オーディオミキサーを登録
    public Slider bGMSlider;//BGMのスライダーを登録
    public Slider sESlider;//SEのスライダーを登録

    private void Start() {
        //BGMとSEのスライダーの位置をロード。データがなければ最大値を入れる。
        float bgmSliderPosition = ES3.Load<float>("BGM_SLIDER", 5.0f);
        float seSliderPosition = ES3.Load<float>("SE_SLIDER", 5.0f);
        //BGMとSEのセットメソッドを呼び出す
        SetBGM(bgmSliderPosition);
        SetSE(seSliderPosition);
    }

    public void SetBGM(float bgmSliderPosition) {
        //スライダーの位置から相対量をdBに変換してvolumeに入れる
        var volume = Mathf.Clamp(Mathf.Log10(bgmSliderPosition/5) * 20f, -80f, 0f);
        //スライダーの位置のデータとビジュアルを合わせる
        bGMSlider.value = bgmSliderPosition;
        //オーディオミキサーにvolumeの値をセットする。
        audioMixer.SetFloat("BGM", volume);
        //スライダーの位置をセーブする。
        ES3.Save<float>("BGM_SLIDER", bGMSlider.value);
    }

    public void SetSE(float seSliderPosition) {
        var volume = Mathf.Clamp(Mathf.Log10(seSliderPosition/ 5) * 20f, -80f, 0f);
        sESlider.value = seSliderPosition;
        audioMixer.SetFloat("SE", volume);
        ES3.Save<float>("SE_SLIDER", sESlider.value);
    }
}

3.BGMSliderとSESliderの「値の変更時(Single)」を以下の画像を参考に変更します。

AudioVolume.SetBGM(SetSE)であることに注意。
下のほうにSetBGM(float)とSetSE(float)があるので注意。

4.以下のように記述して、音量を確かめましょう。

soundManager.PlaySe(SE);
soundManager.PlayBGM(BGM);

SoundManagerとAudioVolumeは別々のPrefabにしたほうがいいと思います。AudioVolumeはSliderを探しますが、SoundManagerは以下のようにDontDestroyOnLoadとして運用するので、同じPrefabにするとSliderがないシーンでは消失となり、対策が必要なります。
それならば、AudioVolumeはSliderのあるシーンにしか置かないPrefabとするのが手っ取り早いです。
AudioVolume、SoundManager、BGMSlider、SESlider、オーディオミキサーは他のプロジェクトでもすぐ使いまわせます。

using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.SceneManagement;

public class SoundManager : MonoBehaviour
{
    [SerializeField] AudioMixer audioMixer;
    [SerializeField] AudioSource bgmAudioSource;
    [SerializeField] AudioSource seAudioSource;

    public static SoundManager instance;
    void Awake() {
        CheckInstance();
    }
    void CheckInstance() {
        if (instance == null) {
            instance = this;
        } else {
            Destroy(gameObject);
        }
    }

    void Start() {
        DontDestroyOnLoad(gameObject);//シーン遷移しても破棄されない
    }

    /// <summary>
    /// BGMを再生
    /// </summary>
    /// <param name="clip"></param>
    public void PlayBgm(AudioClip clip) {
        bgmAudioSource.clip = clip;
        bgmAudioSource.Play();
    }

    /// <summary>
    /// BGMを停止
    /// </summary>
    public void StopBgm() {
        bgmAudioSource.Stop();
    }

    /// <summary>
    /// 効果音を再生
    /// </summary>
    /// <param name="clip"></param>
    public void PlaySe(AudioClip clip) {
        seAudioSource.PlayOneShot(clip);
    }

    /// <summary>
    /// 引数のAudioClipの中からランダムに再生
    /// </summary>
    /// <param name="clips"></param>

    public void RandomizeSfx(params AudioClip[] clips) {
        var randomIndex = UnityEngine.Random.Range(0, clips.Length);
        seAudioSource.PlayOneShot(clips[randomIndex]);
    }
}

今回の反省点

  1. ゲームジャムでは使い慣れないアセットを使おうとしない

  2. ゲームジャムでは作ったことがないジャンルのゲームを作ろうとしない

  3. 備忘録は正確に書く

  4. 汎用アセットや汎用Prefabを今以上にしっかり用意して、効率化を図る

↓汎用アセットについての記事

参考にしようと思ったが、できなかった記事

この記事が気に入ったらサポートをしてみませんか?