Вращение объекта вокруг точки на основе движения мыши, включая диагонали - PullRequest
3 голосов
/ 06 августа 2020
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.

Но когда мышь перемещается по диагонали, ось не является диагональной. Как я могу заставить объект вращаться вокруг точки на диагональной оси, когда мышь перемещается по диагонали?

Ответы [ 2 ]

1 голос
/ 07 августа 2020

Найдите направление мыши в мировом пространстве, используя 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);
}
0 голосов
/ 06 августа 2020

Вместо:

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);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...