ステゴカップ

錬成したらスライムだった件 / 2024ステゴカップ

https://github.com/Conken-NitKit/2024_HACKZ_STEGO_CUP

GitHub

Azure

Unity

魔物の素材を入手して合成!自分だけの最強スライムを作っちゃおう!

林壱仁_++志井++

Aizaki Sohshun

推しアイデア

ただ錬成するだけじゃない!ステージをクリアしたり敵を倒すことで素材を集めて多種多様なスライムを錬成! どういうふうにクリアするかはあなた次第!

作った背景

自分だけの最強スライム、欲しくないですか

推し技術

Unity最新バージョンであるUnity6 Previewを使用! 今まで使用していたRx系ライブラリUniRxに変わって次世代Rx「R3」を使用! Spring Jointを用いてスライムの動きを完全再現!

プロジェクト詳細

2024_HACKZ_STEGO_CUP

ゲームについて

タイトル

錬成したらスライムだった件 錬スラ

概要

スライム錬成系横スクロールアクションゲーム。

素材を選択してスライムを錬成!大きさ、粘着度などのパラメータによって多種多様なスライムを錬成してステージをクリアしよう!

素材はステージクリアや敵を倒すことで手に入るぞ!より強いスライムを作るためにはより強大な敵と戦わなければいけないのだ!

企画書

1_0 2_0 3_0

フォルダ管理について

基本Assetの中しかいじらないです。

Assets ├── DownLoadAssets │   ├── DOTween │   └── Zenject └── MyAssets ├── Commmon //共通して使うもの │   ├── Animations //アニメーション入れるとこ │   ├── Fonts //フォント入れるとこ │  ├── Musics //曲入れるとこ │   │ ├── SEs //効果音を入れるとこ │   │ └── BGMs //音楽入れるところ │   ├── Prefabs //プレファブ入れるとこ │   ├── Scripts //コード入れるとこ │   ├── Sprites //画像入れるとこ │   └── 同階層の他のフォルダの中身も大体こんな感じです    ├── Develops │   └── 個人の開発シーンの置き場    ├── GameOver    ├── InGame    ├── MakeSlime    ├── MaterialLibrary    ├── Result    └── Title

クラス図

Hackthon

SlimeCoreに基本的に必要な情報を集め、関連するコードを抽象クラスBaseSlimeComponentを継承することで情報の受け渡しや初期化のタイミングをそろえているような構成になっています。 Enemyも大体同じような設計になっています。

スライムの挙動の実装について

スライムのやわらかい挙動はUnityのSpringJointという機能を活用して実装しています。 SpringJointは2つの物体間(または、1つの物体と空間の点)の間にばねのように働く力を加えることができます。 これを複数の球の間に働かせると、全体がまとまりつつある程度緩さがある物体ができます。下の図は赤で実際のJointのつなぎ方を示したものです。 image

また、スライムの粘着性もSpringJointを用いています。先ほどの小球が他の物体と接触したときそこに非常に短いばねを作ることで、小球と他の物体の間に粘着力が働いているような挙動になります。こちらは一定以上大きい力が加わることで接合が切れるようにしています。

描画はSprite Skin機能を使用しています。円のテクスチャの外周部分にBoneが仕込んであり、Boneは小球の位置に追従させています。Sprite Skin機能によってテクスチャがBoneの影響を受け変形し、全体が1つのスライムであるように見えるようになります。
同時に糸が引いているような表現でベトベト感を演出しています。これは粘着性を実現しているSpringJointをLineRendererで可視化したものです。

使用技術

Unity 6

今回使用したUnity 6は、正確にはUnity 6ではなくそのプレビュー版です。 正式リリース前のお試し利用、早めに利用することで最新バージョンのリリースに備えたいようなエンジニアのためのバージョンになっています。 使えそうだったので使いました。

この段階から機能追加、破壊的変更は行われなくなるらしい。

今までと何が違うの? 第一にレンダリングパフォーマンス。 今回は利用する機会はなかったですが、ユニバーサルレンダーパイプラインやHD レンダーパイプラインに大きくパフォーマンス強化が入ったことで、CPU フレーム時間を最大 50%も削減できるとのこと。

第二にライティングの強化。 一言で言えば、ライティング周りで機能拡張があったことによって昼夜の切り替えだったり照明周りのライティングがしやすくなったことで細かい表現の調整ができるようになったとのこと。

そして個人的に面白いなと思っているのがマルチプラットフォームの充実。 元々Unity自体はいろんなプラットフォームに対してビルドが可能だったのがさらに便利に。 特にAndroid、iOSはWeb上でアプリを動かすことができるようになっため、ウェブビューにアプリを乗せて実行する、なんてこともできるようです。

