はこねのはこ

はこねさんの備忘録

Unity1週間ゲームジャム[逆]"逆上がりJUMPERS"をHingeJoint2DとUniRxを使って作った話

はじめに

今回も作りました。
イラスト:はいき丸さん
f:id:hakonebox:20200303231059g:plain
unityroom.com

逆上がりで回転して遠心力でできるだけ遠くに飛ぶゲームです。
逆上がりするのに手が短すぎるのでつり革を持たせています。
これじゃ逆上がりに見えないね。

このはこねこの動きはHingeJoint2Dを採用しています。
また、何か新しいこと学びたいなと思って、
使おう使おうと思いながら全く使ってなかったUniRxを使ってみることにしました。

こちらは着地の様子。
かわいいので実際に遊んでみてほしいです。
f:id:hakonebox:20200304002007p:plain

そして遊んだ後にきっと思うと思います。 ”逆じゃん...” と。

HingeJoint2D

はこねこの動きはアニメーションを作るのではなく、
物理演算に身を任せた動きのほうが見てて楽しいし、
遊ぶうえで楽しい要素になると思い、体のパーツをHingeJoint2Dを採用しました。

特に曲がる角度に制限を設けないことにしました。
動かすとこんな感じです。
f:id:hakonebox:20200304001611g:plain

はこねことポール接続の接続は以下のようになってます。
f:id:hakonebox:20200304000612p:plain

ばらしてみるとこんな感じ
f:id:hakonebox:20200304001341p:plain

ポールの固定について

ConnectedRigitBodyをNoneとすることで
Connected Anchor 設定で定義した空間上の点に固定しています。
f:id:hakonebox:20200304000829p:plain

はこねこの接続について

こちらはポールに固定したつり革部分を設定しています。 同じようにはこねこの体におさげ、両足、しっぽを接続しています。 f:id:hakonebox:20200304001108p:plain

UniRx

github.com

ついでにMV(R)Pパターンを意識して開発しました。
ここではスコア表示の部分の紹介です。(一部抜粋)

View

気持ち程度のラベル初期化を行い、
ラベル更新用の関数を用意。

using UnityEngine;
using TMPro;

public class ScoreView : MonoBehaviour
{
    [SerializeField] private TextMeshProUGUI _scoreText;

    // Start is called before the first frame update
    void Start()
    {
        _scoreText.text = 0.ToString("#,#0");
    }

    // 値が更新されたときにラベル更新
    public void OnScoreChanged(int score)
    {
        _scoreText.text = score.ToString("#,#0");
    }
}

Model

ReactivePropertyでストリームソースの準備。

using UnityEngine;
using UniRx;

public class GameModel : MonoBehaviour
{
    private static ReactiveProperty<int> _score = new ReactiveProperty<int>(0);
    
    public IReadOnlyReactiveProperty<int> Score => _score;

    public static void SetScore(int score)
    {
        _score.Value = score;
    }
}

Presenter

値が変更になった時にラベルを変更するように設定。

using UnityEngine;
using UniRx;

public class MenuPresenter : MonoBehaviour
{
    // View
    [SerializeField] private ScoreView _scoreView;
    
    // Model
    [SerializeField] private GameModel _gameModel;
    
    void Awake()
    {
        Bind();
    }

    private void Bind()
    {
        _gameModel.Score
            .Subscribe(_scoreView.OnScoreChanged)
            .AddTo(gameObject);
    }
}

まだ自信をもって記述できてないので、
少しずつ触っていこうと思います。

1週間振り返り

2/24

今回こそはスキージャンプ台を逆走するゲームでオンライン対戦ありにしようとしてました。
意気揚々とオンライン対戦ボタンを準備。
また、PUN2の動作確認を進める。

しかし、今回もオンライン要素は見送りとなりました。
だってデバッグものすごい面倒なんだもん。

3/1

しばらく時間が空いて3/1。 このゲーム面白いのか?病が発症。
ゲームデザインの再考をし、悩んだ挙句変更を決意。

3/2

締め切り日20:00には間に合わず、翌日深夜4時までかけて開発しきりました。

びっくりするくらい進捗報告してませんでした。

さいごに

私としては、この作品はとてもよくできたと思っています。
物理演算を活かした動きは見ててかわいらしいし、
結果が出るまでの時間が短く、何度もリトライしやすいデザイン。
ここ最近、難しいことをしようとして複雑で最後まで遊びにくいものばかりでした。

かわいいイラストを描いてくれたはいき丸さんと
ゲーム内容の相談に乗ってくれた友人に感謝。