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プレハブのSpeedを3、Angleを0とした場合の実行イメージです。
角度0が、右方向となります。
反時計回りに1周すると360度です。
イメージ
Bulletプレハブを3つシーンに配置し、Speedを全て3、Angleをそれぞれ右から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を掛け合わせると角度(度数)からラジアンへの変換が簡単にできます。
求めたラジアン(rad)を
X方向 | cos(rad) |
Y方向 | sin(rad) |
としてVector3型の変数directionに代入して移動方向を求めています。
// ラジアンから進行方向を設定 Vector3 direction = new Vector3(Mathf.Cos(rad), Mathf.Sin(rad), 0f);
Mathf.Cos、Mathf.Sinは引数がラジアンとなります。
最後に速度を掛け合わせて移動ベクトルを求めます。
// 方向に速度を掛け合わせて移動ベクトルを求める vec = direction * Speed * Time.deltaTime;
Updateメソッドでは実際の移動処理を行っています。
これはtransform.positionに移動ベクトルを加算することで実現できます。
// 物体を移動する
transform.position += vec;
一応画面から消えたときのことも考慮してカメラに表示されなくなったときに1度だけ実行されるOnBecomeInvisibleメソッドを利用してカメラから見えなくなったらオブジェクトを消去しています。
// カメラに表示されなくなった時、消去する private void OnBecameInvisible() { Destroy(gameObject); }
参考
以上、Unity2D:指定した角度とスピードで物体を移動させるでした。
コメント
初めまして、プログラムを勉強しているものです。
ボールが設置した壁に反射した後、同じ速さのまま反発する(DVDの待機画面のやつのイメージです)スクリプトを書きたいのですが、初心者すぎてわかりません………。
もしよろしければ教えてください
こんばんは。管理人です。
DVDの待機画面は正直分からなかったのですが、壁に反射する感じのプログラムは、JavaScriptの以下記事で実践しているので参考になさってください。(Unityではないですが…)
JavaScript:canvasで壁に当たったら跳ね返るアニメーション
https://dianxnao.com/javascript%ef%bc%9acanvas%e3%81%a7%e5%a3%81%e3%81%ab%e5%bd%93%e3%81%9f%e3%81%a3%e3%81%9f%e3%82%89%e8%b7%b3%e3%81%ad%e8%bf%94%e3%82%8b%e3%82%a2%e3%83%8b%e3%83%a1%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3/
ポイントとなる部分は、記事中のプログラムの中で使っている変数vxとvyで、跳ね返るとき(壁にぶつかったとき)にそれぞれ-1を掛けて反転させています。