【Unity】自機に向かってくる弾をつくる(2D)
弾幕STGでよくある自機に向かってくる弾をつくります(追尾弾ではありません)
テスト
— 相生葵 (@pirorirori_n712) 2018年10月14日
可愛いキャラクターは【Rド】様(https://t.co/80g5E20XwZ) pic.twitter.com/kLBg9BhWEw
※注意(10/21 追記)
この記事ではRigidBody2Dコンポネントのvelocityを使っていますが
Vector3.MoveTowardsを使う方法が一番簡単です。
使い方は以下の通りです。
gameObject.transform.position = Vector3.MoveTowards(gameObject.transform.position, player.transform.position, distance);
gamebjectは弾、playerはプレイヤー、つまり目的地、ターゲットです。
このメソッドの3つ目の引数、distanceには距離が入るらしいです。
Time.deltaTimeが入れられていることが多いですが、私はまだよく分かっていないです。
以下、velocityを使う本記事の内容です。
前提
弾を動かす方法はRigidBody2Dコンポネントのvelocityを使います。 使い方は、
gameObject.GetComponent<RigidBody2D>().velocity=Vector2;
gameObjectはプレイヤーに向かって飛んでいく弾です。
弾の飛んでいく向きは右辺のVector2次第なので
Vector2に何の値を入れればいいかを考えていきます。
UnityのVector2について
ベクトルについて
考えるパート
目標:Vector2に適当な値(方向)を入れて、弾を「敵がいる位置からプレイヤーに向かって飛ばす」
ベクトルには方向と大きさがありますが、
方向は大きさが変わっても変わらないので
ここでは、ベクトルの大きさは考えません。
弾を敵からプレイヤーに向かって飛ばしたいということは、
ベクトルの向きは「敵の位置→プレイヤーの位置」となります。
青い丸を自機、赤い三角を敵とするとベクトルは以下のようになります。
このベクトルを求められれば、弾を自機に向かって飛ばすことができます。
まず今分かっているベクトルは
原点から「敵機へのベクトル」、
そして原点から「自機へのベクトル」です。
なぜこの二つのベクトルが分かっているかというと、
二つのgameObjectの位置は
gameObject.tranform.positionで取得することができるからです。
さらに、
なぜgameObject.tranform.positionで取得した座標で
原点からそれぞれ「敵」、「プレイヤー」へのベクトルが分かると言えるかというと
2つの点A(a1,a2),B(b1,b2)のベクトルは(b1-a1,b2-b2)で求められるからです。
原点の座標は(0,0)なので、
例えば敵の座標をgameObject.transform.positionで取得したときに(1,5)だった場合、
原点から敵へのベクトルは(1-0,5-0)となり、
そのまま敵の座標が「原点から敵へのベクトル」となります。
よって、
敵、プレイヤーともにgameObject.transform.positionで座標を取得できるので
どちらも既に原点からのベクトルが分かっていることになります。
それでは、この二つのベクトルを用いて
敵からプレイヤーに伸びているベクトルを求めます。
ここでは、ベクトルの引き算を使います。
ベクトルの引き算の定理は以下です。
ベクトルAとベクトルBがあるとすると
ベクトルA-ベクトルB=ベクトルBの終点からベクトルAの終点に伸びるベクトル
ここから、
「原点から自機へのベクトル」から「原点から敵へのベクトル」を引けば
「敵から自機へのベクトル」を導きだすことができます。
コード例
(このスクリプトは敵につけています)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class TamaToPlayer : MonoBehaviour { //プレイヤーオブジェクト public GameObject player; //弾のプレハブオブジェクト public GameObject tama; //一秒ごとに弾を発射するためのもの private float targetTime = 1.0f; private float currentTime = 0; // Update is called once per frame void Update () { //一秒経つごとに弾を発射する currentTime += Time.deltaTime; if (targetTime<currentTime) { currentTime = 0; //敵の座標を変数posに保存 var pos = this.gameObject.transform.position; //弾のプレハブを作成 var t = Instantiate(tama) as GameObject; //弾のプレハブの位置を敵の位置にする t.transform.position = pos; //敵からプレイヤーに向かうベクトルをつくる //プレイヤーの位置から敵の位置(弾の位置)を引く Vector2 vec = player.transform.position-pos; //弾のRigidBody2Dコンポネントのvelocityに先程求めたベクトルを入れて力を加える t.GetComponent<Rigidbody2D>().velocity= vec; } } }