半ニートブログ

最低限の収入で生き永らえながら、人生の不安と向き合うブログです

Unity備忘録: トップビューの移動制限

ほげぴよです。

しばらく触っていませんでしたが久々にUnityの記事を書きたいと思います。

 

今回はUnity公式のサンプルシューティングゲームを使用しています。

検証したバージョンはUnity2017.2.0f3です。

unity3d.com

 

サンプルコードのプレイヤー移動関数を見てみると画面端に移動しないように移動制限が記述されています。

 

// 機体の移動
void Move (Vector2 direction)
{
    // 画面左下のワールド座標をビューポートから取得
    Vector2 min = Camera.main.ViewportToWorldPoint (new Vector2 (0, 0));

    // 画面右上のワールド座標をビューポートから取得
    Vector2 max = Camera.main.ViewportToWorldPoint (new Vector2 (1, 1));

    // プレイヤーの座標を取得
    Vector2 pos = transform.position;

    // 移動量を加える
    pos += direction * spaceship.speed * Time.deltaTime;

    // プレイヤーの位置が画面内に収まるように制限をかける
    pos.x = Mathf.Clamp (pos.x, min.x, max.x);
    pos.y = Mathf.Clamp (pos.y, min.y, max.y);

    // 制限をかけた値をプレイヤーの位置とする
    transform.position = pos;
}

 

ただこのコードだと4:3の解像度にしか対応しておらず、16:9等の解像度に変更して左右に余白ができたりするとプレイヤーが余白まで移動することができ、背景画像に接触しなくなった時点でプレイヤーが消失してしまいます。

(詳しい説明は割愛しますがDestroyAreaの処理が関係しています)

 

私は余白部分に情報を乗せる画面レイアウトを実現させたかったので、背景オブジェクトの端座標を取得してプレイヤーを移動を制限させることにしました。

 

public class Player : MonoBehaviour
{
    // 背景画像
    GameObject bg;

    // Spaceshipコンポーネント
    Spaceship spaceship;

    void Awake()
    {
        // 背景オブジェクトを取得
        bg = GameObject.Find("Backgrounds/Back");
    }

 

~~~省略~~~

 

    // 機体の移動
    void Move (Vector2 direction)
    {

        // 背景左下の座標を取得
        Vector3 min = bg.GetComponent<Renderer>().bounds.min;

        // 背景右上の座標を取得
        Vector3 max = bg.GetComponent<Renderer>().bounds.max;

        // プレイヤーの座標を取得
        Vector2 pos = transform.position;

        // 移動量を加える
        pos += direction * spaceship.speed * Time.deltaTime;

        // プレイヤーの位置が画面内に収まるように制限をかける
        pos.x = Mathf.Clamp (pos.x, min.x + 0.32f, max.x - 0.32f);
        pos.y = Mathf.Clamp (pos.y, min.y + 0.38f, max.y - 0.38f);

        // 制限をかけた値をプレイヤーの位置とする
        transform.position = pos;
    }

※赤字部分は追加コードです

 

 まずAwakeを追加してそこでHierarchy上にある背景画像のオブジェクトを取得します。

public宣言をしてInspector上で直接指定する方法は手軽ですが、自機はプレハブから生成される仕様となっていますのでHierarchy上のオブジェクトを指定することができません。なのでGameObject.Find関数を使用してそこから取得しています。

 

次が今回のキモとなる部分です。

ビューポートからではなく取得した背景オブジェクトから座標を取得します。これによってプレイヤーの移動範囲を背景上に制限することができます。

 

Mathf.Clampに追加した値は変更前のままだと自機が半分はみ出していたのでオフセット値を与えて画面外から出ないようにしています。この辺りはお好みで。

 

以上の追加・変更を行って実行すると自機が画面外にはみ出すことはないはずです。