Unity Windows 登入卡在 localhost Callback?先檢查 Run In Background

Ted Liou 2026.05.21 Unity 最後更新 2026.05.21

快速摘要

Windows 版 Unity 遊戲外開瀏覽器登入時,若 Callback 已經導回 localhost,但切回遊戲視窗後才成功,先檢查 Run In Background。問題可能出在 Unity 失焦後暫停,導致本機 Server 沒繼續回應。

線上遊戲常常會綁特定的網頁平台,當 Windows 遊戲在外開瀏覽器進行登入時,若發現 Callback 導回 localhost 後一直轉圈圈,我們可能要先檢查「Run In Background」設定是否有打開。

這是最近遇到的坑:Unity 遊戲開啟系統瀏覽器,玩家登入完成後,瀏覽器會嘗試導向遊戲內正在監聽的 localhost:8080,遊戲會接收這個回應,再取出裡面的 Access Token,以進行後續用途 (例如:遊戲扣點)。

此坑的重點在於,瀏覽器其實已經做到 Callback,但畫面卻一直像在轉圈圈的等待 localhost:8080 回應。這看起來好像是網頁平台壞掉,又或者是本機 HTTP Server、TcpListener、Callback 設計問題。後來除錯到一半,我突然想說切回遊戲視窗看一下狀況,Callback 就突然成功了。

這現象證明了什麼事?瀏覽器和網頁沒問題,資料早就導回來了,只是 Unity 因為失去焦點被凍結,本機監聽也暫停處理資料接收 (但他還是有在監聽,但沒辦法回應),才會卡住。

問題也可能在 Unity,不一定是平台登入的鍋

當平台登入卡在 Callback 時,因為最終畫面是停在瀏覽器,直覺上就會認為是平台在搞。玩家已經登入了,平台也把網頁導回指定的 Callback URL 了,但這個 URL 指向的 localhost:8080 是 Unity 負責,如果 Unity 掛了,就會卡在上一個網頁的畫面。

遊戲切出到瀏覽器視窗後,若 Unity 沒有把允許背景執行的功能打開,內部的 Player loop 可能就停在那裡。本機 listener 也許還佔著 Port,但 Coroutine 等回應流程沒繼續往下跑,資料會收不了也回應不了,瀏覽器就只能乖乖等,等到超時為止。

所以看到「切出去就卡住,切回遊戲才繼續」時,先檢查一下 Unity 失焦後到底有沒有繼續執行。這種坑一旦踩過,下次看到這個症狀就會先查背景執行。

Run In Background 控制畫面失焦後還能不能動

「Run In Background」的位置在 Player Settings:

1Edit > Project Settings > Player > Resolution and Presentation > Run In Background

Unity 的 Windows Player settings 說明了:啟用後,失去焦點時仍會在背景執行;關閉後,失去焦點就會暫停。

回到這次的登入流程,畫面雖然切到瀏覽器,但 Callback 流程是遊戲控制。Unity 還能不能繼續處理本機 Server 的功能,才是這個坑的重點。

也可以用 Application.runInBackground 這個 C# API 打開,直接控制 Player 在背景時是否繼續執行,預設值是 false

必要時可以在遊戲打開時,或在開啟外部瀏覽器前先設定:

1Application.runInBackground = true;

我自己的習慣是在建立專案時就先把這個設定勾起來,讓專案從一開始就符合需求。用 C# API 的設定可以當做一種保險,以免手誤把功能關了。

同一頁 Player Settings 還有一個很容易看錯的「Visible in Background」。它管的是在 Windowed Fullscreen 模式下,遊戲視窗在背景時還要不要顯示畫面;這次卡住的點在 Player loop 會不會繼續跑,兩者的意思差遠了。

專案若有 Editor 腳本或 CI 自動化輸出 Build,保險起見也建議確認 PlayerSettings.runInBackground 設定,避免介面勾了、實際 Build 設定卻沒有套用。

哪種專案必須檢查這個屬性

只要遊戲切出去後,你希望它繼續運作,而不是凍結,或有要等外部服務送資料回來,就建議把「Run In Background」列進 Build 前檢查。像瀏覽器登入、本機 Server、Socket、Launcher、展演控制,這些流程只要被失焦凍住,看起來就很像掛了,這一定要修。

有些遊戲會另外做背景降頻,減少性能佔用與電量消耗,那是另一個主題;但要設計這套機制,前提仍然是先確認「Run In Background」有開。

行動平台的邏輯稍微不同

本文主要是針對 Windows Standalone Player 來討論「Run In Background」設定。桌面版可以靠這設定來修好這個流程,但手機或 Web 不能直接照抄,尤其是外開瀏覽器登入這種會碰到 App 生命週期的地方。

手機上麻煩的是 App 進入背景後,生命週期就不再是 Unity 自己說了算,而是「作業系統」。例如 Application.runInBackground 在 Android 只有 App 仍可見、但沒有 Focus 的情境下才適用;App 真正進入背景時仍然會被暫停,需要背景工作就要走 Android 原生的 Background Service。iOS 更乾脆,它會忽略這個屬性,生命週期全權由作業系統管理。

Web 平台也有自己的限制。就算開了背景執行,瀏覽器仍可能有節流機制,背景時 Update Loop 可能會只剩每秒一次,手機的瀏覽器在鎖定畫面時也可能直接凍結。

所以在行動裝置上不能帶著桌面版 local listener 的邏輯去做。手機上要回傳資料,通常會改走 Custom URL Scheme、Android App Links、iOS Universal Links 或平台 SDK;Web 則要看登入頁是 Popup、iframe 還是同頁流程,再決定用 postMessage 或 JavaScript Bridge。

如何重現問題

要確認是不是踩到這個坑,可以直接做一個快速測試。

先關掉「Run In Background」,重新輸出 Windows Build,讓遊戲開啟外部瀏覽器登入。登入完成後,瀏覽器導向 localhost:8080 開始轉圈圈時,先不要急著改本機 listener,直接切回 Unity 遊戲視窗。若切回來的瞬間 Callback 成功,八成就是這坑在搞了。

接著打開「Run In Background」,用同一個 Windows Build 流程再跑一次。瀏覽器導回 Callback URL 後,若 localhost:8080 能正常回應,Unity 端也能取得 Access Token,前面那個卡住點就可以先排除了。

除錯時也可以暫時印出 Application.runInBackgroundOnApplicationFocusOnApplicationPause,以及收到 Callback request 的時間戳。若切回視窗後 Unity 端才印出收到 request,問題多半在失焦後主流程停住。

若 request 早就進來,只是沒有寫回 HTTP response,瀏覽器一樣會轉圈,但接下來就要往回應流程的設計除錯,和本文主要提到的問題方向不一樣。

總結

這個坑可以記成一句話:切回視窗才成功,就先別怪登入 SDK。尤其是外部瀏覽器登入卡在 localhost Callback 時,先檢查「Run In Background」。

「Run In Background」真正影響的是 Windows Player 失焦後還會不會繼續處理本機 Server、Socket 或 Callback 流程。先把 Unity 背景執行確認好,再去查登入、Callback 或本機監聽設計,才不會一開始就查錯方向。

作者

Ted Liou

現職 Unity C# 工程師,主要分享 Unity、C# 與 Vibe Coding 相關技術教學。

下一篇 AI Coding 工具怎麼選?先看工作流,再比較模型、IDE 與採買方式