推荐阅读

  • CSDN主页
  • GitHub开源地址
  • Unity3D插件分享
  • 简书地址
  • 我的个人博客

大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

一、前言

使用Unity3D实现UI的擦拭效果、刮刮卡功能的效果实现方式比较多,比如说用Shader、Texture渲染都是可以的。

本篇文章就使用Texture渲染来实现擦除的效果,效果图如下:


接下来就来看一下如何实现吧。

二、正文

2-1、实现原理

(1)取得遮罩图的像素数据。
(2)在鼠标滑动的时候,将屏幕坐标转换到遮罩在父节点下的坐标。
(3)以鼠标点击的点为中心,生成需要擦除的区域大小,通过与记录的遮罩数据进行对比,替换擦除的区域的像素值。
(4)计算每一个像素的alpha值,设置为0,达到透明的效果。
(5)拖动的话使用了贝塞尔平滑,让擦除更加的丝滑。

2-2、实现步骤

(1)设置摄像机的属性

Projection设置为Orthographic

(2)新建一个Canvas,设置属性:

Render ModeScreen Space-Camera
Render Camera摄像机对象
UI Scale ModeScale With Screen Size
Reference Resolution1920 * 1080

(3)新建一个Image,再新建一个RawImage


底板和蒙版的图:


(4)新建脚本命名为EraseMask.cs,双击打开脚本,修改脚本:

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;public class EraseMask : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{[Header("是否启用")] public bool isEnable = true;  //是否启用[Header("毛刷大小")] public int brushSize = 50; //毛刷大小[Header("擦拭比例")] public int rate = 90;      //可以设置当到达一定比例后全部显示Action eraserEvent;         //擦拭事件RawImage uiTex;             //渲染对象Texture2D MyTex;            //渲染材质int mWidth, mHeight;        //宽,高int maxColor, startColor;   //最大颜色量,开始颜色量bool twoPoints = false;     //判断鼠标是否松开Vector2 startPos, endPos;   //开始点,结束点float radius = 12f;         //平滑的段数float distance = 1f;        //鼠标滑动的距离double fate;                //进度void Awake(){if (!isEnable) { return; }uiTex = GetComponentInChildren<RawImage>();Texture2D tex = (Texture2D)uiTex.mainTexture;MyTex = new Texture2D(tex.width, tex.height, TextureFormat.ARGB32, false);mWidth = MyTex.width;mHeight = MyTex.height;MyTex.SetPixels(tex.GetPixels());MyTex.Apply();uiTex.texture = MyTex;maxColor = MyTex.GetPixels().Length;startColor = 0;eraserEvent += getTransparentPercent;}#region 事件public void OnPointerDown(PointerEventData eventData){if (!isEnable) { return; }startPos = eventData.position;CheckPoint(startPos);}public void OnDrag(PointerEventData eventData){if (!isEnable) { return; }if (twoPoints && Vector2.Distance(eventData.position, endPos) > distance)//如果两次记录的鼠标坐标距离大于一定的距离,开始记录鼠标的点{Vector2 pos = eventData.position;float dis = Vector2.Distance(endPos, pos);CheckPoint(eventData.position);int segments = (int)(dis / radius);//计算出平滑的段数                                              segments = segments < 1 ? 1 : segments;if (segments >= 10) { segments = 10; }Vector2[] points = Beizier(startPos, endPos, pos, segments);//进行贝塞尔平滑for (int i = 0; i < points.Length; i++){CheckPoint(points[i]);}endPos = pos;if (points.Length > 2)startPos = points[points.Length - 2];}else{twoPoints = true;endPos = eventData.position;}}public void OnPointerUp(PointerEventData eventData){if (!isEnable) { return; }twoPoints = false;}void CheckPoint(Vector3 pScreenPos){Vector3 worldPos = Camera.main.ScreenToWorldPoint(pScreenPos);Vector3 localPos = uiTex.gameObject.transform.InverseTransformPoint(worldPos);if (localPos.x > -mWidth / 2 && localPos.x < mWidth / 2 && localPos.y > -mHeight / 2 && localPos.y < mHeight / 2){for (int i = (int)localPos.x - brushSize; i < (int)localPos.x + brushSize; i++){for (int j = (int)localPos.y - brushSize; j < (int)localPos.y + brushSize; j++){if (Mathf.Pow(i - localPos.x, 2) + Mathf.Pow(j - localPos.y, 2) > Mathf.Pow(brushSize, 2))continue;if (i < 0) { if (i < -mWidth / 2) { continue; } }if (i > 0) { if (i > mWidth / 2) { continue; } }if (j < 0) { if (j < -mHeight / 2) { continue; } }if (j > 0) { if (j > mHeight / 2) { continue; } }Color col = MyTex.GetPixel(i + (int)mWidth / 2, j + (int)mHeight / 2);if (col.a != 0f){col.a = 0.0f;startColor++;MyTex.SetPixel(i + (int)mWidth / 2, j + (int)mHeight / 2, col);}}}//开始刮的时候 去判断进度if (isEnable){eraserEvent.Invoke();}MyTex.Apply();}}#endregion/// <summary> /// 检测当前刮刮卡 进度/// </summary>/// <returns></returns>public void getTransparentPercent(){if (!isEnable) { return; }fate = (float)startColor / maxColor * 100;fate = (float)Math.Round(fate, 2);Debug.Log("当前百分比: " + fate);if (fate >= rate){isEnable = false;uiTex.gameObject.SetActive(false);}}/// <summary>/// 贝塞尔平滑/// </summary>/// <param name="start">起点</param>/// <param name="mid">中点</param>/// <param name="end">终点</param>/// <param name="segments">段数</param>/// <returns></returns>public Vector2[] Beizier(Vector2 start, Vector2 mid, Vector2 end, int segments){float d = 1f / segments;Vector2[] points = new Vector2[segments - 1];for (int i = 0; i < points.Length; i++){float t = d * (i + 1);points[i] = (1 - t) * (1 - t) * mid + 2 * t * (1 - t) * start + t * t * end;}List<Vector2> rps = new List<Vector2>();rps.Add(mid);rps.AddRange(points);rps.Add(end);return rps.ToArray();}
}

