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

扫一扫,访问微社区

开发者专栏

关注:2103

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

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

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

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

  [复制链接]  [移动端链接]
排名
3822
昨日变化
1

13

主题

73

帖子

828

积分

Rank: 9Rank: 9Rank: 9

UID
97961
好友
5
蛮牛币
1268
威望
0
注册时间
2015-5-6
在线时间
378 小时
最后登录
2018-2-12
发表于 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, 下载次数: 2018, 售价: 2 蛮牛币)

评分

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

查看全部评分


回复

使用道具 举报

7日久生情
2520/5000
排名
3670
昨日变化
21

2

主题

1840

帖子

2520

积分

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

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

回复

使用道具 举报

5熟悉之中
827/1000
排名
5162
昨日变化
27

27

主题

277

帖子

827

积分

Rank: 5Rank: 5

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

回复

使用道具 举报

7日久生情
2559/5000
排名
385
昨日变化

1

主题

584

帖子

2559

积分

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

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

回复 支持 反对

使用道具 举报

6蛮牛粉丝
1220/1500
排名
2024
昨日变化
1

17

主题

185

帖子

1220

积分

Rank: 6Rank: 6Rank: 6

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

回复

使用道具 举报

7日久生情
3790/5000
排名
4180
昨日变化
2

5

主题

3129

帖子

3790

积分

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

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

回复

使用道具 举报

7日久生情
1907/5000
排名
3785
昨日变化

7

主题

1025

帖子

1907

积分

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

UID
168159
好友
3
蛮牛币
5650
威望
0
注册时间
2016-9-12
在线时间
557 小时
最后登录
2018-2-9

锦衣玉食

发表于 2018-1-23 09:19:05 | 显示全部楼层

回复

使用道具 举报

6蛮牛粉丝
1025/1500
排名
4647
昨日变化
1

28

主题

483

帖子

1025

积分

Rank: 6Rank: 6Rank: 6

UID
219600
好友
5
蛮牛币
1844
威望
0
注册时间
2017-4-27
在线时间
258 小时
最后登录
2018-2-6

迈向小康

发表于 2018-1-23 09:27:41 | 显示全部楼层
厉害了,感谢分享

回复

使用道具 举报

5熟悉之中
506/1000
排名
4647
昨日变化
1

0

主题

140

帖子

506

积分

Rank: 5Rank: 5

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

回复 支持 反对

使用道具 举报

7日久生情
1656/5000
排名
2011
昨日变化
1

26

主题

611

帖子

1656

积分

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

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

回复

使用道具 举报

4四处流浪
349/500
排名
10050
昨日变化
2

0

主题

110

帖子

349

积分

Rank: 4

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

回复

使用道具 举报

5熟悉之中
886/1000
排名
3977
昨日变化

1

主题

358

帖子

886

积分

Rank: 5Rank: 5

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

回复

使用道具 举报

4四处流浪
393/500
排名
9318
昨日变化
1

1

主题

190

帖子

393

积分

Rank: 4

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

回复

使用道具 举报

3偶尔光临
163/300
排名
9784
昨日变化
3

0

主题

47

帖子

163

积分

Rank: 3Rank: 3Rank: 3

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

回复 支持 反对

使用道具 举报

6蛮牛粉丝
1135/1500
排名
2410
昨日变化

3

主题

92

帖子

1135

积分

Rank: 6Rank: 6Rank: 6

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

回复 支持 反对

使用道具 举报

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

本版积分规则

关闭

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

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