【unity】透明遮罩动画与Tiling和Offset的关系

原创 2018年04月15日 19:53:06
最近我们的游戏要实现这样一个效果。

即死亡之后,出现一个圆圈,圆圈之外都是黑色的,这个圆圈从屏幕外慢慢减小到人物大小。
复活之后,这个圆圈慢慢变大到人物外面。
一开始想了好多方案最后都pass掉了。
留下了最后的方案,使用Shader完成。
首先准备两张图片。一张纯黑背景。一张白色圆圈。


首先是新建一个shader,将shader拖入Material,将Material拖入纯黑背景。
Shader代码如下。
Shader "Custom/magic" {
        Properties {
                _MainTex ("Albedo (RGB)", 2D) = "white" {}
                _Mask("Culling Mask", 2D) = "white"{}
                _Cutoff("Alpha cutoff", Range(0,1)) = 0.1

        }
        SubShader {
                Tags { "Quene"="Transparent" }
                Lighting Off

      ZWrite Off

      Blend SrcAlpha OneMinusSrcAlpha

      AlphaTest GEqual [_Cutoff]

      Pass

      {
         SetTexture [_Mask] {combine texture}

         SetTexture [_MainTex] {combine texture,texture-previous}

      }
        }
        FallBack "Diffuse"
}


这段代码可以实现重叠部分透明度变为全透明。
在纯黑背景的Inspect中的Shader的Culling Mask选择为白色圆圈。
重点来了。
怎么样实现重叠处变大变小。
如果你用到过Shader那就应该知道Culling Mask里面的Tiling和Offset并不是Scale和position的意思。具体是什么可以百度一下。
我们要实现这功能就是要在Culling Mask仍然处于Albedo的中心的前提下,变大变小。
根据数学归纳法,我求得了在Tiling变化时候Offset的值以保持Culling Mask仍处于Albedo中心。

Offset.x = -(Tiling.x - 1) / 2;

Offset.y同理。
那么我们只需要在改变Tiling的时候改变Offset那么就可以实现上文提到的圆圈变大变小且中心点处在人物中间。

下面的脚本是我现在游戏过后的死亡和重生脚本。需修改之后才能使用。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Prime31;
using UnityEngine.SceneManagement;
public class Die2 : MonoBehaviour {

        public bool inDie;
        public Vector2 scale;
        public bool Big;
        public float scaleX;
        public float sishu ;
        public float offsetX;
        public float tx;
        public float r;
        public bool ifStart;
        public bool inLiving;
        public GameObject Black;
        public Material BlackMaterial;

        Vector3 saved_position;
        void Start () {
                Black = GameObject.Find ("background");//background是黑色背景
                inDie = false;
                Big = true;
                sishu = 0.1f;
                tx = 20.48f;
                r = 10f;
                ifStart = false;
                Black.transform.localScale = new Vector3 (0, 0, 0);
                BlackMaterial = Black.GetComponent<Renderer> ().material;
                inLiving = false;
        }
                
        void Update () {
                if(inDie)
                {
                        scale = BlackMaterial.GetTextureScale ("_Mask");
                        offsetX = BlackMaterial.GetTextureOffset ("_Mask").x;
                        scaleX = scale.x;
                        if (scale.x > 80) {
                                BlackMaterial.SetTextureOffset ("_Mask", new Vector2 (0, 0)); 
                                AfterDie ();
                                return;

                        }
                        scaleX = Mathf.Lerp (scaleX, 100f, sishu);

                        offsetX = -(scaleX - 1) / 2;
                        BlackMaterial.SetTextureOffset ("_Mask", new Vector2 (offsetX, offsetX));
                        BlackMaterial.SetTextureScale ("_Mask", new Vector2 (scaleX, scaleX));
                }
                else if(inLiving)
                {
                        scale = BlackMaterial.GetTextureScale ("_Mask");
                        offsetX = BlackMaterial.GetTextureOffset ("_Mask").x;
                        scaleX = scale.x;
                        if (scale.x < 0) {
                                ifStart = false;
                                //gameObject.transform.localScale = new Vector3 (0, 0, 0);
                                scaleX = 1;
                                offsetX = -(scaleX - 1) / 2;
                                BlackMaterial.SetTextureOffset ("_Mask", new Vector2 (offsetX, offsetX));
                                BlackMaterial.SetTextureScale ("_Mask", new Vector2 (scaleX, scaleX));
                                AfterLiving ();
                                return;

                        }
                        scaleX = Mathf.Lerp (scaleX, -1f, sishu);

                        offsetX = -(scaleX - 1) / 2;
                        BlackMaterial.SetTextureOffset ("_Mask", new Vector2 (offsetX, offsetX));
                        BlackMaterial.SetTextureScale ("_Mask", new Vector2 (scaleX, scaleX));
                }
        }



