鸟语天空
角色残影
post by:追风剑情 2020-12-18 17:14

参考 https://blog.csdn.net/memories_sunset/article/details/60145327?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

工程截图

11111.png

残影脚本


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 残影效果
/// </summary>
public class AfterimageEffect : MonoBehaviour
{
    //是否开启效果
    public bool enabledEffect = false;
    [SerializeField]
    private SkinnedMeshRenderer m_SkinnedMeshRenderer;
    //生成残影间隔时间
    [SerializeField]
    private float interval = 0.2f;
    //残影淡出速度
    [SerializeField]
    private float fadeOutSpeed = 1f;
    [Tooltip("是否只在移动时产生残影")]
    [SerializeField]
    private bool onlyMove = true;
    private float lastGenTime = 0;
    private Transform cacheTransform;
    private Vector3 lastPosition = Vector3.zero;

    private List<Afterimage> afterimageList = new List<Afterimage>();

    void Awake()
    {
        cacheTransform = transform;
    }

    void Update()
    {
        for (int i = afterimageList.Count-1; i >= 0; i--)
        {
            Afterimage afterimage = afterimageList[i];
            float fadeOutAlpha = Time.deltaTime * fadeOutSpeed;
            afterimage.FadeOutAlpha(fadeOutAlpha);
            if (!afterimage.lifeCycle)
                afterimageList.RemoveAt(i);
        }

        if (!enabledEffect)
            return;

        if (onlyMove)
        {
            //如果未移动,则不产生残影
            Vector3 position = cacheTransform.position;
            if (Mathf.Approximately(position.x, lastPosition.x) &&
                Mathf.Approximately(position.y, lastPosition.y) &&
                Mathf.Approximately(position.z, lastPosition.z))
                return;
            lastPosition = position;
        }

        if (Time.time - lastGenTime < interval)
            return;
        lastGenTime = Time.time;

        CreateAfterimage();
    }

    //创建快照
    public void CreateAfterimage()
    {
        Mesh mesh = new Mesh();
        m_SkinnedMeshRenderer.BakeMesh(mesh);
        GameObject go = new GameObject();
        //残影对象不显示在层级面板及场景中
        go.hideFlags = HideFlags.HideAndDontSave;
        //设置layer层
        go.layer = 8; //可选
        go.transform.position = cacheTransform.position;
        Vector3 eulerAngles = cacheTransform.rotation.eulerAngles;
        //可能其他3D软件生成的Mesh采用的坐标系与Unity不一致,需要特殊处理下
        Vector3 go_eulerAngles = new Vector3(eulerAngles.x-90, eulerAngles.z, eulerAngles.y);
        go.transform.rotation = Quaternion.Euler(go_eulerAngles);
        MeshFilter meshFilter = go.AddComponent<MeshFilter>();
        meshFilter.mesh = mesh;
        MeshRenderer meshRenderer = go.AddComponent<MeshRenderer>();
        int materialsLength = m_SkinnedMeshRenderer.materials.Length;
        meshRenderer.materials = new Material[materialsLength];
        for (int i = 0; i < materialsLength; i++)
        {
            meshRenderer.materials[i] = m_SkinnedMeshRenderer.materials[i];
            meshRenderer.materials[i].shader = Shader.Find("Sprites/Diffuse");
            Color col = new Color(0.85f, 0.43f, 0.84f, 0.2f);
            meshRenderer.materials[i].SetColor("_Color", col);
        }

        Afterimage afterimage = new Afterimage();
        afterimage.go = go;
        afterimage.meshRenderer = meshRenderer;
        afterimageList.Add(afterimage);
    }

    public class Afterimage
    {
        public GameObject go;
        public MeshRenderer meshRenderer;
        //生命周期
        public bool lifeCycle = true;

        public void FadeOutAlpha(float alpha)
        {
            for (int i = 0; i < meshRenderer.materials.Length; i++)
            {
                Color color = meshRenderer.materials[i].color;
                color.a -= alpha;
                meshRenderer.materials[i].color = color;
                if (color.a <= 0)
                   lifeCycle = false;
            }
            if (!lifeCycle)
                Destroy();
        }

        public void Destroy()
        {
            GameObject.Destroy(go);
        }
    }
}


运行效果 (这里是手动拖动角色移动,所以产生的残影间隔不一致)

222.png

3333.png

评论:
发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容