###実現したいこと
上方向に高く飛ぶプレイヤーに対して、プレイヤーの真横を平行移動する敵が偏差射撃をする機能を実現したいと考えています。
###現在の状況
・敵のY座標にプレイヤーのY座標を代入することで、敵がプレイヤーの真横を平行移動するようにしています。
・偏差射撃の予測位置として、プレイヤーの現在位置に速度ベクトルを加えた座標に敵を向けています。
###行き詰まっていること
上記の状態で弾を発射したところ、プレイヤーと敵が弾を置き去りにしてしまったので、その問題を解消するためにプレイヤーのフレーム毎の上昇値を弾の座標に加えました。弾が置き去りになることは無くなったのですが、このままだと弾がプレイヤーと同じ距離だけ上昇してしまうので、衝突することなく弾が過ぎ去ってしまいます。
弾がちょうどプレイヤーに衝突するよう、弾の上昇値を変えなければならないとは思っているのですが、具体的にどの要素が必要なのかが分かっていない状況です。
ヒントやアドバイス、解決法の提案等、何でも構いませんので、お答え頂きたく思います。
よろしくお願い致します。
###追記
文章のみの質問で申し訳ありませんでした。
以下に当問題に関係があると考えているスクリプトを添付させて頂きます。
読みにくいコードかとは思いますが、よろしくお願い致します。
c#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class PlayerParameter : MonoBehaviour { 6 7 //PlayerのRigidbody2D 8 private Rigidbody2D rb2d; 9 //Playerの速度 10 private float v = 0.0f; 11 //Playerの速度ベクトル 12 private Vector3 vVector; 13 //Playerの現在位置 14 private Vector3 nowPos; 15 //Playerの前フレームの位置 16 private Vector3 prevPos = Vector3.zero; 17 //Playerの移動ベクトル 18 private Vector3 moveVec = Vector3.zero; 19 20 // Use this for initialization 21 void Start () { 22 //Rigidbody2Dコンポーネントを取得 23 rb2d = this.GetComponent<Rigidbody2D> (); 24 } 25 26 // Update is called once per frame 27 void Update () { 28 //Playerの現在位置を格納 29 nowPos = this.transform.position; 30 //Playerの速度値を格納 31 v = rb2d.velocity.magnitude; 32 //Playerの速度ベクトルを格納 33 vVector = rb2d.velocity; 34 //Playerの移動ベクトルを格納 35 moveVec = nowPos - prevPos; 36 //Playerの現在位置を前フレームの位置にする 37 prevPos = nowPos; 38 } 39 40 //Playerの速度を返す関数 41 public float GetVelocity(){ 42 return v; 43 } 44 45 //Playerの速度ベクトルを返す関数 46 public Vector3 GetVelocityVector(){ 47 return vVector; 48 } 49 50 //Playerの移動ベクトルを返す関数 51 public Vector3 GetMoveVector(){ 52 return moveVec; 53 } 54}
c#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Enemy : MonoBehaviour { 6 7 //標的(Player) 8 private GameObject playerObj; 9 //自分(Enemy)の座標 10 private Vector3 mPos; 11 //Playerの座標 12 private Vector3 pPos; 13 //Playerの移動予測座標(偏差射撃のため) 14 private Vector3 forecastPos; 15 //Playerの速度 16 private float p_velocity; 17 //PlayerとEnemy間の距離 18 private float p_distance; 19 20 // Use this for initialization 21 void Start () { 22 //Playerオブジェクトを取得 23 playerObj = GameObject.FindWithTag ("Player"); 24 } 25 26 // Update is called once per frame 27 void Update () { 28 //PlayerにアタッチされているPlayerParameterスクリプトを参照 29 PlayerParameter pp = playerObj.GetComponent<PlayerParameter> (); 30 //Shootingスクリプトを参照 31 Shooting st = GetComponent<Shooting> (); 32 //自分(Enemy)の座標を取得 33 mPos = transform.position; 34 //Playerの座標を取得 35 pPos = playerObj.transform.position; 36 //Playerの速度を格納 37 p_velocity = pp.GetVelocity(); 38 //PlayerとEnemy間の距離を格納 39 //p_distance = Vector3.Distance(mPos, pPos); 40 //Playerの速度を送る 41 st.SetPlayerVelocity (p_velocity); 42 //Playerの予測移動位置を格納 43 forecastPos = pPos + pp.GetVelocityVector(); 44 //targetを向く 45 transform.rotation = Quaternion.FromToRotation( Vector3.up, forecastPos); 46 //PlayerのY座標を取得し、自分(Enemy)の座標に反映(=Playerと平行移動) 47 mPos.y = pPos.y; 48 transform.position = mPos; 49 } 50}
c#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5//Rigidbody2Dコンポーネントを必須にする 6[RequireComponent(typeof(Rigidbody2D))] 7public class Shooting : MonoBehaviour { 8 9 //Bulletプレハブ 10 [SerializeField] 11 private GameObject muzzle; 12 //弾を撃つ間隔 13 [SerializeField] 14 private float shotDelay = 1f; 15 //弾の速度 16 [SerializeField] 17 private float bulletSpeed = 5f; 18 //Playerの速度 19 private float p_velocity = 0f; 20 21 // Update is called once per frame 22 void Update () { 23 24 } 25 26 // Startメソッドをコルーチンとして呼び出す 27 IEnumerator Start () 28 { 29 while (true) { 30 //Debug.Log (GetBulletSpeed()); 31 32 // 弾を敵オブジェクトと同じ位置/角度で作成 33 Instantiate (muzzle, transform.position, transform.rotation); 34 // shotDelay秒待つ 35 yield return new WaitForSeconds (shotDelay); 36 } 37 } 38 39 //Enemyの速度を加算した弾の速度を返す 40 public float GetBulletSpeed(){ 41 return bulletSpeed; 42 } 43 44 //Playerの速度をセットする関数 45 public void SetPlayerVelocity(float v){ 46 p_velocity = v; 47 } 48 49 //Playerの速度を取得する関数 50 public float GetPlayerVelocity(){ 51 return p_velocity; 52 } 53} 54
c#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5//Rigidbody2Dコンポーネントを必須にする 6[RequireComponent(typeof(Rigidbody2D))] 7public class Bullet : MonoBehaviour { 8 9 //敵オブジェクト 10 private GameObject eneObj; 11 //Playerオブジェクト 12 private GameObject playerObj; 13 14 // Use this for initialization 15 void Start () { 16 //Playerオブジェクトを取得 17 playerObj = GameObject.FindWithTag ("Player"); 18 //Enemyオブジェクトを取得 19 eneObj = GameObject.FindWithTag ("Enemy"); 20 //EnemyオブジェクトのShootingスクリプトを参照 21 Shooting st = eneObj.GetComponent<Shooting> (); 22 //弾を発射する 23 GetComponent<Rigidbody2D> ().AddForce (transform.up.normalized * st.GetBulletSpeed(),ForceMode2D.Impulse); 24 } 25 26 // Update is called once per frame 27 void Update () { 28 //PlayerにアタッチされているPlayerParameterスクリプトを参照 29 PlayerParameter pp = playerObj.GetComponent<PlayerParameter> (); 30 //Playerの移動ベクトルを加える 31 transform.position += pp.GetMoveVector (); 32 } 33}