好多新内容
This commit is contained in:
+166
-16
@@ -1,3 +1,4 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.SceneManagement;
|
||||
@@ -7,36 +8,70 @@ public class gTransBlack : MonoBehaviour
|
||||
[SerializeField] private Canvas b_Canvas;
|
||||
[SerializeField] private CanvasGroup b_CG;
|
||||
[SerializeField] private Text nowLoadingText;
|
||||
[SerializeField] private int postSceneLoadCameraRefreshFrames = 12;
|
||||
|
||||
public Canvas Canvas => b_Canvas;
|
||||
public CanvasGroup CanvasGroup => b_CG;
|
||||
|
||||
private Camera boundCamera;
|
||||
private Coroutine cameraRefreshRoutine;
|
||||
private int lastScreenWidth;
|
||||
private int lastScreenHeight;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
EnsureReferences();
|
||||
ApplySceneCamera();
|
||||
ConfigureCanvasForLetterbox();
|
||||
ApplySceneCamera(true);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
SceneManager.sceneLoaded -= HandleSceneLoaded;
|
||||
SceneManager.sceneLoaded += HandleSceneLoaded;
|
||||
ApplySceneCamera();
|
||||
SceneManager.activeSceneChanged -= HandleActiveSceneChanged;
|
||||
SceneManager.activeSceneChanged += HandleActiveSceneChanged;
|
||||
|
||||
ConfigureCanvasForLetterbox();
|
||||
StartCameraRefreshRoutine();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
SceneManager.sceneLoaded -= HandleSceneLoaded;
|
||||
SceneManager.activeSceneChanged -= HandleActiveSceneChanged;
|
||||
|
||||
if (cameraRefreshRoutine != null)
|
||||
{
|
||||
StopCoroutine(cameraRefreshRoutine);
|
||||
cameraRefreshRoutine = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Screen.width != lastScreenWidth || Screen.height != lastScreenHeight || NeedsCameraRefresh())
|
||||
{
|
||||
ConfigureCanvasForLetterbox();
|
||||
ApplySceneCamera(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleSceneLoaded(Scene scene, LoadSceneMode mode)
|
||||
{
|
||||
ApplySceneCamera();
|
||||
StartCameraRefreshRoutine();
|
||||
}
|
||||
|
||||
private void HandleActiveSceneChanged(Scene oldScene, Scene newScene)
|
||||
{
|
||||
StartCameraRefreshRoutine();
|
||||
}
|
||||
|
||||
public void RefreshCanvasCamera()
|
||||
{
|
||||
ApplySceneCamera();
|
||||
ConfigureCanvasForLetterbox();
|
||||
ApplySceneCamera(true);
|
||||
StartCameraRefreshRoutine();
|
||||
}
|
||||
|
||||
public void SetNowLoadingText(string text)
|
||||
@@ -64,7 +99,7 @@ public class gTransBlack : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplySceneCamera()
|
||||
private void ConfigureCanvasForLetterbox()
|
||||
{
|
||||
EnsureReferences();
|
||||
|
||||
@@ -73,10 +108,9 @@ public class gTransBlack : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
if (b_Canvas.renderMode == RenderMode.ScreenSpaceOverlay)
|
||||
if (b_Canvas.renderMode != RenderMode.ScreenSpaceCamera)
|
||||
{
|
||||
b_Canvas.worldCamera = null;
|
||||
return;
|
||||
b_Canvas.renderMode = RenderMode.ScreenSpaceCamera;
|
||||
}
|
||||
|
||||
if (b_Canvas.transform.localScale == Vector3.zero)
|
||||
@@ -84,19 +118,107 @@ public class gTransBlack : MonoBehaviour
|
||||
b_Canvas.transform.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
if (b_Canvas.planeDistance <= 0f)
|
||||
{
|
||||
b_Canvas.planeDistance = 100f;
|
||||
}
|
||||
|
||||
b_Canvas.sortingOrder = short.MaxValue;
|
||||
|
||||
CanvasScaler scaler = b_Canvas.GetComponent<CanvasScaler>();
|
||||
if (scaler != null)
|
||||
{
|
||||
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
||||
scaler.referenceResolution = new Vector2(1920f, 1080f);
|
||||
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
|
||||
// 锁高度缩放:分辨率跟随屏幕后,非 16:9 屏也能保证各 UI 层一致缩放、不错位。
|
||||
scaler.matchWidthOrHeight = 1f;
|
||||
}
|
||||
}
|
||||
|
||||
private bool ApplySceneCamera(bool force)
|
||||
{
|
||||
EnsureReferences();
|
||||
|
||||
if (b_Canvas == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ConfigureCanvasForLetterbox();
|
||||
|
||||
Camera targetCamera = ResolveFirstSceneCamera();
|
||||
if (targetCamera == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (force || b_Canvas.worldCamera != targetCamera || boundCamera != targetCamera)
|
||||
{
|
||||
b_Canvas.worldCamera = targetCamera;
|
||||
boundCamera = targetCamera;
|
||||
}
|
||||
|
||||
lastScreenWidth = Screen.width;
|
||||
lastScreenHeight = Screen.height;
|
||||
Canvas.ForceUpdateCanvases();
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool NeedsCameraRefresh()
|
||||
{
|
||||
if (b_Canvas == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (boundCamera == null || !boundCamera.isActiveAndEnabled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (b_Canvas.renderMode != RenderMode.ScreenSpaceCamera)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return b_Canvas.worldCamera != boundCamera;
|
||||
}
|
||||
|
||||
private void StartCameraRefreshRoutine()
|
||||
{
|
||||
if (!isActiveAndEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
b_Canvas.worldCamera = targetCamera;
|
||||
if (cameraRefreshRoutine != null)
|
||||
{
|
||||
StopCoroutine(cameraRefreshRoutine);
|
||||
}
|
||||
|
||||
cameraRefreshRoutine = StartCoroutine(RefreshCameraForSeveralFrames());
|
||||
}
|
||||
|
||||
private IEnumerator RefreshCameraForSeveralFrames()
|
||||
{
|
||||
int frames = Mathf.Max(1, postSceneLoadCameraRefreshFrames);
|
||||
for (int i = 0; i < frames; i++)
|
||||
{
|
||||
ApplySceneCamera(true);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
yield return new WaitForEndOfFrame();
|
||||
ApplySceneCamera(true);
|
||||
cameraRefreshRoutine = null;
|
||||
}
|
||||
|
||||
private static Camera ResolveFirstSceneCamera()
|
||||
{
|
||||
Scene activeScene = SceneManager.GetActiveScene();
|
||||
Camera mainCam = Camera.main;
|
||||
if (mainCam != null && mainCam.gameObject.scene.IsValid() && mainCam.gameObject.scene.isLoaded)
|
||||
if (IsUsableSceneCamera(mainCam, activeScene, true))
|
||||
{
|
||||
return mainCam;
|
||||
}
|
||||
@@ -105,19 +227,47 @@ public class gTransBlack : MonoBehaviour
|
||||
for (int i = 0; i < cameras.Length; i++)
|
||||
{
|
||||
Camera camera = cameras[i];
|
||||
if (camera == null || !camera.isActiveAndEnabled)
|
||||
if (IsUsableSceneCamera(camera, activeScene, true))
|
||||
{
|
||||
continue;
|
||||
return camera;
|
||||
}
|
||||
}
|
||||
|
||||
if (!camera.gameObject.scene.IsValid() || !camera.gameObject.scene.isLoaded)
|
||||
if (IsUsableSceneCamera(mainCam, activeScene, false))
|
||||
{
|
||||
return mainCam;
|
||||
}
|
||||
|
||||
for (int i = 0; i < cameras.Length; i++)
|
||||
{
|
||||
Camera camera = cameras[i];
|
||||
if (IsUsableSceneCamera(camera, activeScene, false))
|
||||
{
|
||||
continue;
|
||||
return camera;
|
||||
}
|
||||
|
||||
return camera;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool IsUsableSceneCamera(Camera camera, Scene preferredScene, bool requirePreferredScene)
|
||||
{
|
||||
if (camera == null || !camera.isActiveAndEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Scene cameraScene = camera.gameObject.scene;
|
||||
if (!cameraScene.IsValid() || !cameraScene.isLoaded)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (requirePreferredScene && cameraScene != preferredScene)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user