Unity3D学习(8)——粒子效果的实现

来源:互联网 发布:淘书网软件下载 编辑:程序博客网 时间:2024/05/18 15:30

-本节我们仿制参考网站的粒子效果。我们主要利用unity自带的Particle system实现。下面先展示参考的运行效果:

这里写图片描述

首先建立一个空对象halo,并且为其添加两个子对象Inner和Outer,并为这两个子对象添加粒子组件。Inner对应内环,Outer对应外环,相应的层次结构图和粒子属性设置如下:

这里写图片描述

这里写图片描述

这里写图片描述

两个组件中粒子的材质都选择默认粒子材质:

这里写图片描述

下面考虑使用代码对粒子效果进行修改。首先创建HaloParticle类,它用于记录每一个粒子的位置和时间信息:
HaloParticle.cs

using System.Collections;using System.Collections.Generic;using UnityEngine;public class HaloParticle : MonoBehaviour {    public float radius, angle, time;    public HaloParticle(float radius_, float angle_, float time_) {        radius = radius_; // 粒子的分布半径        angle = angle_; // 粒子的和水平轴成的角度,本实验中单位均为弧度        time = time_; // 时间,主要用于关联后期粒子的来回周期性运动    }}

下面考虑内外环光圈的代码实现。大体上内外环光圈的脚本代码是一样的,但它们也有少数区别需要注意到:

  1. 内环的半径相对外环要小一些,考虑分开设定两个类各自的最小半径和最大半径
  2. 内环粒子更加密集一些,而且分布上有角度的聚集性,考虑专门为内环类增加实现角度偏移的语句
  3. 内环粒子更加明晰一些,考虑适当将内环的粒子大小相对于外环调大一些

完成了上述分析,我们给出具体代码,读者可以参考注释部分进行理解。
Inner.cs

using System.Collections;using System.Collections.Generic;using UnityEngine;public class Inner : MonoBehaviour {    public ParticleSystem ps; // 粒子系统对象    private ParticleSystem.Particle[] particle_arr; // 存储粒子的仓库    private int resolution = 3000; // 最大粒子数    private HaloParticle[] hp; // 存储每一个粒子位置信息的数组    // 内环的粒子总体分布半径要小一些    private float min_radius = 2F;    private float max_radius = 4F;    private float pingPong = 0.01F; // 粒子在来回运动的时候的游离范围    void Start() {        ps = this.GetComponent<ParticleSystem>();        particle_arr = new ParticleSystem.Particle[resolution];        hp = new HaloParticle[resolution];        ps.Emit(resolution);        ps.GetParticles(particle_arr);        // 初始化各个粒子的位置        for (int i = 0; i < resolution; i++) {            // 使得粒子集中在平均半径处            float shiftMinRadius = Random.Range(1, (min_radius + max_radius) / (2 * min_radius));            float shiftMaxRadius = Random.Range((min_radius + max_radius) / (2 * max_radius), 1);            //粒子角度,添加一个偏移量,使粒子集中于π/4和5π/4处              float shiftMinAngle = Random.Range(1, 1.5f);            float shiftMaxAngle = Random.Range(0.75f, 1);            // 粒子的角度为[0, 2π], 按照平面直角坐标系的参数方程进行设定            float angle = Random.Range(Mathf.PI * shiftMinAngle, Mathf.PI * 2 * shiftMaxAngle) - Mathf.PI / 4;            if (Random.Range(0, 100) > 50) angle -= Mathf.PI;            float radius = Random.Range(min_radius * shiftMinRadius, max_radius * shiftMaxRadius);            float time = Random.Range(0.0f, 360.0f);            hp[i] = new HaloParticle(radius, angle, time);            particle_arr[i].position = new Vector3(radius * Mathf.Cos(angle), radius * Mathf.Sin(angle), 0);        }        ps.SetParticles(particle_arr, particle_arr.Length);    }    void Update() {        for (int i = 0; i < resolution; i++) {            // 使粒子旋转            hp[i].angle -= Random.Range(0, 1F / 360);            particle_arr[i].position = new Vector3(hp[i].radius * Mathf.Cos(hp[i].angle), hp[i].radius * Mathf.Sin(hp[i].angle), 0);            // 调整粒子上下浮动            hp[i].time += Time.deltaTime;            hp[i].radius += Mathf.PingPong(hp[i].time / min_radius / max_radius, pingPong) - pingPong / 2.0f;        }        ps.SetParticles(particle_arr, particle_arr.Length);    }}

Outer.cs

using System.Collections;using System.Collections.Generic;using UnityEngine;public class Outer : MonoBehaviour {    public ParticleSystem ps; // 粒子系统对象    private ParticleSystem.Particle[] particle_arr; // 存储粒子的仓库    private int resolution = 3000;    private HaloParticle[] hp; // 存储每一个粒子信息的数组    // 外环的粒子总体分布半径要大一些    private float min_radius = 2.5F;    private float max_radius = 5F;    private float pingPong = 0.01F; // 粒子在来回运动的时候的游离范围    void Start () {        ps = this.GetComponent<ParticleSystem>();        particle_arr = new ParticleSystem.Particle[resolution];        hp = new HaloParticle[resolution];        ps.Emit(resolution);        ps.GetParticles(particle_arr);        // 初始化各个粒子的位置        for (int i = 0; i < resolution; i++) {            // 使得粒子集中在平均半径处            float shiftMinRadius = Random.Range(1, (min_radius + max_radius) / (2*min_radius));            float shiftMaxRadius = Random.Range((min_radius + max_radius) / (2*max_radius), 1);            float radius = Random.Range(min_radius * shiftMinRadius, max_radius * shiftMaxRadius);            // 粒子的角度为[0, 2π], 按照平面直角坐标系的参数方程进行设定            float angle = Random.Range(0, 2 * Mathf.PI);             float time = Random.Range(0.0f, 360.0f);            hp[i] = new HaloParticle(radius, angle, time);            particle_arr[i].position = new Vector3(radius * Mathf.Cos(angle), radius * Mathf.Sin(angle), 0);        }        ps.SetParticles(particle_arr, particle_arr.Length);    }    void Update () {        for (int i = 0; i < resolution; i++) {            // 使粒子旋转            hp[i].angle -= Random.Range(0, 1F / 360);            particle_arr[i].position = new Vector3(hp[i].radius * Mathf.Cos(hp[i].angle), hp[i].radius * Mathf.Sin(hp[i].angle), 0);            // 调整上下浮动            hp[i].time += Time.deltaTime;            hp[i].radius += Mathf.PingPong(hp[i].time / min_radius / max_radius, pingPong) - pingPong / 2.0f;        }        ps.SetParticles(particle_arr, particle_arr.Length);    }}
0 0
原创粉丝点击