Files
Nitrox/NitroxClient/Unity/Helper/RendererHelpers.cs
2025-07-06 00:23:46 +02:00

135 lines
5.0 KiB
C#

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<SkinnedMeshRenderer>();
}
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;
}
}
}