mob-sakai / SoftMaskForUGUI

Enhance Unity UI (uGUI) with advanced soft-masking features to create more visually appealing effects!
https://github.com/mob-sakai/SoftMaskForUGUI
MIT License
1.91k stars 257 forks source link

[v1] All SoftMasks disappear when screen orientation is changed #161

Closed flowerhouse-dev closed 13 hours ago

flowerhouse-dev commented 8 months ago

Describe the bug Changing the screen orientation makes all SoftMasks disappear. Buffers seem to be updating correctly.

To Reproduce Make sure Player Settings > Resolution and Presentation > Default Orientation is set to Auto Rotation

In the editor:

  1. Install Device Simulator package
  2. Run demo from sample
  3. Rotate orientation using the buttons from the simulator
  4. SoftMasks disappear

On device:

  1. Build demo from sample
  2. Rotate orientation of device
  3. SoftMasks disappear

Expected behavior SoftMasks should be updated similar to it updating when the resolution is changed.

Screenshots

afbeelding afbeelding

Environment (please complete the following information):

Additional context Also tested with the changes from #151 but that does not fix it. Tried some workarounds with disabling & enabling the component, but that only works in the editor.

jhclaura commented 7 months ago

Having the same issue with the demo app, it doesn't work in Android Landscape mode. It seems this issue is back? https://github.com/mob-sakai/SoftMaskForUGUI/issues/46 Would love to use this in Android Landscape mode, hope it'd be an easy fix... thank you @mob-sakai !

flowerhouse-dev commented 7 months ago

We made a workaround that disables the canvas for one frame after orientation change. Not ideal but it works for now.

MarkZaytsev commented 5 months ago

I can confirm the bug. To reproduce it:

Unfortunately I was limited in time I can spare for debugging, so I had to go with a workaround. Simply disabling softmask if screen orientation happened and enabling it 10 frames later. With a smaller amount of frames there is a chance that softmask still not work. This workaround is ugly, but does the job.

Important thing to note. Initially I tired to force rebuild the mask, instead of disabling the script. Using hasChanhed flag. It didn't work.

    private ScreenOrientation _cachedOrientation;

    private async void LateUpdate()
    {
        if (_cachedOrientation == Screen.orientation)
            return;

        enabled = false;
        _cachedOrientation = Screen.orientation;

        await UniTask.DelayFrame(10);
        if (this == null)
            return;

        enabled = true;
    }
mob-sakai commented 5 months ago

Thank you for your reporting!

MarkZaytsev commented 5 months ago

For everyone looking for a workaround. I've updated my solution, feel free to use it. Place the script on a static dedicated game object on a starting scene. Works just fine. It will affect only SoftMask components that were part of a scene when the scene was loaded and were enabled. I think 7 frames delay should be enough.

Keep in mind that this works only in case if screen orientation change happened after you have loaded the scene, in my case in do it in Awake callback. Otherwise you will need to modify the script.

Also I'm using Unity 2023.1.3f1

internal class ScreenOrientationBugFixer : MonoBehaviour
{
    private static bool _isInitialized;
    private ScreenOrientation _cachedOrientation;

    private void Awake()
    {
        if (_isInitialized)
        {
            Destroy(gameObject);
            return;
        }

        DontDestroyOnLoad(gameObject);
        StartCoroutine(MonitorOrientationChange());
        _isInitialized = true;
    }

    private IEnumerator MonitorOrientationChange()
    {
        _cachedOrientation = Screen.orientation;

        var wait = new WaitForEndOfFrame();
        while (true)
        {
            yield return wait;

            if (_cachedOrientation == Screen.orientation)
                continue;

            _cachedOrientation = Screen.orientation;
            StartCoroutine(FixSoftMasks());
        }
    }

    private static IEnumerator FixSoftMasks()
    {
        var masks =
            FindObjectsByType<SoftMask>(FindObjectsInactive.Exclude, FindObjectsSortMode.None)
                .Where(m => m.enabled)
                .ToArray();

        masks.ForEach(m => m.enabled = false);

        var wait = new WaitForEndOfFrame();
        for (var i = 0; i < 7; i++)
            yield return wait;

        //It's not guaranteed that component still exists
        masks.Where(m => m != null)
            .ForEach(m => m.enabled = true);
    }
}
AlirezaTabasi7 commented 5 months ago

Any plan to fix this the proper way please? @mob-sakai

mob-sakai commented 13 hours ago

Please try v2: https://github.com/mob-sakai/SoftMaskForUGUI/releases/tag/v2.0.0