【问题标题】:Clamping problems with diagonal camera rotation around object based on mouse input基于鼠标输入的对角相机围绕对象旋转的钳位问题
【发布时间】:2020-04-11 15:43:03
【问题描述】:

我正在编写一个脚本,它可以围绕玩家对象对角旋转相机(3D x 和 3D y 轴)。输入如下:

  • 鼠标在 z 轴上绕对象旋转 y 轴
  • 鼠标 x 轴进行对角线“过肩”旋转,从而修改相机旋转的 y 和 x:

demo of my current camera script

它可以工作,但是,我无法限制相机的 y 轴旋转。 X 轴按预期工作。观看上面的视频,看看最后的问题。它在 y 轴上过度旋转,因此相机以完全错误的方向朝向玩家。也许有大脑功能的人可以想出一个解决方案?太棒了,提前谢谢!

这是我的脚本:

void Update() {
        mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
        mouseY = -(Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime);

        rotationXAxis += mouseY;
        rotationXAxis = ClampAngle(rotationXAxis, -30f, 30f);

        float rotationYAxis = rotationXAxis;
        rotationYAxis = ClampAngle(rotationYAxis, 0f, 30f);

        Quaternion fromRotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, 0);
        Quaternion toRotation = Quaternion.Euler(rotationXAxis, transform.rotation.eulerAngles.y - rotationYAxis * Time.deltaTime, 0);
        Quaternion rotation = toRotation;

        Vector3 negDistance = new Vector3(xPosOffset, yPosOffset, -distance);
        Vector3 position = rotation * negDistance + player.position;

        transform.rotation = rotation;
        transform.position = position;

        player.Rotate(Vector3.up * mouseX);
        mouseY = Mathf.Lerp(mouseY, 0, Time.deltaTime);
    }

    float ClampAngle(float angle, float min, float max) {
        if (angle < -360F)
            angle += 360F;
        if (angle > 360F)
            angle -= 360F;
        return Mathf.Clamp(angle, min, max);
    }

【问题讨论】:

  • 对我来说最大的问题是您没有或使用原始位置。因为您将能够计算一些旋转并添加到原始位置。

标签: c# unity3d 3d camera physics


【解决方案1】:

我尝试用伪语言向你解释。

sinus 和 cosinus 基本相同,但相差 90 度。

这个函数产生的是 -1 .. 1 个数字是什么 -100% .. 100%

基本上你需要的是

var _x,_y,_z; //original position
var deg; // 0..360
x = _x * sin(deg);
y = _y * cos(deg);
z = _z;

这是围绕世界 [0,0,0] 旋转

如果你想绕另一个轴旋转

var a_x,a_y,a_z;

x = _x + a_x * sin(deg);
y = _y + a_y * cos(deg);
z = _z + a_z;

最大的关键是保留默认位置 [_x,_y,_z] 不要犯这个错误

x = x * sin(deg);

正好是一个矩阵

   _x   _y  _z
x [cos -sin  0]
y [sin  cos  0]
z [0      0  1]

x = _x * cos(deg) + _y * -sin(deg) + _z * 0;
y = _x * sin(deg) + _y * cos(deg)  + _z * 0;
z = _x * 0        + _y * 0         + _z * 1; 

查看轴的 3d 矩阵。 https://en.wikipedia.org/wiki/Rotation_matrix#In_three_dimensions

试试这样的方法

void Update(Player player) {
    _position = player.position;

    mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
    mouseY = -(Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime);

    _delta_x = mouseX - _position.x;
    _delta_y = mouseY - _position.y;
    _delta_z = 0;

    _rot_x = ClampAngle(mouseX, mouseY, -30f, 30f);         
    _rot_y = ClampAngle(mouseX, mouseY, -30f, 30f);
    _rot_z = 0;

    Vector3 position = new Vector3(_delta_x, _delta_y, _delta_z);
    position = position.rotate (rot_x, rot_y, rot_z);
    position = position.add(_position.x,_position.y,_position.z);

    player.position = position;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    • 2016-11-23
    • 2019-04-14
    • 1970-01-01
    相关资源
    最近更新 更多