Files
bansonic_beta_main/Assets/scripts/WebView/WebViewPanelFollower.cs
T

162 lines
5.4 KiB
C#

// NOTE: Windows-only. Depends on WebViewWin32 (user32.dll) and WebViewLauncher,
// which are Windows-only. Wrapped in UNITY_STANDALONE_WIN so the Windows
// build/logic is unchanged while Android compiles this class out.
#if UNITY_STANDALONE_WIN
using UnityEngine;
using Bansonic;
public class WebViewPanelFollower : MonoBehaviour
{
public RectTransform panelRect; // Documentation text normalized.
public Camera uiCamera; // Documentation text normalized.
private Rect lastPanelRect;
private WebViewWin32.RECT lastUnityWindowRect;
private bool hasLastRect = false;
// track subscription
private bool subscribedToWebViewReady = false;
void OnEnable()
{
gNotice.warning.display("已尝试启动浮动小游戏");
TrySubscribeWebViewReady();
}
void OnDisable()
{
if (subscribedToWebViewReady && WebViewLauncher.Instance != null)
{
WebViewLauncher.Instance.WebViewReady -= OnWebViewReady;
subscribedToWebViewReady = false;
}
}
void TrySubscribeWebViewReady()
{
if (!subscribedToWebViewReady && WebViewLauncher.Instance != null)
{
WebViewLauncher.Instance.WebViewReady += OnWebViewReady;
subscribedToWebViewReady = true;
}
}
void Update()
{
// Ensure subscription in case WebViewLauncher wasn't ready earlier
TrySubscribeWebViewReady();
if (panelRect == null || uiCamera == null || WebViewLauncher.Instance == null)
return;
// Documentation text normalized.
Rect currentPanelRect = GetPanelScreenRect(panelRect);
// Documentation text normalized.
#if !UNITY_EDITOR
WebViewWin32.RECT currentUnityWindowRect = new WebViewWin32.RECT();
if (!WebViewWin32.TryGetClientScreenRect(System.Diagnostics.Process.GetCurrentProcess(), out currentUnityWindowRect))
return;
#endif
// Update position when first initialized, panel rect changed, or window rect changed.
if (!hasLastRect ||
!ApproximatelyEqual(currentPanelRect, lastPanelRect)
#if !UNITY_EDITOR
|| !WindowRectsEqual(currentUnityWindowRect, lastUnityWindowRect)
#endif
)
{
int x, y;
#if UNITY_EDITOR
x = Mathf.RoundToInt(currentPanelRect.x);
y = Mathf.RoundToInt(Screen.height - currentPanelRect.y - currentPanelRect.height);
#else
x = Mathf.RoundToInt(currentUnityWindowRect.Left + currentPanelRect.x);
y = Mathf.RoundToInt(currentUnityWindowRect.Top + (Screen.height - currentPanelRect.y - currentPanelRect.height));
#endif
int w = Mathf.RoundToInt(currentPanelRect.width);
int h = Mathf.RoundToInt(currentPanelRect.height);
// Documentation text normalized.
bool success = WebViewLauncher.Instance.TryUpdateWebViewRect(x, y, w, h);
if (success)
{
lastPanelRect = currentPanelRect;
#if !UNITY_EDITOR
lastUnityWindowRect = currentUnityWindowRect;
#endif
hasLastRect = true;
}
}
}
void OnWebViewReady()
{
// Force next update to recalc and send position, and also perform immediate update
hasLastRect = false;
UpdatePositionNow();
}
// perform immediate position update (same logic as in Update)
void UpdatePositionNow()
{
if (panelRect == null || uiCamera == null || WebViewLauncher.Instance == null)
return;
Rect currentPanelRect = GetPanelScreenRect(panelRect);
#if !UNITY_EDITOR
WebViewWin32.RECT currentUnityWindowRect = new WebViewWin32.RECT();
if (!WebViewWin32.TryGetClientScreenRect(System.Diagnostics.Process.GetCurrentProcess(), out currentUnityWindowRect))
return;
#endif
int x, y;
#if UNITY_EDITOR
x = Mathf.RoundToInt(currentPanelRect.x);
y = Mathf.RoundToInt(Screen.height - currentPanelRect.y - currentPanelRect.height);
#else
x = Mathf.RoundToInt(currentUnityWindowRect.Left + currentPanelRect.x);
y = Mathf.RoundToInt(currentUnityWindowRect.Top + (Screen.height - currentPanelRect.y - currentPanelRect.height));
#endif
int w = Mathf.RoundToInt(currentPanelRect.width);
int h = Mathf.RoundToInt(currentPanelRect.height);
bool success = WebViewLauncher.Instance.TryUpdateWebViewRect(x, y, w, h);
if (success)
{
lastPanelRect = currentPanelRect;
#if !UNITY_EDITOR
lastUnityWindowRect = currentUnityWindowRect;
#endif
hasLastRect = true;
}
}
Rect GetPanelScreenRect(RectTransform rect)
{
Vector3[] corners = new Vector3[4];
rect.GetWorldCorners(corners);
Vector2 min = RectTransformUtility.WorldToScreenPoint(uiCamera, corners[0]);
Vector2 max = RectTransformUtility.WorldToScreenPoint(uiCamera, corners[2]);
return new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
}
bool ApproximatelyEqual(Rect a, Rect b)
{
return Mathf.Approximately(a.x, b.x) &&
Mathf.Approximately(a.y, b.y) &&
Mathf.Approximately(a.width, b.width) &&
Mathf.Approximately(a.height, b.height);
}
bool WindowRectsEqual(WebViewWin32.RECT a, WebViewWin32.RECT b)
{
return a.Left == b.Left && a.Top == b.Top && a.Right == b.Right && a.Bottom == b.Bottom;
}
}
#endif