11

I wanted my UI to not resize when user is still resizing the game (holding click in the window border) and only when the user has released the mouse the resize event will trigger.

I have tried to achieve it on Unity but so far I only able to detect windows size change, which my script checked every 0.5 second and if detected change it will resize the UI. But of course resizing everything caused a heavy lag, so resizing every 0.5 second is not a good option but resizing every 1 second is not a good idea either because 1 second is considered too long.

The question might be too broad but I have specified the problem as small as possible, how do I detect if user is still resizing the window? And how do I detect if user has stopped resizing the window (stop holding click at window border)?

halfer
  • 19,824
  • 17
  • 99
  • 186
  • 1
    i think its a rather well-formed concrete question - adding the code that you already tried to the answer would help a bit tho. – sommmen May 10 '20 at 12:47
  • 2
    i don't think it is necessary , because it wouldn't help to answer the question . After all there's so many way to replicate what my code do without using the same code that my code uses . – i'm ashamed with what i asked May 10 '20 at 12:58
  • Might be a bit of a hacky fix but would just waiting for a mouseClick-up event work? – Jay May 10 '20 at 14:43
  • @sommmen - code is irrelevant, the problem is perfectly described. – Fattie Aug 12 '20 at 14:55
  • 1
    Check this callback: [OnRectTransformDimensionsChange](https://docs.unity3d.com/Packages/com.unity.ugui@1.0/api/UnityEngine.EventSystems.UIBehaviour.html#UnityEngine_EventSystems_UIBehaviour_OnRectTransformDimensionsChange) – shingo Nov 19 '20 at 12:38
  • Not sure, does Screen.width/height change during the drag? If they are, you can pause UI at the first time it change, resume when it stop changing. – Ren Aug 31 '21 at 01:02

4 Answers4

5

You can't tell when someone stops dragging a window, unless you want to code a low level solution for ever desktop environment and every operating system.

Here's what worked for me with any MonoBehavior class, using the OnRectTransformDimensionsChange event:

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}");
    }
    
}
Dr-Bracket
  • 4,299
  • 3
  • 20
  • 28
0

It may be useful to someone:

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();
        }
    }

}
Acsell
  • 11
  • 2
  • This looks useful, but it could be improved with some body text as to why it solves the problem presented. Readers (and beginners especially) are more likely to learn something that way. – halfer Aug 31 '23 at 21:50
-1

I have some good news - sort of.

When the user resizes the window on Mac or PC,

Unity will AUTOMATICALLY re-layout everything.

BUT in fact ONLY when the user is "finished" resizing the Mac/PC window.

I believe that is what the OP is asking for - so the good news, what the OP is asking for is quite automatic.

However. A huge problem in Unity is Unity does not smoothly resize elements as the user is dragging the mouse to expand the Mac/PC window.

I have never found a solution to that problem. (A poor solution often mentioned is to check the size of the window every frame; that seems to be about the only approach.)

Again interestingly, what the OP mentions

" ..and if window has stopped resizing .."

is automatically done in Unity; in fact do nothing to achieve that.

Fattie
  • 27,874
  • 70
  • 431
  • 719
-2

I needed something like this for re generating a line chart, but as it has too many elements, it would be heavy to do it on every update, so I came up with this, which for me worked well:

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...
        }
    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186