残影实现:
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 }
效果:
时间: 2024-10-14 19:07:40