見出し画像

開発記録:unity1week 「かわる」 Jump to Change

2024/3/18~24のUnity 1週間ゲームジャム(unity1week、お題:「かわる」)に参加した四次元ベクトルです。

※この記事は気が向いたときに更新される可能性があります。

ゲームはこちらからプレイできます。

前回の制作記録・振り返り記事はこちら

今回の事前準備や目標はこちら


「Jump to Change」について

キャラクターがジャンプすると実体化したり消えたり、動いたり止まったりと状態が変わるブロックをうまく制御して、ゴールの宝箱を目指すアクションパズルゲームです。

ジャンプすると実体化したり、透明になってすり抜けられたりするブロック(オレンジ色)
ジャンプすると動いたり止まったりするブロック(紫色)

各ステージにはコイン・時間・ジャンプ数の目標があり、達成した数に応じて星が付いて記録(自動保存)されるシステムとなっています。
クリアするだけなら簡単なステージが多いのですが、星を全部集めるのはなかなか難しくそこがやり込み要素となっています。

ステージクリア画面。この場合星は1個として記録される
ステージ選択画面。これまでに獲得した最大の星の数が表示される

今回のゲームは、次の日程で開発しました。

開発記録

事前準備

今回も本イベントに向けて有給休暇(平日午後)を取得し、独創的なゲームのアイデアをいくつか出しました。

今回は、私が今までにUnityで作ったことはあるがunity1weekで出したことのないサイドビューアクションゲームを作ろうと思いました。

作るにあたってキャラクターや地面などの素材を集めようとしましたが、いい感じの素材は調べてもあまりありませんでした(トップビューゲームの素材はたくさんある)。
そこで、素材は事前に自作してストックすることに決めました。

私には絵心があまりないのですが、ドット絵はキャンバスサイズが小さくて色数も少なく、考えることが少ないので練習を兼ねて描いてみたら、いい感じに量産できました。

ついでにドット絵に合う8bit曲・効果音も自作し、unity1week本番で絵や音などの素材を集めたり作ったりする手間を削減することにしました。


また、システム面においても、私が数年前にUnityで作ったサイドビューアクションゲームのキャラクターコントローラーを改良し、アクションゲームの土台を作りました。これで、本番で書くプログラムのコードも最小限にしました。

さらに、ただジャンプしてゴールを目指すだけのアクションゲームだと面白くないので、操作を複雑にしない範囲での面白い仕掛け(ジャンプすると状態が変わる)というものも思いつきました。

以下のような、過去のunity1weekの総合ランキング上位のアクションゲームの絵作りやシステムも参考にしました。

1日目(3/18 月)

お題「かわる」を、事前に考えた上記のアイデアとそのまま、「ブロックの状態が変わる」という解釈で結び付けました。

事前に作ったキャラクターコントローラーやドット絵、BGM、効果音などをどんどんプロジェクトに投げ込みました。

地面のタイルマップは、以下の無料アセットを用いてWolf RPG Editor規格で作った画像から作成しました。

さらに、ステージごとにコインや時間、ジャンプの目標数を設定し、その達成状況をステージクリア画面に表示するようにしました。

2日目(3/19 火)

本番用のステージの制作を始めました。

ジャンプすると実体化したり透明になったりするブロックや、移動したり止まったりするブロックも実装し、さらにステージクリア状況をEasy Save(定価だと1万円くらいするが、アセットストアのセールの時に半額で購入)で保存するようにしました。
これで、ゲームの根幹部分は完成しました。

敵キャラクターも作ろうと思いましたが、本番で描くのは時間がかかるし踏みつけるなどの操作が難しくなりがちなので、敵は作らずトゲ(地形。当たるとやられる)を実装する程度にしました。

3日目(3/20 水)

下のポスト(ツイート)は前日の進捗の続きです。

エンディング画面(Thank You for Playing!)や、タイトルロゴ(Jump to Change)を作りました。
ステージもこの日までに14個できました。

4日目(3/21 木)

