以下使用Unity2017.4.10 + VS2017
================================================================================================== 角色资源包为Asset Store -> Unity Chan的角色包,接下来我们会使用这个Modle来进行操作
为了方便查看,我们首先进入FaceUpdate 这个脚本,把OnGUI全部注释,
================================================================================================ 首先,我们来了解一下什么是网格:网格其实就是一堆顶点,按照不同的连接方式所组成大小,旋转各不相同的三角面,而将这些三角面组合在一起,我们才可以看到各种各样的模型,而网格在Unity中的组件名称为 MeshRenderer
而在我们做出动画的时候,网格是在不断改变绘制的,所以,我们可以在代码中保存动画特定帧数的网格数据,将其渲染到一个空物体上,之后我们动态生成的网格材质随时间渐变为透明。
================================================================================================
public class SkinMeshT : MonoBehaviour
{
// 定义一个蒙皮网格数组,蒙皮网格继承自MeshRenderer的
private SkinnedMeshRenderer[] skinMesh;
void Start()
{
// 通过Unity自带的方法 递归获取物体及其子物体上的网格实例
skinMesh = transform.GetComponentsInChildren();
}
void Update()
{
// 这个很长的语句是 UnityChanControlScriptWithRgidBody 里面的轴控制
IsRunning = (transform.parent.GetComponent().h == 0 ? false : true) || (transform.parent.GetComponent().v == 0 ? false : true) ? true : false;
if (IsRunning)
{
Plays();
}
}
}
/////
private void Plays()
{
for (int i = 0; i < skinMesh.Length; i++)
{
Mesh mesh = new Mesh();
skinMesh[i].BakeMesh(mesh); // 烘焙网格数据到我们创建的空Mesh中
GameObject t = new GameObject();
MeshFilter mesh_ = t.AddComponent();
MeshRenderer meshRenderer = t.AddComponent();
t.hideFlags = HideFlags.HideAndDontSave; // 我们创建的GameObject不会显示在Hierarchy面板上
meshRenderer.material = skinMesh[i].material; // 给与材质
t.AddComponent(); // 这个是随时间消失 下面会介绍到
mesh_.mesh = mesh;
t.transform.position = skinMesh[i].transform.position; // 使网格坐标和旋转对其
t.transform.rotation = skinMesh[i].transform.rotation;
}
}
/////
class DesT:MonoBehaviour{
private float timer, rate = 0.50f;
void Update()
{
timer += Time.deltaTime;
if (timer > rate)
{
Destroy(this.gameobject);
}
}
}
这样,当你把SkinMeshT挂载到UnityChan下面时,运行就会出现残影了,但是看一下我们上面的代码,貌似在IsRunning为True时,我们每帧需要都需要创建很多东西啊,所以,在着手写个对象池
SkinMeshT全部代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SkinMeshT : MonoBehaviour
{
private SkinnedMeshRenderer[] skinMesh;
void Start()
{
skinMesh = transform.GetComponentsInChildren();
}
bool IsRunning = false;
public float timer, rate = 0.3f;
void Update()
{
IsRunning = (transform.parent.GetComponent().h == 0 ? false : true) || (transform.parent.GetComponent().v == 0 ? false : true) ? true : false;
if (IsRunning)
{
timer += Time.deltaTime;
if (timer > rate)
{
timer = 0;
Plays();
}
}
else
{
timer = 0.3f;
}
}
private void Plays()
{
for (int i = 0; i < skinMesh.Length; i++)
{
Mesh mesh = new Mesh();
skinMesh[i].BakeMesh(mesh);
GameObject t = ObjPool.Instance.TackOut("SkinMesh");
MeshFilter mesh_ = null;
MeshRenderer meshRenderer = null;
if (t == null)
{
t = new GameObject();
t.hideFlags = HideFlags.HideAndDontSave;
mesh_ = t.AddComponent();
meshRenderer = t.AddComponent();
meshRenderer.material = skinMesh[i].material;
t.AddComponent();
}
else
{
t.SetActive(true);
mesh_ = t.GetComponent();
}
mesh_.mesh = mesh;
t.transform.position = skinMesh[i].transform.position;
t.transform.rotation = skinMesh[i].transform.rotation;
}
}
}
public class ObjPool
{
private Dictionary> pool;
private static ObjPool instance;
public static ObjPool Instance
{
get
{
if (instance == null)
instance = new ObjPool();
return instance;
}
}
private ObjPool()
{
pool = new Dictionary>();
}
public void Add(string name, GameObject o)
{
if (pool.ContainsKey(name))
{
pool[name].Add(o);
return;
}
pool.Add(name, new List());
pool[name].Add(o);
}
public GameObject TackOut(string name)
{
GameObject o = null;
if (!pool.ContainsKey(name))
{
pool.Add(name, new List());
return o;
}
if (pool[name].Count == 0)
{
return o;
}
o = pool[name][0];
pool[name].RemoveAt(0);
return o;
}
}
---------------------------------------------------------------销毁(压入对象池)的全部代码----------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DesT : MonoBehaviour
{
private float alphaValue = 150;
void Start()
{
}
private void OnEnable()
{
GetComponent().material.shader = Shader.Find("First Fantasy/Water/Water Diffuse");
GetComponent().material.SetFloat("_IsPlay", 1);
GetComponent().material.SetColor("_MainTexColor", new Color(1, 0, 0, alphaValue / 255));
GetComponent().material.SetFloat("_MainTexMultiply", 3.21f);
gameObject.layer = LayerMask.NameToLayer("Temp");
alphaValue = 150;
timer = 0;
GetComponent().material.SetTexture("_MainTex", Resources.Load("Mask"));
}
private float timer, rate = 0.50f;
void Update()
{
timer += Time.deltaTime;
alphaValue -= Time.deltaTime * 300;
GetComponent().material.SetColor("_MainTexColor", new Color(1, 0, 0, alphaValue/ 255));
if (timer > rate)
{
GetComponent().material.SetFloat("_MainTexMultiply", 0);
GetComponent().material.SetColor("_MainTexColor", new Color(0, 0, 0, 0));
gameObject.SetActive(false);
ObjPool.Instance.Add("SkinMesh",this.gameObject);
return;
}
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Shader代码如下,(PS:这个Shader忘记是从哪个包里面找到的了,我魔改了一下,加了个Alpha和UV流转控制)
Shader "First Fantasy/Water/Water Diffuse" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_MainTexColor ("Diffuse", Color) = (1,1,1,0.55)
_MainTexMultiply ("Multiply", Range(0,5)) = 1
_MainTexMoveSpeedU ("U Move Speed", Range(-10,10)) = 0.5
_MainTexMoveSpeedV ("V Move Speed", Range(-10,10)) = 0.5
_IsPlay("Is Play A",Range(0,1)) = 0
_LightStrength("Light Strength",Range(-1,1)) = 0
}
SubShader {
Tags {"IgnoreProjector"="True" "Queue"="Transparent"}
ZWrite Off
Alphatest Greater 0
Blend SrcAlpha OneMinusSrcAlpha
LOD 200
CGPROGRAM
#pragma surface surf Lambert alpha
sampler2D _MainTex;
fixed4 _MainTexColor;
fixed _MainTexMultiply;
fixed _MainTexMoveSpeedU;
fixed _MainTexMoveSpeedV;
float _IsPlay;
float _LightStrength;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed2 MainTexMoveScrolledUV = IN.uv_MainTex;
fixed MainTexMoveU = _MainTexMoveSpeedU * _Time * _IsPlay;
fixed MainTexMoveV = _MainTexMoveSpeedV * _Time * _IsPlay;
MainTexMoveScrolledUV += fixed2(MainTexMoveU, MainTexMoveV);
half4 c = tex2D (_MainTex, MainTexMoveScrolledUV);
o.Albedo = c.rgb * _MainTexColor * _MainTexMultiply + _LightStrength;
o.Alpha = _MainTexColor.a;
}
ENDCG
}
FallBack "Diffuse"
}
其实Shader的话,Unity自带的Diffuse有Fade,所以应该也可以使用(PS:我没有实验)
效果如下,:
参考Blog : https://blog.csdn.net/x__dream/article/details/50571427
全部资源包下载:https://download.csdn.net/download/mikulingsss/10671859