前提・実現したいこと
マウスをドラッグすることによって球面座標上にカメラが移動する。
というものを実装したいと考えていますが、現状以下のスクリプトをカメラにアサインして実行すると、ドラッグした瞬間にカメラが対象オブジェクトの上方向に瞬間的に移動してしまう問題が発生しています。
ドラッグした瞬間にカメラの座標に大きな値が入ってしまうような状況です。
実行直後の位置からカメラをドラッグして動かせるようにするにはどうしたら良いでしょうか?
発生している問題・エラーメッセージ
マウスをドラッグした瞬間にカメラが上方向に移動してしまう
該当のソースコード
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}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/27 12:40
2021/11/28 01:40