版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/memories_sunset/article/details/60145327
之前发现很多残影系统的教学课程都是花钱的,五十一百什么的。
要不就什么插件,费钱的很。本来没有那么复杂的东西都那么蛋疼的要钱,我把我之前整理的残影代码发出来供大家分享。
原理:实现人物残影和所用的人物模型当中有几个材质有关。可以考虑使用一个容器进行存储。接下来在单位时间内copy素白模型并且对shader内部的透明度进行线性降低,就可以实现残影特效。最后在把透明度为0的删除就好。逻辑非常简单。下面发出我的代码,和CSDN诸君共勉。
public class FadeInOut : MonoBehaviour {
public float lifeCycle = 1.0f; //残影存在时间
float startTime; //产生的时间
Material[] mat = null; //材质球
void Start()
{
startTime = Time.time;
MeshRenderer meshRenderer = GetComponent<MeshRenderer>();
mat = new Material[meshRenderer.materials.Length];
//如果没有meshRenderer 或者 没有材质 禁用对象
if (!meshRenderer || !meshRenderer.material)
{
base.enabled = false;
}
else
{
for (int i = 0; i < meshRenderer.materials.Length; i++)
{
mat[i] = meshRenderer.materials[i];
}
}
}
void Update()
{
float time = Time.time - startTime;
//存在时间到了就消灭掉
if (time > lifeCycle)
{
DestroyImmediate(gameObject);
}
else
{
//通过remainderTime来控制残影的透明度
float remainderTime = lifeCycle - time;
//如果得到了材质球
for (int p = 0; p < mat.Length; p++)
{
//控制sharder透明度
Color col = new Color(0.85f, 0.43f, 0.84f, 0.2f);
col.a *= remainderTime;
mat[p].SetColor("_Color", col);
}
}
}
}
public class GostShadow : MonoBehaviour {
public float interval = 0.1f; //每0.1秒生成一个残影
public float lifeCycle = 0.5f; //残影存在时间
public float lastCombinedTime = 0.0f; //上一次组合的时间
public MeshFilter[] meshFilters = null; //存贮对象包含的MeshFilter组件
public MeshRenderer[] meshRenderers = null; //存贮对象包含的MeshRenderer组件
public SkinnedMeshRenderer skinnedMeshRenderers = null; //存贮对象包含的skinnedMeshRenderers组件
public List<GameObject> objs = new List<GameObject>(); //存储残影
// Use this for initialization
public Animator witchAnimator;
void Awake()
{
witchAnimator = GetComponent<Animator>();
}
void Start()
{
meshFilters = gameObject.GetComponentsInChildren<MeshFilter>();
skinnedMeshRenderers = gameObject.GetComponentInChildren<SkinnedMeshRenderer>();
}
void OnDisable()
{
//消灭所有残影
foreach (GameObject go in objs)
{
DestroyImmediate(go);
}
objs.Clear();
objs = null;
}
// Update is called once per frame
void Update()
{
if (witchAnimator.GetCurrentAnimatorStateInfo(0).IsName("Base Layer.Idlefly"))
{
return;
}
else
{
if (Time.time - lastCombinedTime > interval)
{
lastCombinedTime = Time.time;
Mesh mesh = new Mesh();
//skinnedMeshRenderers.BakeMesh取出的mesh是原始mesh不会随动画改变
skinnedMeshRenderers.BakeMesh(mesh);
GameObject go = new GameObject();
//设置layer层(可自行修改或去掉)
go.layer = 8;
//物体是否被隐藏、保存在场景中或被用户修改?
//HideFlags.HideAndDontSave; 不能显示在层级面板并且不能保存到场景。
go.hideFlags = HideFlags.HideAndDontSave;
//将mesh赋给残影
MeshFilter meshFilter = go.AddComponent<MeshFilter>();
meshFilter.mesh = mesh;
//将材质球赋给残影
MeshRenderer meshRenderer = go.AddComponent<MeshRenderer>();
meshRenderer.materials = new Material[skinnedMeshRenderers.materials.Length];
for (int p = 0; p < skinnedMeshRenderers.materials.Length; p++)
{
meshRenderer.materials[p].shader = Shader.Find("Sprites/Diffuse");
meshRenderer.materials[p] = skinnedMeshRenderers.materials[p];
Color col = new Color(0.85f, 0.43f, 0.84f, 0.2f);
meshRenderer.materials[p].SetColor("_Color", col);
}
//残影的淡入淡出
InitFadeInObj(go, skinnedMeshRenderers.transform.position
, skinnedMeshRenderers.transform.rotation, lifeCycle);
}
}
}
//残影的淡入淡出 对象、位置、旋转、存在时间
private void InitFadeInObj(GameObject go, Vector3 position, Quaternion rotation, float lifeCycle)
{
go.hideFlags = HideFlags.HideAndDontSave;
go.transform.position = position;
go.transform.rotation = rotation;
FadeInOut fi = go.AddComponent<FadeInOut>();
fi.lifeCycle = lifeCycle;
//加入列表
objs.Add(go);
}
}
附上效果图,这是我用unity官网上一个小姐姐素材开发的一个小游戏。