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

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

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

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

Unity

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

Q&A

1回答

1261閲覧

Unityにて戦車の砲塔をカメラ方向に向かせる

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity

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

1グッド

1クリップ

投稿2019/03/09 00:54

編集2019/03/09 09:05

Unityにて戦車の砲塔をカメラ方向に向かせる(BFシリーズのTPS視点での操作のイメージ)スクリプトを作成したのですが砲塔はカメラの方向に回転するのですが砲塔が細かく左右にぶれるというかガタガタします。また戦車がひっくり返った状態だと砲塔が逆の方向に向いてしまいます。Slerpの感度部分を低くすることでブレはなくなるのですが回転速度が遅くなってしまうのでこれ以外で解決方法を伺いたいです。
追記:すいません原因がわかりました。カメラY軸と砲塔のXZ平面の交差点への角度を求める際に回転角の方向を求めるvar angle = Vector3.Angle(houtou.transform.up, diff)* (axis.y < 0 ? -1 : 1);の部分が三次元的な動きをするオブジェクトだと正しくない結果になることが原因のようです。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class TankController : MonoBehaviour 6{ 7 [SerializeField] float m_MovingTurnSpeed = 360; 8 [SerializeField] float m_StationaryTurnSpeed = 180; 9 [SerializeField] float m_JumpPower = 12f; 10 [SerializeField] float m_GroundCheckDistance = 10f; 11 [SerializeField] float groundDistamce = 3f; 12 [SerializeField] float toruque = 100; 13 [SerializeField] Transform houtou; 14 [SerializeField] Transform mainca; 15 [SerializeField] float RotationSensitivity = 10f; 16 [SerializeField] float uppoer = 500f; 17 [SerializeField] Transform camera; 18 19 [SerializeField] Transform iPoint; 20 21 float inputHorizontal; 22 Vector3 intersectPoint; 23 float inputVertical; 24 Rigidbody m_Rigidbody; 25 Animator m_Animator; 26 [SerializeField] bool m_IsGrounded; 27 float m_OrigGroundCheckDistance; 28 const float k_Half = 0.5f; 29 float m_TurnAmount; 30 float m_ForwardAmount; 31 Vector3 m_GroundNormal; 32 float m_CapsuleHeight; 33 Vector3 m_CapsuleCenter; 34 CapsuleCollider m_Capsule; 35 bool m_Crouching; 36 bool jumppress; 37 public bool TPSMode; 38 bool TPSModeInput; 39 float h = 0f; 40 float v = 0f; 41 float trigger = 0f; 42 43 44 void Start() 45 { 46 m_Rigidbody = GetComponent<Rigidbody>(); 47 m_Animator = GetComponent<Animator>(); 48 m_Rigidbody.maxAngularVelocity = 7; 49 intersectPoint = houtou.position; 50 iPoint.transform.position = transform.position; 51 52 53 //m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ; 54 } 55 56 void Update() 57 { 58 h = Input.GetAxisRaw("Horizontal"); 59 v = Input.GetAxisRaw("Vertical"); 60 trigger = Input.GetAxisRaw("LRTrigger"); 61 62 } 63 64 void FixedUpdate() 65 { 66 //移動処理 67 68 m_Rigidbody.AddForce(transform.forward * 50f * -trigger, ForceMode.Impulse); 69 70 Vector3 tpow = transform.up * toruque * h; 71 Vector3 tpowv = transform.right * toruque * v; 72 m_Rigidbody.AddTorque(tpow + tpowv); 73 74 75 RaycastHit hitInfo; 76 if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance)) 77 { 78 //m_Rigidbody.AddForce(new Vector3(0, -(1000f-hitInfo.distance), 600f)); 79 float uppower = -(1 / (1 + Mathf.Exp(-(hitInfo.distance - groundDistamce)))) * 1000f + 1500f; 80 //print("Found an object - distance: " + hitInfo.distance + "Power:" + uppower + "h:" + h + "Tpow:" + tpow); 81 m_Rigidbody.AddForce(Vector3.up * uppower); 82 83 } 84 //移動処理ここまで 85 86 //砲塔回転処理 87 88 //カメラのY軸が砲塔のXZ平面に直行するポイントを計算 89 var houtouXZNormal = houtou.transform.forward; 90 var houtoouXZPlane = houtou.transform.position; 91 var cameraPoint = camera.transform.position; 92 var targetVector = Vector3.down; 93 var houtouXZPoint = Vector3.Dot(houtouXZNormal, houtoouXZPlane); 94 var tmp = cameraPoint + ((houtouXZPoint - Vector3.Dot(houtouXZNormal, cameraPoint)) / (Vector3.Dot(houtouXZNormal, targetVector))) * targetVector; 95 intersectPoint = tmp;//Vector3.Slerp(intersectPoint, tmp, 1f); 96 iPoint.position = intersectPoint; 97 //直行ポイントまでの角度を計算 98 var diff = intersectPoint - houtou.transform.position; 99 var axis = Vector3.Cross(houtou.transform.up, diff); 100 var angle = Vector3.Angle(houtou.transform.up, diff)* (axis.y < 0 ? -1 : 1); 101 print(angle); 102 //houtou.Rotate(0f, 0f, angle, Space.Self); 103 //houtou.rotation = (Quaternion.AngleAxis(angle, houtou.transform.forward) * houtou.rotation); 104 //houtou.rotation = Quaternion.Slerp(houtou.rotation, Quaternion.LookRotation((intersectPoint - houtou.position)), Time.deltaTime * RotationSensitivity); 105 //houtou.rotation = Quaternion.FromToRotation(houtou.TransformDirection(Vector3.forward), intersectPoint); 106 //Quaternion backR = houtou.rotation; 107 houtou.rotation = Quaternion.Slerp(houtou.rotation, (Quaternion.AngleAxis(angle, houtou.transform.forward) * houtou.rotation), Time.deltaTime * RotationSensitivity); 108 //砲塔回転処理ここまで 109 110 111 112 113 } 114 void LateUpdate() 115 { 116 117 } 118 119} 120
bochan2👍を押しています

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

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

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

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

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

ikadzuchi

2019/03/11 00:27

解決したのでしたら自己解決で締め切り、まだ疑問が残っているのでしたらそのように編集してください。
guest

回答1

0

まず、ガタガタする理由は砲身の動きがデジタルだからです

例えば、3度ずつ回転している時、後1度で敵の方向を向くときも3度回転するので、
-2度となり、逆方向に3度回転→1度を繰り返しています
回転角度以下のときは直接回転角度を入れれば解決です

また、ひっくり返っているところは、下記部分をupにする必要があると思います
var targetVector = Vector3.down;

投稿2019/03/09 07:44

izmktr

総合スコア2856

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問