シューティングゲームを作ろー
コード解説編はこちらから!
Unityって?
ユニティ・テクノロジーズ社が提供しているゲームエンジンです。もっとも有名なゲームエンジンの中のひとつとされており、Pokemon GO、原神、Among Usなど、様々なゲーム制作に利用されています。
Unityダウンロード、プロジェクトのダウンロード
https://qiita.com/51hamu51/private/19a7dd5a05885a2f3af8
事前に、上の記事でUnity、プロジェクトのダウンロードを終わらせておいてください!
バージョンは2021.3.25f1を使います
準備をしよう
プロジェクトを開くと、こんな画面が出てきます。(名前とか配置とかは少し違うかもです)
タブ(HierarchyとかGameとか)は、名前のところや境目のところにカーソルを合わせてドラッグすることで位置や大きさを自由に編集できます。(PCの画面分割のイメージ)
自分の操作しやすい配置を見つけてみてください!
各タブの説明
タブ名 | できること |
---|---|
Hierarchy | ゲームの世界に配置したオブジェクト(物体)を階層表示します |
Scene | このタブで直接オブジェクトを動かしたり、ゲーム画面に表示するボタンや文字などのUIを配置したりします |
Game | ゲームをプレイしたときに見えるのと同じ画面が表示されます。ゲームを実行する環境に合わせて縦横の比率を設定したりできます |
Project | スクリプトや画像、プレハブなど、ゲームで使用するファイルがここに表示されます |
Console | スクリプトにエラーがあったときとかにConsoleにエラーメッセージが表示されます。ログを出したときもここに表示されます |
Inspector | 各オブジェクトの詳細な設定をしたりするところです |
自分の触りたいタブがみつからないときは、各タブの右上にある3つの点のマークをクリックして、AddTabから開きたいタブを選択してください。
画面設定
Gameタブを開き、FreeAspectとなっているところをクリックして16:9に変えておいてください。
mainシーンの作成
シーンって?
ゲーム画面ごとに必要なオブジェクトとコンポーネントをまとめたデータのこと。
タイトル画面、実際にゲームをプレイするメイン画面、クリア画面とかでそれぞれのシーンに分けることが多いです。
実際に作ってみる
プロジェクトタブでAssets配下のScensを開き、右クリックしてください。
下画像のようなメニューが出るので、Create→Sceneを選んでシーンを作成します。
新しく作成したものの上で右クリックし、renameを選んでMainSceneという名前にしてください。
今後も、何か新しく作るときはCreateで作成した後、renameで名前を変更という操作を行います。
最後に、MainSceneをダブルクリックで開いてください。
下画像のように、左上のシーン名がMainSceneになっていたら成功です。
プレイヤーの配置、移動
Assets/SpaceShooterAssets/Artwork/player内のplayer1(戦闘機の絵の方)をシーン上に配置してください。
projectタブでplayer1を選択し、Hierarchyタブにドラッグ&ドロップで配置できます。
配置したら、Hierarchyのplayer1を右クリックし、名前をPlayerに変えておいてください。
このままだと小さくて見えずらいので、大きくします。
Playerを選択した状態でInspectorタブを開き、Scaleのところを全部5にしてください。
次に、当たり判定を付けていきます。
Inspectorの下にあるAddComponentをクリックし、BoxCollider2DとRigidbody2Dを追加してください。
BoxCollider2D(当たり判定)の大きさをPlayerに合わせていきます。
BoxCollider2DのEditColliderをクリックするとSceneに緑色の線が出てきます。
(見ずらい人は、Sceneでマウスのホイールをくるくるすると拡大縮小できます!)
緑の線の真ん中をドラッグすることで当たり判定の大きさを調整できます
大体でいいので調整してみましょう
次にRigidbody2Dを調整します。
まず、GravityScaleを0にしてください。(このまま1にしておくとゲーム開始後すぐに落下していきます)
次にConstrainsを開き、FreezeRotationにチェックを入れてください。
いよいよスクリプトを実装していきます。スクリプトの細かい意味は記事では説明しないので、気になった人は質問してください!
Assets/Scriptsで右クリックして、PlayerManagerスクリプトを作成してください。
(create→C#Scriptです)
作製したらダブルクリックでスクリプトを編集できます。
最初にエディターを開くときには上のような画面が出てきます。好きなものを選んで大丈夫です。
この記事では、VisualStudioCode を使用します。
エディターが開けたら、下のスクリプトをそのままコピペしちゃいましょう!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerManager : MonoBehaviour
{
/// <summary>
/// プレイヤーの移動速度
/// </summary>
public float _moveSpeed = 5f;
void Update()
{
Move();
}
/// <summary>
/// プレイヤーの移動
/// </summary>
private void Move()
{
//矢印キーまたはWASDで操作できる
float x = Input.GetAxis("Horizontal") * _moveSpeed;
float y = Input.GetAxis("Vertical") * _moveSpeed;
transform.position += new Vector3(x, y, 0) * Time.deltaTime;
}
}
出来たら、セーブしてUnityに戻ってください。
Ctrl+Sでセーブできます。
エディター上で保存した後Unityに戻ると下のような画面が出て、少し待つと消えます。
以上でスクリプトの作成ができました!
スクリプトを作成しただけでは何も起こらないので、Playerにスクリプトをアタッチしていきます。
HierarchyタブでPlayerを選択すると、InspectorタブでPlayerが選択された状態になります。
その状態でInspectorタブの一番下のAddComponentをクリックし、PlayerManagerを選択することでアタッチできます。
セーブして実行しましょう。
Ctrl+Sでセーブできます。
作業が消えたら困るので、特に指示がなくてもセーブはこまめに行っておくことをおすすめします。
次に、画面の上の方の再生ボタン(▶)をクリックすると実行できます。
ボタンが青くなっている状態で、WASDや矢印キーを使って動かすことができます!
ここからどんどんゲームっぽくしていきましょう
弾を発射
プレハブって?
Prefabとは再利用を可能にしたアセットです。複数の場所に同じものを配置したいときに大活躍します。
Webでいうコンポーネントみたいな感じ(合ってる?)
弾のプレハブを作ろう
Playerを作ったときと同じ感じで作っていきます
Assets/SpaceShooterAssets/Artwork/shoot内のshoot1(弾の絵の方)をシーン上に配置
scaleを全部5にする
名前をBulletに変える
Playerと被って見にくいので、位置を変えます
HierarchyでBulletを選択した状態で、Sceneで左の上から二番目のマークをクリックしてください。
矢印が出てきて、それをドラッグすると好きな場所に移動できます
次に、BulletにもBoxCollider2DとRigidbody2DをAddComponentからアタッチしてください。
アタッチできたら、先ほどと同じ要領でBoxCollider2Dの大きさを変更し、Rigidbody2DのGravityScaleを0にしてください。
それができたらプレハブ化します。
ProjectタブでAssets/Prefabsを開いた状態で、HierarchyのBulletをProjectタブにドラッグ&ドロップしてください。
上の画面のようになったらもうBulletはシーン上になくていいので、選択してdeleteで消してしまいましょう。
弾を生成しよう
いよいよ弾を発射できるようにします。
発射するにはまず発射する場所を作る必要があります。
Playerを選んだ状態で右クリック→CreateEmptyでオブジェクトを作成してください。名前はFiringPositionにします。下の画像のようになっているはずです。
作製出来たら、positionのxを0.2にしておいてください。
次に、PlayerManagerスクリプトを変更します。
先ほど作ったスクリプトを上書きする形ですべてコピペしてください。
(興味がある人は、どこが変わったかとかを見比べてみてください)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerManager : MonoBehaviour
{
/// <summary>
/// プレイヤーの移動速度
/// </summary>
public float _moveSpeed = 5f;
/// <summary>
/// 弾のプレハブ
/// </summary>
public GameObject bulletPrefab;
/// <summary>
/// 弾を発射する場所
/// </summary>
public GameObject firingPosition;
void Update()
{
Move();
Shot();
}
/// <summary>
/// プレイヤーの移動
/// </summary>
private void Move()
{
//矢印キーまたはWASDで操作できる
float x = Input.GetAxis("Horizontal") * _moveSpeed;
float y = Input.GetAxis("Vertical") * _moveSpeed;
transform.position += new Vector3(x, y, 0) * Time.deltaTime;
}
/// <summary>
/// 弾を発射
/// </summary>
private void Shot()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Instantiate(bulletPrefab, firingPosition.transform.position, transform.rotation);
}
}
}
UnityにもどってPlayerのInspectorをみるとこんな感じになっていると思います。このままでは動かないので、bulletPrefab、firingPositionをアタッチします。
bulletPrefabはProjectタブから、firingPositionはHierarchyから、「None」となっているところにそれぞれドラッグ&ドロップすることでアタッチできます。
こんな感じになるはずです!
実行すると、スペースキーを押すことで弾が生成できます。
弾が前に飛ばないので、今からそれを修正します。
弾が飛ぶようにしよう
Assets/ScriptsでBulletスクリプトを作成してください。
(右クリック→Create→C#Script)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
/// <summary>
/// 弾のスピード
/// </summary>
public float bulletSpeed = 10f;
void Update()
{
BulletMove();
OffScreen();
}
/// <summary>
/// 弾の動きを管理
/// </summary>
private void BulletMove()
{
transform.position += new Vector3(bulletSpeed, 0, 0) * Time.deltaTime;
}
/// <summary>
/// 弾が画面外に出たら
/// </summary>
private void OffScreen()
{
if (this.transform.position.x > 10f)
{
Destroy(this.gameObject);
}
}
}
Assets/PrefabsからBulletを選び、InspectorからAddComponentでアタッチできます。
この状態で実行すると、生成した弾が前に飛ぶようになっています!
敵を追加
弾を撃っても、敵がいないと面白くないですよね。
というわけで敵を作成します。
弾が当たると消える敵を作ろう
Assets/SpaceShooterAssets/Artwork/enemy内のenemy1(戦闘機の絵の方)をシーン上に配置
名前をEnemyに変更
InspectorのTransformで、scaleを全部4、posotionのxを6にする
BoxCollider2DとRigidbody2DをAddComponentからアタッチしてください。
アタッチできたら、先ほどと同じ要領でBoxCollider2Dの大きさを変更し、Rigidbody2DのGravityScaleを0にしてください。
次に、Bullet.csを変更を加えていきます。以下のようにすべて書き換えて(コピペして)ください
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
/// <summary>
/// 弾のスピード
/// </summary>
public float bulletSpeed = 10f;
void Start()
{
}
void Update()
{
BulletMove();
OffScreen();
}
/// <summary>
/// 弾の動きを管理
/// </summary>
private void BulletMove()
{
transform.position += new Vector3(bulletSpeed, 0, 0) * Time.deltaTime;
}
/// <summary>
/// 弾が画面外に出たら
/// </summary>
private void OffScreen()
{
if (this.transform.position.x > 10f)
{
Destroy(this.gameObject);
}
}
/// <summary>
/// 何かとぶつかったら
/// </summary>
/// <param name="collision">ぶつかった物体の情報</param>
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Enemy"))
{
Destroy(collision.gameObject);
Destroy(this.gameObject);
}
}
}
Enemyのタグを変更します。タグとは、オブジェクトについている目印みたいなものです。
Untaggedとなっているところをクリックし、AddTagを選んでください
+ボタンを押し、Enemyと入力してsaveボタンを押してください
下の画像のようになったら成功です。
Hierarchyでもう一度Enemyを選択してInspectorからTagを選択しようとするとEnemyが選べるようになっているので、それを選んでください。Tagの表示が変わるはずです
この状態で実行しましょう。撃った弾が敵に当たると、敵が消えます!
やっとシューティングゲームっぽくなってきました
敵が自動で出てくるようにしよう
Enemyをプレハブ化します。
Bulletのときと同様に、Assets/PrefabにEnemyをドラッグ&ドロップします。
プレハブ化できたら、HierarchyにあるEnemyは削除しましょう。
(右クリック→deleteもしくは選択してdeleteキー)
敵を管理するオブジェクトを作ります。
Hierarchyタブで右クリックし、CreateEmptyを選択してください。
名前はEnemyManagerにします。
次に、EnemyManagerスクリプトを作成し、下のスクリプトをコピペしてください。
(Assets/Scriptsのなかで右クリック→Create/C#Script→名前を変更→ダブルクリックで編集画面)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyManager : MonoBehaviour
{
/// <summary>
/// 敵を生成する間隔
/// </summary>
public float generateInterval;
/// <summary>
/// 敵のプレハブ
/// </summary>
public GameObject enemyPrefab;
void Start()
{
//決まった時間ごとにSpawn()を実行
InvokeRepeating("Spawn", generateInterval, generateInterval);
}
/// <summary>
/// 敵をランダムな位置に生成
/// </summary>
private void Spawn()
{
Vector2 randomPos = new Vector2(8f, Random.Range(-4f, 4f));
Instantiate(enemyPrefab, randomPos, transform.rotation);
}
}
作製出来たら、先ほど作ったEnemyManagerオブジェクトにEnemyManagerスクリプトをアタッチします。
次に、「None」となっているところにEnemyのプレハブをアタッチします。
Assets/PrefabsからEnemyをドラッグしてきてください。
最後に、生成間隔を指定します。
GenerateIntervalで、整数または小数で指定してください。
実行すると、敵が一定間隔で出てくるようになりました!
敵が動くようにする
敵が動かないとゲームっぽくないので、敵を動かすスクリプトを作ります。
Assets/ScriptsでEnemyスクリプトを作成し、下のスクリプトをコピペしてください。
(Assets/Scriptsのなかで右クリック→Create/C#Script→名前を変更→ダブルクリックで編集画面)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public float moveSpeed;
void Update()
{
Move();
}
/// <summary>
/// 敵の移動
/// </summary>
private void Move()
{
transform.position += new Vector3(-moveSpeed, 0, 0) * Time.deltaTime;
}
}
Enemyプレハブにアタッチするのを忘れないようにしてください。
Enemyプレハブを選択し、InspectorのAddComponentからアタッチできます
MoveSpeedを自由に変更してください。
敵がこっちに向かってくるようになりました!
後編に続きます