将脚本附到Canvas对象上:

(4)运行程序

三、后记

如果觉得本篇文章有用别忘了点个关注,关注不迷路,持续分享更多Unity干货文章。


你的点赞就是对博主的支持,有问题记得留言:

博主主页有联系方式。

博主还有跟多宝藏文章等待你的发掘哦:

专栏 方向 简介
Unity3D开发小游戏 小游戏开发教程 分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。
Unity3D从入门到进阶 入门 从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。
Unity3D之UGUI UGUI Unity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。
Unity3D之读取数据 文件读取 使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。
Unity3D之数据集合 数据集合 数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。
Unity3D之VR/AR(虚拟仿真)开发 虚拟仿真 总结博主工作常见的虚拟仿真需求进行案例讲解。
Unity3D之插件 插件 主要分享在Unity开发中用到的一些插件使用方法,插件介绍等
Unity3D之日常开发 日常记录 主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等
Unity3D之日常BUG 日常记录 记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。

【Unity3D小功能】Unity3D中实现UI擦除效果、刮刮卡功能相关推荐

  1. 【Unity3D】在Unity中实现UI指向箭头

    本问转载自http://ghostyii.com/uiarrow/,为什么转载呢,怕以后找不到了! ps:博主写到超级详细,复制粘贴即可使用,超赞的! 0x0.引言 屏幕UI指示箭头,非常常见的游戏U ...

  2. 诺基亚301支持java评测_功能机中的拍照王 诺基亚301单卡版评测

    界面:五颜六色的圆角图标 诺基亚301采用了Series 40操作系统,回想诺基亚最新发布的非智能手机,在界面设计上也都是很相似的.尽管是非智能系统,但是熟悉诺基亚Symbian系统的用户都可以感觉到 ...

  3. 微信小程序开发中调用button组件添加微信客服功能

    个人比较喜欢这个解决方案,原因一是由腾讯官方运营,比较稳定.二是确实很方便啊,直接用微信回复就好了.核心代码就一行,如下 <button open-type="contact" ...

  4. 关于微信小程序开发中的显示个人信息以及重置密码功能

    最近我们学习了微信小程序中的显示个人信息以及重置密码,因为是老师做好的接口,所以我们只需要搭好前台页面以及编写好JS代码就可以了. 以上是显示个人信息的页面,包含了用户的学号,姓名,系别,班级(因为是 ...

  5. 微信小程序----地理围栏实现员工防作弊地图打卡功能

    效果图 业务场景 小程序用户(公司员工)需要在小程序选择位置打卡并上传位置,为了保证员工是真实的去指定的地点开展了公司的业务而不是虚假打卡上传的位置,需要进行地理围栏限制,要求打卡上传的位置地点必须和 ...

  6. Unity中制作UI光晕效果(发光效果)

    Unity中,我们怎么制作UI物体发光的渐隐渐现的效果呢? 比如说我们有一张月亮光晕的精灵图片 我们可以给它添加一个CanvasGroup组件 我们可以发现,组件上的Alpha值可以控制图片的透明度, ...

  7. 微信新增“亲属卡”功能:帮家人支付 上限3000元

    近日,有微信用户发现微信钱包中悄然新增了一项"亲属卡"功能,目前尚处于灰度测试阶段,只有部分用户可见. 据悉,"亲属卡"功能与支付宝"亲密付" ...

  8. 【Unity3D小功能】Unity3D中在创建完项目后自动创建文件夹列表

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦. 一.前言 ...

  9. Unity3D小功能 小技巧 小教程 小原理(持续更新...)

    Unity3D小功能 小技巧 小教程 小原理(持续更新...) 1.Unity的.NET版本是2.0 按道理来说,C#能用的功能Unity也能用,但是Unity的.NET却不是最新版 要是用一些别的D ...

最新文章

  1. Alyona and a tree (树上倍增+差分)
  2. 不懂管理,你拿什么赢别人!商业奇才10句话,老板奉为管理圣经
  3. maven设置本地仓库路径
  4. Linux中断技术、门描述符、IDT(中断描述符表)、异常控制技术总结归类
  5. sqlserver数据库同步解决方案
  6. LDA线性判别原理解析<数学推导>
  7. python传奇自动打怪脚本_大漠传奇自动打怪源码分享
  8. Python暴力破解密码
  9. 写在微信小程序一周年
  10. 植物大战僵尸修改游戏存档
  11. 齐兴皓 团队项目(任务五):项目回顾
  12. 文件包含漏洞及漏洞利用
  13. C++为什么空格无法输出_47个快捷键、50个CAD技巧,终于知道为什么别人用CAD总比我快了!...
  14. 最近所学的Json以及ajax的应用
  15. CYPRESS代理铁电存储器中文资料FM25V05-GTR
  16. 基于Excel的标定数据(DCM文件)查询及核对工具
  17. 【新版】模拟量输入模块的2、3、4线制的接法图解
  18. Redhat7/CentOS7 网络配置与管理(nmtui、nmcli、GNOME GUI、ifcfg文件、IP命令)
  19. 微型计算机的发展是以何种技术为特征标志的?微处理器
  20. hadoop数仓建设之离线数据开发

热门文章

  1. 洛谷·[SCOI2003]字符串折叠
  2. 小程序客服消息之如何引导自动关注公众号(5种方法)
  3. 软件测试项目实战之性能测试篇,软件测试项目实战之性能测试篇
  4. cv岗工作做什么_电视台都有什么工作职位
  5. 打飞碟(动作与物理兼容版)
  6. linux 单调时间实现原理,Linux系统下的单调时间函数
  7. 瑞星原副总卖传奇3外挂获利280万 终审被判6年
  8. 塑钢瓦图片_清新区塑钢瓦图片安装说明
  9. error 2059 C语言,求助大神指点,error C2059: syntax error : 'constant'
  10. Linux 解压.gz文件