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