Guest User

cleanablenMoreOptions

a guest
Feb 6th, 2026
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.44 KB | None | 0 0
  1.  
  2. using TMPro;
  3. using UnityEngine;
  4. using UnityEngine.Events;
  5. using UnityEngine.UI;
  6.  
  7. public class Cleanable : MonoBehaviour
  8. {
  9.     [SerializeField]
  10.     Renderer rend;
  11.  
  12.     [SerializeField]
  13.     MeshFilter meshFilter;
  14.  
  15.     [SerializeField]
  16.     int mipmapLevel = 3;
  17.  
  18.  
  19.     [SerializeField]
  20.     RawImage img;
  21.  
  22.     [SerializeField]
  23.     TextMeshProUGUI text;
  24.  
  25.     public UnityEvent onCleaned = new();
  26.  
  27.     public UnityEvent onReset = new();
  28.  
  29.     int resolution = 512;
  30.  
  31.     Texture2D cachedReadTex;
  32.  
  33.     Color32[] mapPixels;
  34.  
  35.     Material renderMat;
  36.  
  37.     float cacheStartRedPixels;
  38.  
  39.     RenderTexture m_CurrentDrawMap;
  40.  
  41.     public RenderTexture currentPaintMap
  42.     {
  43.         get { return m_CurrentDrawMap; }
  44.     }
  45.  
  46.  
  47.     public void SetTex(RenderTexture tex)
  48.     {
  49.         if (m_CurrentDrawMap == null)
  50.         {
  51.             m_CurrentDrawMap = tex;
  52.             rend.material.SetTexture("_DrawMap", m_CurrentDrawMap);
  53.         }
  54.  
  55.         ReadFromRT(m_CurrentDrawMap);
  56.         GetClearedPercentageFromTexture(cachedReadTex, false);
  57.         img.texture = cachedReadTex;
  58.  
  59.     }
  60.  
  61.  
  62.     void ReadFromRT(RenderTexture rt)
  63.     {
  64.         if (cachedReadTex == null)
  65.             cachedReadTex = new Texture2D(resolution, resolution, TextureFormat.RGBA32, true);
  66.         cachedReadTex.filterMode = FilterMode.Bilinear;
  67.  
  68.         RenderTexture prev = RenderTexture.active;
  69.         RenderTexture.active = rt;
  70.  
  71.         cachedReadTex.ReadPixels(new Rect(0, 0, resolution, resolution), 0, 0);
  72.         cachedReadTex.Apply();
  73.  
  74.         RenderTexture.active = prev;
  75.  
  76.     }
  77.  
  78.  
  79.     public void ResetTex(RenderTexture clearTex)
  80.     {
  81.         onReset.Invoke();
  82.         m_CurrentDrawMap = clearTex;
  83.         rend.material.SetTexture("_DrawMap", m_CurrentDrawMap);
  84.         SetTex(m_CurrentDrawMap);
  85.     }
  86.  
  87.     public Texture2D GetUVCheckedTex()
  88.     {
  89.         cachedReadTex = RenderUVsToTexture(meshFilter.mesh, resolution);
  90.         return cachedReadTex;
  91.     }
  92.  
  93.  
  94.     public Texture2D GetReadTex()
  95.     {
  96.         return cachedReadTex;
  97.     }
  98.  
  99.  
  100.     void Start()
  101.     {
  102.         // find the shader to draw to the texture
  103.         renderMat = new Material(Shader.Find("Custom/UVRender"));
  104.         // render the lightmap uvs to the texture
  105.         cachedReadTex = RenderUVsToTexture(meshFilter.mesh, resolution);
  106.         // get the amount of pixels from the unpainted texture
  107.         GetClearedPercentageFromTexture(cachedReadTex, true);
  108.         img.texture = cachedReadTex;
  109.     }
  110.  
  111.  
  112.     public Texture2D RenderUVsToTexture(Mesh mesh, int resolution)
  113.     {
  114.         // create a snapshot of the uvs to base the cleaning/painting on
  115.         RenderTexture rt = new RenderTexture(
  116.      resolution,
  117.      resolution,
  118.      0,
  119.      RenderTextureFormat.ARGB32
  120.     );
  121.         rt.Create();
  122.         RenderTexture prev = RenderTexture.active;
  123.         RenderTexture.active = rt;
  124.         GL.Clear(true, true, Color.black);
  125.  
  126.         renderMat.SetPass(0);
  127.         Graphics.DrawMeshNow(mesh, Matrix4x4.identity);
  128.  
  129.         // create a new texture from the rendertexture
  130.         Texture2D tex = new Texture2D(resolution, resolution, TextureFormat.RGBA32, true);
  131.         tex.filterMode = FilterMode.Bilinear;
  132.         tex.ReadPixels(new Rect(0, 0, resolution, resolution), 0, 0);
  133.         tex.Apply();
  134.  
  135.         RenderTexture.active = prev;
  136.  
  137.         // release and destroy the rendertexture to stop memory leaks
  138.         rt.Release();
  139.         Destroy(rt);
  140.         return tex;
  141.     }
  142.  
  143.     public float GetClearedPercentageFromTexture(Texture2D tex, bool fromStart)
  144.     {
  145.         mapPixels = tex.GetPixels32(mipmapLevel);
  146.  
  147.         int redPixels = 0;
  148.         int total = mapPixels.Length;
  149.         for (int i = 0; i < total; i++)
  150.         {
  151.             if (mapPixels[i].r > 1) //get all the red "dirty" pixels
  152.                 redPixels++;
  153.         }
  154.  
  155.         if (fromStart)
  156.         {
  157.             // cache them on start to compare later
  158.             cacheStartRedPixels = redPixels;
  159.         }
  160.  
  161.         float percentage = (redPixels - cacheStartRedPixels) / cacheStartRedPixels * -100f;
  162.         percentage = Mathf.Round(percentage * 10f) / 10f;
  163.  
  164.         text.text = percentage + "%";
  165.         // ful lclear after 98.5 so its not super annoying to 100%
  166.         if (percentage >= 98.5 && percentage < 100)
  167.         {
  168.             percentage = 100;
  169.             text.text = "100% Cleared! ";
  170.             onCleaned.Invoke();
  171.         }
  172.         return percentage;
  173.     }
  174. }
  175.  
Advertisement
Add Comment
Please, Sign In to add comment