R3

イベント管理を行うことのできるライブラリです。 元々UnityにおいてRx系といえばUnirxというくらいには蔓延っていましたが、2020年を最後にUniRxの更新がストップ。それからしばらく音沙汰がありませんでしたが、今年に入ってからUniRxの製作者neuecさん主導でCysharpが新しいライブラリR3を開発しました。 その目的は既存のRxの再定義、再実装。現在、非同期処理のベストプラクティスはasync/awaitですが、それに比べるとRxは価値が低下。実装自体も古いC#で実装していたため、機能面でもかなり劣っていました。async/awaitとの共存や、最新のC#の環境に合わせるためにR3は作られました。

例えばどんなことが変わったの? 1番面白い変更はObservableの定義について。 元々、Observable はSystem定義のインタフェースに依存していましたが、R3ではSystem定義のインタフェースに依存していない独自の抽象クラスObservableとして定義されています。

RxとR3のObservableを比較すると、変更されているのはOnErrorとOnCompletedの挙動です。 元々Rxでは例外が発生した時はOnErrorを発行し、そのままObservableは動作を停止するように作られていました。

(たかだか)例外一個出ただけでイベントが止まると困る場面が出てきます。破棄されたObservableを再構築するのもパフォーマンス的にはいかがなものかと、そういった問題を解決するために、OnErrorで動作を停止するのはなく、例外を通知しObservable自体の寿命は関係しないOnErrorResumeが追加されました。

また、既存のOnErrorとOnCompletedは統合されてOnCompletedになり、停止理由が送ることが可能になっています。

個人的にこのことを表す1番好きな一文が**「すべてのObservableは「完了」する」**元々の実装を考えるとかなり大胆な変更がされていることがよくわかりますね。

これ以外にも今までを振り返ってよりよく実装され直している部分が多々あります。 使用感的にはあまりUniRxとは違いは大きく感じませんが、より深いところを見てみるとなかなかに面白いです。

R3なし

クラスAは自身の変数を変更したときにクラスBを参照して、クラスBのメソッドを発火する必要があります。 この時クラスBはクラスAのことを知る必要はありません。

image

R3あり

クラスAが自身の変数を変更したという通知をクラスBが受け取ることでクラスBが自身の処理を発火させます。 この時クラスAはクラスBのことを知る必要はありません。

image

例の場合、変更を行う、変更から処理を行うの関係が1 : 1の関係なので、いまいちピンと来ないかも知れませんが、変更から処理を行うクラスがもしも複数個あった場合、変更を行うクラスはそれだけたくさんのクラスを参照することになります。

image

依存性の逆転を行うことで、それぞれの変更から処理を行うクラスは変更を行うクラス1つを参照すれば良いため、擬似的に1 : 1の関係を生み出すことができます。

image

今回は、データとUIを完全にわけ、データ間でのやりとりやUIの表示を行いやすくしました

DoTween

高品質なアニメーションを行うことのできるライブラリです。 例えば三角形を上に移動させたい時は以下のコードを1行書くだけで動画のように動きます。

this.gameObject.transform.DOMove(Vector3.up * 2, 3);

image

動きながら回転は以下のように

this.gameObject.transform.DOMove(Vector3.up * 2, 3); this.gameObject.transform.DORotate(new Vector3(0, 0, 360), 3, RotateMode.FastBeyond360);

image

ちょっと力を貯めて

this.gameObject.transform.DOMove(Vector3.up * 2, 3).SetEase(Ease.InBack); this.gameObject.transform.DORotate(new Vector3(0, 0, 360), 3, RotateMode.FastBeyond360).SetEase(Ease.InBack);

image

といった具合に簡単にアニメーションを行うことができます。

今回は、ほぼ全てのシーンにおいて、アニメーション実装で用いました。

Azure PlayFab

Azureのゲーム向けのサービスです。 ランキングの実装、プレイヤーごとに報酬を渡す実装などが簡単に出来ます。

今回はfirebaseを使おうとしましたが、Android、iOS版にしか対応していなかったので断念。 どれだけ素材を入手しているかを記録するためのDBとして利用しました。

メンバー

  • 5年佐藤 - 画面のUIデザイン、遷移処理
  • 4年林 - マネジメント、メインロジック実装
  • 3年荒巻 - ステージ製作
  • 2年相崎 - スライムの挙動作成、エネミーの実装

林壱仁_++志井++

@ITI0820