unity实现刮刮乐效果,网上一大堆使用ugui实现的,但没有一篇解释使用fgui的,本篇文章基于fgui实现刮刮乐效果。
核心代码来源于这个篇博客,这篇博客基于ugui实现的,我把它换成了fgui的方式
【Unity】刮刮乐效果(擦除图片像素值)_unity2d清除像素-CSDN博客
using System;
using UnityEngine;
using FairyGUI;
public class FguiErasePoint : MonoBehaviour
{
//遮罩 要操作的对象
private GLoader maskLoader;
//要操作的纹理 新建出来的
private Texture2D eraseTexture;
//图片大小
private float textureLength;
//擦除部分图片大小
private float eraseLength;
//纹理宽度
private int textureWidth;
//纹理高度
private int textureHeight;
//擦除完成调用事件
public Action eraseFinishEvent;
//擦除比例,擦除比例高于该值,是为擦除完成,自动擦除剩余部分
private float finishPercent = 0.9f;
//当前进度
private float currentPercent;
//擦除的半径
public int radius = 10;
//遍历时候 上下左右的值
private int startX, endX, startY, endY, pixelY;
//鼠标的坐标
private Vector3 tmpLocalPos;
//是否以擦除完成
private bool isFinish;
private void Start()
{
GComponent component = this.GetComponent<UIPanel>().ui;
maskLoader = component.GetChild("n3").asLoader;
//加载出文理
Texture2D tmp = Resources.Load<Texture2D>("testTexture");
//创建一个新的文理 后续操作这个文理
eraseTexture = new Texture2D(tmp.width, tmp.height, TextureFormat.ARGB32, false);
eraseTexture.SetPixels(tmp.GetPixels());
eraseTexture.Apply();
//将创建的新文理 传给GLoader
NTexture nTexture = new NTexture(eraseTexture);
maskLoader.texture = nTexture;
textureWidth = eraseTexture.width;
textureHeight = eraseTexture.height;
textureLength = eraseTexture.GetPixels().Length;
//添加事件
component.onTouchBegin.Add(OnTouchBegin);
component.onTouchMove.Add(OnTouchMove);
component.onTouchEnd.Add(OnTouchEnd);
}
private void OnTouchBegin(EventContext context)
{
if (isFinish)
return;
ErasePoint(context.inputEvent.position);
context.CaptureTouch();
}
private void OnTouchMove(EventContext context)
{
if (isFinish)
return;
ErasePoint(context.inputEvent.position);
}
private void OnTouchEnd(EventContext context)
{
if (isFinish)
return;
ErasePoint(context.inputEvent.position);
}
private void ErasePoint(Vector3 pScreenPos)
{
//屏幕坐标——>本地坐标
tmpLocalPos = maskLoader.GlobalToLocal(pScreenPos);
//点击位置是否在图片范围内
if (tmpLocalPos.x < 0 || tmpLocalPos.x >= textureWidth || tmpLocalPos.y < 0 || tmpLocalPos.y > textureHeight)
{
return;
}
//最大最小值 已鼠标点为中心
startX = (int)tmpLocalPos.x - radius;
endX = (int)tmpLocalPos.x + radius;
startY = (int)tmpLocalPos.y - radius;
endY = (int)tmpLocalPos.y + radius;
for (int i = startX - 1; i < endX; i++)
{
//超左/右边界
if (i < 0 || i >= textureWidth)
continue;
for (int j = startY - 1; j < endY; j++)
{
//fgui坐标是左上角开始的 y坐标需要做个减法 才能对应到像素坐标
pixelY = textureHeight - j;
//超上/下边界
if (pixelY < 0 || pixelY >= textureHeight)
{
continue;
}
//是否在圆形范围内
if (Vector3.Distance(new Vector3(i, j), tmpLocalPos) > radius)
{
continue;
}
//像素点色值
Color col = eraseTexture.GetPixel(i, pixelY);
//判断透明度,是否已擦除
if (Mathf.Approximately(col.a, 0))
continue;
//修改像素点透明度
col.a = 0.0f;
eraseTexture.SetPixel(i, pixelY, col);
//擦除数量统计
eraseLength++;
}
}
eraseTexture.Apply();
//判断擦除进度
RefreshErasePercent();
}
private void RefreshErasePercent()
{
if (isFinish)
return;
currentPercent = eraseLength / textureLength;
currentPercent = (float)Math.Round(currentPercent, 2);
Debug.Log("擦除百分比 : " + currentPercent);
if (currentPercent >= finishPercent)
{
isFinish = true;
//触发结束事件
eraseFinishEvent?.Invoke();
}
}
}