开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

开发者专栏

关注:2212

当前位置:游戏蛮牛 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 3691|回复: 94

[大锅的案例] unity制作刮刮乐效果

  [复制链接]  [移动端链接]
排名
4034
昨日变化
2

15

主题

79

帖子

911

积分

Rank: 9Rank: 9Rank: 9

UID
97961
好友
5
蛮牛币
1359
威望
0
注册时间
2015-5-6
在线时间
448 小时
最后登录
2018-5-25
发表于 2018-1-22 20:30:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

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

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


QQ截图20180122200928.png

然后我们要创建一个笔刷预设体,这个笔刷预设体主要实现笔刷效果:
QQ截图20180122201138.png

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

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

[C#] 纯文本查看 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

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;
    // Use this for initialization
    void Start () {
	}
	
	// Update is called once per frame
	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:
[C] 纯文本查看 复制代码
// 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"
}



项目源码:
guaguale.rar (6.29 MB, 下载次数: 2149, 售价: 2 蛮牛币)

评分

参与人数 6鲜花 +23 收起 理由
copylightlee + 2 很给力!
凡水 + 4 赞一个!
lilexy + 5 赞一个!
海峡同城哥 + 5 赞一个!
研究者 + 5 很给力!
侯大人 + 2 赞一个!

查看全部评分


回复

使用道具 举报

7日久生情
2533/5000
排名
3334
昨日变化
2

2

主题

1780

帖子

2533

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
241666
好友
0
蛮牛币
10193
威望
0
注册时间
2017-9-6
在线时间
360 小时
最后登录
2018-5-23
发表于 2018-1-23 07:42:24 来自Mobile--- | 显示全部楼层
感谢分享

回复

使用道具 举报

6蛮牛粉丝
1290/1500
排名
3334
昨日变化
2

50

主题

363

帖子

1290

积分

Rank: 6Rank: 6Rank: 6

UID
119735
好友
1
蛮牛币
13765
威望
0
注册时间
2015-8-26
在线时间
509 小时
最后登录
2018-5-24
发表于 2018-1-23 08:24:51 | 显示全部楼层
感谢分享

回复

使用道具 举报

7日久生情
2761/5000
排名
362
昨日变化

1

主题

645

帖子

2761

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
27356
好友
1
蛮牛币
4071
威望
0
注册时间
2014-5-30
在线时间
557 小时
最后登录
2018-5-25
发表于 2018-1-23 09:08:27 | 显示全部楼层
有意思,图片更有意思 :)

回复 支持 反对

使用道具 举报

7日久生情
1511/5000
排名
1569
昨日变化
7

18

主题

200

帖子

1511

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
172976
好友
4
蛮牛币
427
威望
0
注册时间
2016-9-30
在线时间
565 小时
最后登录
2018-5-26
发表于 2018-1-23 09:12:46 | 显示全部楼层
厉害了

回复

使用道具 举报

7日久生情
4053/5000
排名
3165
昨日变化
19

5

主题

3109

帖子

4053

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
209186
好友
5
蛮牛币
4915
威望
0
注册时间
2017-3-1
在线时间
533 小时
最后登录
2018-5-25
发表于 2018-1-23 09:18:54 | 显示全部楼层
谢谢分享

回复

使用道具 举报

7日久生情
2082/5000
排名
3552
昨日变化
15

7

主题

1093

帖子

2082

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
168159
好友
4
蛮牛币
6066
威望
0
注册时间
2016-9-12
在线时间
614 小时
最后登录
2018-5-25
发表于 2018-1-23 09:19:05 | 显示全部楼层

回复

使用道具 举报

6蛮牛粉丝
1488/1500
排名
3210
昨日变化
12

37

主题

674

帖子

1488

积分

Rank: 6Rank: 6Rank: 6

UID
219600
好友
7
蛮牛币
2177
威望
0
注册时间
2017-4-27
在线时间
373 小时
最后登录
2018-5-26
发表于 2018-1-23 09:27:41 | 显示全部楼层
厉害了,感谢分享

回复

使用道具 举报

5熟悉之中
516/1000
排名
4747
昨日变化
3

0

主题

140

帖子

516

积分

Rank: 5Rank: 5

UID
241750
好友
0
蛮牛币
949
威望
0
注册时间
2017-9-6
在线时间
112 小时
最后登录
2018-3-26
发表于 2018-1-23 09:29:37 | 显示全部楼层
66666666666666666666666666666666666666666

回复 支持 反对

使用道具 举报

7日久生情
1807/5000
排名
1795
昨日变化
1

31

主题

620

帖子

1807

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
174225
好友
1
蛮牛币
71
威望
0
注册时间
2016-10-9
在线时间
492 小时
最后登录
2018-5-24
QQ
发表于 2018-1-23 09:30:50 | 显示全部楼层
谢谢分享

回复

使用道具 举报

5熟悉之中
536/1000
排名
6074
昨日变化
53

0

主题

113

帖子

536

积分

Rank: 5Rank: 5

UID
151151
好友
0
蛮牛币
753
威望
0
注册时间
2016-6-7
在线时间
227 小时
最后登录
2018-5-25
QQ
发表于 2018-1-23 09:32:58 | 显示全部楼层
感谢分享

回复

使用道具 举报

6蛮牛粉丝
1007/1500
排名
3552
昨日变化
15

1

主题

379

帖子

1007

积分

Rank: 6Rank: 6Rank: 6

UID
173098
好友
0
蛮牛币
16
威望
0
注册时间
2016-9-30
在线时间
265 小时
最后登录
2018-5-25
发表于 2018-1-23 09:33:34 | 显示全部楼层
谢谢。。。。。。。。。。。。。。。。。。。。。。。

回复

使用道具 举报

5熟悉之中
539/1000
排名
7286
昨日变化
6

2

主题

242

帖子

539

积分

Rank: 5Rank: 5

UID
229218
好友
1
蛮牛币
650
威望
0
注册时间
2017-6-28
在线时间
145 小时
最后登录
2018-5-11
发表于 2018-1-23 09:43:40 | 显示全部楼层
谢谢分享 有意思

回复

使用道具 举报

4四处流浪
318/500
排名
7212
昨日变化

0

主题

107

帖子

318

积分

Rank: 4

UID
248343
好友
0
蛮牛币
597
威望
0
注册时间
2017-10-12
在线时间
59 小时
最后登录
2018-5-10
发表于 2018-1-23 09:51:04 | 显示全部楼层
v5v5v5v5v5v5v5v5

回复 支持 反对

使用道具 举报

6蛮牛粉丝
1296/1500
排名
2030
昨日变化
3

3

主题

93

帖子

1296

积分

Rank: 6Rank: 6Rank: 6

UID
35774
好友
1
蛮牛币
1767
威望
0
注册时间
2014-7-22
在线时间
598 小时
最后登录
2018-5-26
发表于 2018-1-23 09:52:22 | 显示全部楼层
用GL来,性能会几何级提升

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

关闭

站长推荐 上一条 /1 下一条

快速回复 返回顶部 返回列表