unity3d:运动残影

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/luoyikun/article/details/88579480
Shader "Custom/GhostOnly_Transparent" 
{
	Properties 
	{
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_GhostColor ("Ghost Color", Color) = (0, 1, 0, 1)
		_Pow ("Pow Factor", int) = 2
	}
	
	SubShader 
	{
		Tags { "RenderType"="Transparent" "Queue" = "Transparent"}
		LOD 200
		
		Zwrite Off
        Ztest Always
        Blend SrcAlpha One
		CGPROGRAM
		#pragma surface surf Unlit keepalpha
        
        sampler2D _MainTex;
		half4 _GhostColor;
		int _Pow;

		struct Input 
		{
		    float3 viewDir;
		    float2 uv_MainTex;
		};
		
		fixed4 LightingUnlit(SurfaceOutput s, fixed3 lightDir, fixed atten)
		 {
		     fixed4 c;
		     c.rgb = s.Albedo; 
		     c.a = s.Alpha;
		     return c;
		 }

		void surf (Input IN, inout SurfaceOutput o) 
		{
		    half4 c = tex2D (_MainTex, IN.uv_MainTex);
		    float3 worldNormal = WorldNormalVector(IN, o.Normal);
			o.Albedo = _GhostColor.rgb;
			
			half alpha = 1.0 - saturate(dot (normalize(IN.viewDir), worldNormal));
			alpha = pow(alpha, _Pow);
			o.Alpha = c.a * _GhostColor.a * alpha;
		}
		ENDCG
	} 
	FallBack "Diffuse"
}

挂载脚本到需要的残影的GameObject上

using UnityEngine;
using System.Collections;

public class GhostShadow : MonoBehaviour {
    public Color shadowColor;
    //持续时间
    public float duration = 2f;
    //创建新残影间隔
    public float interval = 0.1f;
    
    //网格数据
    SkinnedMeshRenderer[] meshRender;

    //X-ray
    Shader ghostShader;

    void Start()
    {
        //获取身上所有的Mesh
        meshRender = this.gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
        ghostShader = Shader.Find("Custom/GhostOnly_Transparent");
    }

    private float lastTime = 0;

    private Vector3 lastPos = Vector3.zero;

    void Update()
    {
        //人物有位移才创建残影
        if (lastPos == this.transform.position)
        {
            return;
        }
        lastPos = this.transform.position;
        if (Time.time - lastTime < interval)
        {//残影间隔时间
            return;
        }
        lastTime = Time.time;

        if (meshRender == null)
            return;
        for (int i = 0; i < meshRender.Length; i++)
        {
            Mesh mesh = new Mesh();
            meshRender[i].BakeMesh(mesh);

            GameObject go = new GameObject();
            go.hideFlags = HideFlags.HideAndDontSave;

            GhostItem item = go.AddComponent<GhostItem>();//控制残影消失
            item.duration = duration;
            item.deleteTime = Time.time + duration;

            MeshFilter filter = go.AddComponent<MeshFilter>();
            filter.mesh = mesh;

            MeshRenderer meshRen = go.AddComponent<MeshRenderer>();

            meshRen.material = meshRender[i].material;
            meshRen.material.shader = ghostShader;
            meshRen.material.SetInt("_Pow", -10);
            shadowColor.a = 1;
            meshRen.material.SetColor("_GhostColor", shadowColor);

            go.transform.localScale = meshRender[i].transform.localScale;
            go.transform.position = meshRender[i].transform.position;
            go.transform.rotation = meshRender[i].transform.rotation;

            item.meshRenderer = meshRen;
        }
    }
}

using UnityEngine;
using System.Collections;

public class GhostItem : MonoBehaviour {

    //持续时间
    public float duration;
    //销毁时间
    public float deleteTime;

    public MeshRenderer meshRenderer;

    void Update()
    {
        float tempTime = deleteTime - Time.time;
        if (tempTime <= 0)
        {//到时间就销毁
            GameObject.Destroy(this.gameObject);
        }
        else if (meshRenderer.material)
        {
            meshRenderer.material.SetInt("_Pow", meshRenderer.material.GetInt("_Pow") + 1);
        }

    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/luoyikun/article/details/88579480
今日推荐