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

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

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

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Q&A

解決済

1回答

1298閲覧

船の上に搭載されている大砲の向きを基準にしてその船をPlayerのいる方向にちょっとずつ向けたい

hosituka

総合スコア15

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

0グッド

0クリップ

投稿2021/04/24 06:22

編集2021/04/24 13:47

船の上に搭載されている大砲の向きを基準にしてその船をPlayerのいる方向にちょっとずつ向けたい
どういうことかと言いますと船の向いている方向からみて大砲が後ろにあった場合船の後ろをPlayerのいる方向に向けたいのです。
自分では難しかったのでなにか知識を分けていただけるとありがたいです。投げやりでごめんなさい。

現段階では船の前を基準にしてPlayerのいる方向を向くようになっていますが一応UnityroomのURLを張っておきますそのUnityroomのURL※UnityroomとはwebGLでビルドするとweb上でゲームを動かせるのですがそのゲームを置かせてもらっているサイトです

イメージ説明
開発環境表記

プラットフォームはwebGLです
unityエディターのバージョンは2020.1.14f1

船がPlayerを見つけたときの移動関係のコードを切り取ったやつ

C#

1 if (rb.velocity.magnitude < 30) 2 { 3 //回転を分かりやすくするために前進するコードは切ってあります 4 //rb.AddForce(transform.forward * 100, ForceMode.Acceleration); 5 } 6          //★ここが問題の所です現段階では船の前を基準にしてPlayerのいる方向にちょっとずつ向いていきます 7 Vector3 relativePos = target_Player.transform.position - transform.position; 8 9 relativePos.y = 0; 10 11 12 Quaternion rotation = Quaternion.LookRotation(relativePos); 13 14 transform.rotation = Quaternion.Slerp(transform.rotation, rotation , 0.015f); 15

一応船の全体のコードも載せときます

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class teki1 : MonoBehaviour 6{ 7 public GameObject target_Player; 8 public Rigidbody rb; 9 public GameObject[] taihou; 10 public GameObject bullet; 11 public bool taihou_syahuru = true; //大砲の向きをシャッフルするかどうかに使うbool型変数 12 13 RaycastHit hit; 14 public int HP = 5; //HPに使うint型変数 15 private bool sinimasita = false; //死んだときの合図に使うbool型変数 16 private bool kougeki = false;//攻撃の合図に使うbool型変数 17 private Vector3 bullet_forward;//Playerのbulletに当たった時にそのbulletの方向を入れるVector型 18 private bool riro_do; //弾のリロードに使うbool型変数 19 private new Transform saisyono_iti;//このスクリプトをつけるgameObjectの最初の位置を入れるため用のTransform型 20 // Start is called before the first frame update 21 void Start() 22 { 23 24 saisyono_iti = GetComponent<Transform>(); ; 25 //ここで大砲の向きをシャッフルしている 26 if(taihou_syahuru == true) 27 { 28 foreach (GameObject a in taihou) 29 { 30 a.transform.rotation = Quaternion.Euler(0, 90 * Random.Range(0, 4), 0); 31 32 } 33 } 34 35 } 36 37 38 // Update is called once per frame 39 void FixedUpdate() 40 { 41 if (sinimasita == false)//生きている間の処理 42 { 43 if (kougeki == true)//攻撃の体制に入った場合の処理 44 { 45 46 //ここに攻撃のコードがある 47 foreach (GameObject a in taihou) 48 { 49 if (Physics.Raycast(a.transform.position, a.transform.forward, out hit, 1200) && hit.collider.gameObject.CompareTag("Player")) 50 { 51 if (riro_do == false) 52 { 53 riro_do = true; 54 Instantiate(bullet, a.transform.position, Quaternion.Euler(a.transform.localEulerAngles.x, a.transform.localEulerAngles.y, a.transform.localEulerAngles.z) * transform.rotation); 55 Invoke("zikann", 4); 56 } 57 58 } 59 60 } 61 62 //この下でこのgameObjectとPlayerの距離を測っている 63 float distance = (transform.position - target_Player.transform.position).sqrMagnitude / 1000; 64 65 if (rb.velocity.magnitude < 30) 66 { 67 //回転を分かりやすくするために前進するコードは切ってあります 68 //rb.AddForce(transform.forward * 100, ForceMode.Acceleration); 69 } 70 71 72 //★ここが問題の所です現段階では船の前を基準にしてPlayerのいる方向にちょっとずつ向いていきます 73 Vector3 relativePos = target_Player.transform.position - transform.position; 74 75 relativePos.y = 0; 76 77 78 Quaternion rotation = Quaternion.LookRotation(relativePos); 79 80 transform.rotation = Quaternion.Slerp(transform.rotation, rotation , 0.015f); 81 82 83 } 84 85 if(kougeki == false) //攻撃の合図が来ていなかった時の処理 86 { 87 if (rb.velocity.magnitude < 30) 88 { 89 rb.AddForce(transform.forward * 100, ForceMode.Acceleration); 90 } 91 92 Vector3 relativePos = saisyono_iti.position - transform.position; 93 94 relativePos.y = 0; 95 96 97 Quaternion rotation = Quaternion.LookRotation(relativePos); 98 99 transform.rotation = Quaternion.Slerp(transform.rotation, rotation, 0.02f); 100 } 101 102 } 103 //ここでPlayerが障害物に隠れているかどうか確認しているifが隠れていない場合の処理その下のelseが隠れていた場合の処理 104 int layerMask = 1; 105 if (Physics.Raycast(transform.position, target_Player.transform.position - transform.position, out hit, 400, layerMask) && hit.collider.gameObject.CompareTag("Player")) 106 { 107 kougeki = true;//ここで攻撃の体制に入っている 108 109 } 110 else 111 { 112 kougeki = false;//ここで攻撃の体制を切っている。 113 } 114 115 if (sinimasita == true)//死んだときの処理 116 { 117 transform.Rotate(bullet_forward); 118 transform.position -= new Vector3(0, 0.1f, 0); 119 Destroy(gameObject, 9); 120 } 121 } 122 123 void zikann() 124 { 125 riro_do = false;//ここで弾をまた打てるようにしている。 126 } 127 128 void OnCollisionStay(Collision collision) 129 { 130 //ここはまだ何もないです 131 132 } 133 134 //ここでPlayerのbulletに当たった時の処理。用はダメージ処理 135 void OnTriggerEnter(Collider collision) 136 { 137 if(collision.gameObject.CompareTag("bullet")) 138 { 139 rb.AddForce(collision.gameObject.transform.forward * 10, ForceMode.Impulse); 140 HP -= 1; 141 kougeki = true; 142 collision.gameObject.GetComponent<bullet>().bakuhatu(); 143 if (HP < 1) 144 { 145 BoxCollider component = GetComponent<BoxCollider>(); 146 Destroy(component); 147 bullet_forward = -collision.gameObject.transform.forward / 10; 148 Destroy(rb); 149 sinimasita = true; 150 } 151 } 152 } 153 154}

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

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

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

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

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

guest

回答1

0

ベストアンサー

全体のコードの方を拝見しますに、敵船は大砲を複数門装備していて、それぞれバラバラな方角へ向けている可能性があると考えていいでしょうか?
でしたら、ご質問者さんのコードの下記部分を...

lang

1 //★ここが問題の所です現段階では船の前を基準にしてPlayerのいる方向にちょっとずつ向いていきます 2 Vector3 relativePos = target_Player.transform.position - transform.position; 3 4 relativePos.y = 0; 5 6 7 Quaternion rotation = Quaternion.LookRotation(relativePos); 8 9 transform.rotation = Quaternion.Slerp(transform.rotation, rotation , 0.015f);

下記のようにしてみてはいかがでしょう。

lang

1 // まずプレイヤーの相対位置は元のコードと同じように求め... 2 Vector3 relativePos = target_Player.transform.position - transform.position; 3 relativePos.y = 0; 4 5 // 最小回転角を保持する変数を用意しておく 6 float minimumAngle = 0.0f; 7 float minimumAbsAngle = Mathf.Infinity; 8 9 // そしてこの船に搭載されている大砲をそれぞれ調べていく 10 foreach (GameObject taihouObject in taihou) 11 { 12 // 大砲の向きを取得し... 13 Transform taihouTransform = taihouObject.transform; 14 Vector3 taihouDirection = taihouTransform.forward; 15 taihouDirection.y = 0; 16 17 // 現在の向きからプレイヤーの方角への符号付き角度を求める 18 float taihouToPlayerAngle = Vector3.SignedAngle(taihouDirection, relativePos, Vector3.up); 19 20 // その回転角の大きさがminimumAbsAngleより小さいなら 21 // それを仮の最小回転角として覚えておく 22 // この作業をすべての大砲について行うことで、最もプレイヤーの方角に 23 // 近い方角を向いている大砲の回転角が選ばれることになる 24 float taihouToPlayerAbsAngle = Mathf.Abs(taihouToPlayerAngle); 25 if (taihouToPlayerAbsAngle < minimumAbsAngle) 26 { 27 minimumAngle = taihouToPlayerAngle; 28 minimumAbsAngle = taihouToPlayerAbsAngle; 29 } 30 } 31 32 // 選ばれた回転角をもとに目標回転を決める 33 Quaternion currentRotation = transform.rotation; 34 Quaternion rotation = Quaternion.Euler(0.0f, minimumAngle, 0.0f) * currentRotation; 35 transform.rotation = Quaternion.Slerp(currentRotation, rotation, 0.015f);

この場合、下図のようにプレイヤーに一番近い方角を向いている大砲をプレイヤーに向けるように回転するかと思います。
なお、大砲の向きがわかりやすいようにしようと思い、大砲の前方に黄色い線を描画してみました。

図

念のため申し上げますと、大砲の中心は船の回転中心からはいくらかずれているでしょうから、このやり方だとプレイヤー船の中心をぴったり射線上に捉えられるとは限らないはずです。
正確にプレイヤーの中心を狙いたい場合、つい先日「Unity2D 銃の照準のずれを直したい」とのご質問を見かけたのですが、あちらに投稿しました案のようにずれを考慮した回転を求めてやる必要があるでしょう。

とはいえ、船中心からの大砲のずれがさほど影響しないようなスケールで撃ち合うのなら問題ないかもしれませんね。むしろ敵側ということでしたら、多少狙いが甘い方がゲーム性の観点からは好ましいんじゃないでしょうか。
もしプレイヤーより何倍も大きなボス船とかでしたら、大砲の位置のずれが大きくなるでしょうから何らかの対策が必要かもしれませんが...

投稿2021/04/29 06:42

Bongo

総合スコア10807

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

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

hosituka

2021/05/02 08:57 編集

回答ありがとうございます、遅れてしまって申し訳ございません。それぞれバラバラな方角へ向けている可能性があると考えていいでしょうか?とのことですがそれで大丈夫です。とてもいい回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問