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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

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

Q&A

解決済

2回答

7587閲覧

Unityの2Dゲームで発射した弾をクリックした位置に飛ばす

hain

総合スコア25

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

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

0グッド

1クリップ

投稿2017/09/26 14:22

###前提・実現したいこと
シューティングゲームで画面上のクリックした座標に向かって弾を飛ばすスクリプトを書いています。
クリックした座標を取得し、そこに向かって弾が飛ぶように書きたいと考えています。

###発生している問題・エラーメッセージ
クリックした座標は取得できているのですが自機から発射した弾はまっすぐと進んでいきます。

発射される弾のプレハブにアタッチしているプログラムを以下に示します。

C#

1public class playerbullet : MonoBehaviour 2{ 3 Vector2 vec; 4 public float speeds = 2; 5 6 void Start() 7 { 8 9 } 10 11 void Update() 12 { 13 if (Input.GetMouseButtonDown(0)) 14 { 15 vec = Camera.main.ScreenToWorldPoint(Input.mousePosition); 16 // Debug.Log(vec); 17//vecに2次元座標の値を代入し、その方向に向かってMoveTowardを使て飛ばそうとしています。 18 transform.position = Vector2.MoveTowards(transform.position, new Vector2(vec.x, vec.y), speeds * Time.deltaTime); 19 } 20 21 22 transform.Translate(0.2f, 0, 0); 23//上記のスクリプトが右方向にまっすぐ進む要因です。取り除くと弾は発射口から動かなくなります。 24 25 if (transform.position.x > 10) 26 { 27 Destroy(gameObject); 28 } 29 } 30} 31
###試したこと そのままのスクリプトをMainCameraに貼り付けましたが変化はありませんでした。 ###補足情報(言語/FW/ツール等のバージョンなど) Unity 2017 1.1f1 を使用

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

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

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

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

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

guest

回答2

0

ベストアンサー

最初のコードを出来るだけ崩さず指定した方向に進むよう修正すると

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class playerbullet : MonoBehaviour 6{ 7 Vector2 vec; 8 public float speeds = 2; 9 10 void Start() 11 { 12 13 } 14 15 void Update() 16 { 17 if (Input.GetMouseButtonDown(0)) 18 { 19 Vector3 mousePositionVec3 = Input.mousePosition; 20 mousePositionVec3.z = -Camera.main.transform.position.z; 21 vec = Camera.main.ScreenToWorldPoint(mousePositionVec3); 22 // Debug.Log(vec); 23 } 24 25 //vecに2次元座標の値を代入し、その方向に向かってMoveTowardを使て飛ばそうとしています。 26 transform.position = Vector2.MoveTowards(transform.position, new Vector2(vec.x, vec.y), speeds * Time.deltaTime); 27 28 //transform.Translate(0.2f, 0, 0); 29 //上記のスクリプトが右方向にまっすぐ進む要因です。取り除くと弾は発射口から動かなくなります。 30 31 if (transform.position.x > 10) 32 { 33 Destroy(gameObject); 34 } 35 } 36}

これでクリックした方向に弾は向かっていくのではないでしょうか。
ただこれだと指定した位置に移動するだけなので近くをクリックするとそこで止まってしまいますし、途中で方向転換も可能です。

次にクリック角度方向に真っすぐ進み、進行中は入力を受け付けない作りにすると

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class playerbullet : MonoBehaviour 6{ 7 Vector2 vec; 8 private float speeds = 0; 9 private bool isBulletStart; 10 11 void Start() 12 { 13 14 } 15 16 void Update() 17 { 18 if (Input.GetMouseButtonDown(0) && !isBulletStart) 19 { 20 Vector3 mousePositionVec3 = Input.mousePosition; 21 mousePositionVec3.z = -Camera.main.transform.position.z; 22 23 vec = Camera.main.ScreenToWorldPoint(mousePositionVec3); 24 25 float zRotation = Mathf.Atan2(vec.y - transform.position.y, vec.x - transform.position.x) * Mathf.Rad2Deg; 26 transform.rotation = Quaternion.Euler(0f, 0f, zRotation); 27 speeds = 0.2f; 28 isBulletStart = true; 29 } 30 31 transform.Translate(Vector2.right * speeds); 32 33 if (transform.position.x > 10 || transform.position.y > 10) 34 { 35 isBulletStart = false; 36 Destroy(gameObject); 37 } 38 } 39}

こちらの方が想定している動きをしてくれるかと思います。

投稿2017/09/29 09:43

編集2017/09/29 09:56
Hawn

総合スコア1222

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

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

hain

2017/09/29 12:17

ありがとうございます!理想の動きです! しかし、このコードに書き換えたところ、最初の1発目が自機の発射口に止まり続けてしまうようになりました…もしも原因がわかりましたらお力をお貸しください。よろしくお願いします。
Hawn

2017/09/29 14:15

最初の1発目が自機の発射口に止まり続けてしまう問題は上記の方のソースコードで大丈夫そうですね。
guest

0

Vector2.MoveTowardsは、指定した位置に向かって、指定しただけベクトルを動かす関数なので、その条件では、クリックしている間だけしか動きません。
そこで、オブジェクト自体を回して指定の位置がオブジェクトの正面に来るようにし、オブジェクトのローカル座標系のベクトルで正面に向かって動かすように変更しました。

PlayerBullet.cs

using System.Collections; using System.Collections.Generic; using UnityEngine; public class playerbullet : MonoBehaviour { Vector2 vec; public float speeds = 0.2f; void Start() { } void Update() { if (Input.GetMouseButtonDown(0)) { vec = Camera.main.ScreenToWorldPoint(Input.mousePosition); //進む方向をセットする transform.rotation = Quaternion.Euler(Vector2.Angle(vec, transform.position), 0f, 0f); } //どこまでも飛んでいくのを防ぐ。要らなければif分を消して。 if (Vector2.Distance(vec, transform.position) > 1f) { transform.Translate(transform.TransformVector(Vector2.up * 0.2f)); } if (transform.position.x > 10) { Destroy(gameObject); } } }

投稿2017/09/26 16:41

frodo821

総合スコア322

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

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

hain

2017/09/29 07:51

返事が遅くなってしまい申し訳ありません。 私の書いたプログラムについても解説いただき助かりました。 いただいたコードを改めてplayerbulletに貼り付けたところ、y軸方向(真上)に弾が飛んでしまい 、クリック方向に飛びませんでした… どこかをx軸方向で指定すればいいと思うのですが、もう一度お力を貸していただけないでしょうか?
hain

2017/09/29 07:57

if (Vector2.Distance(vec, transform.position) > 1f) { transform.Translate(transform.TransformVector(Vector2.up * 0.2f)); } を if (Vector2.Distance(vec, transform.position) > 1f) { transform.Translate(transform.TransformVector(Vector2.right * 0.2f)); } とすることで右に飛ぶようになりました。失礼いたしました。 しかしクリックした方向へ飛ばすことができていません。引き続きご回答いただけるとありがたく思います。
frodo821

2017/09/29 10:06

using System.Collections; using System.Collections.Generic; using UnityEngine; public class playerbullet : MonoBehaviour { Vector2 vec; public float speeds = 2f; Vector2 direnction = Vector2.zero; void Start() { vec = transform.position; } void Update() { if (Input.GetMouseButtonDown(0)) { var MouseCoords = Camera.main.ScreenToWorldPoint(Input.mousePosition); direnction = (new Vector2(MouseCoords.x, MouseCoords.y) - vec).normalized; } print(new Vector3((direnction * speeds).x, (direnction * speeds).y, 0f)); transform.Translate((direnction * speeds).x, (direnction * speeds).y, 0f); if (transform.position.x > 10) { Destroy(gameObject); } } } すみません、深夜テンションで書いたコードで、自分でも何やってるのかわからなかったので、新しく書き直しました。
hain

2017/09/29 12:09

ありがとうございます!クリックされた方向に弾が飛んでいきました!! 書いていただいたコードですと、最初の1発だけ発射口に止まり続けてしまう(自機の上に弾の画像がかぶって止まっている状態)のですが原因はわかりますでしょうか。何度も申し訳ありません。
frodo821

2017/09/29 12:28 編集

そういう風に書いてるからですね... 最初の一発を前に飛ばすには、directionに適当なベクトルを入れて初期化してください。 例 (PlayerBullet.cs, 10行目): Vector2 direction = Vector2.right; それか、以下のように書き換えるとInstantiateでオブジェクトを生成した際のマウスポインタの位置に向けて勝手に飛んでいきます。 シューティングゲームとかに使うならこちらの方が向いてますねw using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerBullet : MonoBehaviour { Vector2 vec; bool velocityAdded = false; public float speeds = 2f; Vector2 direnction = Vector2.zero; void Start() { vec = transform.position; } void Update() { if (!velocityAdded) { var MouseCoords = Camera.main.ScreenToWorldPoint(Input.mousePosition); direnction = (new Vector2(MouseCoords.x, MouseCoords.y) - vec).normalized; velocityAdded = true; } print(new Vector3((direnction * speeds).x, (direnction * speeds).y, 0f)); transform.Translate((direnction * speeds).x, (direnction * speeds).y, 0f); if (transform.position.x > 10) { Destroy(gameObject); } } } 後は、クラスの命名が少し気になったので修正しました。 クラス名、関数名は単語の先頭を大文字で、変数名は変数名先頭以外の単語の先頭を大文字で書くようにするといいと思います。
hain

2017/09/29 12:25

うわぁ!くわしくありがとうございます…!何度もお時間取らせてしまってすみません!!本当にありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問