/// <summary>Clears all content from the UI and all WorldUI's. /// Please note that it is safer to set innerHTML to a blank string for a particular UI than calling this.</summary> public static void ClearAll() { content = null; if (Renderer != null) { Renderer.Destroy(); Renderer = null; document = null; } Fonts.Clear(); AtlasStacks.Clear(); Web.Clear(); Spa.SPA.Clear(); UIAnimation.Clear(); ScreenInfo.Clear(); WorldUI currentWorldUI = FirstWorldUI; while (currentWorldUI != null) { currentWorldUI.Destroy(); currentWorldUI = currentWorldUI.UIAfter; } LastWorldUI = null; FirstWorldUI = null; }
/// <summary>Clears all content from the UI and all WorldUI's. /// Please note that it is safer to set innerHTML to a blank string for a particular UI than calling this.</summary> public static void ClearAll() { content = null; if (Renderer != null) { Renderer.Destroy(); Renderer = null; document = null; } Fonts.Clear(); AtlasStacks.Clear(); Http.Clear(); SPA.Clear(); UIAnimation.Clear(); DynamicTexture.RemoveAll(); PowerUI.Input.Clear(); ScreenInfo.Clear(); WorldUI currentWorldUI = FirstWorldUI; while (currentWorldUI != null) { currentWorldUI.Destroy(); currentWorldUI = currentWorldUI.UIAfter; } LastWorldUI = null; FirstWorldUI = null; }
/// <summary>Sets the update rate of the UI.</summary> /// <param name="fps">The rate in frames per second. Default is UI.DefaultRate.</param> public static void SetRate(int fps) { if (fps <= 0) { fps = DefaultRate; } RedrawRate = 1f / (float)fps; // Let the atlases know: AtlasStacks.SetRate(fps); }
/// <summary>Updates the UI. Don't call this - PowerUI knows when it's needed; This is done from Start and WorldUI constructors.</summary> public static void InternalUpdate() { // Get a deltaTime unaffected by timeScale: float deltaTime = Time.unscaledDeltaTime; RedrawTimer += deltaTime; // Update any callbacks: if (Callbacks.FirstToRun != null) { Callbacks.RunAll(); } // OnUpdate queue too: if (OnUpdate.FirstElement != null) { OnUpdate.Update(); } // Update animations: Spa.SPA.Update(deltaTime); if (WorldUI.LiveUpdatablesAvailable) { WorldUI.UpdateAll(); } if (RedrawTimer < RedrawRate) { return; } // Currently, RedrawTimer is exactly the amount of time we took: float frameTime = RedrawTimer; RedrawTimer = 0f; if (GUICamera == null) { return; } // Check for timeouts: Web.Update(frameTime); // Atlases: AtlasStacks.Update(); // Screen size: ScreenInfo.Update(); // Update Input (mouse/keys etc). PowerUI.Input.Update(); // Animations: UIAnimation.Update(frameTime); // Dynamic graphics: DynamicTexture.Update(); // Redraw the root html document (if it needs to be redrawn): Renderer.Update(); // Redraw any in-world documents (if they need it). // Did we call update all above? bool worldUIRequiresUpdate = !WorldUI.LiveUpdatablesAvailable; // Clear the flag: WorldUI.LiveUpdatablesAvailable = false; if (FirstWorldUI != null) { WorldUI current = FirstWorldUI; while (current != null) { if (worldUIRequiresUpdate) { // Update: current.Update(); // Was it destroyed? if (current.Renderer == null) { // Hop to the next one: current = current.UIAfter; continue; } } if (current.Expires) { current.ExpiresIn -= frameTime; if (current.ExpiresIn <= 0f) { // Expire it: current.Expire(); // Hop to the next one: current = current.UIAfter; continue; } } // Update the renderer: current.Renderer.Update(); // Update the flag: if (current.PixelPerfect || current.AlwaysFaceCamera) { // We have at least one which is updateable: WorldUI.LiveUpdatablesAvailable = true; } current = current.UIAfter; } } // Draw characters: Blaze.TextureCameras.Update(frameTime); // Flush any atlases: AtlasStacks.Flush(); }
/// <summary>Used internally - don't call this one. Startup the UI for use in the Editor with AOT Nitro.</summary> /// <param name="nitroAot">True if no gameobject should be generated.</param> public static void Start(bool nitroAot) { if (_Started) { return; } _Started = true; // Setup atlas stacks: AtlasStacks.Start(); // Hookup the wrench logging method: Dom.Log.OnLog += OnLogMessage; // Hookup the InfiniText logging method: InfiniText.Fonts.OnLog += OnLogMessage; #if !NoBIDI // Setup bidi character metadata: InfiniText.DirectionCategory.Setup(); #endif // Setup the character entities such as CharacterEntities.Setup(); // Start modules now! UI is always available so we use that: Modular.Start.Now(typeof(UI)); // Setup language metadata: Languages.globalLoader.Setup(); // Setup alert/confirm dialogues: BlockingDialogues.Setup(); // Setup input: PowerUI.Input.Setup(); // Setup the text/language service: if (Variables == null) { Variables = new FullVariableSet(); if (!nitroAot) { // Sign up to the variable on change event - whenever a custom var is changed, we need to refresh the screen. Variables.OnChange += OnVariableChange; // Sign on to the event that occurs when the language changes. Dom.Text.OnLanguageChanged += OnLanguageChange; // Sign on to the event that occurs when the gender changes. Dom.Text.OnGenderChanged += ResolveAllVariables; } } // Setup the callback queue: Callbacks.Start(); // Setup the character providers (for e.g. Emoji): CharacterProviders.Setup(); Layer = LayerMask.NameToLayer("PowerUI"); #if !NO_LAYER_CHECK if (Layer < 0) { // Invalid layer. #if UNITY_EDITOR // Create the new layer now (this will actually be a permanent change): Layer = PowerUI.LayerManager.Add(); #else // On device - make one up: Layer = 21; #endif } #endif // Default FPS: SetRate(DefaultRate); #if !NoNitroRuntime // Link up the text/javascript type by creating the engine: ScriptEngines.Add(new JavaScriptEngine()); #endif if (nitroAot) { return; } GUINode = GameObject.Find("#PowerUI"); if (GUINode == null) { // Not started yet. // Create the UI game object: GUINode = new GameObject(); GUINode.name = "#PowerUI"; // Create the camera: CameraNode = new GameObject(); CameraNode.name = "Camera"; // Create the updater: GlobalUpdater = GUINode.AddComponent <StandardUpdater>(); // Setup the camera: GUICamera = CameraNode.AddComponent <Camera>(); // Apply the new settings to the camera: GUICamera.orthographic = (CurrentCameraMode == CameraMode.Orthographic); } else { // Already started, but we might have updated. if (CameraNode == null) { // This can happen if the PowerUI assembly is actively reloaded (e.g. runtime updates). CameraNode = GameObject.Find("#PowerUI/Camera"); CameraTransform = CameraNode.transform; GUICamera = CameraNode.GetComponent <Camera>(); } else { // Already started! return; } } // Hide the PowerUI layer from all cameras other than GUICamera: Camera[] cameras = Camera.allCameras; int layerMask = ~(1 << UI.Layer); for (int i = 0; i < cameras.Length; i++) { // Grab the camera: Camera camera = cameras[i]; // Is it the GUICamera? if (camera == GUICamera) { continue; } // Hide the UI layer from it: camera.cullingMask &= layerMask; } // Setup the transform: CameraTransform = CameraNode.transform; CameraTransform.parent = GUINode.transform; GUICamera.nearClipPlane = 0.2f; GUICamera.depth = CameraDepth; GUICamera.clearFlags = CameraClearFlags.Depth; GUICamera.cullingMask = (1 << UI.Layer); GUICamera.renderingPath = RenderingPath.Forward; SetCameraDistance(60f); SetFieldOfView(60f); Renderer = new Renderman(); // Render Mesh.OutputGameObject with the GUI camera: Renderer.RenderWithCamera(UI.Layer); document = Renderer.RootDocument as HtmlDocument; document.window.top = document.window; // Fire the camera event: CameraGotCreated(GUICamera); }
/// <summary>Updates the UI. Don't call this - PowerUI knows when it's needed; This is done from Start and WorldUI constructors.</summary> public static void InternalUpdate() { // Update any callbacks: if (Callbacks.FirstToRun != null) { Callbacks.RunAll(); } // Update animations: SPA.Update(); // Update any Http requests: Http.Update(); if (WorldUI.LiveUpdatablesAvailable) { WorldUI.UpdateAll(); } RedrawTimer += Time.deltaTime; if (RedrawTimer < RedrawRate) { return; } RedrawTimer = 0f; if (GUICamera == null) { return; } // Atlases: AtlasStacks.Update(); // Screen size: ScreenInfo.Update(); // Update Input (mouse/keys etc). PowerUI.Input.Update(); // Animations: UIAnimation.Update(); // Dynamic graphics: DynamicTexture.Update(); // Redraw the root html document (if it needs to be redrawn): Renderer.Update(); if (MainCameraPool != null && MainCameraPool.DidLayout) { // The main UI did a layout and we have a camera pool. // We now need to do some post-layout spring cleaning. MainCameraPool.ClearPool(); } // Redraw any in-world documents (if they need it). // Did we call update all above? bool worldUIRequiresUpdate = !WorldUI.LiveUpdatablesAvailable; // Clear the flag: WorldUI.LiveUpdatablesAvailable = false; if (FirstWorldUI != null) { WorldUI current = FirstWorldUI; while (current != null) { if (worldUIRequiresUpdate) { // Update: current.Update(); // Was it destroyed? if (current.Renderer == null) { // Hop to the next one: current = current.UIAfter; continue; } } if (current.Expires) { current.ExpiresIn -= RedrawRate; if (current.ExpiresIn <= 0f) { // Expire it: current.Expire(); // Hop to the next one: current = current.UIAfter; continue; } } // Update the renderer: current.Renderer.Update(); // Update the flag: if (current.PixelPerfect || current.AlwaysFaceCamera) { // We have at least one which is updateable: WorldUI.LiveUpdatablesAvailable = true; } current = current.UIAfter; } } // Flush any atlases: AtlasStacks.Flush(); }
/// <summary>Used internally - don't call this one. Startup the UI for use in the Editor with AOT Nitro.</summary> /// <param name="nitroAot">True if no gameobject should be generated.</param> public static void Start(bool nitroAot) { if (!Started) { Started = true; // Setup atlas stacks: AtlasStacks.Start(); // Hookup the wrench logging method: Wrench.Log.OnLog += OnLogMessage; // Hookup the InfiniText logging method: InfiniText.Fonts.OnLog += OnLogMessage; // Startup the tag handlers: Wrench.TagHandlers.Setup(); // Startup the file protocols (internally also starts up the CSS engine): FileProtocols.Setup(); // Setup the text/language service: if (Variables == null) { Variables = new FullVariableSet(); if (!nitroAot) { // Sign up to the variable on change event - whenever a custom var is changed, we need to refresh the screen. Variables.OnChange += OnVariableChange; // Ensure that variables is set to whatever the default/current language is. OnLanguageChange(Wrench.Text.Language); // Sign on to the event that occurs when the language changes. Wrench.Text.OnLanguageChanged += OnLanguageChange; // Sign on to the event that occurs when the gender changes. Wrench.Text.OnGenderChanged += ResolveAllVariables; } } // Setup the callback queue: Callbacks.Start(); // Setup the character providers (for e.g. Emoji): CharacterProviders.Setup(); Layer = LayerMask.NameToLayer("PowerUI"); if (Layer < 0) { // Invalid layer. #if UNITY_EDITOR // Create the new layer now (this will actually be a permanent change): Layer = PowerUI.LayerManager.Add(); #else throw new Exception("Error: PowerUI layer not found. Go to Edit->Project Settings->Tags and add a layer called PowerUI to fix this." + " Don't forget to make sure it doesn't render with your main camera too!" ); #endif } // Default FPS: SetRate(DefaultRate); #if !NoNitroRuntime // Setup the compiler: NitroCode.Setup(); #endif } if (nitroAot) { return; } GUINode = GameObject.Find("#PowerUI"); if (GUINode == null) { // Not started yet. // Create the UI game object: GUINode = new GameObject(); GUINode.name = "#PowerUI"; // Create the camera: CameraNode = new GameObject(); CameraNode.name = "Camera"; // Create the updater: GlobalUpdater = GUINode.AddComponent <StandardUpdater>(); // Setup the camera: GUICamera = CameraNode.AddComponent <Camera>(); } else { // Already started, but we might have updated. if (CameraNode == null) { // This can happen if the PowerUI assembly is actively reloaded (e.g. runtime updates). CameraNode = GameObject.Find("#PowerUI/Camera"); CameraTransform = CameraNode.transform; GUICamera = CameraNode.GetComponent <Camera>(); } else { // Already started! return; } } // Hide the PowerUI layer from all cameras other than GUICamera: Camera[] cameras = Camera.allCameras; int layerMask = ~(1 << UI.Layer); for (int i = 0; i < cameras.Length; i++) { // Grab the camera: Camera camera = cameras[i]; // Is it the GUICamera? if (camera == GUICamera) { continue; } // Hide the UI layer from it: camera.cullingMask &= layerMask; } // Setup the transform: CameraTransform = CameraNode.transform; CameraTransform.parent = GUINode.transform; GUICamera.nearClipPlane = 0.2f; GUICamera.depth = CameraDepth; GUICamera.clearFlags = CameraClearFlags.Depth; GUICamera.cullingMask = (1 << UI.Layer); GUICamera.renderingPath = RenderingPath.Forward; SetCameraDistance(60f); SetFieldOfView(60f); Renderer = new Renderman(); // Render Mesh.OutputGameObject with the GUI camera: Renderer.RenderWithCamera(UI.Layer); document = Renderer.RootDocument; document.window.top = document.window; // Some overriding default UI settings: document.html.Style.Computed.ChangeTagProperty("color", new PowerUI.Css.Value("#ffffff", PowerUI.Css.ValueType.Color)); document.html.Style.Computed.ChangeTagProperty("font-size", new PowerUI.Css.Value("14px", PowerUI.Css.ValueType.Pixels)); document.body.Style.Computed.ChangeTagProperty("overflow", new PowerUI.Css.Value("hidden hidden", PowerUI.Css.ValueType.Point)); UpdateTextDirection(); // Fire the camera event: CameraGotCreated(GUICamera); }