【问题标题】:How to move objects with perspective camera and rotating the camera in Unity3D?如何使用透视相机移动物体并在 Unity3D 中旋转相机?
【发布时间】:2020-04-19 20:08:34
【问题描述】:

我正在尝试旋转我的相机(X 轴为 50 度)并在触摸位置之后放置一个对象,这是我的脚本,可以旋转相机并移动对象,但由于它是透视的,所以对象没有移动正确地跟随手指,关于如何实现这一点的任何提示?

目标是实现类似于此视频https://www.youtube.com/watch?v=Ljnpp5ibfGQ

using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;

 public class CameraRotator : MonoBehaviour
 {
     private float initialX;
     public float offset = 10f;
     public float speed = 10f;
     public GameObject cube;
     public bool movingPlayer = false;

     void Update()
     {

         if (Input.touchCount > 0 && !movingPlayer)
         {
             Touch touch = Input.GetTouch(0);
             Vector3 touchPosition = Camera.main.ScreenToWorldPoint(touch.position);

             switch (touch.phase)
             {
                 case TouchPhase.Began:

                     initialX = touch.position.x;
                     break;
                 case TouchPhase.Moved:
                     if (touch.position.x + offset < initialX)
                         transform.rotation = Quaternion.Euler(0f, transform.rotation.eulerAngles.y - speed, 0f);
                     else if (touch.position.x - offset > initialX)
                         transform.rotation = Quaternion.Euler(0f, transform.rotation.eulerAngles.y + speed, 0f);

                     initialX = touch.position.x;
                     break;
             }
         }


         if (Input.touchCount > 0 && movingPlayer)
         {
             Touch touch = Input.GetTouch(0);
             Vector3 touchPosition = Camera.main.ScreenToWorldPoint(touch.position);

             Ray raycast = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);

             if (Input.GetTouch(0).phase == TouchPhase.Moved)
             {
                 Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
                 Vector3 xx = ray.GetPoint(10f);
                 xx.y = 1f;
                 xx.x = (int)xx.x;
                 xx.z = (int)xx.z;
                 cube.transform.position = xx;
             }

         }
     }
 }

【问题讨论】:

    标签: c# unity3d perspectivecamera


    【解决方案1】:

    我前段时间创造了类似的东西。

    你需要小心ScreenToWorldPoint()。 Click 位置基本上不是世界上的 3D 点,而是一条射线。空间中有一整行位置都将出现在屏幕上的同一个位置。

    Unity 函数ScreenToWorldPoint() 使用来自输入向量的 Z 坐标作为距离。既然你只是从Input.GetTouch()捡来的,那肯定不是你想要的距离。

    文档:https://docs.unity3d.com/2020.1/Documentation/ScriptReference/Camera.ScreenToWorldPoint.html

    最好使用Camera.ScreenPointToRay()。然后使用该射线来确定您要考虑单击的点。

    在我的抓取实现中,我用它来调用 Physics.Raycast()Physics.RaycastAll() ,查看找到的命中,然后决定命中点。

    当玩家拖动时,你需要决定如何改变距离。如果在您的示例视频链接中的地图上单击,您可能会保留单击目标的 Y 坐标,然后每次鼠标移动都将新的 Ray 与该 Y 平面相交。

    在我的示例中,我只是保持距离,让玩家移动物品,保持与拾取时相同的距离。

    在我的示例中,单击时我会这样做:

        // try to grab something.
        Ray beam = new Ray(){origin=head.transform.position,direction=head.transform.forward};
        RaycastHit hit;
        if( ! Physics.Raycast(beam,out hit,15.0f) )
            return;
        grab_item = hit.rigidbody;
        if( grab_item==null || grab_item.isKinematic )
            return;
        grab_pos_on_item = grab_item.transform.InverseTransformPoint(hit.point);
        grab_distance = (hit.point-beam.origin).magnitude;
    

    然后,在每次更新中,检查新点的位置,然后将项目移动到那里。

        if(grab_item!=null)
        {
            // p1: hand, p2: item
            Vector3 p1 = head.transform.position + head.transform.forward * grab_distance;
            Vector3 p2 = grab_item.transform.TransformPoint(grab_pos_on_item);
            Vector3 dist = p1-p2;
            // code to make the item move by 'dist'
    

    如果我理解正确,您可能更愿意保持 Y 坐标不变?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-15
      • 1970-01-01
      • 2016-09-28
      相关资源
      最近更新 更多