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

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

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

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

Unity3D

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

Unity

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

Q&A

解決済

1回答

1780閲覧

マウスをドラッグすることによって球面座標上にカメラが移動するような仕組みを作りたい

expressBO2

総合スコア1

C#

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

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2021/11/26 13:48

前提・実現したいこと

マウスをドラッグすることによって球面座標上にカメラが移動する。

というものを実装したいと考えていますが、現状以下のスクリプトをカメラにアサインして実行すると、ドラッグした瞬間にカメラが対象オブジェクトの上方向に瞬間的に移動してしまう問題が発生しています。
ドラッグした瞬間にカメラの座標に大きな値が入ってしまうような状況です。

実行直後の位置からカメラをドラッグして動かせるようにするにはどうしたら良いでしょうか?

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

マウスをドラッグした瞬間にカメラが上方向に移動してしまう

該当のソースコード

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5[RequireComponent(typeof(Camera))] 6public class ArcballScript : MonoBehaviour 7{ 8 bool ballEnabled = false; 9 float rotationSpeed = 0.5f; 10 float radius = 10.0f; 11 Vector3 _last = new Vector3(); 12 Vector3 _target = new Vector3(0.0f, 0.0f, 0.0f); 13 Vector3 _sphericalCoordinates = new Vector3(); 14 15 void Start() 16 { 17 transform.position = new Vector3(radius, 0.0f, 0.0f); 18 transform.LookAt(_target); 19 _sphericalCoordinates = getSphericalCoordinates(transform.position); 20 } 21 22 Vector3 getSphericalCoordinates(Vector3 cartesian) 23 { 24 float r = Mathf.Sqrt( 25 Mathf.Pow(cartesian.x, 2) + 26 Mathf.Pow(cartesian.y, 2) + 27 Mathf.Pow(cartesian.z, 2) 28 ); 29 30 float phi = Mathf.Atan2(cartesian.z / cartesian.x, cartesian.x); 31 float theta = Mathf.Acos(cartesian.y / r); 32 33 if (cartesian.x < 0) phi += Mathf.PI; 34 35 return new Vector3(r, phi, theta); 36 } 37 38 Vector3 getCartesianCoordinates(Vector3 spherical) 39 { 40 Vector3 ret = new Vector3(); 41 42 ret.x = spherical.x * Mathf.Cos(spherical.z) * Mathf.Cos(spherical.y); 43 ret.y = spherical.x * Mathf.Sin(spherical.z); 44 ret.z = spherical.x * Mathf.Cos(spherical.z) * Mathf.Sin(spherical.y); 45 46 return ret; 47 } 48 49 // Update is called once per frame 50 void Update() 51 { 52 if (Input.GetMouseButtonDown(0)) 53 { 54 _last = Input.mousePosition; 55 56 ballEnabled = true; 57 } 58 59 if (Input.GetMouseButtonUp(0)) 60 ballEnabled = false; 61 62 if (ballEnabled) 63 { 64 // フレーム間でマウスカーソルがどれだけ移動したかを表すデルタ値を取得する 65 float dx = (_last.x - Input.mousePosition.x) * rotationSpeed; 66 float dy = (_last.y - Input.mousePosition.y) * rotationSpeed; 67 68 // マウスがどちらかの方向に移動した場合のみ、カメラの位置を更新する 69 if (dx != 0f || dy != 0f) 70 { 71 // カメラを左右に回転させる 72 _sphericalCoordinates.y += dx * Time.deltaTime; 73 74 // カメラを上下に回転させる 75 // カメラが逆さまになるのを防ぐ(1.5f=約Pi / 2) 76 _sphericalCoordinates.z = Mathf.Clamp(_sphericalCoordinates.z + dy * Time.deltaTime, -1.5f, 1.5f); 77 78 // Unityの直交座標を算出 79 transform.position = getCartesianCoordinates(_sphericalCoordinates); 80 81 // カメラをターゲットに向ける 82 transform.LookAt(_target); 83 } 84 85 // 最後のマウスの位置を更新する 86 _last = Input.mousePosition; 87 } 88 } 89}

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

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

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

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

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

guest

回答1

0

ベストアンサー

getSphericalCoordinatesgetCartesianCoordinates とは互いに逆の計算をするのだと見受けますが,
一方の結果を他方に入れたらちゃんと元の値に戻るのでしょうか?……っていうのを確認してみてはどうでしょう.

コードぱっと見で,

float phi = Mathf.Atan2(cartesian.z / cartesian.x, cartesian.x);

なる演算の / cartesian.x が要らないのでは…?
と思います.

投稿2021/11/26 23:42

fana

総合スコア11996

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

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

expressBO2

2021/11/27 12:40

ご回答ありがとうございます。 ご教示頂いた通り、画面中心をクリックしたと想定して、(960.0 , 540.0 , 0.0)という値をSphericalCoordinatesに入れたところ(1101.5 , 0.0 , 1.1)という値が返ってきました。 続いてCartesianCoordinatesに値を入れると、(540.0 , 960.0 , 0.0)という値が返ってきました。 xとyの座標値が逆になって返ってきてしまっているので、このあたりの計算の手順が違うという事なんでしょうか float phi を求める演算の / cartesian.x を削除しても、数値の挙動は変わりませんでした。
fana

2021/11/28 01:40

何らかの演算を行うメソッドを書いたならば, 「この入力に対してはこの出力が返ってくるハズ」という既知のパターンを用いてテストを行うべきではないでしょうか. > 一方の結果を他方に入れたらちゃんと元の値に戻る ハズのものなのに,そうならないのであれば, SphericalCoordinates と CartesianCoordinates のいずれか,あるいは両方が間違っていると考えられます.これらのメソッドは個別に動作の正当性をテストされるべきです.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問