Unity实现刮刮乐效果

本文转自:http://www.manew.com/thread-113128-1-1.html,请点击链接查看原文,尊重楼主版权。

网上看过了很多刮刮乐的文章,自己参考了一些,也改良了一些方法,比如说改良了画的每个点不连续的情况。具体效果如下:

做出这种效果,其实挺简单,主要就是利用unity的render texture加上自己写的遮罩shader。
我们首先设置两个摄像机,一个是专门渲染render texture用的,让它只能看到笔刷图层,命名为brushCamera,并且要设为dont clear模式:

然后我们要创建一个笔刷预设体,这个笔刷预设体主要实现笔刷效果:

下面的实现思路就是:
当按下鼠标时,我们就克隆一个笔刷,这样就形成了涂画的效果。
然后我们写一个遮罩shader,shader中需要两张图,一张是遮罩的图片(就是图中的蓝色图片),另一张是用于剔除遮罩的图片,我们将渲染出的rendertexture作为剔除遮罩的图片。这样就完成了刮刮乐效果。

其中,我们要注意几个问题:
1、由于当鼠标快速滑动时,可能会产生每个点不连续的情况,这里我们用了贝塞尔平滑方法进行处理。
2、大量克隆笔刷,会非常消耗性能,这里我们采用创建对象池方法的方法解决这个问题。

下面是主要的代码:
c#代码:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DrawMask : MonoBehaviour {
public float radius = 0.5f;//半径
public GameObject brush;
bool startDraw = false;
bool twoPoints = false;
Vector2 lastPos;//最后一个点
Vector2 penultPos;//倒数第二个点
List<GameObject> brushesPool = new List<GameObject>(),activeBrushes = new List<GameObject>();//笔刷对象池public delegate void DrawHandler(Vector2 pos);
public event DrawHandler onStartDraw;
public event DrawHandler onEndDraw;
public event DrawHandler drawing;void Update () {GetInput();
}void GetInput()
{
if (Input.GetMouseButtonDown(0))
{
startDraw = true;
if (onStartDraw != null)
{
onStartDraw(VectorTransfer(Input.mousePosition));
}
penultPos = Input.mousePosition;
}
else if (Input.GetMouseButton(0))
{
if (twoPoints && Vector2.Distance(Input.mousePosition,lastPos) > 0.5f)//如果两次记录的鼠标坐标距离大于一定的距离,开始记录鼠标的点
{
Vector2 pos = Input.mousePosition;
float dis = Vector2.Distance(lastPos, pos);
int segments = (int)(dis / radius);//计算出平滑的段数
segments = segments < 1 ? 1 : segments;
Vector2[] points = Beizier(penultPos, lastPos, pos, segments);//进行贝塞尔平滑
for (int i = 0; i < points.Length; i++)
{
InstanceBrush(VectorTransfer(points[i]));
}
if (drawing != null)
{
drawing(VectorTransfer(Input.mousePosition));
}
lastPos = pos;
penultPos = points[points.Length - 2];
}
else
{
twoPoints = true;
lastPos = Input.mousePosition;
}
}
else if (Input.GetMouseButtonUp(0))
{
if (onEndDraw != null)
{
onEndDraw(VectorTransfer(Input.mousePosition));
}
startDraw = false;
twoPoints = false;
}
}private void OnPostRender()
{
InitBrushes();
}void InitBrushes()
{
for (int i = 0; i < activeBrushes.Count; i++)
{
activeBrushes[i].SetActive(false);
brushesPool.Add(activeBrushes[i]);
}
activeBrushes.Clear();
}void InstanceBrush(Vector2 pos)
{
GameObject brushClone;
if (brushesPool.Count > 0)
{
brushClone = brushesPool[brushesPool.Count - 1];
brushesPool.RemoveAt(brushesPool.Count - 1);
}
else
{
brushClone = Instantiate(brush, pos, Quaternion.identity);
}
brushClone.transform.position = pos;brushClone.transform.localScale = Vector3.one * radius;
brushClone.SetActive(true);
activeBrushes.Add(brushClone);
}/// <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();
}Vector2 VectorTransfer(Vector2 point)
{
return Camera.main.ScreenToWorldPoint(new Vector3(point.x, point.y, 0));
}
}

遮罩shader:

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "Custom/MaskShader" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
//_MainTex ("Albedo (RGB)", 2D) = "white" {}
_MaskTex("Mask Texture",2D) = "white"{}
_Mask("Mask",2D) = "white"{}}
SubShader {
Tags{"RenderType" = "Transparent" "Queue" = "Transparent"}
pass
{
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc"struct v2f
{
float4 pos:POSITION;
float2 uv:TEXCOORD1;
};//sampler2D _MainTex;
sampler2D _MaskTex;
sampler2D _Mask;v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}float4 frag(v2f i):COLOR
{
//float4 mainColor = tex2D(_MainTex,i.uv);
float4 maskTexColor = tex2D(_MaskTex,i.uv);
float4 maskColor = tex2D(_Mask,i.uv);
maskTexColor.a = 1 - maskColor.a;
return maskTexColor;
}
ENDCG
}
}
FallBack "Diffuse"
}

