【Unity 入門】《第1回》大砲で弾を撃つ|シューティングゲームを作ろう!


Unity入門のゲーム作成チュートリアル第4弾の「城防衛シューティングゲーム」です!

襲来してくる敵を大砲で迎撃し、城を守りきることができれば勝利というゲームを作成していきます。

城防衛完成イメージ
完成イメージ

※そのほかのゲーム作成記事に関する情報は以下記事をご参考ください。

参考記事)Unity入門オリジナルチュートリアル集

第1回の今回は「大砲で弾を撃つ」方法をご紹介します。

作成する大砲は1.カメラと連動して動き(一人称視点)2.特定キーを押すことで弾を発射するという仕組みです。

準備(フォルダ構成)

フォルダ構成

まずはじめにファイルを整理するためにフォルダを準備します。

後々フォルダを追加する可能性もありますが、準備段階では基本的な要素を保存しておくためのフォルダを作成します。

Assets下に以下のフォルダを作成してください。

  • Assets
    • Fonts・・・フォント
    • Images・・・画像
    • Items・・・アセットストアで取得したアセット
    • Materials・・・マテリアル
    • Prefabs・・・プレハブ
    • Scenes・・・シーン
    • Scripts・・・C#スクリプト
Shooting_folder
フォルダ構成

このようにそれぞれのファイルを種類別に保存しておくことで開発環境を整えることができます。

また、保存にはゲーム要素ごとにフォルダを作成することもできます。

例えば今回の例を用いると、大砲関連のファイルを保存しておくための「Cannon」フォルダ、敵関連のファイルを保存するための「Enemy」フォルダ、フィールド情報を保存するための「Field」フォルダ・・・などのようにゲーム要素ごとにファイルを整理する方法もあります。

今回は種類別に保存する方法を採用しますが、ゲーム要素ごとの保存方法を利用していただいても全く問題ありません。

カメラと連動した動きを実現する

いよいよここからゲーム作成に入ります!

まずは大砲とカメラの動きを連動させます。

以下のような流れでこの機能を実装していきます。

  1. カメラを矢印キー入力で360度向きが変わるようにする
  2. カメラの向きと大砲の動きを連動させる(親子オブジェクト)

準備(大砲をアセットストアからダウンロードする)

この章はアセットをダウンロードしてくるだけですので手短に説明します。

まずはアセットストアで「Victorian PBR Cannon」と検索して以下のアセットをダウンロード・インポートしてください。

Victorian PBR Cannon

このように無料でありながらクオリティの高いアセットがストアには多数あります。自作する前に一度アセットストアを探してみるのも良いかもしれません。

参考サイト)Unity Asset Store

インポートしたフォルダはItemsフォルダに移動しておきましょう。

カメラを矢印キー入力で360度向きが変わるようにする

準備

まずはじめにカメラのポジションを全て0(ゼロ)に変更します。

MainCameraポジション
MainCamera_Transform

次にカメラが回転していることを把握するために一時的にオブジェクトを配置します。キューブなどの適当なオブジェクトをカメラの周りに配置してください。(わかりやすくするためのものですのでどんなオブジェクトを置いていただいても構いません)

オブジェクト配置例(任意)
オブジェクト配置例(任意)

ここで配置したオブジェクトを任意の空オブジェクトの子オブジェクトにしておくと後で削除するときにわかりやすいです。

(ここでは空オブジェクト「Debug」の子オブジェクトにしておきます)

Debugオブジェクトの子オブジェクトに設定
Debugオブジェクトの子オブジェクトに設定

カメラを回転させるスクリプトを作成する

カメラを回転させるスクリプトを作成していきます。

カメラを回転させるときの条件として、あらかじめ回転に制限(上下左右どこまで回転可能か)を設けます。

このように設定することで後ほどの開発がスムーズに進みます。

それではScriptsフォルダに「CameraController」スクリプトを作成して以下のように編集してください。

注目してほしい部分をピックアップして説明します。

7行目〜14行目を確認してください。

ここではエディターから値を指定する変数を宣言しています。

