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

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

ただいまの
回答率

90.43%

  • C#

    7979questions

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

  • Unity

    4675questions

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

クリックした方向に弾を飛ばしたい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 107

lalal

score 4

前提・実現したいこと

unityで2Dシューティングゲームを作っています.(NavMeshAgent機能を使いたかったので3Dで作り,カメラを90度回転して2Dに見せています(xz平面))
プレイヤーが画面上にいて(プレイヤーは矢印キーで動く),画面をクリックしたらプレイヤーからそのクリックした座標に向かって弾が打たれる設定にしたいのですが,どこをクリックしても一方向(-z方向)にしか飛びません.Unity初心者でネット上のあらゆる情報の寄せ集めで作ったコードなのでおそらくぐちゃぐちゃですすみません.自分でも何してるのかよくわかってません.どうしたら良いかおしえていただけますか?

発生している問題・エラーメッセージ

クリックした場所の座標に向かって弾がとばない

該当のソースコード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class bombController : MonoBehaviour {

    public Transform muzzle;


    void Shoot(Vector3 dir)
    {
        transform.position = muzzle.position;
        GetComponent<Rigidbody>().AddForce(dir);

    }




    // Use this for initialization
    void Start () {



    }

    // Update is called once per frame
    void Update () {
        if (Input.GetMouseButtonDown (0)) {
            Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
            RaycastHit hit;

            if (Physics.Raycast (ray, out hit)) {
                if (hit.collider.tag == "Ground") {
                    Vector3 direction = hit.point;
                    Shoot (direction.normalized * 20);

                }
            } 
        } 
    }

}

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

muzzleにはPlyerの位置を入れてます.なのでプレイヤーからの発射には成功してます.
Inspector上のRigidbodyの項目でで弾のy軸のpositionは固定しているのできちんと平面上は動きます.

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

Vector3 direction = hit.point;

の箇所を

Vector3 direction = hit.point - muzzle.position;

にしてみてはどうですか?

説明

  • 質問のコードでは、【hit.point】にはカメラからマウス位置に向かうRayが、Groundタグのオブジェクトとぶつかった【位置】が格納されています。
  • しかし、【direction】には、位置ではなく【発射方向】を格納すべきです。発射方向は【狙う位置 - 発射位置】のベクトル計算で求められるでしょう。
  • もし muzzle.position の Y 座標が Ground の Y 座標と異なる場合は一致させたほうがよいでしょう(発射方向がY座標の上下にずれるので)。適切に修正してください。

参考コード

質問のコードでは、撃ち出す側(プレイヤー)と撃ち出される側(弾丸)が混在しているようです。
以下のように修正するのが一案です。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerShoot : MonoBehaviour
{
    [SerializeField] Transform muzzle;          // 射出口

    [SerializeField] GameObject bulletPrefab;   // 弾丸オブジェクトのプレハブ
    [SerializeField] float shootPower;          // 撃ち出す力

    void Shoot ( Vector3 dir )
    {
        // 弾丸を生成する
        var bullet = Instantiate(bulletPrefab, muzzle.position, Quaternion.identity);

        // 弾丸に力を加えて飛ばす
        bullet.GetComponent<Rigidbody> ().AddForce ( dir );
    }

    private void Update ()
    {
        if ( Input.GetMouseButtonDown ( 0 ) )
        {
            Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
            RaycastHit hit;

            if ( Physics.Raycast ( ray, out hit ) )
            {
                if ( hit.collider.tag == "Ground" )
                {
                    // 発射方向を定める
                    Vector3 direction = hit.point - muzzle.position;

                    // 発射方向の上下の傾きを無くす
                    direction.y = 0f;

                    Shoot ( direction.normalized * shootPower );
                }
            }
        }
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/14 13:00

    詳しいご回答ありがとうございます!大変わかりやすかったです.そして新たなる問題が発生したのですが,一発目は確実に打ちたい位置に打てるのですが,2発目からどんどん発射方向がクリック位置の方向とずれてきます.なんか一発目の計算式に次のがどんどん追加されていっててずれてる感じがします.Updateのところに書いてるのが悪いのでしょうか?

    キャンセル

  • 2019/01/14 13:15

    なるほど。状況が分かりました。
    このスクリプトはどのオブジェクトにアタッチしていますか?
    このスクリプトの書き方だと、以下の(a)(b)が同居しています。
    (a) このスクリプトのアタッチされた位置から発射する
    (b) このスクリプトと同じオブジェクトにアタッチされているRigidbodyに力を加えて移動させる

    (b) は、本来は弾のオブジェクトに対して力を加えるべきでしょう。現状は、射出口ごと飛んで行ってしまっているのだと思います。

    キャンセル

  • 2019/01/14 14:15

    回答に参考コードを追記したので確認願います。

    キャンセル

  • 2019/01/14 15:22

    参考コードありがとうございます!プレハブを作ってスクリプト内で生成することからヒントを得て,いろいろ変えてみたら正に自分のやりたかったことができるようになりました!
    いままではbulletのオブジェクトに質問に載せたスクリプトをアタッチしていたのですが,bulletのプレハブをAssets内に作って,PlayerのControllerスクリプトに直接
    void Update () {
    // 発砲
    if (Input.GetMouseButtonDown (0)) {
    GameObject bullets = Instantiate(bullet) as GameObject;
    Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
    RaycastHit hit;

    if (Physics.Raycast (ray, out hit)) {
    if (hit.collider.tag == "Ground") {
    Vector3 direction = hit.point - muzzle.position;
    bullets.transform.position = muzzle.position;
    bullets.GetComponent<Rigidbody>().AddForce(direction.normalized * 100);

    }
    }
    }
    }
    としたらクリックしたところに直接飛ぶようになった上に,弾も連続的に出せるようになって最高の出来になりました!ご協力ありがとうございました!!!!

    キャンセル

  • 2019/01/14 16:30

    解決したようでよかったです。

    キャンセル

0

directionにクリックした座標が代入されています。クリックした座標 - 玉が出る座標 を正規化したものが、球が飛ぶ方向になります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.43%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C#

    7979questions

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

  • Unity

    4675questions

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