using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Threading; using UnityEngine; using Cysharp.Threading.Tasks; using System.Threading.Tasks; using BITKit.UX; using Microsoft.Extensions.DependencyInjection; #if ENABLE_INPUT_SYSTEM using UnityEngine.InputSystem; #endif using Debug = UnityEngine.Debug; #if !UNITY_EDITOR using UnityEngine; using UnityEngine.Rendering; public class SkipSplash { [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)] private static void BeforeSplashScreen() { #if UNITY_WEBGL Application.focusChanged += Application_focusChanged; #else System.Threading.Tasks.Task.Run(AsyncSkip); #endif } #if UNITY_WEBGL private static void Application_focusChanged(bool obj) { Application.focusChanged -= Application_focusChanged; SplashScreen.Stop(SplashScreen.StopBehavior.StopImmediate); } #else private static void AsyncSkip() { SplashScreen.Stop(SplashScreen.StopBehavior.StopImmediate); } #endif } #endif namespace BITKit { public class MouseNotOverGameViewException : System.Exception { public MouseNotOverGameViewException() { } } public class BITAppForUnity : MonoBehaviour { [Serializable] public class OpenUrl { [SerializeField] public string url; [SerializeReference,SubclassSelector] public IReference urlReference; public virtual void Execute() { Application.OpenURL(urlReference is not null?urlReference.Value:url); } } [RuntimeInitializeOnLoadMethod] public static void Initialize() { stopWatcher = new Stopwatch(); stopWatcher.Start(); } public struct Path { public const string Entity = nameof(Entity); public const string Services = nameof(Services); public const string Prefabs = nameof(Prefabs); } public static bool IsPlaying { get;private set; } public static bool IsPointerOverUI { get; set; } public static bool IsEditor { get { #if UNITY_EDITOR return Application.isEditor; #else return false; #endif } } public static ValidHandle AllowCursor = new(); public static ValidHandle AllowTouchSupport = new(); public static GameObject GameObject; private static Stopwatch stopWatcher; public static void ThrowIfNotPlaying() { #if UNITY_EDITOR if (IsPlaying is false) { throw new AppIsNotPlayingException(); } #endif } public static void ThrowIfWindowNotFocus() { #if UNITY_EDITOR && ENABLE_INPUT_SYSTEM switch (Camera.main) { case {} camera: if (camera.pixelRect.Contains(Input.mousePosition) is false) { throw new MouseNotOverGameViewException(); } break; } var window = UnityEditor.EditorWindow.focusedWindow; var windowName = window is not null ? window.ToString() : string.Empty; switch (windowName) { case " (UnityEditor.GameView)": return; default: throw new MouseNotOverGameViewException(); } #endif } [RuntimeInitializeOnLoadMethod] private static void Reload() { BITApp.WalkUntilInitialize = new(); IsPlaying = true; //启动BITApp BITApp.SynchronizationContext = SynchronizationContext.Current; BITApp.Start(Application.productName, new BITApp.AppSettings()).Forget(); AllowCursor = new(); AllowTouchSupport = new(); GameObject = new(nameof(BITApp)); GameObject.AddComponent(); DontDestroyOnLoad(GameObject); AllowCursor.AddListener(ToggleCursor); AllowTouchSupport.AddListener(ToggleTouchSupport); } private static void ToggleCursor(bool active) { Cursor.lockState = active ? CursorLockMode.None : CursorLockMode.Locked; Cursor.visible = active; } private static void ToggleTouchSupport(bool active) { #if ENABLE_INPUT_SYSTEM if (active) { UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.Enable(); } else { UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.Disable(); } #endif } [BITCommand] public static async void Exit() { await BITApp.SwitchToMainThread(); BITApp.Stop(); Data.Clear(); #if UNITY_EDITOR UnityEditor.EditorApplication.isPlaying = false; #else Application.Quit(); #endif } [SerializeField, ReadOnly] private bool allowCursor; private void Start() { BIT4Log.Log($"已创建{nameof(BITApp)}"); stopWatcher.Stop(); BIT4Log.Log($"从初始化到创建{nameof(BITApp)}耗时:{stopWatcher.ElapsedMilliseconds}ms"); } private void OnDestroy() { IsPlaying = false; Exit(); } private void Update() { BITApp.Time.ElapsedTime = Time.time; BITApp.Time.DeltaTime = Time.deltaTime; BITApp.Time.TimeAsDouble = Time.timeAsDouble; allowCursor = AllowCursor.Allow; if (Touchscreen.current is not null && Touchscreen.current.IsPressed()) { AllowCursor.AddElement(int.MaxValue); }else if (Mouse.current is not null && Mouse.current.IsPressed()) { AllowCursor.RemoveElement(int.MaxValue); } } public string GetName() { return nameof(BITApp); } public object GetDiagnostics() { return BITApp.State; } } }