移動するブロックは線で軌跡を示すだけでなく、中心を表示して分かりやすくしました。
さらに、本作はキーボード操作中心のゲームなので、テンキーに対応した前回同様、音量調整もキーボードのみで操作できるようにしました。

この日までに19ステージが完成しました。

5日目(3/22 金)

最終ステージ(20面)を作成しました。
移動ブロックの中心は矢印にして、止まっているときも次に動きだす向きが分かるようにしました。

中心に矢印を表示

初回のWebGLビルドを行いました。
エディター上では正常に動いたのに、ビルドして判明した不具合は以下の3点です。

  1. 全画面モードにして戻したときに、ボタンなどの文字(TextMesh Pro)が消える

  2. Shader Graphで作った自動スクロールの背景画像が横に伸びた縞模様になってしまう

  3. 最終面がクリア不能な(宝箱が運搬されない)ことがある

上記はいずれもネットを調べたりして自己解決しました。
このうち1については、同じマテリアルを用いたTMPの文字をワールドとUIの両方で用いると発生することが判明しました。
過去作「中心を見極めろ!」でも同様の不具合が発生していましたが、まさにこれだったようです。

そこで、TMPのマテリアルをワールド(ステージ内説明文)とUI(ボタンなど)で分けました。

2については、画像(スプライト)の設定を以下のように変更することで解決しました(赤線部分を変更。黄色の線はドット絵ゲームの画像の基本設定)。なぜエディター上では設定を変えなくても正常に画像がループされるのかと思います。

Wrap Mode=Repeat(デフォルトではClamp)にする

unityroomへの投稿も行いました。

6日目(3/23 土)

X(Twitter)への画像付き投稿や、unityroom専用ランキングを実装しました。

上記の不具合3(最終面で宝箱がうまく運ばれない)はなかなか解決策が見つからず、最終面の実装をあきらめようとも思いましたが、動くブロックの上にトリガー(Box Collider 2D)を設定しそこにキャラクターや宝箱が乗るとそれがブロックの子になりブロックと連動するシステムで、宝箱が横からブロックの上面に当たるときに親子関係がうまく設定されないことによるものだと判明しました。

ブロック同士が交差していて、宝箱の右にある縦長ブロックの位置が低いと発生
[SerializeField] Transform movePoint;//移動先の空オブジェクト

[SerializeField, Tooltip("片道の移動にかかる時間")] float moveTime = 4f;

Sequence sequence;

void Start()
    {
        //…(省略)

        //2点間を往復させる        
        Vector3 startPos = transform.position;
        Vector3 direction = movePoint.position - startPos;
        ShowDirection(direction);//向きを表示

        sequence = DOTween.Sequence();
        sequence.AppendCallback(() => ShowDirection(direction));//向きを表示
        sequence.Append(transform.DOMove(movePoint.position, moveTime).SetLink(gameObject).SetEase(Ease.Linear));//移動
        sequence.AppendCallback(() => ShowDirection(-direction));//向きを表示
        sequence.Append(transform.DOMove(startPos, moveTime).SetLink(gameObject).SetEase(Ease.Linear));//逆向きに移動

        sequence.SetLink(gameObject);
        sequence.SetLoops(-1);//無限ループ

        //…(省略)

        this.OnTriggerEnter2DAsObservable().Where(other => IsGravityItem(other)).Subscribe(other =>
        {
            other.transform.SetParent(transform);//このブロックの子オブジェクトにする
        }).AddTo(this);

        this.OnTriggerExit2DAsObservable().Where(other => IsGravityItem(other)).Subscribe(other =>
        {
            Transform otherParent = other.transform.parent;//相手の親オブジェクト
            if (otherParent != null && otherParent != transform) return;//別オブジェクトの子に既になっている場合は何もしない
            if (other.gameObject.activeInHierarchy) other.transform.SetParent(null);//親子関係を切る
        }).AddTo(this);
    }

