public void Display(object data, bool isRowOdd)
        {
            SetupControls();

            m_building = data as BuildingData;

            m_name.text = m_building.displayName;

            float maxLabelWidth = width - 120;

            if (m_building.hasAuthor)
            {
                m_author.spriteName = "AchievementCheckedTrue";
            }
            else
            {
                m_author.spriteName = "AchievementCheckedFalse";
            }

            if (m_building.hasLocal)
            {
                m_local.spriteName = "AchievementCheckedTrue";
            }
            else
            {
                m_local.spriteName = "AchievementCheckedFalse";
            }

            if (isRowOdd)
            {
                background.backgroundSprite = "UnlockingItemBackground";
                background.color            = new Color32(0, 0, 0, 128);
            }
            else
            {
                background.backgroundSprite = null;
            }
        }
        public static bool Prefix(BuildingInfo __instance)
        {
            // Basic sanity check before proceeding; if failed, don't do anything here - just continue on to game method.
            if (__instance.name == null)
            {
                return(true);
            }

            // Create a new building record for this prefab and add it to our lists.
            BuildingData buildingData = new BuildingData
            {
                prefab   = __instance,
                name     = __instance.name,
                density  = Loading.xmlManager.SetPrefabDensity(__instance),
                category = Loading.xmlManager.AssignCategory(__instance),
            };

            Loading.xmlManager.prefabHash[__instance] = buildingData;

            // Add to broken prefabs list (will be removed later if it's not broken).
            Loading.brokenPrefabs.Add(__instance);

            // Search for PloppableRICODefinition.xml files with this asset.
            // Need to use FindAssetByName(string, AssetType) because FindAssetByName(string) doesn't catch all assets at this stage of initialisation
            // (those two methods are more different than you might think - discovered that the hard way).
            Package.Asset asset = PackageManager.FindAssetByName(__instance.name, Package.AssetType.Object);

            // Get custom asset filesystem location (if CRP pacakge).
            string crpPath = asset?.package?.packagePath;

            if (!string.IsNullOrEmpty(crpPath))
            {
                // Look for RICO settings file.
                string ricoDefPath = Path.Combine(Path.GetDirectoryName(crpPath), "PloppableRICODefinition.xml");

                if (File.Exists(ricoDefPath))
                {
                    // Parse the file.
                    PloppableRICODefinition tempRicoDef = RICOReader.ParseRICODefinition(ricoDefPath);

                    if (tempRicoDef != null)
                    {
                        foreach (RICOBuilding buildingDef in tempRicoDef.Buildings)
                        {
                            // Go through each building parsed and check to see if we've got a match for this prefab.
                            if (MatchRICOName(buildingDef.Name, __instance.name, asset.package.packageName))
                            {
                                // Match!  Add these author settings to our prefab dictionary.
                                Logging.Message("found author settings for ", buildingDef.Name);
                                Loading.xmlManager.prefabHash[__instance].author    = buildingDef;
                                Loading.xmlManager.prefabHash[__instance].hasAuthor = true;
                            }
                        }
                    }
                }
            }


            // Check for and add any local settings for this prefab to our list.
            if (Loading.localRicoDef != null)
            {
                // Step through our previously loaded local settings and see if we've got a match.
                foreach (RICOBuilding buildingDef in Loading.localRicoDef.Buildings)
                {
                    if (buildingDef.Name.Equals(__instance.name))
                    {
                        // Match!  Add these author settings to our prefab dictionary.
                        Loading.xmlManager.prefabHash[__instance].local    = buildingDef;
                        Loading.xmlManager.prefabHash[__instance].hasLocal = true;
                    }
                }
            }


            // Check for any Workshop RICO mod settings for this prefab.
            if (Loading.mod1RicoDef != null)
            {
                // Step through our previously loaded local settings and see if we've got a match.
                foreach (RICOBuilding buildingDef in Loading.mod1RicoDef.Buildings)
                {
                    if (buildingDef.Name.Equals(__instance.name))
                    {
                        // Match!  Add these author settings to our prefab dictionary.
                        Loading.xmlManager.prefabHash[__instance].mod    = buildingDef;
                        Loading.xmlManager.prefabHash[__instance].hasMod = true;
                    }
                }
            }

            // Check for Modern Japan CCP mod settings for this prefab.
            if (Loading.mod2RicoDef != null)
            {
                // Step through our previously loaded local settings and see if we've got a match.
                foreach (RICOBuilding buildingDef in Loading.mod2RicoDef.Buildings)
                {
                    if (buildingDef.Name.Equals(__instance.name))
                    {
                        // Match!  Add these author settings to our prefab dictionary.
                        Loading.xmlManager.prefabHash[__instance].mod    = buildingDef;
                        Loading.xmlManager.prefabHash[__instance].hasMod = true;
                    }
                }
            }


            // Apply appropriate RICO settings to prefab.
            if (Loading.convertPrefabs != null)
            {
                // Start with local settings.
                if (Loading.xmlManager.prefabHash[__instance].hasLocal)
                {
                    // If local settings disable RICO, dont convert.
                    if (Loading.xmlManager.prefabHash[__instance].local.ricoEnabled)
                    {
                        Loading.convertPrefabs.ConvertPrefab(Loading.xmlManager.prefabHash[__instance].local, __instance);
                    }
                }
                // If no local settings, apply author settings.
                else if (Loading.xmlManager.prefabHash[__instance].hasAuthor)
                {
                    // If author settings disable RICO, dont convert.
                    if (Loading.xmlManager.prefabHash[__instance].author.ricoEnabled)
                    {
                        Loading.convertPrefabs.ConvertPrefab(Loading.xmlManager.prefabHash[__instance].author, __instance);
                    }
                }
                // If none of the above, apply mod settings.
                else if (Loading.xmlManager.prefabHash[__instance].hasMod)
                {
                    // If mod settings disable RICO, dont convert.
                    if (Loading.xmlManager.prefabHash[__instance].mod.ricoEnabled)
                    {
                        Loading.convertPrefabs.ConvertPrefab(Loading.xmlManager.prefabHash[__instance].mod, __instance);
                    }
                }
                else
                {
                    // No RICO settings; replicate game InitializePrefab checks overridden by transpiler.
                    int privateServiceIndex = ItemClass.GetPrivateServiceIndex(__instance.m_class.m_service);
                    if (privateServiceIndex != -1)
                    {
                        if (__instance.m_placementStyle == ItemClass.Placement.Manual)
                        {
                            throw new PrefabException(__instance, "Private building cannot have manual placement style");
                        }
                        if (__instance.m_paths != null && __instance.m_paths.Length != 0)
                        {
                            throw new PrefabException(__instance, "Private building cannot include roads or other net types");
                        }
                    }
                }
            }
            else
            {
                // This means that there's been a significant failure.  Ploppable RICO settings can't be applied.
                Logging.Error("convertPrefabs not initialised");
            }

            // Continue on to execute game InitializePrefab.
            return(true);
        }
