Мышь.текущая.Кажется, что WarpCursorPosition работает правильно только при движении влево или вверх (не вправо или вниз)?

#c# #unity3d

Вопрос:

Вот простой сценарий, демонстрирующий проблему. Этот скрипт должен переместить курсор влево на 1 секунду, а затем снова вправо на 1 секунду. Однако вы увидите, что он просто перемещает его влево, а затем останавливается. Вы можете перевернуть заказ и попытаться сначала двигаться вправо, но вы заметите, что это все равно не сработает. Я также протестировал движение вверх / вниз, движение вверх работает, как и ожидалось, движение вниз-нет.

 public class dumbtestscript : MonoBehaviour
{

    void Start()
    {
        Mouse.current.WarpCursorPosition(new Vector3(123, 123));

        StartCoroutine(MoveCursorLeftThenRightCoroutine());
    }

    IEnumerator MoveCursorLeftThenRightCoroutine()
    {
        float startTime = Time.time;
        while (Time.time < startTime   1)
        {
            Mouse.current.WarpCursorPosition(Input.mousePosition   

                (Time.deltaTime * new Vector3(-0.1f, 0)));

            yield return null;
        }

        while (Time.time < startTime   2)
        {
            Mouse.current.WarpCursorPosition(Input.mousePosition   

                (Time.deltaTime * new Vector3(0.1f, 0)));

            yield return null;
        }

    }
}
 

Я что-то неправильно понимаю в том, как должна работать WarpCursorPosition?

Любой совет приветствуется. Спасибо.

Правка: При дальнейшем рассмотрении это может иметь отношение к вектору, передаваемому в WarpCursorPosition. Например, независимо от того, используем ли мы это для перемещения влево:

 Mouse.current.WarpCursorPosition(Input.mousePosition   new Vector3(-0.1f, 0));
 

или это:

  Mouse.current.WarpCursorPosition(Input.mousePosition   new Vector3(-1f, 0));
 

он движется влево с той же скоростью. Таким образом, кажется, что все, что находится между -0,1 и -1, округляется до -1. И наоборот, для правильного выбора все между 0,1 и чуть меньше 1 округляется до 0, что объясняет, почему он не двигался в оригинале.

Значит, по какой-то причине все округляется до ближайшего целого числа? Как Input.MousePosition, так и Вектор3, который мы добавляем, являются Вектором3, и я подумал, что могу обрабатывать числа с плавающей запятой, поэтому не уверен, почему все округляется до ints, если это то, что происходит?

Ответ №1:

Проблема

Значит, по какой-то причине все округляется до ближайшего целого числа?

Скорее всего, Да!

WarpCursorPosition заставляет ваш фактический системный курсор перейти к заданным координатам пикселей.

В то время как внутри Unity пространство пикселей всегда предусмотрено float для многих вещей и в основном для выполнения прямых вычислений с его помощью, фактический системный курсор использует пиксели (как и все, что на самом деле происходит на экране), которые всегда являются полными int значениями!

Так что, да, он всегда будет (не округлять, а скорее) уменьшать ваш заданный ввод до следующего int (полного пикселя). В принципе, что произойдет, если вы просто используете

 var x = (int) (Input.mousePosition.x - 0.1f);
 

=> Вы увидите, что > x будет точно Input.mousePosition.x - 1 , так как, например, если ток Input.mousePosition.x был 230 , то вы получите (int) 229.9f , что есть 229 .

В другом направлении, хотя вы получаете, например 230 0.1f , так (int) 230.1f снова просто есть 230 .

=> Ваши шаги должны быть как минимум >одним полным пикселем!


Решение

Поэтому вместо того, чтобы постоянно считывать ток Input.mousePosition , лежащий в основе вышеупомянутых координат пикселей, скорее используйте и обновляйте локальный вектор, который не:

 IEnumerator MoveCursorLeftThenRightCoroutine()
{
    // Store the current mousePosition as a Vector2
    // This uses floats and is not restricted to full pixel jumps
    var currentPosition = Input.mousePosition;

    for(var passedTime = 0f; passedTime < 1; passedTime  = Time.deltaTime)
    {
        // simply continously add to the float vector
        currentPosition  =  Vector2.left * speedInPixelsPerSecond * Time.deltaTime;
        // Using that float vector as input may in some frames cause no movement where the clamp results
        // still in the same pixel but it will catch up as soon as the vector was increased/reduced enough
        Mouse.current.WarpCursorPosition(currentPosition);               

        yield return nnull;
    }

    for(var passedTime = 0f; passedTime < 1; passedTime  = Time.deltaTime)
    {
        currentPosition  =  Vector2.right * speedInPixelsPerSecond * Time.deltaTime;
        Mouse.current.WarpCursorPosition(currentPosition);

        yield return null;
    }
}
 

В общем, для новой системы ввода я бы предпочел использовать Mouse.current.position вместо Input.mousePosition .

Комментарии:

1. Я понимаю это, и это работает. Спасибо!

Ответ №2:

У меня нет никакого опыта использования WarpCursorPosition, но когда я экспериментировал, чтобы ответить на эту тему, я почувствовал, что это не согласуется, и хотел бы посоветовать не использовать его.


Код

 using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;

public class Q69189325 : MonoBehaviour
{
    private void Start()
    {
        Mouse.current.WarpCursorPosition(Input.mousePosition);
        StartCoroutine(MoveLogicCrt());
    }

    IEnumerator MoveLogicCrt()
    {
        yield return MoveCursorToDirectionCrt(Vector3.left, 150, 5);
        yield return null;
        yield return MoveCursorToDirectionCrt(Vector3.right, 350, 5);
    }

    private IEnumerator MoveCursorToDirectionCrt(Vector3 direction, float speed, float movementTime)
    {
        float startTime = Time.time;

        while(Time.time < startTime   movementTime)
        {
            Vector2 newMousePosition = Input.mousePosition   (Time.deltaTime * direction * speed);
            Mouse.current.WarpCursorPosition(newMousePosition);
            yield return null;
        }
    }
}
 

Примечание:

По какой-то причине, когда я двигаюсь с одинаковой скоростью влево и вправо, она не движется вправо, что было странно.


Обзор выполнения

https://gfycat.com/eventhriftyannelida

Счастливого кодирования!

Комментарии:

1. Я обновил свою операцию. Кажется, что какое-то очень странное поведение с добавлением Vector3 может быть причиной, но все еще не уверен