「[Range(float,float)]」を変数宣言の前につけることで値の範囲を制限することができます。その範囲外の値を入力することができなくなるためとても便利です。このように範囲を指定することでユーザーが予期しない数値を入力することを防ぎます。

Rangeで値を指定するとエディターでは以下のように値を指定できるようになります。メインカメラにスクリプトをアタッチして確認してみてください。

Rangeによる値の範囲指定
Rangeによる値の範囲指定

それぞれの値は速度や回転範囲を制限するための変数です。

22行目〜35行目を確認してください。

左矢印キーが押されたときの処理を記述しています。

「if ( Input.GetKey( KeyCode.LeftArrow ) )」で左矢印キーが押されていることを確認します。押されている間中はこの中の処理を実行します。

中では以下のような処理をしています。

  1. カメラの左方向の角度が制限範囲を超えていないか判定
    1. 超えている場合、以降の処理を実行しない
    2. 超えていない場合、以降の処理を実行
  2. 現在の回転角度に指定したスピード分だけ加算する
  3. 縦方向に回転するためにX軸を軸として回転する

ここではQuaternionに関する詳しい説明は省略しますが、詳しく知りたいという方は以下記事をご参考ください。

参考記事)Quaternionでオブジェクトを回転させる方法

この処理を上下左右全てで実装することでカメラの回転を実現します。

このスクリプトをメインカメラにアタッチして実行してみましょう。

CameraController動作確認
CameraController動作確認

矢印キーで回転することが確認できました。

カメラの向きと大砲の動きを連動させる

次にカメラの向きと大砲の動きを連動させます。

まずは大砲を呼び出しましょう。

Items→Victorian PBR Cannon→Prefab→Cannonをシーンビューにドラッグ&ドロップしてください。

ヒエラルキーウィンドウで新しく作成されたCannonを右クリックしてUnpack Prefabを選択してプレハブ化を解除しておきましょう。

Cannon呼び出し
Cannon呼び出し&プレハブ解除

新しく作成したCannonを丁度良い位置に移動します。

ポジションの値を( X, Y, Z ) = ( 0, -1.5, 1 )に変更してください。

CannonのTransform
CannonのTransform
Cannonの位置
Cannonの位置

これだけではカメラだけが回転してしまいますのでCannonをメインカメラの子オブジェクトに変更します。

Cannonを子オブジェクト化
Cannonを子オブジェクト化

これによってCannonが親オブジェクトであるメインカメラの座標を基準にするので動きが連動します。

実際に確認してみましょう。

カメラと大砲が連動
カメラと大砲が連動

シーンビューで見ると台座ごと動いてしまっているため違和感がありますが、きちんとカメラと大砲の動きを連動させることができました。

弾を発射する

ここから球を発射する方法をご紹介します。

以下のような流れでこの機能を実装していきます。

  1. 弾のプレハブを作成する
  2. 作成したプレハブを特定キー入力で生成する
  3. 弾に勢いをつけて発射する

弾のプレハブを作成する

まずはじめに弾のプレハブを作成します。

ヒエラルキーウィンドウのCreateからSphereを作成して、名前を「Bullet」としてください。

作成したBulletのスケールの値を全て0.3に変更してください。(ポジションの値は後ほどスクリプトで変更しますので任意です)

BulletのTransform
BulletのTransform

次に色を変更します。

プロジェクトウィンドウのCreateからMaterialsフォルダにMaterial「BulletColor」を作成してください。

作成したらBulletColorを選択して色を変更します。色の変更はColorウィンドウで変更可能です。

BulletColorを変更
BulletColorの色を変更

マテリアルの色を変更したら、BulletColorをBulletにドラッグ&ドロップすると色を変更できます。

Bulletの色を変更
BulletにBulletColorをアタッチ

次に弾に重力が発生するようにします。

Bulletを選択してインスペクターウィンドウ最下部のAddComponent→Physics→Rigidbodyを選択してアタッチしてください。

BulletにRigidbodyをアタッチ
BulletにRigidbodyをアタッチ

これでBulletに対して重力が発生するようになります。

最後にBulletをプレハブ化してヒエラルキーウィンドウから削除すれば大砲の弾のプレハブは完成です。