Example #3
0
        /// <summary>
        /// Generates building thumbnail images (normal, focused, hovered, pressed and disabled) for the given building prefab.
        /// Thumbnails are no longer applied to the m_Thumbnail and m_Atlas fields of the prefab, but to the BuildingData record.
        /// </summary>
        /// <param name="prefab">The BuildingInfo prefab to generate thumbnails for</param>
        /// <param name="name">The display name of the prefab.</param>
        internal void CreateThumbnail(BuildingData building)
        {
            // Reset zoom.
            renderer.Zoom = 4f;

            // Don't do anything with null prefabs.
            if (building?.prefab == null)
            {
                return;
            }

            // Set mesh and material for render.
            if (!renderer.SetTarget(building.prefab))
            {
                // Something went wrong - this isn't a valid rendering target; exit.
                Logging.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;
                renderer.Render(true);
                building.prefab.m_material.color = originalColor;
            }
            else
            {
                // No temporary colour change needed.
                renderer.Render(true);
            }

            // Back up game's current active texture.
            RenderTexture gameActiveTexture = RenderTexture.active;

            // Convert the render to a 2D texture.
            Texture2D thumbnailTexture = new Texture2D(renderer.Texture.width, renderer.Texture.height);

            RenderTexture.active = renderer.Texture;
            thumbnailTexture.ReadPixels(new Rect(0f, 0f, (float)renderer.Texture.width, (float)renderer.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 our building data record.
            building.thumbnailAtlas = thumbnailAtlas;
        }
Example #4
0
        /// <summary>
        /// Generates and displays a building row.
        /// </summary>
        /// <param name="data">Object to list</param>
        /// <param name="isRowOdd">If the row is an odd-numbered row (for background banding)</param>
        public void Display(object data, bool isRowOdd)
        {
            // Perform initial setup for new rows.
            if (buildingName == null)
            {
                isVisible     = true;
                canFocus      = true;
                isInteractive = true;
                width         = parent.width;
                height        = 40;

                buildingName       = AddUIComponent <UILabel>();
                buildingName.width = 200;

                // Checkboxes to indicate which items have custom settings.
                hasModSettings                  = AddUIComponent <UISprite>();
                hasModSettings.size             = new Vector2(20, 20);
                hasModSettings.relativePosition = new Vector3(340, 10);
                hasModSettings.tooltip          = Translations.Translate("PRR_SET_HASMOD");

                hasAuthorSettings                  = AddUIComponent <UISprite>();
                hasAuthorSettings.size             = new Vector2(20, 20);
                hasAuthorSettings.relativePosition = new Vector3(340, 10);
                hasAuthorSettings.tooltip          = Translations.Translate("PRR_SET_HASAUT");

                hasLocalSettings                  = AddUIComponent <UISprite>();
                hasLocalSettings.size             = new Vector2(20, 20);
                hasLocalSettings.relativePosition = new Vector3(340, 10);
                hasLocalSettings.tooltip          = Translations.Translate("PRR_SET_HASLOC");
            }

            // Set selected building.
            buildingData      = data as BuildingData;
            buildingName.text = buildingData.displayName;

            // Update custom settings checkboxes to correct state.
            if (buildingData.hasMod)
            {
                // Mod settings found.
                hasModSettings.spriteName = "AchievementCheckedTrue";
            }
            else
            {
                // No mod settings.
                hasModSettings.spriteName = "AchievementCheckedFalse";
            }

            if (buildingData.hasAuthor)
            {
                // Author settings found.
                hasAuthorSettings.spriteName = "AchievementCheckedTrue";
            }
            else
            {
                // No mod settings.
                hasAuthorSettings.spriteName = "AchievementCheckedFalse";
            }

            if (buildingData.hasLocal)
            {
                // Local settings found.
                hasLocalSettings.spriteName = "AchievementCheckedTrue";
            }
            else
            {
                // No mod settings.
                hasLocalSettings.spriteName = "AchievementCheckedFalse";
            }

            // Set initial background as deselected state.
            Deselect(isRowOdd);
        }
Example #5
0
        /// <summary>
        /// Updates the options panel when the building selection changes, including showing/hiding relevant controls.
        /// </summary>
        /// <param name="buildingData">RICO building data</param>
        internal void SelectionChanged(BuildingData buildingData)
        {
            // Disable the event logic while dropdowns are being updated.
            disableEvents = true;

            // Disable all input controls by default; activate them later if needed.
            ricoEnabled.Disable();
            growable.Disable();
            growable.parent.Hide();
            service.Disable();
            subService.Disable();
            level.Disable();
            uiCategory.Disable();
            construction.Disable();
            manual.Disable();
            realityIgnored.Disable();
            uneducated.Disable();
            educated.Disable();
            welleducated.Disable();
            highlyeducated.Disable();

            // Update option UI elements, in priority order (local, author, mod).
            if (buildingData.hasLocal)
            {
                currentSelection = buildingData.local;
                UpdateElements(buildingData.local.service);
                UpdateValues(buildingData.local);
                label.text = Translations.Translate("PRR_SET_HASLOC");

                // If the building has local settings, enable input fields.
                ricoEnabled.Enable();
                service.Enable();
                subService.Enable();
                level.Enable();
                uiCategory.Enable();
                construction.Enable();
                manual.Enable();
                realityIgnored.Enable();
                uneducated.Enable();
                educated.Enable();
                welleducated.Enable();
                highlyeducated.Enable();

                // 'Growable' can only be set in local settings.
                // Only show growable checkbox where assets meet the prequisites:
                // Growables can't have any dimension greater than 4 or contain any net structures.
                if (buildingData.prefab.GetWidth() <= 4 && buildingData.prefab.GetLength() <= 4 && !(buildingData.prefab.m_paths != null && buildingData.prefab.m_paths.Length != 0))
                {
                    growable.Enable();
                    growable.parent.Show();
                }
            }
            else if (buildingData.hasAuthor)
            {
                // If the building has author settings, then disable input fields.
                currentSelection = buildingData.author;
                UpdateElements(buildingData.author.service);
                UpdateValues(buildingData.author);
                label.text = Translations.Translate("PRR_SET_HASAUT");
            }
            else if (buildingData.hasMod)
            {
                // If the building has mod settings, then disable input fields.
                currentSelection = buildingData.mod;
                label.text       = Translations.Translate("PRR_SET_HASMOD");
                UpdateElements(buildingData.mod.service);
                UpdateValues(buildingData.mod);
            }
            else
            {
                // Fallback - building has no Ploppable RICO data anywhere, disable Ploppable RICO.
                ricoEnabled.isChecked = false;
                ricoEnabled.Disable();
                label.text = Translations.Translate("PRR_SET_HASNON");
            }

            // Re-enable event logic now that dropdowns are up-to-date before returning.
            disableEvents = false;
        }
 public void SelectionChanged(BuildingData buildingData)
 {
     currentSelection = buildingData;
 }
        /// <summary>
        /// Generates a button for each ploppable building in the relevant panel as determined by UI category.
        /// </summary>
        /// <param name="buildingData">RICO building to add</param>
        /// <param name="uiCategory">UI category</param>
        internal void AddBuildingButton(BuildingData buildingData, string uiCategory)
        {
            // Set UI category index for this buildingData instance.
            buildingData.uiCategory = UICategoryIndex(uiCategory);

            // Don't do anything if UI category is set to 'none'.
            if (uiCategory.Equals("none"))
            {
                return;
            }

            try
            {
                // Add building button to relevant panel.
                buildingData.buildingButton = new UIButton();
                buildingData.buildingButton = BuildingPanels[buildingData.uiCategory].AddUIComponent <UIButton>();

                // Appearance.
                buildingData.buildingButton.size = new Vector2(109, 100);
                buildingData.buildingButton.horizontalAlignment = UIHorizontalAlignment.Center;
                buildingData.buildingButton.verticalAlignment   = UIVerticalAlignment.Middle;
                buildingData.buildingButton.pivot = UIPivotPoint.TopCenter;

                // Assign prefab.
                buildingData.buildingButton.objectUserData = buildingData.prefab;

                // Thumbnail.
                Thumbnails.CreateThumbnail(buildingData);

                // Information label - building name.
                UILabel nameLabel = new UILabel();
                nameLabel                  = buildingData.buildingButton.AddUIComponent <UILabel>();
                nameLabel.textScale        = 0.6f;
                nameLabel.useDropShadow    = true;
                nameLabel.dropShadowColor  = new Color32(80, 80, 80, 255);
                nameLabel.dropShadowOffset = new Vector2(2, -2);
                nameLabel.text             = buildingData.displayName;
                nameLabel.autoSize         = false;
                nameLabel.autoHeight       = true;
                nameLabel.wordWrap         = true;
                nameLabel.width            = buildingData.buildingButton.width - 10;
                nameLabel.isVisible        = true;
                nameLabel.relativePosition = new Vector3(5, 5);

                // Information label - building level.
                UILabel levelLabel = new UILabel();
                levelLabel                  = buildingData.buildingButton.AddUIComponent <UILabel>();
                levelLabel.textScale        = 0.6f;
                levelLabel.useDropShadow    = true;
                levelLabel.dropShadowColor  = new Color32(80, 80, 80, 255);
                levelLabel.dropShadowOffset = new Vector2(2, -2);
                levelLabel.text             = Translations.Translate("PRR_LVL") + " " + ((int)buildingData.prefab.m_class.m_level + 1);
                levelLabel.autoSize         = true;
                levelLabel.isVisible        = true;
                levelLabel.relativePosition = new Vector3(5, buildingData.buildingButton.height - levelLabel.height - 5);

                // Information label - building size.
                UILabel sizeLabel = new UILabel();
                sizeLabel                  = buildingData.buildingButton.AddUIComponent <UILabel>();
                sizeLabel.textScale        = 0.6f;
                sizeLabel.useDropShadow    = true;
                sizeLabel.dropShadowColor  = new Color32(80, 80, 80, 255);
                sizeLabel.dropShadowOffset = new Vector2(2, -2);
                sizeLabel.text             = buildingData.prefab.GetWidth() + "x" + buildingData.prefab.GetLength();
                sizeLabel.autoSize         = true;
                sizeLabel.isVisible        = true;
                sizeLabel.relativePosition = new Vector3(buildingData.buildingButton.width - sizeLabel.width - 5, buildingData.buildingButton.height - sizeLabel.height - 5);

                // Tooltip.
                buildingData.buildingButton.tooltipAnchor    = UITooltipAnchor.Anchored;
                buildingData.buildingButton.tooltip          = BuildingTooltip(buildingData);
                buildingData.buildingButton.eventClick      += (component, clickEvent) => BuildingBClicked(buildingData.prefab);
                buildingData.buildingButton.eventMouseHover += (component, mouseEvent) =>
                {
                    // Reset the tooltip before showing each time, as sometimes it gets clobbered either by the game or another mod.
                    component.tooltip = BuildingTooltip(buildingData);
                };

                // Ready to use!
                buildingData.buildingButton.isEnabled = true;
            }
            catch (Exception e)
            {
                Debugging.Message("BuildingButton creation exception with UI category '" + uiCategory);
                Debug.LogException(e);
            }
        }
        public void SelectionChanged(BuildingData buildingData)
        {
            //When dropdowns are updated, this disables the event logic
            disableEvents = true;

            ricoEnabled.Enable();
            service.Enable();
            subService.Enable();
            level.Enable();
            uiCategory.Enable();
            construction.Enable();
            manual.Enable();
            popBalanceEnabled.Enable();

            //If selected asset has local settings, update option UI elements with those settings.
            if (buildingData.hasLocal)
            {
                currentSelection = buildingData.local;
                UpdateElements(buildingData.local.service);
                UpdateValues(buildingData.local);
                label.text    = "Local Settings";
                disableEvents = false;
                return;
            }
            else if (buildingData.hasAuthor)
            {
                currentSelection = buildingData.author;
                UpdateElements(buildingData.author.service);
                UpdateValues(buildingData.author);
                label.text = "Author Settings";
                ricoEnabled.Disable();
                service.Disable();
                subService.Disable();
                level.Disable();
                uiCategory.Disable();
                construction.Disable();
                manual.Disable();
                popBalanceEnabled.Disable();
                disableEvents = false;
                return;
            }
            else if (buildingData.hasMod)
            {
                currentSelection = buildingData.mod;
                label.text       = "Mod Settings";
                UpdateElements(buildingData.mod.service);
                UpdateValues(buildingData.mod);
                ricoEnabled.Disable();
                service.Disable();
                subService.Disable();
                level.Disable();
                uiCategory.Disable();
                construction.Disable();
                manual.Disable();
                popBalanceEnabled.Disable();
                disableEvents = false;
                return;
            }
            else
            {
                ricoEnabled.isChecked = false;
                ricoEnabled.Disable();
                label.text = "No Settings";
            }

            disableEvents = false;
        }
        /// <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";
        }