Unity刮刮乐效果(擦除图片像素值)
Posted 萧然CS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity刮刮乐效果(擦除图片像素值)相关的知识,希望对你有一定的参考价值。
实现类似刮刮乐效果,擦除图片指定像素值(修改图片Alfa通道)
参考Unity刮刮乐工程源码的实现原理,对实现方式有一些调整
这里RawImage需要保持原图大小,不能缩放,不然坐标计算会有偏差
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
[RequireComponent(typeof(RawImage))]
public class EraseHandler : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
//擦除完成调用事件
public Action eraseFinishEvent;
//笔刷半径
[SerializeField] int brushRadius = 50;
//擦除比例,擦除比例高于该值,是为擦除完成,自动擦除剩余部分
[SerializeField] float finishPercent = 0.9f;
//擦除点偏移量,距离上个擦除点>=该值时开始新的擦除点
[SerializeField] float drawOffset = 10f;
//是否以擦除完成
bool isFinish;
//要擦除的图片
RawImage eraseImage;
Texture2D eraseTexture;
//图片长宽
int textureWidth;
int textureHeight;
//图片大小
float textureLength;
//擦除部分图片大小
float eraseLength;
Camera mainCamera;
void Awake()
eraseImage = GetComponent<RawImage>();
mainCamera = Camera.main;
void Start()
Init();
void Init()
isFinish = false;
eraseLength = 0;
//原擦除图片
//Texture2D originalTexture = (Texture2D)eraseImage.mainTexture;
Texture2D originalTexture = (Texture2D)eraseImage.texture;
//被擦除的图片,展示擦除过程
eraseTexture = new Texture2D(originalTexture.width, originalTexture.height, TextureFormat.ARGB32, false);
textureWidth = eraseTexture.width;
textureHeight = eraseTexture.height;
eraseTexture.SetPixels(originalTexture.GetPixels());
eraseTexture.Apply();
Debug.Log(textureWidth + " - " + textureHeight);
eraseImage.texture = eraseTexture;
textureLength = eraseTexture.GetPixels().Length;
#region Pointer Event
public void OnPointerDown(PointerEventData eventData)
if (isFinish)
return;
tempLastPoint = eventData.position;
ErasePoint(eventData.position);
Vector2 tempEventPoint;
Vector2 tempLastPoint;
public void OnDrag(PointerEventData eventData)
if (isFinish)
return;
tempEventPoint = eventData.position;
//距离上个擦除点 >= 该值时开始新的擦除点
if ((tempEventPoint - tempLastPoint).sqrMagnitude < drawOffset * drawOffset)
return;
//擦除点
ErasePoint(tempEventPoint);
//记录点
tempLastPoint = tempEventPoint;
public void OnPointerUp(PointerEventData eventData)
if (isFinish)
return;
ErasePoint(eventData.position);
#endregion
Vector3 tempWorldPoint;
Vector3 tempLocalPoint;
Vector2Int pixelPos;
void ErasePoint(Vector2 screenPos)
//点击位置坐标转换,正交相机无效,试着改成平行相机试一下
tempWorldPoint = mainCamera.ScreenToWorldPoint(screenPos);
tempLocalPoint = transform.InverseTransformPoint(tempWorldPoint);
//相对图片像素点坐标
pixelPos.x = (int)tempLocalPoint.x + textureWidth / 2;
pixelPos.y = (int)tempLocalPoint.y + textureHeight / 2;
//点击位置是否在图片范围内
if (pixelPos.x < 0 || pixelPos.x >= textureWidth || pixelPos.y < 0 || pixelPos.y >= textureHeight)
return;
//遍历笔刷长宽范围内像素点
for (int i = -brushRadius; i <= brushRadius; i++)
//超左/右边界
if (pixelPos.x + i < 0 || pixelPos.x + i >= textureWidth)
continue;
for (int j = -brushRadius; j <= brushRadius; j++)
//超上/下边界
if (pixelPos.y + j < 0 || pixelPos.y + j >= textureHeight)
continue;
//是否在圆形范围内
if (Mathf.Pow(i, 2) + Mathf.Pow(j, 2) > Mathf.Pow(brushRadius, 2))
continue;
//像素点色值
Color color = eraseTexture.GetPixel(pixelPos.x + i, pixelPos.y + j);
//判断透明度,是否已擦除
if (Mathf.Approximately(color.a, 0))
continue;
//修改像素点透明度
color.a = 0;
eraseTexture.SetPixel(pixelPos.x + i, pixelPos.y + j, color);
//擦除数量统计
eraseLength++;
eraseTexture.Apply();
//判断擦除进度
RefreshErasePercent();
float tempPercent;
void RefreshErasePercent()
if (isFinish)
return;
tempPercent = eraseLength / textureLength;
tempPercent = (float)Math.Round(tempPercent, 2);
Debug.Log("擦除百分比 : " + tempPercent);
if (tempPercent >= finishPercent)
isFinish = true;
eraseImage.enabled = false;
//触发结束事件
if (eraseFinishEvent != null)
eraseFinishEvent.Invoke();
以上是关于Unity刮刮乐效果(擦除图片像素值)的主要内容,如果未能解决你的问题,请参考以下文章
Android刮刮乐效果-proterDuffXfermode