项目源码:请点击原链接查看楼主原文,尊重楼主版权,

Unity实现刮刮乐效果相关推荐

  1. 【Unity】刮刮乐效果(擦除图片像素值)

    实现类似刮刮乐效果,擦除图片指定像素值(修改图片Alfa通道) 参考Unity刮刮乐工程源码的实现原理,对实现方式有一些调整 这里RawImage需要保持原图大小,不能缩放,不然坐标计算会有偏差 us ...

  2. Unity 实现 (刮刮卡/刮刮乐) 效果

    Unity 实现 (刮刮卡/刮刮乐) 效果 一款功能超级强大的挂卡插件, 可用于Mesh,Sprite以及UI,可以自定义笔刷,修改笔刷大小:可以设置填充模式(可刮,可填充),自带挂卡进度识别,性能超 ...

  3. Unity 图片 涂抹/擦除/刮刮乐 效果展示 包含 Sprite, Image, Mesh的涂抹效果

    Unity 2D图片 涂抹/擦除/刮刮乐 效果展示 包含 Sprite, Image, Mesh的涂抹效果 参数 progressText: 显示百分比的文本 maskImg: 需要擦除的图片 bru ...

  4. 【你问我答】unity实现一个刮刮乐效果

    文章目录 一.前言 二.原理 三.实操 1.安装环境 2. 渲染纹理RenderTexture 3.写脚本:ScratchUI.cs 4.ShaderGraph 5. UI制作 6.材质球 7.挂脚本 ...

  5. unity实现抽奖刮刮乐效果

    最终效果 代码部分 using DG.Tweening; using System; using System.Collections; using System.Collections.Generi ...

  6. 刮刮乐html5效果擦除,利用HTML5的画布Canvas实现刮刮卡效果

    先给大家展示效果: 你玩过刮刮卡么?一不小心可以中奖的那种.今天我给大家分享一个基于HTML5技术实现的刮刮卡效果,在PC上只需按住鼠标,在手机上你只需按住指头,轻轻刮去图层就可以模拟真实的刮奖效果. ...

  7. iOS 仿支付宝刮刮乐效果

    支付宝里有个刮刮乐中奖, 和大街小巷里的类似彩票刮刮乐的效果一样. 实现思路, 其实很简单的三步: 展示刮出来的效果的view: 即刮开后刮刮乐效果展示-显示的文字Label 设置遮挡在外面的Imag ...

  8. iOS-仿支付宝刮刮乐效果

    概述 仿支付宝刮刮乐效果, 可以按照自己需求更改展示刮出来的效果的view(即刮开后刮刮乐效果展示) 详细 代码下载:http://www.demodashi.com/demo/10673.html ...

  9. 【游戏客户端】实现刮刮乐效果

    [游戏客户端]实现刮刮乐效果       之前的博客中,我和大家分享了如何做: 商业化的充值活动 :[商业化充值活动博客] 抽卡系统:[抽奖,抽卡系统博客] 装备系统:[装备系统博客] 红点系统:[红 ...

最新文章

  1. linux卸载pci驱动,linux的PCI驱动固件问题
  2. [python] LDA处理文档主题分布及分词、词频、tfidf计算
  3. spectral安装
  4. 联想回文字符串的编程题
  5. [系统安全] 逆向工程进阶篇之对抗逆向分析
  6. Linux学习——linux网络配置、修改主机名、网络映射、远程连接工具XShell的使用(超详细)
  7. ES slop问题纪录
  8. 读书笔记——OpenGL超级宝典
  9. php网页通过鼠标画图,一个神奇的网站:三步秒速画图,一键鼠标发文章
  10. 获得淘系商品详情展示
  11. 数字摄影测量之特征点提取算法
  12. java12/13新特性
  13. GitLab之something went wrong during merge pre-receive hook问题
  14. 多因子模型水平测试题试答(因子部分)
  15. WordPress 如何判断访客浏览器显示不同内容
  16. 干货 : 聚焦于用户行为分析的数据产品
  17. 前端导出zip格式压缩包
  18. OA成为中国制造企业的最大挑战
  19. 护眼灯和白炽灯哪个更保护眼睛?推荐真正护眼的护眼灯
  20. 传智黑马java基础学习——day25

热门文章

  1. 林志玲结婚,让微博程序员加班
  2. 解决windows输入法出不来两招
  3. MySQL ERROR1118报错详解
  4. 防止计算机被远程控制停止服务器,电脑被远程控制.doc
  5. VISIO标准图-BPMN
  6. 阿里云资深技术专家易立:我对云原生软件架构的观察与思考
  7. C++汉诺塔问题(河内塔)
  8. 弹出一个自定义的Diglog
  9. 力扣 790. 多米诺和托米诺平铺
  10. win32下Qt5BLE蓝牙开发笔记