質問編集履歴

2 誤字の修正

shorter

shorter score 13

2017/05/21 21:37  投稿

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

    8490 questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity2D

    2068 questions

1 ソースコードの追加

shorter

shorter score 13

2017/05/11 00:47  投稿

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

    8490 questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity2D

    2068 questions

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る