Unity2D:指定した角度とスピードで物体を移動させる

unityのロゴ画像 Unity

45度、90度などといった角度と、速度をそれぞれ指定すればその方向に弾などが飛んでいくスクリプト例です。シューティングゲームの弾などに応用できる考え方です。

こんな感じのものを作ります。

シーンの準備

まずはUnity 2Dでプロジェクトを作成します。

Assetに飛んでいく物体としてtamaというスプライト画像を用意しました。

使ったのは以下の画像です。(右クリックして 名前を付けて画像を保存… でダウンロードできます。Assetsフォルダにドラッグ&ドロップしてお使い下さい)

シーンにスプライト画像を配置します。

シーンの準備は以上です。

スクリプトの作成

BulletControllerという名前でC#スクリプトを作成します。

スクリプトに以下を記述します。

BulletController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BulletController : MonoBehaviour
{
    // 速度
    public float Speed;
    // 角度
    public float Angle;
    // 移動ベクトル
    Vector3 vec;

    // Start is called before the first frame update
    void Start()
    {
        // 角度をラジアンに変換
        float rad = Angle * Mathf.Deg2Rad;
        // ラジアンから進行方向を設定
        Vector3 direction = new Vector3(Mathf.Cos(rad), Mathf.Sin(rad), 0);
        // 方向に速度を掛け合わせて移動ベクトルを求める
        vec = direction * Speed * Time.deltaTime;
    }

    // Update is called once per frame
    void Update()
    {
        // 物体を移動する
        transform.position += vec;
    }

    // カメラに表示されなくなった時、消去する
    private void OnBecameInvisible()
    {
        Destroy(gameObject);
    }
}

BulletControllerスクリプトをシーン上のスプライト画像にアタッチします。

Inspectorウインドウを確認すると以下のようにSpeed(速度)Angle(角度)が設定できるようになっています。

この状態で、シーン上のスプライトをAssetsにドラッグ&ドロップしてプレハブ化しておきます。

プレハブ名はBulletとしておきました。(プレハブ化したのでシーン上のスプライトは削除して大丈夫です)

例として、シーン上に1つ配置したBulletプレハブのSpeedAngleとした場合の実行イメージです。

角度0が、右方向となります。
反時計回りに1周すると360度です。

イメージ

Bulletプレハブを3つシーンに配置し、Speed全て3Angleをそれぞれ右から60, 90, 120とした場合の実行イメージです。

スクリプトの解説

速度角度から移動ベクトルを求めるため以下変数を宣言しています。

// 速度
public float Speed;
// 角度
public float Angle;
// 移動ベクトル
Vector3 vec;

速度(Speed)と角度(Angle)はpublic宣言のためInspectorウインドウから設定できます。

ポイントはスクリプト開始時に行われるStartメソッドの処理です。

角度(Θ)が分かれば、下図のようにcos、sinを使ってX方向とY方向のベクトルを求めることが出来ます。

1つ問題があります。
図のΘ(シータ)が30度などの度数ではなく、ラジアンという単位であることです。
そこで、角度をラジアンに直してからX方向とY方向のベクトルを求めています。

// 角度をラジアンに変換
float rad = Angle * Mathf.Deg2Rad;

角度にMathf.Deg2Radを掛け合わせると角度(度数)からラジアンへの変換が簡単にできます。

Mathf-Deg2Rad - Unity スクリプトリファレンス
度からラジアンに変換する定数(読み取り専用)

求めたラジアン(rad)を

X方向cos(rad)
Y方向sin(rad)

としてVector3型の変数directionに代入して移動方向を求めています。

// ラジアンから進行方向を設定
Vector3 direction = new Vector3(Mathf.Cos(rad), Mathf.Sin(rad), 0f);

最後に速度を掛け合わせて移動ベクトルを求めます。

// 方向に速度を掛け合わせて移動ベクトルを求める
vec = direction * Speed * Time.deltaTime;

Updateメソッドでは実際の移動処理を行っています。
これはtransform.positionに移動ベクトルを加算することで実現できます。

// 物体を移動する
transform.position += vec;

一応画面から消えたときのことも考慮してカメラに表示されなくなったときに1度だけ実行されるOnBecomeInvisibleメソッドを利用してカメラから見えなくなったらオブジェクトを消去しています。

// カメラに表示されなくなった時、消去する
private void OnBecameInvisible()
{
    Destroy(gameObject);
}

参考

Renderer-OnBecameInvisible() - Unity スクリプトリファレンス
OnBecameInvisible is called when the object is no longer visible by any camera.

以上、Unity2D:指定した角度とスピードで物体を移動させるでした。

コメント

  1. こんにちは より:

    初めまして、プログラムを勉強しているものです。
    ボールが設置した壁に反射した後、同じ速さのまま反発する(DVDの待機画面のやつのイメージです)スクリプトを書きたいのですが、初心者すぎてわかりません………。
    もしよろしければ教えてください

タイトルとURLをコピーしました