        void OnTriggerEnter2D(Collider2D other) {
                if(other.gameObject.transform.tag == "Save")
                {
                        saved_position = other.gameObject.transform.position;
                        other.GetComponent<SpriteRenderer> ().color = new Color (255, 0, 0);
                }        
                if (other.gameObject.transform.tag == "Finish") {        
                        if(!inDie)
                        {
                                GetComponent<CharacterController2D> ().move (new Vector3 (0, 0, 0));
                                inDie = true;
                                Black.transform.localScale = new Vector3 (4, 4, 4);
                                scaleX = 1;
                                offsetX = 0;
                                BlackMaterial.SetTextureOffset ("_Mask", new Vector2 (offsetX, offsetX));
                                BlackMaterial.SetTextureScale ("_Mask", new Vector2 (scaleX, scaleX));}
                }
        }

        void AfterDie()
        {
                inDie = false;
                inLiving = true;
                this.transform.position = saved_position;
                GetComponent<Mover> ().Initialization ();
        }

        void AfterLiving()
        {
                inLiving = false;
                inDie = false;
                Black.transform.localScale = new Vector3 (0, 0, 0);
        }
}

GitHub: https://github.com/TaurusGGBOY
CSDN: https://blog.csdn.net/q378992971
微信公众号:GameOldMemory
知乎:zhihu.com/people/gao-guo-bin-34

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q378992971/article/details/79952307

unity material之tiling和offset属性

在Unity中,使用材质或者着色器是通过创建一个材质来实现的,新建一个材质,会要求选择使用哪个着色器,默认的是Diffuse着色器。确定了着色器后,在材质属性面板中就会出现该着色器需要用到的一些属性,...
  • kfqcome
  • kfqcome
  • 2014-02-17 17:16:54
  • 18566

Unity Tiling和offset的使用

offset是显示框的偏移量 Tiling是显示框的缩放量
  • u010232305
  • u010232305
  • 2016-04-06 14:31:18
  • 2370

material之UV,offset,tiling

UV坐标系如图: offset指定使用贴图的起始位置, 取值范围[0,1]tiling:从offset位置处开始平铺图片,超过的部分(即空白处)会按比例生成新的区域 拼接 到空白处。 取值范围...
  • long2324066440
  • long2324066440
  • 2016-03-17 20:03:43
  • 964

[UnityShader]material中的tiling与offset

texture的import settings中的wrap mode: repeat表示当一张texture不能覆盖物体表面时,剩余部分再次用该texture。 clamp表示当一张texture不能...
  • lyh916
  • lyh916
  • 2015-03-18 23:05:13
  • 2145

unity 2D 透明遮罩 简单实现

大致需要用到的东西:shader 材质 深度摄像机unity实现2D遮罩找了许多的解决办法,这个是我采取的一种方法,比较便捷,但是不一定是最好的。主要想实现的效果是这样的,小偷有一个在窗户中移动的动画...
  • obilang
  • obilang
  • 2015-02-18 23:40:42
  • 6114

UnityShader中Tiling和Offset参数设置时贴图异常问题

最近在学习UnityShader的一些基础部分,在学习到2D属性时,设置Tiling和Offset的值时发现在Unity5.6中当Tiling大于1时会自动重复贴图,在Offset设置时会正常偏移,而...
  • qq_33716394
  • qq_33716394
  • 2017-12-22 11:11:29
  • 88

Unity3d 遮罩技术。。。找的好辛苦。。。。

遮罩技术是一个基本的技术方法,有很多很多中用法.你可以在Flash中经常看到遮罩的使用,它可以另一些视觉元素更加惊艳.当我看到Unity中没有包含任何几何体和图片的遮罩技术很不爽,不过,幸运的我找到了...
  • ldghd
  • ldghd
  • 2012-10-12 16:20:18
  • 2905

unity3d用动画遮罩(avatar mask)实现动画切换

这里主要是为了实现短枪动作,脚动手不动的简单实现 1、添加shoot layer射击动作图层2、右键 创建一个avatar mask3、设计遮罩(手动,腿不动)4、配置参数...
  • A13155283231
  • A13155283231
  • 2018-01-11 23:33:35
  • 207

unity 实现遮罩效果_1(无遮罩图直接融合)

 转载自风宇冲Unity3D教程学院                         Shader第五讲:LOGO闪光效果                          ...
  • ak4100
  • ak4100
  • 2014-10-23 11:21:33
  • 2093

unity 2D 透明遮罩 简单实现物体一半透明

大致需要用到的东西: shader 材质 深度摄像机 unity实现2D遮罩找了许多的解决方法,这个是我采取的一种方法,比较便捷,但不一定是最好的 主要想实现的效果是这样的,小偷藏在窗户的...
  • wuyouhome
  • wuyouhome
  • 2015-12-28 22:24:56
  • 2452
收藏助手
不良信息举报
您举报文章:【unity】透明遮罩动画与Tiling和Offset的关系
举报原因:
原因补充:

(最多只允许输入30个字)