プレハブにしたいオブジェクトをプロジェクトウィンドウの任意のフォルダにドラッグ&ドロップすることでプレハブ化することができます。プレハブ化したらヒエラルキーウィンドウのBulletは削除しておきましょう。

Bulletをプレハブ化
Bulletをプレハブ化

作成したプレハブを特定キー入力で生成する

先ほど作成した弾のプレハブをスペースキー入力で大砲の先端に生成します。

まずは大砲の先端がどこにあるかをわかりやすくするためにポジションだけに意味があるオブジェクト「BulletPos」を作成します。

ヒエラルキーウィンドウのCreateからCubeを選択して名前を「BulletPos」としてください。

作成したら、BulletPosをCannonの子オブジェクトにします。

BulletPosを子オブジェクト化
BulletPosをCannonの子オブジェクトにする

Cannonの子オブジェクトに変更したのち、BulletPosのTransformを以下のように変更してください。

BulletPosのTransform
BulletPosのTransform
BulletPosの位置
BulletPosの位置

これで大砲の先端をマーキングすることができました。

この位置にあればゲームビューで見えないのであまり気にする必要はないかもしれませんが、このオブジェクトはあくまでPositionの値のみを利用するため描画する必要がありません。

MeshRendererをオフにすることで描画をキャンセルできます。

MeshRendererをオフにする
MeshRendererをオフにする

これによってBulletPosが描画されなくなりました。

描画されなくなったBulletPos
描画されなくなったBulletPos

これで下準備は完了です。

ここから実際にBulletを生成するスクリプトを記述していきます。

Scriptsフォルダに新しいスクリプト「CannonController」を作成し、以下のように編集してください。

注目してほしい部分をピックアップして説明します。

7行目〜12行目を確認してください。

ここでは先ほど作成したプレハブを格納するための変数と弾が生成される場所を保存する変数、弾のスピードを保存する変数の3つを宣言しています。現段階ではspeedは利用しません。

17行目〜23行目を確認してください。

スペースが押されたときに中身を実行します。

中身は「Instantiate(bullet) as GameObject」によってプレハブを生成し、GameObject型の変数「createdBullet」に格納します。

次にcreatedBulletのポジションをあらかじめ決定しておいたbulletPosのポジションに変更して完了です。

これでスペースが押されるたびに大砲の先端にbulletが生成されます。

作成したCannonControllerをアタッチするための空のオブジェクト「CannonController」を作成してスクリプトをアタッチ、BulletプレハブとBulletPosをスクリプトにアタッチしてください。(一連の流れは以下GIFをご参考ください)

CannonControllerを作成
CannonControllerを作成

実際に実行して確認してみましょう。

Bulletをスペースキーで生成
Bulletをスペースキーで生成

スペースキーを押すことでBulletが生成されることが確認できました。

弾に勢いをつけて発射する

次にこの生成した弾に勢いをつけて発射します。

先ほど作成したCannonControllerスクリプトを以下のように編集してください。(追加した部分をマーク)

付け加えた部分によって弾の向きと力を決定してBulletに加えることで弾を発射します。

実際に実行して確認してみましょう。

弾を発射
弾を発射

弾を発射できていることが確認できましたが、これだと非常に見づらいです。そこで弾の発射角度を変更します。

方法は簡単で、先ほど作成したBulletPosの向きを少しだけ上向きにすることで改善することができます。

理由は今回弾の向きをBulletPosの向きに設定しているため、このオブジェクトの向きを変えると弾の発射角度も変わります。

今回はBulletPosのRotationのXを-15に変更してください。

BulletPosの向きを変更
BulletPosの向きを変更

それでは改めて実行してみましょう。

弾の発射角度を変更
弾の発射角度を変更

弾が綺麗に発射されるようになりました。

まとめ

いかがでしたでしょうか。

弾の発射は簡単なスクリプトを作成するだけで実装できることがお分りいただけたでしょうか。

次回は敵を作成して大砲で敵を倒す方法をご紹介します。

敵と弾との当たり判定やエフェクトの作成など、よりゲームらしい要素の作成を進めていきます。

※そのほかのゲーム作成記事については以下記事をご参考ください。

参考記事)Unity入門オリジナルチュートリアル集


Furui