首页 > 解决方案 > Mouse.current.WarpCursorPosition 似乎只有在向左或向上(而不是向右或向下)移动时才能正常工作?

问题描述

这是一个简单的脚本来演示这个问题。此脚本应将光标向左移动 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 和 Vector3 都是 Vector3,我认为可以处理浮点数,所以不知道为什么事情被四舍五入到整数,如果发生了什么?

标签: c#unity3d

解决方案


问题

所以出于某种原因,一切都在四舍五入到最接近的整数?

很可能是的!

WarpCursorPosition使您的实际系统光标跳转到给定的像素坐标

虽然在 Unity 内部,像素空间始终float为许多事物提供,主要用于直接计算,但实际的系统光标使用像素(就像屏幕上实际发生的一切),它们始终是完整int值!

所以,是的,它总是(不是圆形,而是)将你给定的输入放到下一个int(全像素)。基本上如果你简单地使用会发生什么

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

=>你会看到这x正是Input.mousePosition.x - 1因为如果例如当前Input.mousePosition.x230那么你得到(int) 229.9f的是229

在另一个方向上,尽管您再次得到例如230 + 0.1f,只是简单地是。(int) 230.1f230

=> 你的步数至少需要一个完整的像素


解决方案

因此,与其不断读取作为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.


推荐阅读