我的场景中有一个固定的立方体,我正在绕着摄像机转。我的主摄像机嵌套在我称之为"轨道摄像机"的游戏对象下。
我设置了脚本,以便单击(或点击(和拖动将围绕空间中的对象旋转相机,因此感觉就像您在旋转立方体(即:如果我单击立方体上的面部顶部并向下拉,我正在旋转 X 值(,但您实际上是在旋转相机。
在大多数情况下,我的脚本有效。然而,在旋转Y这么多之后,相机是颠倒的,X被颠倒了。这是我的脚本:
public class OrbitalCamera : MonoBehaviour {
public bool cameraEnabled;
[SerializeField] private float touchSensitivity;
[SerializeField] private float scrollSensitivity;
[SerializeField] private float orbitDampening;
protected Transform xFormCamera;
protected Transform xFormParent;
protected Vector3 localRotation;
protected float cameraDistance;
void Start () {
cameraEnabled = true;
xFormCamera = transform;
xFormParent = transform.parent;
cameraDistance = transform.position.z * -1;
}
void LateUpdate () {
if (cameraEnabled) {
// TODO:: FIX PROBLEM WHERE WHEN CAMERA IS ROTATED TO BE UPSIDEDOWN, CONTROLS GET INVERSED
if (Input.GetMouseButton(0)) {
if (Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0) {
localRotation.x += Input.GetAxis("Mouse X") * touchSensitivity;
localRotation.y -= Input.GetAxis("Mouse Y") * touchSensitivity;
}
}
}
Quaternion qt = Quaternion.Euler(localRotation.y, localRotation.x, 0);
xFormParent.rotation = Quaternion.Lerp(xFormParent.rotation, qt, Time.deltaTime * orbitDampening);
}
}
有没有实现这种360度相机的好方法?我想从右向左拖动以始终向左移动相机,从左拖动到右拖动以始终向右移动相机 - 无论相机如何定向。
也许您可以将上方/下方的平底锅夹在 89 度?
我最近帮一个朋友做了一个鼠标云台,发现允许超过89度的自由度是有问题的,也是不必要的。看起来您的应用程序是相同的,至少对于两个平面中的一个。
在 LateUpdate(( 调用中,您可以添加:
localRotation.x += Input.GetAxis("Mouse X") * touchSensitivity;
localRotation.x = Clamp(localRotation.x);
然后,当然,创建您的钳位函数,这应该相当简单:
float Clamp(float val) // prevent values from ~90 - ~270
{
int lowVal = 89;
int highVal = 271;
int midVal = 180;
if (val > lowVal & val < highVal)
{
if (val > midVal) val = highVal;
else val = lowVal;
}
return val;
}
一个略有不同的应用程序,但我相信您可以看到我是如何设置的:我分两步应用旋转。步骤 1 - 一个简单的 Rotate(( 调用, 步骤 2 - 夹紧部分/全部旋转:
using UnityEngine;
public class MouseGimbal : MonoBehaviour
{
[SerializeField] [Range(0,89)] float maxRotationDegrees = 10.0f; // At 90+ gimbal oddities must be dealt with.
[SerializeField] bool ClampToMaxRotationDegrees = true; // Disable for free rotation.
[SerializeField] float rotationSpeed = 10.0f;
const float fullArc = 360.0f;
const float halfArc = 180.0f;
const float nullArc = 0.0f;
void Update () { Tilt(); }
void Tilt()
{
// Apply the 'pre-clamp' rotation (rotation-Z and rotation-X from X & Y of mouse, respectively).
if (maxRotationDegrees > 0) { SimpleRotation(GetMouseInput()); }
// Clamp rotation to maxRotationDegrees.
if (ClampToMaxRotationDegrees) { ClampRotation(transform.rotation.eulerAngles); }
}
void ClampRotation(Vector3 tempEulers)
{
tempEulers.x = ClampPlane(tempEulers.x);
tempEulers.z = ClampPlane(tempEulers.z);
tempEulers.y = nullArc; // ClampPlane(tempEulers.y); // *See GIST note below...
transform.rotation = Quaternion.Euler(tempEulers);
///Debug.Log(tempEulers);
}
float ClampPlane(float plane)
{
if (OkayLow(plane) || OkayHigh(plane)) DoNothing(); // Plane 'in range'.
else if (BadLow(plane)) plane = Mathf.Clamp(plane, nullArc, maxRotationDegrees);
else if (BadHigh(plane)) plane = Mathf.Clamp(plane, fullArc - maxRotationDegrees, fullArc);
else Debug.LogWarning("WARN: invalid plane condition");
return plane;
}
Vector2 GetMouseInput()
{
Vector2 mouseXY;
mouseXY.x = -Input.GetAxis("Mouse X"); // MouseX -> rotZ.
mouseXY.y = Input.GetAxis("Mouse Y"); // MouseY -> rotX.
return mouseXY;
}
void SimpleRotation(Vector2 mouseXY)
{
Vector3 rotation = Vector3.zero;
rotation.x = mouseXY.y * Time.deltaTime * rotationSpeed;
rotation.z = mouseXY.x * Time.deltaTime * rotationSpeed;
transform.Rotate(rotation, Space.Self);
}
void DoNothing() { }
bool OkayHigh(float test) { return (test >= fullArc - maxRotationDegrees && test <= fullArc); }
bool OkayLow(float test) { return (test >= nullArc && test <= maxRotationDegrees); }
bool BadHigh(float test) { return (test > halfArc && !OkayHigh(test)); }
bool BadLow(float test) { return (test < halfArc && !OkayLow(test)); }
}
当我开发轨道相机时,我创建了 3 个对象:
- x_axis (rotate with vertical mouse moviment)
- y_axis (rotate with horizontal mouse moviment)
- camera (look_at object) (translated Vector3(0,0,-10))