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

最近我们的游戏要实现这样一个效果。

即死亡之后,出现一个圆圈,圆圈之外都是黑色的,这个圆圈从屏幕外慢慢减小到人物大小。
复活之后,这个圆圈慢慢变大到人物外面。
一开始想了好多方案最后都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

猜你喜欢

转载自blog.csdn.net/q378992971/article/details/79952307