//相手が重力の影響を受けるアイテム(プレイヤーキャラクターや宝箱)か
bool IsGravityItem(Collider2D other) => other.CompareTag("Player") || other.CompareTag("Goal");

void ShowDirection(Vector3 direction)
{
    //(ブロックの中心の矢印を表示)
}

//プレイヤーのジャンプによりsequence?.Play();とsequence?.Pause();を交互に行う

動くブロックの上記スクリプトは、ブロック同士の交差を考慮し、OnTriggerExit2D(UniRxだと後にAsObservableが付く)の処理を工夫していますが、物理演算処理がWebGLだと粗くなるようでした(宝箱が振動し、ブロック上面のトリガーが横にある宝箱を子オブジェクトにしてしまう)。

そこで、ブロックの上面トリガーの幅を少し狭くするとうまくいきました。

ちなみに、動くブロックのコライダー・トリガーはどちらもBoxCollider2DのAuto TilingをONにしてブロック画像の大きさに連動するよう設定してある

また、公開後に、動くブロックの上記スクリプトのsequence(DOTweenのSequenceによるアニメーション)にSetUpdate(UpdateType.Fixed)(固定フレームレートで呼び出される)を追加し、安定性の向上(宝箱が振動しない)を期待しましたが、あまり効果はなかったようです。

7日目(3/24 日)

この日は最終的な微調整を行ったくらいで、一日ゆっくり過ごし20時の公開をのんびり待ちました。

目標の振り返り

今回の目標はみんなの評価ではなく自分の健康を大事にすることだったので、ここで振り返りをしておきます。

  • 作業1時間につき10分以上PCから離れてみる→2~3時間くらい連続で作業したことはあったが、過去回よりは短め。1時間の作業より10分何もしないほうが長く感じられたかも

    • タイマーなどを利用する→タイマーは使わなかったが、時計は意識した

    • 不具合やエラーなどが発生したりわからないことがあったりしても根を詰めないで休む

      • その際に思ったことや、次の作業時間でやりたいと思ったことを休憩前に紙にメモする→少しした

    • 軽い運動(首や肩などの体操やもみほぐしなど)を取り入れたり、家の外に出たりする→1~2時間ごとに軽く外に出たり、水曜日(春分の日)にお出かけしたりした

    • ピアノや折り紙などPC以外の趣味も取り入れる→時々ピアノを弾いてみた

  • 時短のため、

    • 自作がしやすいドット絵や8bit音楽などの素材を作り置きする→たくさん作った

    • ゲームシステムも過去作から流用できる部分はどんどん流用する→流用した

    • 外部のアセットや素材も積極的に使用する→画像や音声はほとんど自作で賄えたが、外部素材やアセットも少し用いた

  • 2Dジャンプアクションゲームを作ってみる→達成!

    • 評価の高いアクションゲームのシステムや絵作りなどを考察する→できたと思う

  • 有給休暇を利用し、もちろん遅刻しない→達成!

今回目標としていたところは多く達成できたので、後に(4/7 20時)評価が発表されてそれが低いものだとしても、落ち込まず前向きに行こうと思います。

最後に

今回も事前に作ったシステムや素材を利用し、有給休暇をうまく利用することができたので、作業時間が短めながらも5~6日で本格的なゲームができ上がり、13連続無遅刻でunity1weekに参加できました。
余った時間でデバッグや、機能の追加・改善を行えました。

私は前々回「1ボタン」でもアクション(シューティング)ゲームを作りましたが、

唯一高かった楽しさ(3.844)も物量不足(チュートリアルを除くと6ステージしかなかった)で50位に届かなかったようなので、今回はたっぷり20ステージで星を集めるやり込み要素も取り入れてみました。
絵作り(3.438)やサウンド(3.469)が低かったのも、画像や音声がよくあるフリー素材で独創性があまりない(訴求力が弱い)結果だったと思います。そこで、今回はキャラクター(次元みらい)をはじめ自作の画像・音声中心で独自性を持たせてみました。

unityroomでのプレイ・評価をよろしくお願いします!

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