用raycast拖动对象比较滞后

时间:2019-06-03 00:09:57

标签: unity3d raycasting

使用射线投射缓慢拖动对象时,该对象会稍有滞后地移动。

快速拖动对象时,鼠标指针会脱离图层光线投射的范围,因此对象不再移动。

主要项目是在平面上拖动多维数据集。

但是为了使项目更简单,我打开了一个新的2D项目并制作了一个圆圈,并为其分配了以下脚本,并在其上附加了一个球体碰撞器(主要目标是在3D空间中)。

// If some one wrote:
private Vector2 deltaPos;
    void Update () {
        Vector2 touchPos;
        if (Input.GetMouseButtonDown (0)) {                                                     // Clicking the Target              
            RaycastHit hit;
            var ray = Camera.main.ScreenPointToRay (Input.mousePosition);

            if (Physics.Raycast (ray, out hit, Mathf.Infinity)) {

                touchPos = new Vector3 (hit.point.x, hit.point.y);
                deltaPos.x = touchPos.x - transform.position.x;
                deltaPos.y = touchPos.y - transform.position.y;
                Debug.Log ("You Clicked Me");
            }
        }
        if (Input.GetMouseButton (0)) {
            RaycastHit hit;
            var ray = Camera.main.ScreenPointToRay (Input.mousePosition);

            if (Physics.Raycast (ray, out hit, Mathf.Infinity)) {
                transform.position = new Vector2 (hit.point.x - deltaPos.x, hit.point.y - deltaPos.y);
            }
        }
    }

我希望定期拖动球体,但是发生的事情是,快速移动时指针会移到球体碰撞体的外面,因此圆会停止移动。

我找到了这个article,然后将空白从Update()更改为FixedUpdate(),但结果相同。

1 个答案:

答案 0 :(得分:2)

尝试将物理代码放入为物理计算而构建的FixedUpdate()函数中。那么您就可以在物理设置中更改Fixed Timestep

  

固定时间步长:与帧速率无关的间隔,指示执行物理计算和FixedUpdate()事件的时间。   https://docs.unity3d.com/Manual/class-TimeManager.html

编辑

此代码:

if (Physics.Raycast (ray, out hit, Mathf.Infinity))

检查射线投射是否击中了某些物体,因此当指针移出球体时,没有其他物体可以击中,因此if条件返回false并且您无法移动它,以解决该问题,请添加一个大的四边形或平面作为子,确保它完美地填充了相机视图,并且位于所有其他场景元素的后面。

您还可以创建一个脚本来为您设置此平面。

编辑2

作为解决此问题的另一种方法,您可以使用标志

将其添加到相机中,或根据需要进行编辑。

    public class DragObjects : MonoBehaviour
    {
        Camera thisCamera;
        private Transform DraggingObject;
        bool DraggingFlag = false;
        RaycastHit raycast;
        Ray ray;
        Vector3 deltaPosition;

        void Start()
        {
            thisCamera = GetComponent<Camera>();
        }
        void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                ray = thisCamera.ScreenPointToRay(Input.mousePosition);
                if (Physics.Raycast(ray, out raycast, Mathf.Infinity))
                {
                    DraggingObject = raycast.collider.transform;
                    DraggingFlag = true;
                    deltaPosition = thisCamera.ScreenToWorldPoint (Input.mousePosition) - DraggingObject.position;
                }
            }
            else if (Input.GetMouseButton(0))
            {
                if (DraggingFlag)
                {
                    DraggingObject.position = new Vector3 (thisCamera.ScreenToWorldPoint (Input.mousePosition).x - deltaPosition.x, thisCamera.ScreenToWorldPoint (Input.mousePosition).y - deltaPosition.y, DraggingObject.position.z);
                }
            }
            else if (Input.GetMouseButtonUp(0))
            {
                DraggingFlag = false;
            }
        }
    }
  

请记住在开始时将Camera.main兑现为一个变量,因为它不是高效的,并且在后台执行:   GameObject.FindGameObjectsWithTag("MainCamera").GetComponent<Camera>();