【问题标题】:Rotating object around point based on mouse movement including diagonals基于鼠标移动(包括对角线)围绕点旋转对象
【发布时间】:2020-08-06 02:15:37
【问题描述】:
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    
    if( selectedObjs.Count==0&&Input.GetMouseButtonDown(0))
    {
        if (Physics.Raycast(ray,out hit,100, 1 << 9))
        {
            currentPos = hit.point;
        }
    }

    if (mouseClickMode !=3 && mouseClickMode != 4 && !uiMenu_on 
        && Input.GetMouseButton(0))
    {
        float rotX = Input.GetAxis("Mouse X");
        float rotY = -Input.GetAxis("Mouse Y");
        if (selectedObjs.Count > 0)
            currentPos = objectManager.ReturnPos(selectedObjs[0]);
                    
        transform.RotateAround(currentPos, Vector3.up, Time.deltaTime *450* rotX);
        transform.RotateAround(currentPos, Vector3.right, Time.deltaTime*450 * rotY);

   
    }

这种旋转先在 x 轴上旋转,然后在 y 轴上旋转。

但是当鼠标沿对角线移动时,轴就不是对角线了。当鼠标沿对角线移动时,如何让对象围绕对角轴上的点旋转?

【问题讨论】:

  • 请不要在Update 中使用Camera.main - 您应该不经常使用它,或者最好在StartAwake 中使用它并缓存结果。 See here for more information
  • 我现在正在使用一种方法,如果没有用相机点击对象,则围绕用鼠标拍摄的位置旋转相机,但该方法并不完全正确。

标签: c# unity3d


【解决方案1】:

使用相机的transform.TransformDirection 在世界空间中查找鼠标的方向。 (注意float rotY = Input.GetAxis("Mouse Y"); 没有否定)

使用鼠标的世界方向和相机的前向之间的叉积来确定您感兴趣的旋转轴。

根据鼠标移动的幅度旋转。

总共:

[RequireComponent(typeof(Collider))]
public class TestScript : MonoBehaviour
{
    Vector3 currentPos;
    Camera mainCam;
    
    private void Start()
    {
        mainCam = Camera.main;
    }

    private void Update()
    {
        RaycastHit hit;
        Ray ray = mainCam.ScreenPointToRay(Input.mousePosition);

        if (Input.GetMouseButtonDown(0))
        {
            if (Physics.Raycast(ray, out hit))
            {
                currentPos = hit.point;
            }
        }

        if (Input.GetMouseButton(0))
        {
            float rotX = Input.GetAxis("Mouse X");
            float rotY = Input.GetAxis("Mouse Y");

            Vector3 mouseMove = new Vector3(rotX, rotY, 0f);
            Vector3 mouseWorldDirection = mainCam.transform.TransformDirection(
                    mouseMove);
            Vector3 rotAxis = Vector3.Cross(mouseWorldDirection, 
                    mainCam.transform.forward);

            transform.RotateAround(currentPos, rotAxis, Time.deltaTime * 450f 
                    * mouseMove.magnitude);
        }
    }
}

在您的代码中,它可能如下所示:

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 
if( selectedObjs.Count==0&&Input.GetMouseButtonDown(0))
{
    if (Physics.Raycast(ray,out hit,100, 1 << 9))
    {
        currentPos = hit.point;
    }
}

if (mouseClickMode !=3 && mouseClickMode != 4 && !uiMenu_on 
    && Input.GetMouseButton(0))
{
    float rotX = Input.GetAxis("Mouse X");
    float rotY = Input.GetAxis("Mouse Y");
    if (selectedObjs.Count > 0)
        currentPos = objectManager.ReturnPos(selectedObjs[0]);
                
    Vector3 mouseMove = new Vector3(rotX, rotY, 0f);
    Vector3 mouseWorldDirection = mainCam.transform.TransformDirection(mouseMove);
    Vector3 rotAxis = Vector3.Cross(mouseWorldDirection, mainCam.transform.forward);

    transform.RotateAround(currentPos, rotAxis, Time.deltaTime * 450f 
            * mouseMove.magnitude);
}

【讨论】:

  • camera.transform.Lookat(mouseposition)和camera.transform.TransformDirection(mouseMove)有什么区别 mouseMove是这个页面camera move Mouseposition是input.Mouse x,y
  • @KImJUngsilver camera.transform.TransformDirection 采用局部空间方向 mouseMove 并返回世界空间方向 mouseWorldDirection。例如,如果mouseMoveVector3.right 并且camera.transform.rightVector3.forward,那么mouseWorldDirection 将是Vector3.forwardLookAt 将改变 camera 的旋转,但这还不够,因为我们还想改变位置。
【解决方案2】:

代替:

transform.RotateAround(currentPos, Vector3.up, Time.deltaTime *450* rotX);
transform.RotateAround(currentPos, Vector3.right, Time.deltaTime*450 * rotY);

试试:

transform.RotateAround(currentPos, new Vector3(rotY, rotX, 0), Time.deltaTime * 450);

这样您就不会分别在 2 轴上旋转。


或者如果不想只对角运动:

    float diagonalDeadzone = 0.2f;
    float rotX = Input.GetAxis("Mouse X");
    float rotY = -Input.GetAxis("Mouse Y");
    if (selectedObjs.Count > 0)
        currentPos = objectManager.ReturnPos(selectedObjs[0]);
    if (rotX < diagonalDeadzone && rotX > -diagonalDeadzone)
    {
        transform.RotateAround(currentPos, Vector3.up * rotX, Time.deltaTime * 450);
    }
    else if (rotY < diagonalDeadzone && rotY > -diagonalDeadzone)
    {
        transform.RotateAround(currentPos, Vector3.right * rotY, Time.deltaTime * 450);
    }

【讨论】:

  • 你把它代替你的代码而不是那个代码上下旋转根本不起作用我想我应该只在旋转轴是对角线的时候才做这个驱动器完美的对角线。
  • @KImJUngsilver 答案是transform.RotateAround(currentPos, new Vector3(rotY, rotX, 0), Time.deltaTime * 450);。它是如何工作的?
  • @Ruzihm 可以工作,但它的移动方式与之前使用的上下旋转不同。所以我这样做只在鼠标对角线时尝试使用它
  • @DotCS 谢谢你,我会回家制作视频并上传。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-27
  • 2017-02-20
  • 2021-06-06
  • 1970-01-01
  • 2011-01-24
  • 2021-09-13
  • 2015-07-14
相关资源
最近更新 更多