standalone build suddenly renders a single colored square

I’m working on a game, everything was fine until I made a new build today, and it only renders a single-colored flat square with black borders next to it. (only in the standalone version, not in the editor)

I noticed the game actually works as I can hear the music and sound effects, and the color of the square changes as the scene changes, as if the game is rendering correctly, but to a 1x1 screen.
Which I’m guessing has to do with the fact that I added resolution-options, and it is very much possible I accidentally made it set the resolution to 0.

The weird thing is however that removing the resolution code again doesn’t fix anything, even worse, older builds (in which there is absolutely no code that sets the resolution) behave the same way.

Does anyone have any idea what can be causing this?

I’m using playerprefs, to save the game, but I can’t see how this can have anything to do with it, as in the older builds I’m not storing the resolution. (or setting the resolution)

I thought maybe it’s a problem with my graphics card, but other games, or my own other unity projects, all work fine.

Try finding the runtime preferences for your game (google) and delete those files. Perhaps something is corrupted in the startup stuff that controls resolution, graphics API, etc.

Alternately, try reimport all, rebuild fully.

1 Like

I got it fixed by changing the fullscreen mode of the game.
I noticed if I change the resolution, it will automatically use that new resolution if I run any build of the same game (even way older ones), so apparently windows keeps track of these things (which I’m guessing are these runtime preferences you mention), I had no idea.

So what did you actually change to fix it? I have the same problem here and it is VERY frustrating.

1 Like

That screenshot looks like the resolution has been set to 1x1 using the Screen.SetResolution API.

Also searching for this fix. Tried multiple builds changing resolution settings and still always the same.

Edit: fixed temporarily by changing Project Settings → Player → Resolution and Presentation, I set Exclusive Fullscreen and 1920x1080. I deleted all the data stored in the appdata and made a new build. But once I go back to main menu it happens again. This is infuriating.

Do you call Screen.SetResolution from your scripts anywhere?

1 Like

Thank you for replying. Yes, it’s from a free settings asset because I’m not a good coder.

#if UNITY_STANDALONE_WIN || UNITY_WSA || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX || UNITY_WEBGL
        get
        {
            return Screen.currentResolution;
        }
        set
        {
            Screen.SetResolution(value.width, value.height, FullScreen);
        }

And also for the resolution dropdown, maybe there is a problem somewhere:

Screen.SetResolution(resolutions[dropdown.value].width, resolutions[dropdown.value].height, Screen.fullScreen);

So I built a fresh build with the right resolution to fix the square and immediately quit. Then I opened the project and commented all lines in the code related to the screen resolution and removed the resolution dropdown in the ingame settings. Made a new build and now it’s back to normal. Thank you for pointing out where the issue was.

1 Like

Hi, I’m encountering this as well. Has anyone figured out what causes this? In my project it doesn’t happen on all machines, just some setups but I haven’t yet been able to spot a commonality between the different setups, so not sure what’s causing this. I’m calling SetResolution only in one place in the project and it looks like this:

Screen.SetResolution(newResolution.width, newResolution.height, Settings.CurrentSettings.fullscreen);

Does anyone have an idea what’s causing this? This is happening in a live game of mine so really any help would be super appreciated! <3

Did you verify that newResolution is always the right number?

I’ve been able to fix this by checking if newResolution.width < 640 and setting to 1920 x 1080 if so. So it’s not a bug with SetResolution. Could it be that Screen.resolutions wrongly reports 1x1 resolutions in some cases? The fact that this is happening only on ~1% of players’ machines makes me think it’s not a bug in my code but rather something between Unity and some specific hardware setup.

In any case, here’s the code I’m using to get the available resolutions, maybe I’m messing up somewhere that I’m not aware of:

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using Sirenix.OdinInspector;
using System.Linq;

public class ResolutionDropdownPopulator : MonoBehaviour
{
    public TMP_Dropdown resolutionDropdown;

    private List<Resolution> resolutions;

    void Awake()
    {
        PopulateDropdown();
    }

