1.需求
给物体绑定一个脚本,这个脚本实现物体的透明度渐变变化,并且可以重置回原来的颜色。物体为Unity自带的材质Shader为Standard。
2.代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TransparentChanger : MonoBehaviour
{
/// <summary>
/// 保存原颜色
/// </summary>
private Color[] oldColors;
/// <summary>
/// 控制透明度变化
/// </summary>
[Range(0, 1)]
public float nalpha;
private void Start()
{
Init();
}
private void Update()
{
SetOpacity(nalpha);
}
public void Init()
{
int num = 0;
foreach (Renderer r in GetComponentsInChildren<Renderer>(true))
{
num += r.materials.Length;
}
oldColors = new Color[num];
num = 0;
foreach (Renderer r in GetComponentsInChildren<Renderer>(true))
{
foreach (Material m in r.materials)
{
try
{
oldColors[num++] = m.color;
}
catch (System.Exception e)
{
Debug.Log(e.Message);
}
}
}
}
/// <summary>
/// 重置回原来的颜色
/// </summary>
public void Reset()
{
int num = 0;
foreach (Renderer r in GetComponentsInChildren<Renderer>(true))
{
foreach (Material m in r.materials)
{
try
{
m.color = oldColors[num++];
if (m.color.a >= 1)
{
ChangeMaterialType(0, m);
m.renderQueue = -1;
}
}
catch (System.Exception e)
{
Debug.Log(e.Message);
}
}
}
}
public void SetOpacity(float alpha)
{
int num = 0;
foreach (Renderer r in GetComponentsInChildren<Renderer>(true))
{
foreach (Material m in r.materials)
{
try
{
float mA = Mathf.Min(alpha, oldColors[num++].a);
m.color = new Color(m.color.r, m.color.g, m.color.b, mA);
if (mA >= 0.98f)
{
ChangeMaterialType(0, m);
}
else
{
ChangeMaterialType(1, m);
}
}
catch (System.Exception e)
{
Debug.Log(e.Message);
}
}
}
}
/// <summary>
/// 切换材质的Standard Shader 渲染类型
/// </summary>
/// <param name="mType">0-Opaque, 1-Transparent</param>
/// <param name="m">材质</param>
void ChangeMaterialType(int mType, Material m)
{
if(mType == 0)
{
m.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
m.SetInt("_ZWrite", 1);
m.DisableKeyword("_ALPHATEST_ON");
m.DisableKeyword("_ALPHABLEND_ON");
m.DisableKeyword("_ALPHAPREMULTIPLY_ON");
m.renderQueue = -1;
}
else if(mType == 1)
{
m.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
m.SetInt("_ZWrite", 0);
m.DisableKeyword("_ALPHATEST_ON");
m.DisableKeyword("_ALPHABLEND_ON");
m.EnableKeyword("_ALPHAPREMULTIPLY_ON");
m.renderQueue = 3000;
}
}
}