simplestarの技術ブログ

目的を書いて、思想と試行、結果と考察、そして具体的な手段を記録します。

Unity:ゲームの土台プロジェクト

前書き

Unity ゲームエンジンそのものが土台といえば土台かもしれませんが、Unity でのゲーム作りの土台となると
おおよそ形は決まってくるもので、ゲームの面白さのアイディアなどはその土台の上にのせるだけ

よく上司から勧められるゲームジャムのイベントに「行こう!」という気になれないのは
この土台を作れる or いつでも引き出しから出せる状態にないからと言いたいのですが
ならば、すぐに土台を用意できるように用意しようと思った次第

これまで書いてきた記事を参照しながら、土台の作り方を詳細に記録します。

目次

最初にやるのはバージョン管理

プログラムは資産ですから、長く使うことになるだろうプロジェクトのバージョン管理は必須だと思います。
GitHub を使うのはユーザーが多くて無料という単純な理由です…

simplestar-tech.hatenablog.com

この記事には紹介は無いですが、最近は Source Tree による直感的なソース管理に切り替えています。
新規で Unity プロジェクトを作ったら、まずは空プロジェクトの状態で公開します。
README でどのようなプロジェクトにするか明記して、あとはその目標に足りていない部分を見つけて足していきましょう。

Unity の基礎実装

Unity はエディタ操作でゲーム作りのかなりの領域をカバーしています。マニュアルの各コンポーネントの概要にざっと目を通せばそれに気づけますが…
docs.unity3d.com

これを全部読み終えて感じることは、ゲーム作りの本質はC#プログラミングにあるという一点だけです。
上のマニュアルで紹介されたコンポーネントは、ブロックでいうところの「洗練されたカッコイイ部品」といった役割を果たし
それぞれを縫い合わせる糸、接続のための粘土ともいえるプログラムは、私たちが創らなければなりません。

いきなり極寒の地に裸で放り出されるわけですが、そこには基本的な縫い合わせ方や、粘土をこねる順番や型というものがあるので、そのうちの一つを今回紹介したいと思います。

成果物はこちらに公開していきます。
github.com

プロジェクトのフォルダ構成

Unity 使う上では超重要、自分のスタイルはこちら
Unity初心者向けアドバイス - simplestarの技術ブログ

ちゃんと考えたい人はこちらが参考になるかも
r-ngtm.hatenablog.com

チームロゴの表示

これ Splash Screen と言って Player Settings のこちらで設定できます。

f:id:simplestar_tech:20190106112616j:plain
Splash Screen 設定
今回適当なロゴを使ってみました。
f:id:simplestar_tech:20190106144836g:plain
スプラッシュスクリーンを自作のロゴに変更した結果
ここはプログラミング関係なかったね…

タイトル画面

上記動画にも映っている Press Space Key が点滅表示されているだけのシーン
uGUI と Animation 使うだけです。

忘れちゃった時のために、ウィンドウの出し方だけ記録しますね。

  • Window > Animation > Animation メニューをクリック
  • Create Animation をして、Properties に Text Mesh Pro Text の Font Color を指定し、キーフレームを移動してから Font Color を変更、Add KeyFrame ボタンを押す
  • 作られた .anim ファイルを Text に追加した Animation コンポーネントに設置する

タイトルメニューの表示

Space キーを押すとアクティブなパネルが切り替わる実装について記事を書きました。
simplestar-tech.hatenablog.com

パネルにて GridLayoutGroup コンポーネントを利用すると、自動的にボタンが整列して配置されるので、システマチックで整った UI を見ることができます。

f:id:simplestar_tech:20190106180144g:plain
タイトルメニューの表示とボタンイベント処理

ボタンを押すとゲームが終了するのは、ボタンに次の記事で示すスクリプトを割り当てているからです。
simplestar-tech.hatenablog.com

New Game への移行とローディング画面

少し前に作った VRM を初期フレームで読み込むシーンを NewGame としましょう。
その時のローディング中の画面表示方法について示します。

といっても以下のページを参考にしました。
gametukurikata.com

加工した Slider に次の LoadingSlider.cs をアタッチするだけです。

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(Slider))]
public class LoadingSlider : MonoBehaviour
{
    internal IEnumerator LoadCoroutine(AsyncOperation async)
    {
        while (!async.isDone)
        {
            var progressVal = Mathf.Clamp01(async.progress * 1.1f);
            if (_slider == null)
            {
                _slider = GetComponent<Slider>();
            }
            _slider.value = progressVal;
            yield return null;
        }
    }

    Slider _slider;
}

GameManager

Script 名を GameManager にするとアイコンがギアに変わります。
GameManager はゲーム内に一つだけしか存在しませんので、それを強制する C# プログラミングテクニック「シングルトン」を使います。

いつかの記事を発見、こちらを参考に GameManager クラスを作ります。
Unity:シーンに一つだけしかアタッチできないSingletonMonoBehaviour+実装例 - simplestarの技術ブログ

ファイル選択による VRM のロード

こちらのアセットを導入して、ファイル選択結果で得たパスを使ってロードするように書き換えます。
assetstore.unity.com

InputSystem の InputActions によるカメラカメラ操作

次の記事の通り
simplestar-tech.hatenablog.com

これからの Unity は新しい InputSystem を使うことになります。

高画質でスクリーンショット

機能を付けておきました。
simplestar-tech.hatenablog.com

動的地形生成

簡易的に次のコードで終わらせた。
TimeUpdate はなかなか便利

LevelPlaneGenerator.cs

using System.Collections;
using UnityEngine;

public class LevelPlaneGenerator : MonoBehaviour
{
    [SerializeField]
    GameObject levelPlanePrefab;

    void Start()
    {
        StartCoroutine(TimeUpdate());
    }

    IEnumerator TimeUpdate()
    {
        yield return new WaitForSeconds(4.0f);
        while (true)
        {
            Instantiate(levelPlanePrefab, new Vector3(_levelOffset += 2, _levelOffset / 5.0f, _levelOffset), Quaternion.identity, transform);
            yield return new WaitForSeconds(4.0f);
        }
    }

    int _levelOffset = 0;
}

土台プロジェクト完成

この記事では、次のツィートのようなゲームの土台の作り方を詳しく示しました。

去年からずっとゲームの面白さのコアな部分を作る方法を調べていたのですが
今回はフレーム的な、どんなゲームにも含まれる要素を作ってみました。

今後はこれを土台に、メインのゲーム要素を色々と載せ替えながら作業を記録していこうと思います。