Skip to main content

ボールプレハブはどんどん生成

作ったプレハブを利用し、実行中にたくさんのボールを生成しましょう。

ボール生成する:BallShooter

今度のスクリプトは:

  • 作成したプレハブを Inspector で指定できるようにする。
  • マウスの左ボタンを押したら、プレハブから実際に使うオブジェクトを生成。
  • 最大数を制限する。

スクリプトの変数

Scripts フォルダーの中に新しい「BallShooter」を追加し、Inspector の変数を準備しましょう:

using UnityEngine;

// ボールを生成するスクリプト
public class BallShooter : MonoBehaviour
{
    // Unityでボールのプレハブを指定
    [SerializeField]
    private GameObject ballPrefab;
}

当然、プレハブ変数の「型」は「GameObject」になる。

マウス処理&ボール生成:Update()

フレーム毎に、マウスボタンのクリックがあったかどうかを確認し、クリックの場合は、プレハブから実物を生成し、実行中にシーンに追加しましょう:

void Update()
{
    // もしも左ボタンをクリックしたら…
    if (Input.GetMouseButtonDown(0))
    {
        // 「Instantiate」を使い、プレハブから実物(インスタンス)を作成
        // newBallは新しく作ったボールの参照である
        var newBall = Instantiate(ballPrefab); 
    }
}

ボールを生成するのは、プレーヤーなので、「player」オブジェクト(パドル)にアタッチして、Ball Prefabの中に、前ステップで作ったボールのプレハブを設定してください。

image.png

これを追加することにより、プレーヤーは移動だけではなく、ボール生成もできるようになった!

1スクリプト⇒1責任

1スクリプト⇒1責任

スクリプトが長ければ、長いほど、バグの修正が辛くなり、ゲームの拡張性が狭まる。基礎ルールとして、「1つのスクリプトは1つの責任」の考えすると、大きな課題を解決しやすい細かい課題に分割し、それぞれが別々のスクリプトで実装する。

これで、機能を増やしたり、減らしたりするのは簡単(スクリプトを追加と削除だけ)。また、スクリプトが短くなるので、バグが発生した場合、すぐ解決できることもメリットである。

考えられる例
  •  武器を打つ:ShootWeapon
    • CPUプレーヤー、人間プレーヤーが関係なく、打つことが可能

  • 体力を表示:HPGauge
    • なんでものHPを表示(プレーヤー、敵、壊せるものなど)

  • プレーヤーを追いかける:FollowPlayer
    • 敵に付けると、プレーヤーを追いかける
    • 仲間に付けると、プレーヤーを追いかける
  • アイテム:Item
    • アイテムを表す

  • アイテムを拾う:ItemCollect
    • アイテム(Item)を拾ったら、インベントリに追加

  • アイテムを管理:Inventory
    • アイテムどこから来たのか関係なく、アイテムを管理

  • アイテムを購入:ItemBuy
    • アイテム(Item)をショップで購入し、インベントリに追加

 

この状態で実行して確認してみてください。

問題発見

いっぱいのボールが現れて楽しいが、いくつかの問題の確認ができた

  1. ボールがたまに遅くなる?
  2. プレーヤーの位置が関係なく、ボールがいつも同じ場所から現れる
  3. ボールが多すぎる。

1. ボールが遅くなる?

超弾みしたのに、なんでボールが遅くなる?これは正しい物理の計算の影響であるため。ビリヤードのように、ある物体は別の物体を移動すると、速度を伝達する(運動量の伝達という)

image.png

image.png

固定物体(壁)とぶつかると、強く跳ね返すが…

…移動可能な物体とぶつけると、速度が移る!

これを直すには、実行中に速度を調整し、指定した「speed」を守るようにする。「BallMove」スクリプトを調整し、フレーム毎は以下の処理にしましょう:

// これは「BallMove」スクリプトの更新処理
void Update()
{
    // 現在の速度ベクトルを取得。向きは保護したいが、
    // 長さ(速度)は必ず「speed」であることを保証
    var velocity = _rigidbody.linearVelocity;
    
    // まず、速度ベクトルの長さは「1」にする(単位ベクトル)
    velocity.Normalize();
    
    // そして、長さは「speed」にしよう
    velocity *= speed;
    
    // 速度を上書きする
    _rigidbody.linearVelocity = velocity;
}

2. ボールがいつも同じ場所から現れる

3. ボールが多すぎる