糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > 14.Unity2D 横版 粒子系统特效 飙血粒子+高处落地粒子+对象池管理所有粒子

14.Unity2D 横版 粒子系统特效 飙血粒子+高处落地粒子+对象池管理所有粒子

时间:2020-12-05 20:13:24

相关推荐

14.Unity2D 横版 粒子系统特效 飙血粒子+高处落地粒子+对象池管理所有粒子

主目录/qq_54263076/category_11900070.html?spm=1001..3001.5482

粒子系统常用属性介绍

开始

1.制作飙血粒子预制体

(1)创建 右键->效果->粒子系统物体,并重命名为bloodEffect

(2)各种参数的调整,使得粒子特效相似飙血粒子

完成效果,突然爆发+血液缓慢变淡+地形碰撞

(3)拖到文件夹里面形成预制体

(4)将粒子生成加入到角色脚本受伤函数里面

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;public class CharacterPanel : MonoBehaviour{public bool Iscanjump = false;//是否能跳跃,默认不能public float Hpmax = 100;//最大生命public float Hp = 100;//生命public float Atk = 10;//攻击力public float AtkRan = 1;//攻击浮动public float Def = 10;//防御力public float lookdir;//获取初始Scale.x,用于转向 public float dropConst = 15;//下坠常数public float speed = 10;//地面移动速度public float jumpspeedUp = 20;//上升速度public float jumpspeedVertiacal = 0.5f;//空中左右移动速度private Rigidbody2D rig;//2D刚体private Animator ani;private Transform Canvas;//获取角色个人UI面板// Start is called before the first frame updatevoid Start(){Canvas = transform.Find("Canvas");ani = transform.GetComponent<Animator>();rig = GetComponent<Rigidbody2D>();//获取刚体}// Update is called once per framevoid FixedUpdate(){lookdir = transform.localScale.x;check();//跳跃优化手感Quickjump();//检测卡地面脱离OutLockGround();}//标准化检查private void check(){if (Hp > Hpmax) Hp = Hpmax;//血量不超过上限if (Hp <= 0) { Hp = 0;death(); };//血量不超过下限,且死亡}//受伤,其他脚本调用public void hurt(float atk){float hurtnum= (20 * atk / (20 + Def)) + Random.Range(-AtkRan, AtkRan);//受伤动画 为什么要将触发器中的受伤动画移动在角色面板的hurt函数下?因为受伤不仅有角色攻击受伤,还有陷阱,掉落等伤害,所以直接血量减少时播放受伤动画更加好transform.GetComponent<Animator>().SetBool("Ishurt", true);StartCoroutine(endHurt());//开启协程结束受伤动画//伤害数值显示Canvas.GetComponent<CharaCanvas>().ShowHurtText(hurtnum);Hp -= hurtnum;//受伤粒子生成Instantiate(GameObject.Find("bloodEffect"),new Vector3(transform.position.x, transform.position.y, transform.position.z),new Quaternion(0,0,0,0));}IEnumerator endHurt(){yield return 0;//此处暂停,下一帧执行transform.GetComponent<Animator>().SetBool("Ishurt", false);}//死亡private void death(){ani.SetBool("Isdeath",true);}//跳跃public void jump(){if (Iscanjump == true){rig.velocity = new Vector2(0, jumpspeedUp);//设置刚体速度,给予向量}}//优化跳跃手感,迅速下落,放入帧频率更新函数里面public void Quickjump(){float a = dropConst * 5 - Mathf.Abs(rig.velocity.y);//通过下坠常数,空中速度快为0时,下坠常数a越大,即越快速 度过这个状态rig.velocity -= Vector2.up * a * Time.deltaTime;}//卡住地面脱离public void OutLockGround(){RaycastHit2D hit = Physics2D.Raycast(transform.position, new Vector2(0, -1),0.5f, LayerMask.GetMask("tilemap"));if (hit){if (pareTag("ground"))//检测到地面{transform.Translate(new Vector3(0, 1, 0));}Debug.DrawRay(transform.position, new Vector2(0, -1), Color.blue);}}//以下是敌人的调运行为函数,主角有自己的控制脚本//转向public void Turndir(){transform.localScale = new Vector3(-lookdir, transform.localScale.y, transform.localScale.z);//通过改变scale改变方向}//移动public void move(){if (lookdir == 0) lookdir =0.001f;//预防除零问题弹错Vector3 vt = new Vector3(lookdir/Mathf.Abs(lookdir), 0, 0);//空中左右移动,为地面jumpcharacterPanel.speedVertiacal倍if (Iscanjump == false){gameObject.transform.Translate(jumpspeedVertiacal * speed * Time.deltaTime * vt);//通过这个函数来使用vt使得左右移动}//地面左右移动else { gameObject.transform.Translate(speed * Time.deltaTime * vt); }ani.SetBool("Ismove", true);}//等待public void idle(){ani.SetBool("Ismove", false);}}

注意:

注意:可以选择粒子板块“停止行动”中的“销毁”来自动销毁粒子物体,会使得面板上没有粒子效果

Gameobject.Find()函数是查找面板上存在且激活的物体。如果粒子效果物体面板上没有或者未激活状态,可以通过修改脚本,增加Gameobject变量然后拖动形成粒子预制体参数

(5)效果展示

2.制作高处落地粒子

(1)创建 右键->效果->粒子系统物体,并重命名为dropEffect

(2)各种参数的调整,使得粒子特效相似高处落地粒子

(3)拖到文件夹里面形成预制体

(4)将粒子生成加入到落地检测的函数里面

我将此代码放在了跳跃判断脚本里面,当然根据自己的情况可以放在自己的例如射线检测或者其他脚本里面

using System.Collections;using System.Collections.Generic;using UnityEngine;public class IsJump : MonoBehaviour{//为了优化跳跃碰撞盒,在父物体下面新建空对象bottoom,并添加碰撞盒,用来检测底部(以前碰撞盒头碰到顶部地面还能跳不符合常理,所以需要作此操作)private CharacterPanel characterPanel;//代码优化,将是否能跳跃的检测从原脚本CharacterControl的公共成员变量IscanJump移动到player和enemy共有的脚本CharacterPanel下//将原脚本下的局部变量IscanJump,改成transform.GetComponent<CharacterPanel>().Iscanjumpprivate float befConV;//碰撞前一刻速度public float partDropV=30;//掉落粒子显示的最小速度// Start is called before the first frame updatevoid Start(){characterPanel = transform.GetComponentInParent<CharacterPanel>();}// Update is called once per framevoid Update(){befConV = GetComponentInParent<Rigidbody2D>().velocity.magnitude;}private void OnTriggerEnter2D(Collider2D collision){//掉落粒子生成if (befConV>partDropV)Instantiate(GameObject.Find("dropEffect"), new Vector3(transform.position.x, transform.position.y, transform.position.z), new Quaternion(0, 0, 0, 0));}//检测否在地面碰撞盒子检测,通过给地面碰撞盒子transform的tag标签为groundprivate void OnTriggerStay2D(Collider2D collision){if (collision.transform.tag != "untagged" && collision.transform.tag != "notAtkCheckCollision"&& characterPanel.Iscanjump == false){characterPanel.Iscanjump = true;//获取父物体脚本变量并赋值}}private void OnTriggerExit2D(Collider2D collision){if (collision.transform.tag != "untagged"&& collision.transform.tag != "notAtkCheckCollision" && characterPanel.Iscanjump == true){characterPanel.Iscanjump = false;//获取父物体脚本变量并赋值}}}

(5)效果展示

高级一些,方便一些

1.建立粒子统一管理器空对象,将生成的粒子统一作为它的子物体

(1)建立空对象,并命名为粒子管理器ParticalManager

(2)粒子管理器脚本,加入到粒子管理器的空对象ParticalManager中,并拖动填入粒子对象参数

using System.Collections;using System.Collections.Generic;using UnityEngine;public class particalmanager : MonoBehaviour{public GameObject[] particals;//粒子组}

2.利用对象池机制,避免频繁的创建,销毁。导致运行卡顿

注意右边面板粒子对象池的激活与非激活

回顾5.Unity2D 横版 对象池的创建_ζั͡ ั͡雾 ั͡狼 ั͡✾的博客-CSDN博客Unity2D 横版 对象池的创建。对象池的好处是不用频繁的毁坏和创建重复预制体,而是通过激活与非激活来对重复预制体进行管理。增加了游戏的流畅性。/qq_54263076/article/details/125667394?spm=1001..3001.5501

(1)关闭自动销毁,设置“停止行动”为“禁用“”

(2)对象池Pool脚本 (未更改)

using System.Collections;using System.Collections.Generic;using UnityEngine;public class Pool : MonoBehaviour{//集合public List<GameObject> list = new List<GameObject>();//游戏预设体public GameObject GoPrefab;//最大个数public int MaxCount = 50;//对象保存对象池public void Push(GameObject go){if (list.Count < MaxCount){list.Add(go);//改为非激活go.SetActive(false);}else {Destroy(go);}}//对象池中取出对象public GameObject Pop() {if (list.Count > 0) {GameObject go = list[0];list.RemoveAt(0);//如果对象池里的对象是敌人if (go.tag == "enemy"){go.GetComponent<CharacterPanel>().Hp = go.GetComponent<CharacterPanel>().Hpmax;}//设置为激活状态go.SetActive(true);return go;}return Instantiate(GoPrefab);}//清除对象池public void Clear(){list.Clear();}}

(2)粒子管器particalmanager脚本扩展

using System.Collections;using System.Collections.Generic;using UnityEngine;public class particalmanager : MonoBehaviour{private List<Pool> partPool=new List<Pool>();//粒子组对象池public GameObject[] particals;//粒子组/* 0-血液粒子* 1-高处掉落粒子*/void Start(){//对象池初始化for (int i = 0; i < particals.Length; i++){Pool p = new Pool();p.GoPrefab = particals[i];//将每个对象池的对象改成粒子对象partPool.Add(p);}Debug.Log(partPool.Count);}//粒子保存对象池中public void Pushpart( GameObject part) {int i= partPool.FindIndex(x=>x.GoPrefab.name==part.name||((x.GoPrefab.name+"(Clone)")==part.name));//i为找到的对象池下标if (i != -1){partPool[i].Push(part);Debug.Log(partPool[i].list.Count + " " + partPool[i].list[partPool[i].list.Count-1].name);}}//粒子取出对象池中public GameObject Poppart(int i) //i为对象池下标{GameObject part=partPool[i].Pop();//对象池取出Debug.Log(part.name+" pop");return part;}}

(3)CharacterPanel脚本更新血液粒子效果

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;public class CharacterPanel : MonoBehaviour{public bool Iscanjump = false;//是否能跳跃,默认不能public float Hpmax = 100;//最大生命public float Hp = 100;//生命public float Atk = 10;//攻击力public float AtkRan = 1;//攻击浮动public float Def = 10;//防御力public float lookdir;//获取初始Scale.x,用于转向 public float dropConst = 15;//下坠常数public float speed = 10;//地面移动速度public float jumpspeedUp = 20;//上升速度public float jumpspeedVertiacal = 0.5f;//空中左右移动速度private Rigidbody2D rig;//2D刚体private Animator ani;private Transform Canvas;//获取角色个人UI面板private GameObject pm;//获取粒子管理器// Start is called before the first frame updatevoid Start(){Canvas = transform.Find("Canvas");ani = transform.GetComponent<Animator>();rig = GetComponent<Rigidbody2D>();//获取刚体pm = GameObject.Find("ParticalManager");}// Update is called once per framevoid FixedUpdate(){lookdir = transform.localScale.x;check();//跳跃优化手感Quickjump();//检测卡地面脱离OutLockGround();}//标准化检查private void check(){if (Hp > Hpmax) Hp = Hpmax;//血量不超过上限if (Hp <= 0) { Hp = 0;death(); };//血量不超过下限,且死亡}//受伤,其他脚本调用public void hurt(float atk){float hurtnum= (20 * atk / (20 + Def)) + Random.Range(-AtkRan, AtkRan);//受伤动画 为什么要将触发器中的受伤动画移动在角色面板的hurt函数下?因为受伤不仅有角色攻击受伤,还有陷阱,掉落等伤害,所以直接血量减少时播放受伤动画更加好transform.GetComponent<Animator>().SetBool("Ishurt", true);StartCoroutine(endHurt());//开启协程结束受伤动画//伤害数值显示Canvas.GetComponent<CharaCanvas>().ShowHurtText(hurtnum);Hp -= hurtnum;//受伤粒子生成,不需要对存活粒子进行管理,就不用创建存活粒子集合了GameObject bloodeffect = pm.GetComponent<particalmanager>().Poppart(0);bloodeffect.transform.position = transform.position;//设置位置bloodeffect.transform.parent = pm.transform;//设置父物体}IEnumerator endHurt(){yield return 0;//此处暂停,下一帧执行transform.GetComponent<Animator>().SetBool("Ishurt", false);}//死亡private void death(){ani.SetBool("Isdeath",true);}//跳跃public void jump(){if (Iscanjump == true){rig.velocity = new Vector2(0, jumpspeedUp);//设置刚体速度,给予向量}}//优化跳跃手感,迅速下落,放入帧频率更新函数里面public void Quickjump(){float a = dropConst * 5 - Mathf.Abs(rig.velocity.y);//通过下坠常数,空中速度快为0时,下坠常数a越大,即越快速 度过这个状态rig.velocity -= Vector2.up * a * Time.deltaTime;}//卡住地面脱离public void OutLockGround(){RaycastHit2D hit = Physics2D.Raycast(transform.position, new Vector2(0, -1),0.5f, LayerMask.GetMask("tilemap"));if (hit){if (pareTag("ground"))//检测到地面{transform.Translate(new Vector3(0, 1, 0));}Debug.DrawRay(transform.position, new Vector2(0, -1), Color.blue);}}//以下是敌人的调运行为函数,主角有自己的控制脚本//转向public void Turndir(){transform.localScale = new Vector3(-lookdir, transform.localScale.y, transform.localScale.z);//通过改变scale改变方向}//移动public void move(){if (lookdir == 0) lookdir =0.001f;//预防除零问题弹错Vector3 vt = new Vector3(lookdir/Mathf.Abs(lookdir), 0, 0);//空中左右移动,为地面jumpcharacterPanel.speedVertiacal倍if (Iscanjump == false){gameObject.transform.Translate(jumpspeedVertiacal * speed * Time.deltaTime * vt);//通过这个函数来使用vt使得左右移动}//地面左右移动else { gameObject.transform.Translate(speed * Time.deltaTime * vt); }ani.SetBool("Ismove", true);}//等待public void idle(){ani.SetBool("Ismove", false);}}

(4)跳跃判断IsJump脚本扩展高处掉落粒子

using System.Collections;using System.Collections.Generic;using UnityEngine;public class IsJump : MonoBehaviour{//为了优化跳跃碰撞盒,在父物体下面新建空对象bottoom,并添加碰撞盒,用来检测底部(以前碰撞盒头碰到顶部地面还能跳不符合常理,所以需要作此操作)private CharacterPanel characterPanel;//代码优化,将是否能跳跃的检测从原脚本CharacterControl的公共成员变量IscanJump移动到player和enemy共有的脚本CharacterPanel下//将原脚本下的局部变量IscanJump,改成transform.GetComponent<CharacterPanel>().Iscanjumpprivate float befConV;//碰撞前一刻速度public float partDropV=30;//掉落粒子显示的最小速度private GameObject pm;//获取粒子管理器// Start is called before the first frame updatevoid Start(){characterPanel = transform.GetComponentInParent<CharacterPanel>();pm = GameObject.Find("ParticalManager");}// Update is called once per framevoid Update(){befConV = GetComponentInParent<Rigidbody2D>().velocity.magnitude;}private void OnTriggerEnter2D(Collider2D collision){//掉落粒子生成if (befConV > partDropV){GameObject dropeffect = pm.GetComponent<particalmanager>().Poppart(1);dropeffect.transform.position = transform.position;dropeffect.transform.parent = pm.transform;}}//检测否在地面碰撞盒子检测,通过给地面碰撞盒子transform的tag标签为groundprivate void OnTriggerStay2D(Collider2D collision){if (collision.transform.tag != "untagged" && collision.transform.tag != "notAtkCheckCollision"&& characterPanel.Iscanjump == false){characterPanel.Iscanjump = true;//获取父物体脚本变量并赋值}}private void OnTriggerExit2D(Collider2D collision){if (collision.transform.tag != "untagged"&& collision.transform.tag != "notAtkCheckCollision" && characterPanel.Iscanjump == true){characterPanel.Iscanjump = false;//获取父物体脚本变量并赋值}}}

如果觉得《14.Unity2D 横版 粒子系统特效 飙血粒子+高处落地粒子+对象池管理所有粒子》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。