在Unity中,如何检测窗口是否正在调整大小以及窗口是否停止调整大小

11
我希望我的用户界面在用户调整游戏窗口大小时不会自动调整大小,只有在用户释放鼠标后才触发调整大小事件。
我尝试在Unity中实现它,但迄今为止我只能检测到窗口大小的更改,我每隔0.5秒检查一次,如果检测到了变化就会调整UI。但是当然,重新调整所有内容会导致严重的延迟,所以每0.5秒重新调整大小不是一个好的选择,但是每1秒重新调整大小也不是一个好主意,因为1秒被认为太长了。
这个问题可能太广泛了,但我已经将问题尽可能地缩小了,如何检测用户是否仍在调整窗口大小?如何检测用户是否停止调整窗口大小(停止在窗口边缘按住单击)?

1
我认为这是一个相当完整的具体问题 - 尽管将您已经尝试过的代码添加到答案中会有所帮助。 - sommmen
2
我认为这并不必要,因为它无法帮助回答问题。毕竟,有很多方法可以复制我的代码所做的事情,而不使用与我的代码相同的代码。 - i'm ashamed with what i asked
可能有点粗糙,但等待鼠标点击释放事件会起作用吗? - Jay
@sommmen - 代码无关紧要,问题已经被完美描述。 - Fattie
1
请检查此回调函数:OnRectTransformDimensionsChange - shingo
不确定,在拖动过程中Screen.width/height是否会改变?如果会改变,您可以在第一次更改时暂停UI,当其停止更改时恢复。 - Ren
4个回答

5

如果不想为每个桌面环境和操作系统编写低级解决方案,你无法确定某人何时停止拖动窗口。

以下是我使用任何MonoBehavior类与OnRectTransformDimensionsChange事件的解决方法:

public class StackOverflow : MonoBehaviour
{
    private const float TimeBetweenScreenChangeCalculations = 0.5f;
    private float _lastScreenChangeCalculationTime = 0;

    private void Awake()
    {
        _lastScreenChangeCalculationTime = Time.time;
    }
    
    private void OnRectTransformDimensionsChange()
    {        
        if (Time.time - _lastScreenChangeCalculationTime < TimeBetweenScreenChangeCalculations)
            return;

        _lastScreenChangeCalculationTime = Time.time;
            
        Debug.Log($"Window dimensions changed to {Screen.width}x{Screen.height}");
    }
    
}

1

对某人可能有用:

using UnityEngine;

public class ScreenSizeChecker : MonoBehaviour
{
    public static ScreenSizeChecker Instance;

    private float _previousWidth;
    private float _previousHeight;

    public delegate void OnScreenSizeChanged();
    public OnScreenSizeChanged onScreenSizeChanged;

    private void Awake()
    {
       if (Instance == null)
       {
           Instance = this;
           DontDestroyOnLoad(gameObject);
           Init();
           return;
       }
       Instance.onScreenSizeChanged = null;
       Destroy(gameObject);
    }

    private void Init()
    {
        _previousWidth = Screen.width;
        _previousHeight = Screen.height;
    }   

    private void Update()
    {
        if (onScreenSizeChanged == null) { return; }
        if (_previousWidth != Screen.width || _previousHeight != Screen.height)
        {
            _previousWidth = Screen.width;
            _previousHeight = Screen.height;
            onScreenSizeChanged.Invoke();
        }
    }

}

这看起来很有用,但是如果能加上一些正文来解释为什么它能解决所提出的问题,那就更好了。读者(尤其是初学者)更有可能通过这种方式学到东西。 - halfer

-1

我有一些好消息 - 但是只是部分。

当用户在Mac或PC上调整窗口大小时,

Unity会自动重新布局所有内容。

但事实上,仅当用户“完成”调整Mac / PC窗口大小时才会实现。

我相信这就是OP所要求的 - 所以好消息是,OP所要求的是非常自动化的。

然而,在Unity中一个巨大的问题是Unity不会像用户拖动鼠标扩展Mac / PC窗口时平滑地调整元素大小。

我从未找到解决这个问题的方法。(经常提到的一个不好的解决方案是每帧检查窗口的大小;那似乎是唯一的解决办法。)

有趣的是,OP所提到的

“..并且如果窗口停止调整大小..”

在Unity中是自动完成的; 实际上,无需采取任何措施。


-2

我需要类似于这样的东西来重新生成折线图,但由于它有太多的元素,在每次更新时进行重绘会很耗费资源,所以我想出了这个方法,对我来说效果很好:

public class ToRunOnResize : MonoBehaviour
{
    private float screenWidth;
    private bool screenStartedResizing = false;
    private int updateCounter = 0;
    private int numberOfUpdatesToRunXFunction = 15; // The number of frames you want your function to run after, (usually 60 per second, so 15 would be .25 seconds)

    void Start()
    {
        screenWidth = Screen.width; // Identifies the screen width
    }

    private void Update()
    {
        if (Screen.width != screenWidth) // This will be run and repeated while you resize your screen
        {
            updateCounter = 0; // This will set 0 on every update, so the counter is reset until you release the resizing.
            screenStartedResizing = true; // This lets the application know when to start counting the # of updates after you stopped resizing.
            screenWidth = Screen.width;
        }

        if (screenStartedResizing)
        {
            updateCounter += 1; // This will count the updates until it gets to the numberOfUpdatesToRunXFunction
        }

        if (updateCounter == numberOfUpdatesToRunXFunction && screenStartedResizing)
        { // Finally we make the counter stop and run the code, in my case I use it for re-rendering a line chart.
            screenStartedResizing = false;
            // my re-rendering code...
            // my re-rendering code...
        }
    }
}

非常低效 - Jamie Nicholl-Shelley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接