残影实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 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官网上一个小姐姐素材开发的一个小游戏。这里写图片描述

猜你喜欢

转载自blog.csdn.net/memories_sunset/article/details/60145327