使用光线投射拖动对象是滞后的
Dragging an object with raycast is laggy
当使用光线投射缓慢拖动对象时,对象移动时会有一点滞后。
快速拖动对象时,鼠标指针会超出图层光线投射范围,因此对象不再移动。
主要项目是在平面上拖动立方体。
但是为了使项目更简单,我打开了一个新的 2D 项目并做了一个圆并为其分配了以下脚本,并附加了一个球体碰撞器(主要目标是 3D space).
// 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,然后我将 void 从 Update()
更改为 FixedUpdate()
,但结果相同。
尝试将物理代码放入为物理计算构建的 FixedUpdate()
函数中。然后如果它很慢,你可以在物理设置中更改Fixed Timestep
。
Fixed Timestep: A framerate-independent interval that dictates when physics calculations and FixedUpdate() events are performed.
https://docs.unity3d.com/Manual/class-TimeManager.html
编辑
此代码:
if (Physics.Raycast (ray, out hit, Mathf.Infinity))
检查光线投射是否击中了什么东西,因此当指针离开球体时没有其他东西可以击中,所以 if 条件 returns false 并且你不能移动它,解决问题添加一个大的四边形或平面作为 child 到你的相机并确保它完美地填充相机视图,并且它在你所有其他场景元素的后面。
你也可以制作一个脚本来为你设置这个平面。
编辑 2
作为解决问题的另一种方法,您可以使用 flags.
将此添加到您的相机,或根据您的需要对其进行编辑。
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;
}
}
}
Remember to cash your Camera.main
in a variable at the start, because it is not performant and does this in the background:
GameObject.FindGameObjectsWithTag("MainCamera").GetComponent<Camera>();
当使用光线投射缓慢拖动对象时,对象移动时会有一点滞后。
快速拖动对象时,鼠标指针会超出图层光线投射范围,因此对象不再移动。
主要项目是在平面上拖动立方体。
但是为了使项目更简单,我打开了一个新的 2D 项目并做了一个圆并为其分配了以下脚本,并附加了一个球体碰撞器(主要目标是 3D space).
// 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,然后我将 void 从 Update()
更改为 FixedUpdate()
,但结果相同。
尝试将物理代码放入为物理计算构建的 FixedUpdate()
函数中。然后如果它很慢,你可以在物理设置中更改Fixed Timestep
。
Fixed Timestep: A framerate-independent interval that dictates when physics calculations and FixedUpdate() events are performed. https://docs.unity3d.com/Manual/class-TimeManager.html
编辑
此代码:
if (Physics.Raycast (ray, out hit, Mathf.Infinity))
检查光线投射是否击中了什么东西,因此当指针离开球体时没有其他东西可以击中,所以 if 条件 returns false 并且你不能移动它,解决问题添加一个大的四边形或平面作为 child 到你的相机并确保它完美地填充相机视图,并且它在你所有其他场景元素的后面。
你也可以制作一个脚本来为你设置这个平面。
编辑 2
作为解决问题的另一种方法,您可以使用 flags.
将此添加到您的相机,或根据您的需要对其进行编辑。
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;
}
}
}
Remember to cash your
Camera.main
in a variable at the start, because it is not performant and does this in the background:GameObject.FindGameObjectsWithTag("MainCamera").GetComponent<Camera>();