DCS/ruiyiweiUX/Assets/Scripts/Tool/ScratchMask.cs

116 lines
3.3 KiB
C#
Raw Permalink Normal View History

2026-06-09 13:59:11 +08:00
using UnityEngine;
using UnityEngine.UI;
public class ScratchMask : MonoBehaviour
{
public RawImage maskImage; // 黑白图
public Texture2D brushTex; // 笔刷纹理
Camera uiCamera; // Canvas 摄像机
public int rtResolution = 1024; // 遮罩精度
private Texture2D readTex; // 遮罩纹理
bool HasRevealed = false;
public float revealThreshold = 0.8f; // 擦除面积阈值 (30%)
private RenderTexture maskRT;
private Material mat;
void Start()
{
// 创建遮罩 RT
maskRT = new RenderTexture(rtResolution, rtResolution, 0);
maskRT.Create();
uiCamera = Camera.main;
// 填满为白色(遮罩默认不透明)
RenderTexture.active = maskRT;
GL.Clear(true, true, Color.white);
RenderTexture.active = null;
// 获取材质并设置遮罩纹理
mat = maskImage.material;
mat.SetTexture("_MaskTex", maskRT);
}
void Update()
{
if (Input.GetMouseButton(0))
{
Vector2 localPos;
RectTransformUtility.ScreenPointToLocalPointInRectangle(
maskImage.rectTransform,
Input.mousePosition,
uiCamera,
out localPos
);
Vector2 uv = new Vector2(
(localPos.x + maskImage.rectTransform.rect.width / 2) / maskImage.rectTransform.rect.width,
(localPos.y + maskImage.rectTransform.rect.height / 2) / maskImage.rectTransform.rect.height
);
DrawBrush(uv);
CheckRevealProgress();
}
}
void DrawBrush(Vector2 uv)
{
// int px = (int)(uv.x * maskRT.width);
// int py = (int)(uv.y * maskRT.height);
int px = (int)(uv.x * maskRT.width);
// 反转 Y
int py = maskRT.height - (int)(uv.y * maskRT.height);
RenderTexture.active = maskRT;
GL.PushMatrix();
GL.LoadPixelMatrix(0, maskRT.width, maskRT.height, 0);
// GL.LoadPixelMatrix(0, maskRT.width, 0, maskRT.height);
Graphics.DrawTexture(
new Rect(px - brushTex.width / 2, py - brushTex.height / 2, brushTex.width, brushTex.height),
brushTex
);
GL.PopMatrix();
RenderTexture.active = null;
}
void CheckRevealProgress()
{
if (HasRevealed) return;
RenderTexture.active = maskRT;
if (readTex == null)
readTex = new Texture2D(maskRT.width, maskRT.height, TextureFormat.RGB24, false);
readTex.ReadPixels(new Rect(0, 0, maskRT.width, maskRT.height), 0, 0);
readTex.Apply();
int clearCount = 0;
Color[] pixels = readTex.GetPixels();
foreach (var pixel in pixels)
{
if (pixel.r < 0.5f) // 黑色(已擦除)
clearCount++;
}
float percent = clearCount / (float)pixels.Length;
if (percent > revealThreshold)
{
Debug.Log("✔️ 已擦除足够区域,显示彩色图!");
RevealColorImage();
HasRevealed = true;
}
RenderTexture.active = null;
}
void RevealColorImage()
{
maskImage.gameObject.SetActive(false); // 隐藏黑白图
// 或者maskImage.color = new Color(1,1,1,0);
}
}