質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

3392閲覧

プレイヤー弾がプレイヤーの後ろから出て、プレイヤーが押される

unity_user_a

総合スコア23

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2020/05/09 11:04

編集2020/05/13 02:43

プレイヤーに弾を発射させる設定をしており、プレイヤーと弾自体につけるスクリプトが出来た時点で動作確認をしたところ、弾がプレイヤーの後ろで生成され、プレイヤーが押されてしまいました。
弾をプレイヤーの前方から発射するには、どこを変えたら良いでしょうか?

イメージ説明
※座標は弾が生成された座標で、x座標がプレイヤーの初期位置である「StartPos」のものと同じになっている様です。

また、弾とプレイヤーが衝突しない様にProjectSettingsで設定したのにプレイヤーが押されるのも、よく分かりません。
↓参考サイト
https://yokubari.online/unity/how-to-prefab-and-layer/

イメージ説明
イメージ説明

↓弾のインスペクター
イメージ説明
イメージ説明
イメージ説明

※弾はプレイヤーの子オブジェクトにしたり、Hierarchyに設置したりせず、プレイヤーにつけたスクリプトからProjectにあるプレハブのBulletを選択している状態です。

↓弾のスクリプト

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Bullet : MonoBehaviour { // 弾オブジェクト(Inspectorでオブジェクトを指定) [SerializeField] // Inspectorで操作できるように属性を追加します private GameObject bullet; // 弾オブジェクトのRigidbody2Dの入れ物 private Rigidbody2D rb2d; // 弾オブジェクトの移動係数(速度調整用) float bulletSpeed; void Start() { // オブジェクトのRigidbody2Dを取得 rb2d = GetComponent<Rigidbody2D>(); // 弾オブジェクトの移動係数を初期化 bulletSpeed = 10.0f; // 出現から3秒後に弾オブジェクトを消滅させる(メモリの節約) Destroy(gameObject, 3.0f); } void Update() { // 弾オブジェクトの移動関数 BulletMove(); } // 弾オブジェクトの移動関数 void BulletMove() { // 弾オブジェクトの移動量ベクトルを作成(数値情報) Vector2 bulletMovement = new Vector2(1, 0).normalized; // Rigidbody2D に移動量を加算する rb2d.velocity = bulletMovement * bulletSpeed; } // ENEMYと接触したときの関数 void OnCollisionEnter2D(Collision2D collision) { // ENEMYに弾が接触したら弾は消滅する if (collision.gameObject.tag == "Enemy") { Destroy(gameObject); } } }

↓プレイヤーのインスペクター
イメージ説明
イメージ説明
イメージ説明

↓プレイヤー側のスクリプト
(字数制限で、「Player」のコードが貼れず、画像も反映されなくなったため省略しましたが、解決に必要とあれば、後で追記します。すみません。)

using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerBullet : MonoBehaviour { #pragma warning disable 0649 // InspectorでPrefab化したBulletを指定する [SerializeField] private GameObject bullet; void Update() { // 弾オブジェクトを生成して飛ばす関数を呼び出す ShotAction(); } // 弾オブジェクトを生成して飛ばす関数 void ShotAction() { if (Input.GetButtonDown("Fire1")) { Instantiate(bullet, transform.position, transform.rotation); Debug.Log(transform.position); } } }

Unityバージョン:Unity 2019.2.15f1 (64-bit)

追記:5/13に教えて頂いたスクリプトについて

スクリプトを教えて頂いたものに変更したところ、弾がプレイヤーの後ろに飛んで行く様になりました。
やはりプレイヤーの向きが変わっても、弾の方向は変わっていません。
足りていないと思って、私が自分で足した部分が原因でしょうか?

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Bullet : MonoBehaviour { // 弾オブジェクト(Inspectorでオブジェクトを指定) [SerializeField] // Inspectorで操作できるように属性を追加します private GameObject bullet; // 弾オブジェクトのRigidbody2Dの入れ物 private Rigidbody2D rb2d; // 弾オブジェクトの移動係数(速度調整用) float bulletSpeed; private Vector2 direction = Vector2.right; void Start() { // オブジェクトのRigidbody2Dを取得 rb2d = GetComponent<Rigidbody2D>(); // 弾オブジェクトの移動係数を初期化 bulletSpeed = 10.0f; // 出現から3秒後に弾オブジェクトを消滅させる(メモリの節約) Destroy(gameObject, 3.0f); } void Update() { // 弾オブジェクトの移動関数 BulletMove(); } public void SetDirection(bool isLeft) { // 左方向なら(-1.0, 0.0)方向に、右方向なら(1.0, 0.0)方向に進む direction = isLeft ? Vector2.left : Vector2.right; // スプライト画像の反転処理(画像のデフォルトが右方向の向いているもの前提) var sprite = GetComponent<SpriteRenderer>(); if (sprite != null) { sprite.flipY = isLeft; } } void BulletMove() { // Rigidbody2D に移動量を加算する rb2d.velocity = direction * bulletSpeed; } // ENEMYと接触したときの関数 void OnCollisionEnter2D(Collision2D collision) { // ENEMYに弾が接触したら弾は消滅する if (collision.gameObject.tag == "Enemy") { Destroy(gameObject); } if (collision.gameObject.tag == "Ground") { Destroy(gameObject); } if (collision.gameObject.tag == "MoveFloor") { Destroy(gameObject); } if (collision.gameObject.tag == "JumpStep") { Destroy(gameObject); } if (collision.gameObject.tag == "GroundPlatform") { Destroy(gameObject); } } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerBullet : MonoBehaviour { #pragma warning disable 0649 // InspectorでPrefab化したBulletを指定する [SerializeField] private GameObject bullet; // ユーザーがどちらを向いているか private bool isLeft = true; void Update() { // 弾オブジェクトを生成して飛ばす関数を呼び出す ShotAction(); } void ShotAction() { Vector3 offset = new Vector3(1.0f, 0.0f, 0.0f); // isLeft は仮の変数です。現在向いている方向を判定するフラグなどを用意してみてください。 // 向いている方向が反対ならx座標を反転する if (isLeft) { offset.x = -offset.x; } if (Input.GetButtonDown("Fire1")) { // Bulletコンポーネントがアタッチしている前提 var bulletObj = Instantiate(bullet, transform.position + offset, transform.rotation); bulletObj.GetComponent<Bullet>().SetDirection(isLeft); } } }

イメージ説明
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。
PlayerBulletクラスのShotAction()関数を見る限り、
弾の生成にはInstantiate()関数を使っているようですので、生成する座標を前方分足してあげれば、解決できると思います。
Object.Instantiate

現在記述しているInstantiate(bullet, transform.position, transform.rotation);
の第2引数としてしているtransform.positionが弾の生成される座標になります。
transform.positionPlayerBulletのGameObjectの座標ですから、このままでは同じ位置に生成されてしまいます。
この部分をプレイヤーが右方向なら x座標に+1, 左方向なら-1することで、プレイヤーの前方に弾のGameObjectが生成できるはずです。

cs

1void ShotAction() 2{ 3 if (Input.GetButtonDown("Fire1")) 4 { 5 // 1.0fは適当な数値です。 6 // 前方に出したい分の値を指定してください。 7 Vector3 offset = new Vector3(1.0f, 0.0f, 0.0f); 8 9 // isLeft は仮の変数です。現在向いている方向を判定するフラグなどを用意してみてください。 10 // 向いている方向が反対ならx座標を反転する 11 if (isLeft) 12 { 13 offset.x = -offset.x; 14 } 15 16 // 生成座標をオフセット分足す。 17 Instantiate(bullet, transform.position + offset, transform.rotation); 18 Debug.Log(transform.position); 19 } 20}

また、弾とプレイヤーが衝突しない様にProjectSettingsで設定したのにプレイヤーが押されるのも、よく分かりません。

これに関しては実際に作成したレイヤーを各GameObjectに対して設定してあげる必要があります。
PlayerのameObjectにはPlayerを、弾のGameObjectにはBulletのレイヤーを指定すれば、
現在のProjectSettingsの設定を見る限り、コリジョンの衝突が行われなくなるはずです。
イメージ説明

追記:弾について
弾そのものも右方向に進むのか、左方向に進むのかを設定してあげる必要があると思います。
いろいろやり方がありますが、以下の処理ではシンプルに進行方向を設定する関数を用意してそれを生成時に指定するようにしています。
ご参考ください。

cs

1public class Bullet : MonoBehaviour 2{ 3 // 弾オブジェクトのRigidbody2Dの入れ物 4 private Rigidbody2D rb2d; 5 // 弾オブジェクトの移動係数(速度調整用) 6 float bulletSpeed; 7 8 private Vector2 direction = Vector2.right; 9 10 public void SetDirection(bool isLeft) 11 { 12 // 左方向なら(-1.0, 0.0)方向に、右方向なら(1.0, 0.0)方向に進む 13 direction = isLeft ? Vector2.left : Vector2.right; 14 15 // スプライト画像の反転処理(画像のデフォルトが右方向の向いているもの前提) 16 var sprite = GetComponent<SpriteRenderer>(); 17 if (sprite != null) 18 { 19 sprite.flipY = isLeft; 20 } 21 22 } 23 24 void BulletMove() 25 { 26 // Rigidbody2D に移動量を加算する 27 rb2d.velocity = direction * bulletSpeed; 28 } 29}

cs

1public class PlayerBullet : MonoBehaviour 2{ 3 // InspectorでPrefab化したBulletを指定する 4 [SerializeField] 5 private GameObject bullet; 6 7 // ユーザーがどちらを向いているか 8 private bool isLeft = true; 9 10 void ShotAction() 11 { 12 Vector3 offset = new Vector3(1.0f, 0.0f, 0.0f); 13 14 // isLeft は仮の変数です。現在向いている方向を判定するフラグなどを用意してみてください。 15 // 向いている方向が反対ならx座標を反転する 16 if (isLeft) 17 { 18 offset.x = -offset.x; 19 } 20 21 if (Input.GetButtonDown("Fire1")) 22 { 23 // Bulletコンポーネントがアタッチしている前提 24 var bulletObj = Instantiate(bullet, transform.position + offset, transform.rotation); 25 bulletObj.GetComponent<Bullet>().SetDirection(isLeft); 26 } 27 } 28}

投稿2020/05/10 12:31

編集2020/05/13 00:55
YASU_jrt

総合スコア33

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

unity_user_a

2020/05/10 13:07

ご回答、ありがとうございました! おかげ様で、弾の生成位置、衝突判定ともに修正出来ました!! スクリプトの仮変数の部分も、ちゃんと動作する様にしました。 高評価とベストアンサー、フォローもさせて頂きました。 今後も質問を投稿した際には、知恵を御貸し頂けると幸いです。
unity_user_a

2020/05/12 08:44

動作確認をしていたのですが、プレイヤーの向きが変わっても弾の飛んで行く方向が変わっていませんでした。 offset.xの部分は、isLeftのままでもエラーにならない様に、private bool isLeft; を書き加えました。 isLeftのままだとまずかったのでしょうか? 初心者で、教えてもらったスクリプトを自分で変えるのがまだ上手くできないもので。 何処をどの様に変更したり、書き加えると良いのでしょうか? 自分で調べていても、最適解が見つからなかったので。 後からすみません。
YASU_jrt

2020/05/13 00:56

おっと、これは申し訳ない。 弾が飛んでいく方向に関するフォローが足りませんでしたね。 弾について追記しましたので、参考にしてみてください。
unity_user_a

2020/05/13 02:45

スクリプトについて、私も追記させて頂きました。 お時間がおありの際に、ご確認頂けると幸いです。
YASU_jrt

2020/05/13 10:02

スクリプト確認させていただきました。 用意してもらった isLeft の変数はどのタイミング true と false が切り替わるのでしょうか? 記述されているスクリプトの仲では isLeft の値が変更している個所が無いようにみえます。
unity_user_a

2020/05/16 08:50

新しいコメントがついていることに気づいていませんでした。すみません。 私もよく理解できておらず、教えて頂いたスクリプトをそのまま使っているだけでした。 具体的に、どこにtrue/falseの分岐を作れば良いでしょうか? また、trueの時・falseの時に、どんな内容を書けば良いでしょうか?
YASU_jrt

2020/05/16 12:39

質問でアップしている画像を見る限り、キャラクターが移動しているようなので、 恐らく、キャラクター操作スクリプトは別で用意しているんですよね? キャラクター操作スクリプトなら進行方向がどちらかはわかると思います。 そのキャラクター操作スクリプトから PlayerBullet に対してどちらに向いているかを設定してあげればよいのではないでしょうか。
unity_user_a

2020/05/16 16:48

ありがとうございます。 解決済みの質問のコメント欄でのやり取りが長くなってきているので、情報整理のために新しい質問として投稿しました。 良ければ、ご確認下さい。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問