C# 使用shift键从x-y尺寸更改为x-z尺寸以进行拖动-输入延迟问题
作为我项目的一部分,我开发了一个用户可以使用鼠标移动的球体。由于一次只能考虑两个维度,所以我开发了一种机制,将x-y平面上的拖动更改为x-z平面上的拖动,反之亦然。但是,该程序绝对不是用户友好的,因为在二维平面(即:x-y平面或x-z平面)上拖动时很难控制三维空间中的对象。由于存在严重的输入延迟问题,这一问题只会变得更糟。并不是每按一次shift键就可以换飞机,而且我经常必须多次按shift键才能换飞机 我已尝试将OnMouseDrag()调用的位置更改为update()方法中的不同位置。 这不起作用C# 使用shift键从x-y尺寸更改为x-z尺寸以进行拖动-输入延迟问题,c#,.net,unity3d,graphics,3d,C#,.net,Unity3d,Graphics,3d,作为我项目的一部分,我开发了一个用户可以使用鼠标移动的球体。由于一次只能考虑两个维度,所以我开发了一种机制,将x-y平面上的拖动更改为x-z平面上的拖动,反之亦然。但是,该程序绝对不是用户友好的,因为在二维平面(即:x-y平面或x-z平面)上拖动时很难控制三维空间中的对象。由于存在严重的输入延迟问题,这一问题只会变得更糟。并不是每按一次shift键就可以换飞机,而且我经常必须多次按shift键才能换飞机 我已尝试将OnMouseDrag()调用的位置更改为update()方法中的不同位置。 这不
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
[RequireComponent(typeof(MeshCollider))]
public class UserController : MonoBehaviour
{
bool shiftOn = false;
void OnMouseDrag()
{
if (Input.GetMouseButton(0))
{
if (shiftOn)
{
//3D Drag, courtesy of Unity Forums
float distance_to_screen = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance_to_screen));
}
else
{
//Plane Drag
float distance_to_screen = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
Vector3 pos_move = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance_to_screen));
transform.position = new Vector3(pos_move.x, transform.position.y, pos_move.z);
}
}
}
void changeShift()
{
shiftOn = !shiftOn;
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
{
changeShift();
}
OnMouseDrag();
}
}
输入延迟仍然存在。轮班通话通常不注册,我必须按多次。在尝试切换维度时,我很容易失去对球体的控制
如何消除这种输入延迟?有没有更好的处理方法?有没有一种方法可以让你在一次控制所有三维空间的同时,用鼠标拖动三维空间中的对象
欢迎所有回复
非常感谢您的阅读,我期待着您的建议。如您所知,Update()
每帧调用一次因此,当按住shift键时,在每个帧中,
shiftOn
的值会因函数changeShift()
而改变。因此,如果25/2中有25fps,则没有shiftOn=true
,因此,对象移动可能会有一些延迟或延迟
因此,我建议您如下更改代码:
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftShift))
{
Debug.Log("Shift Pressed"); //Logs message to the Unity Console.
shiftOn = true;
}
if (Input.GetKeyUp(KeyCode.LeftShift))
{
Debug.Log("Shift Released"); //Logs message to the Unity Console.
shiftOn = false;
}
}
根据评论进行更新 我认为,为了使对象的移动稍微平滑,您应该将OnMouseDown事件与OnMouserDrag分开。我的意思是,您应该计算
OnMouseDown
内的初始位置,并计算OnMouseDrag
内的距离和当前位置,以便更新代码如下:
Vector3 Dist;
float PosX;
float Posy;
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftShift))
{
Debug.Log("Shift Pressed");
shiftOn = true;
}
if (Input.GetKeyUp(KeyCode.LeftShift))
{
Debug.Log("Shift Released");
shiftOn = false;
}
}
private void OnMouseDown()
{
if(!shiftOn)
{
Dist = Camera.main.WorldToScreenPoint(transform.position);
PosX = Input.mousePosition.x - Dist.x;
PosY = Input.mousePosition.y - Dist.y;
}
}
private void OnMouseDrag()
{
if(!shiftOn)
{
Vector3 CurrentPos = new Vector3(Input.mousePosition.x - PosX, Input.mousePosition.y -PosY, Dist.z);
Vector3 WorldPos = Camera.main.ScreenToWorldPoint(CurrentPos);
transform.position = WorldPos;
}
}
请注意,我编写的示例用于在2D中移动对象,请将其更改为在3D中使用。正如您所知,Update()
每帧调用一次[RequireComponent(typeof(MeshCollider))]
public class UserController : MonoBehaviour
{
private Vector3 Dist;
private float PosX = 0.0f;
private float PosY = 0.0f;
private float PosZ = 0.0f;
private bool shiftOn = false;
private void OnMouseDown()
{
Dist = Camera.main.WorldToScreenPoint(transform.position);
PosX = Input.mousePosition.x - Dist.x;
PosY = Input.mousePosition.y - Dist.y;
PosZ = Input.mousePosition.z - Dist.z;
}
private void OnMouseDrag()
{
if (Input.GetMouseButton(0))
{
if (shiftOn) // 3D drag
{
transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x - PosX, Input.mousePosition.y - PosY, Input.mousePosition.z - PosZ));
}
else
{
//Plane Drag
Vector3 pos_move = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x - PosX, Input.mousePosition.y - PosY, Input.mousePosition.z - PosZ));
transform.position = new Vector3(pos_move.x, transform.position.y, pos_move.z);
}
}
}
// Update is called once per frame
private void Update()
{
if (Input.GetKeyDown(KeyCode.LeftShift)||Input.GetKeyDown(KeyCode.RightShift))
{
Debug.Log("Shift Pressed"); //Logs message to the Unity Console.
shiftOn = true;
}
if (Input.GetKeyUp(KeyCode.LeftShift) || Input.GetKeyUp(KeyCode.RightShift))
{
Debug.Log("Shift Released"); //Logs message to the Unity Console.
shiftOn = false;
}
}
因此,当按住shift键时,在每个帧中,shiftOn
的值会因函数changeShift()
而改变。因此,如果25/2中有25fps,则没有shiftOn=true
,因此,对象移动可能会有一些延迟或延迟
因此,我建议您如下更改代码:
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftShift))
{
Debug.Log("Shift Pressed"); //Logs message to the Unity Console.
shiftOn = true;
}
if (Input.GetKeyUp(KeyCode.LeftShift))
{
Debug.Log("Shift Released"); //Logs message to the Unity Console.
shiftOn = false;
}
}
根据评论进行更新 我认为,为了使对象的移动稍微平滑,您应该将OnMouseDown事件与OnMouserDrag分开。我的意思是,您应该计算
OnMouseDown
内的初始位置,并计算OnMouseDrag
内的距离和当前位置,以便更新代码如下:
Vector3 Dist;
float PosX;
float Posy;
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftShift))
{
Debug.Log("Shift Pressed");
shiftOn = true;
}
if (Input.GetKeyUp(KeyCode.LeftShift))
{
Debug.Log("Shift Released");
shiftOn = false;
}
}
private void OnMouseDown()
{
if(!shiftOn)
{
Dist = Camera.main.WorldToScreenPoint(transform.position);
PosX = Input.mousePosition.x - Dist.x;
PosY = Input.mousePosition.y - Dist.y;
}
}
private void OnMouseDrag()
{
if(!shiftOn)
{
Vector3 CurrentPos = new Vector3(Input.mousePosition.x - PosX, Input.mousePosition.y -PosY, Dist.z);
Vector3 WorldPos = Camera.main.ScreenToWorldPoint(CurrentPos);
transform.position = WorldPos;
}
}
请注意,我写的示例是在2D中移动对象,请将其更改为在3D中使用。感谢您,穆罕默德!控制仍然非常困难,因为球体经常移动得太快,但至少延迟问题得到了解决。@IDebarshi如果对您有帮助,您可以接受答案。(通过单击答案左侧VoteUp/Down上的勾号)。还有,谢谢你,穆罕默德!我想给你看我的代码。我认为您的解决方案有效,但我不能完全确定我是否正确实施了它。@IDebarshi您正在计算
OnMouseDown
中的初始位置,即Dist
,PosX
,PosY
,PosZ
。然后在OnMouseDrag
中,您应该使用这些点并计算移动距离。我看不到这些变量在代码中的用法。请使用我的完整示例,看看它是否适用于2D模式。请仔细阅读。我看到了你的代码,请从答案中删除,因为它不起作用,穆罕默德,只是更新了它。它看起来平滑多了。非常感谢你!谢谢你,穆罕默德!控制仍然非常困难,因为球体经常移动得太快,但至少延迟问题得到了解决。@IDebarshi如果对您有帮助,您可以接受答案。(通过单击答案左侧VoteUp/Down上的勾号)。还有,谢谢你,穆罕默德!我想给你看我的代码。我认为您的解决方案有效,但我不能完全确定我是否正确实施了它。@IDebarshi您正在计算OnMouseDown
中的初始位置,即Dist
,PosX
,PosY
,PosZ
。然后在OnMouseDrag
中,您应该使用这些点并计算移动距离。我看不到这些变量在代码中的用法。请使用我的完整示例,看看它是否适用于2D模式。请仔细阅读。我看到了你的代码,请从答案中删除,因为它不起作用,穆罕默德,只是更新了它。它看起来平滑多了。非常感谢你!
[RequireComponent(typeof(MeshCollider))]
public class UserController : MonoBehaviour
{
private Vector3 Dist;
private float PosX = 0.0f;
private float PosY = 0.0f;
private float PosZ = 0.0f;
private bool shiftOn = false;
private void OnMouseDown()
{
Dist = Camera.main.WorldToScreenPoint(transform.position);
PosX = Input.mousePosition.x - Dist.x;
PosY = Input.mousePosition.y - Dist.y;
PosZ = Input.mousePosition.z - Dist.z;
}
private void OnMouseDrag()
{
if (Input.GetMouseButton(0))
{
if (shiftOn) // 3D drag
{
transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x - PosX, Input.mousePosition.y - PosY, Input.mousePosition.z - PosZ));
}
else
{
//Plane Drag
Vector3 pos_move = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x - PosX, Input.mousePosition.y - PosY, Input.mousePosition.z - PosZ));
transform.position = new Vector3(pos_move.x, transform.position.y, pos_move.z);
}
}
}
// Update is called once per frame
private void Update()
{
if (Input.GetKeyDown(KeyCode.LeftShift)||Input.GetKeyDown(KeyCode.RightShift))
{
Debug.Log("Shift Pressed"); //Logs message to the Unity Console.
shiftOn = true;
}
if (Input.GetKeyUp(KeyCode.LeftShift) || Input.GetKeyUp(KeyCode.RightShift))
{
Debug.Log("Shift Released"); //Logs message to the Unity Console.
shiftOn = false;
}
}