using System.Collections; using NitroxClient.GameLogic.PlayerLogic.PlayerModel.ColorSwap; using UnityEngine; using UnityEngine.UI; namespace NitroxClient.Unity.Helper; public static class RendererHelpers { //This entire method is necessary in order to deal with the fact that UWE compiles Subnautica in a mode //that prevents us from accessing the pixel map of the 2D textures they apply to their materials. public static Texture2D Clone(this Texture2D sourceTexture) { // Create a temporary RenderTexture of the same size as the texture RenderTexture tmp = RenderTexture.GetTemporary( sourceTexture.width, sourceTexture.height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Linear); // Blit the pixels on texture to the RenderTexture Graphics.Blit(sourceTexture, tmp); // Backup the currently set RenderTexture RenderTexture previous = RenderTexture.active; // Set the current RenderTexture to the temporary one we created RenderTexture.active = tmp; // Create a new readable Texture2D to copy the pixels to it Texture2D clonedTexture = new(sourceTexture.width, sourceTexture.height); // Copy the pixels from the RenderTexture to the new Texture clonedTexture.ReadPixels(new Rect(0, 0, tmp.width, tmp.height), 0, 0); clonedTexture.Apply(); // Reset the active RenderTexture RenderTexture.active = previous; // Release the temporary RenderTexture RenderTexture.ReleaseTemporary(tmp); return clonedTexture; // "clonedTexture" now has the same pixels from "texture" and it's readable. } //This applies a color filter to a specific region of a 2D texture. public static void SwapTextureColors( this Texture2D texture, HsvSwapper filter, TextureBlock textureBlock) { Color[] pixels = texture.GetPixels(textureBlock.X, textureBlock.Y, textureBlock.BlockWidth, textureBlock.BlockHeight); filter.SwapColors(pixels); texture.SetPixels(textureBlock.X, textureBlock.Y, textureBlock.BlockWidth, textureBlock.BlockHeight, pixels); texture.Apply(); } public static void UpdateMainTextureColors(this Material material, Color[] pixels) { Texture2D mainTexture = (Texture2D)material.mainTexture; mainTexture.SetPixels(pixels); mainTexture.Apply(); } //This applies a color filter to a specific region of a 2D texture. public static void UpdateMainTextureColors( this Material material, Color[] pixels, //IColorSwapStrategy colorSwapStrategy, TextureBlock textureBlock) { Texture2D mainTexture = (Texture2D)material.mainTexture; //Color[] pixels = mainTexture.GetPixels(textureBlock.X, textureBlock.Y, textureBlock.BlockWidth, textureBlock.BlockHeight); //pixelIndexes.ForEach(pixelIndex => pixels[pixelIndex] = colorSwapStrategy.SwapColor(pixels[pixelIndex])); mainTexture.SetPixels(textureBlock.X, textureBlock.Y, textureBlock.BlockWidth, textureBlock.BlockHeight, pixels); mainTexture.Apply(); } public static void ApplyClonedTexture(this Material material) { Texture2D mainTexture = (Texture2D)material.mainTexture; Texture2D clonedTexture = mainTexture.Clone(); material.mainTexture = clonedTexture; } public static SkinnedMeshRenderer GetRenderer(this GameObject playerModel, string equipmentGameObjectName) { return playerModel .transform .Find(equipmentGameObjectName) .gameObject .GetComponent(); } public static Color[] GetMainTexturePixels(this Material material) { Texture2D mainTexture = (Texture2D)material.mainTexture; return mainTexture.GetPixels(); } public static Color[] GetMainTexturePixelBlock( this Material material, TextureBlock textureBlock) { Texture2D mainTexture = (Texture2D)material.mainTexture; return mainTexture.GetPixels(textureBlock.X, textureBlock.Y, textureBlock.BlockWidth, textureBlock.BlockHeight); } /// Copied from MainMenuLoadButton.ShiftAlpha() public static IEnumerator ShiftAlpha( this CanvasGroup cg, float targetAlpha, float animTime, float power, bool toActive, Selectable buttonToSelect = null) { float start = Time.time; while (Time.time - start < animTime) { cg.alpha = Mathf.Lerp(cg.alpha, targetAlpha, Mathf.Pow(Mathf.Clamp01((Time.time - start) / animTime), power)); yield return null; } cg.alpha = targetAlpha; if (toActive) { cg.interactable = true; cg.blocksRaycasts = true; } else { cg.interactable = false; cg.blocksRaycasts = false; } } }