    [Button]
    public void PopulateDropdown()
    {
        resolutions = new List<Resolution>(Screen.resolutions);

        // Fall back list if resolutions.Count is 1 or smaller. Just populate it with popular 16:9 options
        bool fallbackListUsed = false;
        if (resolutions.Count <= 1)
        {
            Debug.Log("Less than 2 resolutions reported by Screen.resolutions. Generating Fallback Resolutions List");
            fallbackListUsed = true;
            // Adding common 16:9 resolutions as fallback, including more low-res options
            resolutions.Add(new Resolution { width = 1920, height = 1080 }); // Full HD
            resolutions.Add(new Resolution { width = 1600, height = 900 }); // HD+
            resolutions.Add(new Resolution { width = 1366, height = 768 }); // Common laptop screen
            resolutions.Add(new Resolution { width = 1280, height = 720 }); // HD
            resolutions.Add(new Resolution { width = 1024, height = 576 }); // Lower HD
            resolutions.Add(new Resolution { width = 960, height = 540 });  // qHD
            resolutions.Add(new Resolution { width = 854, height = 480 });  // FWVGA
            resolutions.Add(new Resolution { width = 800, height = 450 });  // WVGA
            resolutions.Add(new Resolution { width = 720, height = 405 });  //
            resolutions.Add(new Resolution { width = 640, height = 360 });  // Standard Definition
            resolutions.Add(new Resolution { width = 2560, height = 1440 }); // QHD
            resolutions.Add(new Resolution { width = 3840, height = 2160 }); // 4K
        }
        // Always have a 1920 x 1080 option in the list
        if (!resolutions.Any(res => res.width == 1920 && res.height == 1080))
            resolutions.Add(new Resolution { width = 1920, height = 1080, refreshRateRatio = resolutions[0].refreshRateRatio });
        // Add Macbook 16:9 for trailer recording.
        //resolutions.Add(new Resolution { width = 3456, height = 1944, refreshRateRatio = resolutions[0].refreshRateRatio });
        // Remove Refreshrate duplicates
        resolutions = resolutions.GroupBy(res => new { res.width, res.height })
                         .Select(group => group.First())
                         .ToList();
        // Order list by descending resolutions
        resolutions = resolutions.OrderByDescending(res => res.width).ThenByDescending(res => res.height).ToList();

        List<string> options = new List<string>();
        int currentResolutionIndex = 0;

        for (int i = 0; i < resolutions.Count; i++)
        {

            string option = resolutions[i].width + " x " + resolutions[i].height;
            options.Add(option);

            if (!fallbackListUsed)
            {
                // If not using fall back list, set current resolution to match Screen.currentResolution
                if (resolutions[i].width == Screen.currentResolution.width &&
                    resolutions[i].height == Screen.currentResolution.height)
                {
                    currentResolutionIndex = i;
                }
            }
            else
            {
                // If using fallback List, set currentResolution to 1920 x 1080 to avoid fuckups.
                if (resolutions[i].width == 1920)
                {
                    currentResolutionIndex = i;
                }
            }
        }

        resolutionDropdown.ClearOptions();
        resolutionDropdown.AddOptions(options);
        resolutionDropdown.SetValueWithoutNotify(currentResolutionIndex);
        resolutionDropdown.RefreshShownValue();
    }
}

This is the code I’m using to then apply the resolution:

public void SetResolution(TMP_Dropdown dropdown)
    {
        if (dropdown.options.Count <= 0)
        {
            Debug.LogError("No Resolution Options.", dropdown.gameObject);
            return;
        }

        previousResolution = Screen.currentResolution;
        resolutionConfirmDialog.StartCountdown();
        string selectedOption = dropdown.options[dropdown.value].text;
        string[] dimensions = selectedOption.Split('x');
        if (dimensions.Length == 2)
        {
            if (int.TryParse(dimensions[0].Trim(), out int width) && int.TryParse(dimensions[1].Trim(), out int height))
            {
                //Screen.SetResolution(width, height, Screen.fullScreen);
                Settings.CurrentSettings.resolution = new Resolution { width = width, height = height };
                Settings.CurrentSettings.Apply();
                Debug.Log($"Setting Resolution to: {width} x {height}. Selected Option from dropdown = {selectedOption}, dimensions = {dimensions[0]} x {dimensions[1]}. New Screen Resolution = {Screen.currentResolution}.");
            }
            else
            {
                Debug.LogError("Failed to parse resolution dimensions from dropdown value.");
            }
        }
        else
        {
            Debug.LogError("Invalid resolution format in dropdown value.");
        }
    }

The Settings.CurrentSettings.Apply() method simply calls Screen.SetResolution(newResolution.width, newResolution.height, Settings.CurrentSettings.fullscreen);

You seem to log what resolution you are setting to: did you manage to obtain any logs from the affected users?

A really hacky solution of resetting the resolution if it’s clearly off would probably work… something like:

void Update()
{
    if (Screen.fullScreenMode != FullScreenMode.Windowed && (Screen.width < 64 || Screen.height < 64))
    {
        var displayInfo = Screen.mainWindowDisplayInfo;
        Screen.SetResolution(displayInfo.width, displayInfo.height, FullScreenMode.FullScreenWindow);
    }
}

Was it something like this that you tried that fixed it? I wouldn’t recommend hardcoding to 1920x1080 as it would not look great if aspect ratio doesn’t match.

Screen.resolutions should not return a resolution of 1x1. It grabs them from this Windows API: IDXGIOutput::GetDisplayModeList (dxgi.h) - Win32 apps | Microsoft Learn