/// <summary> /// Constructor. /// </summary> public ThumbnailGenerator() { Logging.Message("creating thumbnail generator"); // Get local reference from parent. renderer = ThumbnailManager.Renderer; // Size and setting for thumbnail images: 109 x 100, doubled for anti-aliasing. renderer.Size = new Vector2(109, 100) * 2f; renderer.CameraRotation = 210f; }
/// <summary> /// Cleans up when finished. /// </summary> internal static void Close() { if (gameObject != null) { // Destroy gameobject components. GameObject.Destroy(_renderer); GameObject.Destroy(gameObject); // Let the garbage collector cleanup. _generator = null; _renderer = null; gameObject = null; } }
/// <summary> /// Creates our renderer GameObject. /// </summary> internal static void Create() { try { // If no instance already set, create one. if (gameObject == null) { // Give it a unique name for easy finding with ModTools. gameObject = new GameObject("RICOThumbnailRenderer"); gameObject.transform.parent = UIView.GetAView().transform; // Add our queue manager and renderer directly to the gameobject. _renderer = gameObject.AddComponent <UIPreviewRenderer>(); _generator = new ThumbnailGenerator(); } } catch (Exception e) { Logging.LogException(e, "exception creating renderer"); } }
/// <summary> /// Performs initial setup for the panel; we no longer use Start() as that's not sufficiently reliable (race conditions), and is no longer needed, with the new create/destroy process. /// </summary> internal void Setup() { // Set background and sprites. backgroundSprite = "GenericPanel"; previewSprite = AddUIComponent <UITextureSprite>(); previewSprite.size = size; previewSprite.relativePosition = Vector3.zero; noPreviewSprite = AddUIComponent <UISprite>(); noPreviewSprite.size = size; noPreviewSprite.relativePosition = Vector3.zero; // Initialise renderer; use double size for anti-aliasing. previewRender = gameObject.AddComponent <UIPreviewRenderer>(); previewRender.Size = previewSprite.size * 2; // Click-and-drag rotation. eventMouseDown += (component, mouseEvent) => { eventMouseMove += RotateCamera; }; eventMouseUp += (component, mouseEvent) => { eventMouseMove -= RotateCamera; }; // Zoom with mouse wheel. eventMouseWheel += (component, mouseEvent) => { previewRender.Zoom -= Mathf.Sign(mouseEvent.wheelDelta) * 0.25f; // Render updated image. RenderPreview(); }; // Display building name. buildingName = AddUIComponent <UILabel>(); buildingName.textScale = 0.9f; buildingName.useDropShadow = true; buildingName.dropShadowColor = new Color32(80, 80, 80, 255); buildingName.dropShadowOffset = new Vector2(2, -2); buildingName.text = "Name"; buildingName.isVisible = false; buildingName.relativePosition = new Vector3(5, 10); // Display building level. buildingLevel = AddUIComponent <UILabel>(); buildingLevel.textScale = 0.9f; buildingLevel.useDropShadow = true; buildingLevel.dropShadowColor = new Color32(80, 80, 80, 255); buildingLevel.dropShadowOffset = new Vector2(2, -2); buildingLevel.text = "Level"; buildingLevel.isVisible = false; buildingLevel.relativePosition = new Vector3(5, height - 20); // Display building size. buildingSize = AddUIComponent <UILabel>(); buildingSize.textScale = 0.9f; buildingSize.useDropShadow = true; buildingSize.dropShadowColor = new Color32(80, 80, 80, 255); buildingSize.dropShadowOffset = new Vector2(2, -2); buildingSize.text = "Size"; buildingSize.isVisible = false; buildingSize.relativePosition = new Vector3(width - 50, height - 20); }
/// <summary> /// Generates building thumbnail images (normal, focused, hovered, pressed and disabled) for the given building prefab. /// Thumbnails are applied to the m_Thumbnail and m_Atlas fields of the prefab. /// </summary> /// <param name="prefab">The BuildingInfo prefab to generate thumbnails for</param> /// <param name="name">The display name of the prefab.</param> internal static void CreateThumbnail(BuildingData building) { // Create the renderer if it hasn't already been set up. if (thumbnailRenderer == null) { // Use a unique GameObject name to help find it with ModTools. thumbnailRenderer = new GameObject("RICORevisitedThumbnailRenderer").AddComponent <UIPreviewRenderer>(); // Size and setting for thumbnail images: 109 x 100, doubled for anti-aliasing. thumbnailRenderer.Size = new Vector2(109, 100) * 2f; thumbnailRenderer.CameraRotation = 210f; } // Reset zoom. thumbnailRenderer.Zoom = 4f; // Don't do anything with null prefabs or prefabs without buttons. if (building == null || building.buildingButton == null) { return; } // Set mesh and material for render. thumbnailRenderer.SetTarget(building.prefab); if (thumbnailRenderer.Mesh == null) { // If the prefab itself has no mesh, see if there's any sub-buildings to render instead (e.g. Boston Residence Garage). if (building.prefab.m_subBuildings.Count() > 0) { // Use first sub-building as render target; set mesh and material. thumbnailRenderer.Mesh = building.prefab.m_subBuildings[0].m_buildingInfo.m_mesh; thumbnailRenderer.material = building.prefab.m_subBuildings[0].m_buildingInfo.m_material; } } // If we still haven't gotten a mesh after the above, then something's not right; exit. if (thumbnailRenderer.Mesh == null) { Debugging.Message("no thumbnail generated for null mesh " + building.prefab.name); return; } // If the selected building has colour variations, temporarily set the colour to the default for rendering. if (building.prefab.m_useColorVariations) { Color originalColor = building.prefab.m_material.color; building.prefab.m_material.color = building.prefab.m_color0; thumbnailRenderer.Render(true); building.prefab.m_material.color = originalColor; } else { // No temporary colour change needed. thumbnailRenderer.Render(true); } // Back up game's current active texture. RenderTexture gameActiveTexture = RenderTexture.active; // Convert the render to a 2D texture. Texture2D thumbnailTexture = new Texture2D(thumbnailRenderer.Texture.width, thumbnailRenderer.Texture.height); RenderTexture.active = thumbnailRenderer.Texture; thumbnailTexture.ReadPixels(new Rect(0f, 0f, (float)thumbnailRenderer.Texture.width, (float)thumbnailRenderer.Texture.height), 0, 0); thumbnailTexture.Apply(); // Temporary texture for resizing render to thumbnail size (109 x 100). RenderTexture resizingTexture = RenderTexture.GetTemporary(109, 100); // Resize 2D texture (to 109 x 100) using trilinear filtering. resizingTexture.filterMode = FilterMode.Trilinear; thumbnailTexture.filterMode = FilterMode.Trilinear; // Resize. Graphics.Blit(thumbnailTexture, resizingTexture); thumbnailTexture.Resize(109, 100); thumbnailTexture.ReadPixels(new Rect(0, 0, 109, 100), 0, 0); thumbnailTexture.Apply(); // Release temporary texture. RenderTexture.ReleaseTemporary(resizingTexture); // Restore game's current active texture. RenderTexture.active = gameActiveTexture; // Thumbnail texture name is the same as the building's displayed name. thumbnailTexture.name = building.displayName; // Create new texture atlas with thumnails. UITextureAtlas thumbnailAtlas = ScriptableObject.CreateInstance <UITextureAtlas>(); thumbnailAtlas.name = "RICOThumbnails_" + building.displayName; thumbnailAtlas.material = UnityEngine.Object.Instantiate <Material>(UIView.GetAView().defaultAtlas.material); thumbnailAtlas.material.mainTexture = new Texture2D(1, 1, TextureFormat.ARGB32, false); AddTexturesToAtlas(thumbnailAtlas, GenerateThumbnailVariants(thumbnailTexture)); // Add atlas to building button. building.buildingButton.atlas = thumbnailAtlas; building.buildingButton.normalFgSprite = thumbnailTexture.name; // Variants. building.buildingButton.focusedFgSprite = thumbnailTexture.name + "Focused"; building.buildingButton.hoveredFgSprite = thumbnailTexture.name + "Hovered"; building.buildingButton.pressedFgSprite = thumbnailTexture.name + "Pressed"; building.buildingButton.disabledFgSprite = thumbnailTexture.name + "Disabled"; }