【问题标题】:Moving camera "flat", ignoring it's x and z rotation移动相机“平”,忽略它的 x 和 z 旋转
【发布时间】:2018-03-01 17:18:02
【问题描述】:

场景如下 - 用户可以点击一个角色,让主摄像头看到那个选定的角色,使用以下代码:

private void RotateTowardsCharacter() {
     RaycastHit hit;
     var cameraCenter = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width / 2, Screen.height / 2, Camera.main.nearClipPlane));

     if (Physics.Raycast(cameraCenter, transform.forward, out hit, 1000)) {
         var obj = hit.transform.gameObject;

         if (obj == _activeCharacter) {    
             return;
         }
     }

     var relativePos = _activeCharacter.transform.position - transform.position;
     var targetRotation = Quaternion.LookRotation(relativePos.normalized);
     var rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime);

     transform.rotation = rotation;
 }

我还想使用 WSAD(或箭头)键启用相机移动,所以我创建了以下代码:

 private void MoveCamera() {
     var x = Input.GetAxis("Horizontal") * Time.deltaTime * 20;
     var z = Input.GetAxis("Vertical") * Time.deltaTime * 20;

     if (x == 0 && z == 0) {
         return;
     }

     transform.Translate(x, 0, z, Space.Self);
 }

您可能已经看到了问题 - 如果相机在 X 轴上旋转,那么按下 W 键实际上会使相机放大它指向的任何东西。 现在,我想要实现的目标:

想象你走在街上,低着头,看着你的 iPhone - 即使你的头在 X 轴上旋转,你还是沿着人行道向前移动 - 没有靠近地面,这很奇怪: )。如果你绕着 Z 轴稍微倾斜你的头,你仍然会走直线,所以实际上影响你运动方向的一件事是你的身体绕 Y 轴的旋转。

这就是我想要实现的 - 我想在一个平面上移动相机,该平面位于其当前 Y 坐标的高度,向前或向后,向左或向右。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    向量数学很棒

    通过将您的输入乘以 Transform.forwardTransform.right 值,您可以获得相对方向向量,然后您可以将它们相加得到最终的平移向量。

    private void MoveCamera() {
         Vector3 horiz = Input.GetAxis("Horizontal") * Time.deltaTime * 20 * transform.right;
         Vector3 forward = Input.GetAxis("Vertical") * Time.deltaTime * 20 * transform.forward;
    
         if ((horiz + forward).sqrMagnitude < 0.01f) {
             return;
         }
    
         transform.Translate(horiz + forward, Space.Self);
    }
    

    【讨论】:

    • 这给了我奇怪的结果。如果相机在每个轴上旋转,那么向左或向右移动实际上会向左或向右移动相机,但也会影响相机的 Y 坐标,因此它也会稍微向上或向下移动。
    • 我想要的效果可以用Vector3.ProjectOnPlane的方法来表达(下面也是我的解决方案)。
    • 只有在围绕 Z 轴旋转相机时,左右移动才能在 Y 轴上移动相机,这是您永远不想做的。如果它在 X 轴上旋转,你会得到前后 Y 轴移动......但你自己的答案也会有这个问题。
    • 我修复了我的旋转代码以防止在 Z 轴上旋转,但我仍然有提到的问题。
    • @MarekM。我说,“不清楚你在问什么。”您希望相机在旋转的空间中移动,而移动不受旋转的影响。
    【解决方案2】:

    这段代码成功了:

    private void MoveForwardFlat(float z) {
        var fwd = transform.forward;
    
        fwd.y = 0;
    
        fwd.Normalize();
    
        if (fwd != Vector3.zero) {
            transform.position += fwd * z;
        }
    }
    

    它还确保尽管旋转,但移动速度将保持不变。

    【讨论】:

      【解决方案3】:

      简单的方法!无需代码! 使用全局 Gizmo 创建一个 EMPTY OBJECT 并将相机作为子项附加。然后将移动代码附加到父空对象。 现在代码跟随空物体的 (0, 0, 0) 变换,相机跟随他作为一个孩子。

      遇到了同样的问题,我想不用编码来解决它

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-06
        • 1970-01-01
        • 2016-04-18
        • 2017-03-06
        • 1970-01-01
        相关资源
        最近更新 更多