我希望当用户仍在调整游戏大小(按住窗口边框中的单击)时我的 UI 不会调整大小,并且只有当用户释放鼠标时才会触发调整大小事件。
我尝试在 Unity 上实现它,但到目前为止我只能检测到窗口大小的变化,我的脚本每 0.5 秒检查一次,如果检测到变化,它将调整 UI 的大小。但是当然,调整所有内容的大小会导致严重的滞后,因此每 0.5 秒调整一次大小不是一个好的选择,但每 1 秒调整一次大小也不是一个好主意,因为 1 秒被认为太长了。
问题可能太宽泛,但我已将问题指定得尽可能小,如何检测用户是否仍在调整窗口大小?如何检测用户是否已停止调整窗口大小(停止在窗口边框处按住单击)?
您无法判断某人何时停止拖动窗口,除非您想为所有桌面环境和每个操作系统编写低级解决方案。
这是使用
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}");
}
}
它可能不相关,但突然间它会对某人有用
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;
}
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();
}
}
}
我有一些好消息——算是吧。
当用户在 Mac 或 PC 上调整窗口大小时,
Unity 将自动重新布局所有内容。
但实际上仅当用户“完成”调整 Mac/PC 窗口大小时。
我相信这就是 OP 所要求的 - 所以好消息,OP 的要求是完全自动的。
但是。 Unity 中的一个大问题是 Unity 在用户拖动鼠标展开 Mac/PC 窗口时无法平滑地调整元素大小。
我从来没有找到解决这个问题的方法。 (经常提到的一个糟糕的解决方案是检查每帧窗口的大小;这似乎是唯一的方法。)
再次有趣的是,OP提到了什么
“..如果窗口已停止调整大小..”
在Unity中自动完成;事实上,不做任何事情来实现这一目标。
我需要这样的东西来重新生成折线图,但由于它有太多元素,每次更新都会很繁重,所以我想出了这个,这对我来说效果很好:
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...
}
}
}