Unity运动残影技能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity运动残影技能相关的知识,希望对你有一定的参考价值。

  残影实现:

    1、List<DrawMesh> list,此list中包含某一帧动画模型网格、材质

    2、每过一段时间就将运动物体的模型add到list中(优化:未实现,网格合并)

    3、LateUpdate里将list中所有模型材质alpha减少,为0,则remove;其余的模型 DrawMesh

  技能实现:

    技能为两部分,前一部分是运动残影,后一部分是落地爆炸,协程处理即可。

ps

 此例简单实现了这个技能,不过应该能够做的更好一些,就是给运动物体添加状态:空中、即将落地,需要维护这两个状态,并且需要用射线处理将爆炸粒子放在合适的位置play

 

代码:

技术分享
  1 using UnityEngine;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 
  5 class DrawMesh
  6 {
  7     public Mesh mesh;
  8     public Matrix4x4 matrix;
  9     public Material material;
 10     public DrawMesh(Mesh me, Matrix4x4 ma, Material mat, Color color)
 11     {
 12         this.mesh = me;
 13         this.matrix = ma;
 14         this.material = new Material(mat);
 15         this.material.shader = Shader.Find("Transparent/VertexLit");
 16         this.material.SetColor("_Emission", color);
 17     }
 18 }
 19 
 20 public class Skill4 : MonoBehaviour
 21 {
 22     private SkinnedMeshRenderer[] render;
 23     
 24     
 25     public float forwardPower;//移动速度
 26     public float jumpPower;//跳跃速度
 27     private bool isStart;//残影是否开始
 28 
 29     public float Skill4ContinueTime;//残影过程总时间
 30     private float time;
 31     public float fadeSpeed;//残影渐变消失速率
 32 
 33     public float rate;//绘制残影速率
 34     public Color color;//残影颜色
 35     private List<DrawMesh> list;//残影list
 36 
 37     public ParticleSystem particle;//结束爆炸粒子
 38     private Vector3 particlePosition;//粒子初始位置,粒子挂在玩家身上
 39 
 40 
 41     void Awake()
 42     {
 43         render = GetComponentsInChildren<SkinnedMeshRenderer>();
 44         list = new List<DrawMesh>();
 45         isStart = false;
 46         time = 0;
 47         particlePosition = particle.transform.localPosition;
 48     }
 49 
 50     void Update()
 51     {
 52         if (Input.GetKeyDown(KeyCode.H))
 53         {
 54             UseSkill();
 55         }
 56     }
 57 
 58     public void UseSkill()
 59     {
 60         playerCS.CrossFade("Attack3Anim", 0f);
 61         isStart = true;
 62         time = 0;
 63         StartCoroutine(IEStartSkill());
 64     }
 65 
 66     private IEnumerator IEStartSkill()
 67     {
 68         rigidbody.velocity = rigidbody.velocity + Vector3.up * jumpPower;//跳跃速度
 69         while (isStart)
 70         {
 71             for (int i = 0; i < render.Length; i++)
 72             {
 73                 Mesh mesh = new Mesh();
 74                 render[i].BakeMesh(mesh);
 75                 list.Add(new DrawMesh(mesh, render[i].transform.localToWorldMatrix, render[i].material, color));
 76             }
 77             yield return new WaitForSeconds(rate);
 78         }
 79     }
 80 
 81     void FixedUpdate()
 82     {
 83         if (isStart)
 84         {
 85             if (time < Skill4ContinueTime)//残影过程中
 86             {
 87                 time += Time.deltaTime;
 88                 rigidbody.velocity = transform.TransformDirection(Vector3.forward * forwardPower) + Vector3.up * rigidbody.velocity.y;
 89             }
 90             else//残影过程结束  进入爆炸过程
 91             {
 92                 isStart = false;
 93                 rigidbody.velocity = Vector3.up*rigidbody.velocity.y;
 94                 playerCS.CrossFade("IdleAnim", 1f);
 95                 StartCoroutine(IEBoom());
 96             }
 97         }
 98     }
 99 
100     IEnumerator IEBoom()
101     {
102         particle.transform.parent = null;
103 
104         particle.gameObject.SetActive(true);
105         particle.Play();
106         yield return new WaitForSeconds(particle.duration); //爆炸过程结束
107         particle.gameObject.SetActive(false);
108         particle.transform.parent = transform;
109         particle.transform.localPosition = particlePosition;
110     }
111 
112     void LateUpdate()
113     {
114         for (int i = list.Count - 1; i >= 0; i--)
115         {
116             list[i].material.SetColor("_Color", new Color(color.r, color.g, color.b, list[i].material.color.a - Time.deltaTime * fadeSpeed));
117             if (list[i].material.color.a <= 0.05f)
118             {
119                 Destroy(list[i].material);//重要,如果不destroy显存占用越来越多
120                 Destroy(list[i].mesh);
121                 list.RemoveAt(i);
122             }
123         }
124         for (int i = list.Count - 1; i >= 0; i--)
125         {
126             Graphics.DrawMesh(list[i].mesh, list[i].matrix, list[i].material, gameObject.layer);
127         }
128     }
129 }
View Code

效果:

技术分享

以上是关于Unity运动残影技能的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D实战之残影技术

Unity编程Unity动画系统

小松教你手游开发unity实用技能控制摄像头脚本

unity 如何让物体匀加速和匀减速运动,求代码

[Wind] LCM 残影问题分析

Unity FPS 运动