unity3D制作粒子

参考网站首页的光环效果:http://i-remember.fr/en
用unity3d的粒子系统做一个粒子光环
向上效果图
这里写图片描述

可以看到该粒子效果由两部分组成,一部分是粒子光环,另一部分是粒子海洋

设计方法:

    粒子的运动由程序来控制
    光环的粒子使用cos,sin以及圆环半径来确定位置
    粒子海洋中的粒子运动使用柏林噪声来控制
步骤一

新建一个空对象(ParticleHalo),在空对象下载新建两个空对象(Ring, SeaParticle),两个空对象都添加上粒子系统
这里写图片描述

步骤二

新建脚本RingParticle来控制光环中的粒子的运动

public class RingParticle : MonoBehaviour{
    void Start(){}
    void Update(){}
}

为RingParticle添加一些必要的参数

private ParticleSystem ps; //粒子系统(必须)
private ParticleSystem.Particle[] particles; //粒子系统中的粒子(必须)
public int count = 1000; //粒子数量
public float size = 0.3f; //粒子大小,非必须,可在inspector视图中的粒子系统中设置
public float maxRadius = 12f;//圆环的最大半径
public float minRadius = 5f;//圆谎的最小半径
public Gradient gradient; //用来给粒子添加颜色特效
private float[] radiuses; //粒子的半径
private float[] angles; //粒子的角度

在start函数中初始化粒子

    void Start()
    {
        particles = new ParticleSystem.Particle[count];
        radiuses = new float[count];
        angles = new float[count];
        ps = GetComponent<ParticleSystem>();
        ps.maxParticles = count; //设置粒子的数目
        ps.loop = false;//让粒子不循环播放
        ps.startSpeed = 0; //设置粒子的速度
        ps.startSize = size; //设置粒子的数量
        ps.Emit(count); //发射粒子
        ps.GetParticles(particles);
        for (int i = 0; i < count; ++i)
        {   // 随机每个粒子距离中心的半径,同时希望粒子集中在平均半径附近  
            float midRadius = (maxRadius + minRadius) / 2;
            float minRate = Random.Range(1.0f, midRadius / minRadius);
            float maxRate = Random.Range(midRadius / maxRadius, 1.0f);
            float radius = Random.Range(minRadius * minRate, maxRadius * maxRate);

            // 随机每个粒子的角度  
            float angle = Random.Range(0.0f, 360.0f);
            float theta = angle / 180 * Mathf.PI;
            radiuses[i] = radius;
            angles[i] = angle;
            particles[i].position = new Vector3(radius * Mathf.Cos(theta), radius * Mathf.Sin(theta), 0);
        }
        ps.SetParticles(particles, particles.Length);
    }

完成后运行,大致效果
这里写图片描述
在update函数中是粒子运动起来

void Update () {
        for (int i = 0; i < count; ++i)
        {   
            //将粒子的旋转速度分成10个不同的速度,让不同的粒子有不同的速度
            angles[i] -= (i / 100 + 1) / radiuses[i] * Random.Range(1, 3);
            angles[i] = (360.0f + angles[i]) % 360.0f;

            float theta = angles[i] / 180 * Mathf.PI;
            //让粒子的半径在一定范围内波动,产生有利效果
            radiuses[i] += Random.Range(-0.01f, 0.01f);
            particles[i].position = new Vector3(radiuses[i] * Mathf.Cos(theta), radiuses[i] * Mathf.Sin(theta), 0);
            //给粒子加上颜色特效
            particles[i].color = gradient.Evaluate(0.5f);

        }
        ps.SetParticles(particles, particles.Length);
    }

在inspector视图中设置gradient
这里写图片描述
再次运行,就可以看到旋转的粒子光环了

制作粒子海洋

可先参考博文unity制作神奇的粒子海洋
新建SeaPaticle脚本控制粒子运动

public class SeaParticle : MonoBehaviour 

给脚本添加必要的参数

 public ParticleSystem particleSystem;
    private ParticleSystem.Particle[] particlesArray;
    public Gradient colorGradient; //粒子的眼神特效
    public int seaResolution = 50; //每行粒子的数目
    public float spacing = 0.5f;//粒子之间的间隔
    public float noiseScale = 0.2f; //
    public float heightScale = 3f;
    public float noiseX;
    public float noiseY;

初始化粒子

void Start () {
        particleSystem = GetComponent<ParticleSystem>();
        particleSystem.loop = false;
        particlesArray = new ParticleSystem.Particle[seaResolution * seaResolution];
        particleSystem.maxParticles = seaResolution * seaResolution;
        particleSystem.Emit(seaResolution * seaResolution);
        particleSystem.GetParticles(particlesArray);
        for (int i = 0; i < seaResolution; i++)
        {
            for (int j = 0; j < seaResolution; j++)
            {

                float zPos = Mathf.PerlinNoise(i * noiseScale, j * noiseScale) * heightScale;
                particlesArray[i * seaResolution + j].position = new Vector3(i * spacing, zPos, j * spacing);
            }
        }
        particleSystem.SetParticles(particlesArray, particlesArray.Length);
    }

让粒子运动起来

void Update () {
      for (int i = 0; i < seaResolution; i++)
        {
            for (int j = 0; j < seaResolution; j++)
            {

                float zPos = Mathf.PerlinNoise(i * noiseScale + noiseX, j * noiseScale + noiseY);
                //让粒子在x、z方向上波动
                float r = Random.Range(5, 10);
                particlesArray[i * seaResolution + j].color = colorGradient.Evaluate(zPos);

                //重新设置x,y的原因是为了让粒子波动起来
                particlesArray[i * seaResolution + j].position = new Vector3((i + zPos * r) * spacing, zPos * heightScale, (j + zPos * r)* spacing);
            }
        }
        particleSystem.SetParticles(particlesArray, particlesArray.Length);
        noiseX += Time.deltaTime;
        noiseY += Time.deltaTime;
    }

在inspector视图中调整参数,让粒子海洋的运动符合我们的要求
这里写图片描述
最后的静态效果

完整代码:

RingParticle

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Particle : MonoBehaviour {
    private ParticleSystem ps; //粒子系统(必须)
    private ParticleSystem.Particle[] particles; //粒子系统中的粒子(必须)
    public int count = 1000; //粒子数量
    public float size = 0.3f; //粒子大小,非必须,可在inspector视图中的粒子系统中设置
    public float maxRadius = 12f;//圆环的最大半径
    public float minRadius = 5f;//圆谎的最小半径
    public Gradient gradient; //用来给粒子添加颜色特效
    private float[] radiuses; //粒子的半径
    private float[] angles; //粒子的角度
    // Use this for initialization
    void Start()
    {
        particles = new ParticleSystem.Particle[count];
        radiuses = new float[count];
        angles = new float[count];
        ps = GetComponent<ParticleSystem>();
        ps.maxParticles = count; //设置粒子的数目
        ps.loop = false;//让粒子不循环播放
        ps.startSpeed = 0; //设置粒子的速度
        ps.startSize = size; //设置粒子的数量
        ps.Emit(count); //发射粒子
        ps.GetParticles(particles);
        for (int i = 0; i < count; ++i)
        {   // 随机每个粒子距离中心的半径,同时希望粒子集中在平均半径附近  
            float midRadius = (maxRadius + minRadius) / 2;
            float minRate = Random.Range(1.0f, midRadius / minRadius);
            float maxRate = Random.Range(midRadius / maxRadius, 1.0f);
            float radius = Random.Range(minRadius * minRate, maxRadius * maxRate);

            // 随机每个粒子的角度  
            float angle = Random.Range(0.0f, 360.0f);
            float theta = angle / 180 * Mathf.PI;
            radiuses[i] = radius;
            angles[i] = angle;
            particles[i].position = new Vector3(radius * Mathf.Cos(theta), radius * Mathf.Sin(theta), 0);
        }
        ps.SetParticles(particles, particles.Length);
    }
    // Update is called once per frame
    void Update () {
        for (int i = 0; i < count; ++i)
        {   
            //将粒子的旋转速度分成10个不同的速度,让不同的粒子有不同的速度
            angles[i] -= (i / 100 + 1) / radiuses[i] * Random.Range(1, 3);
            angles[i] = (360.0f + angles[i]) % 360.0f;

            float theta = angles[i] / 180 * Mathf.PI;
            //让粒子的半径在一定范围内波动,产生有利效果
            radiuses[i] += Random.Range(-0.01f, 0.01f);
            particles[i].position = new Vector3(radiuses[i] * Mathf.Cos(theta), radiuses[i] * Mathf.Sin(theta), 0);
            //给粒子加上颜色特效
            particles[i].color = gradient.Evaluate(0.5f);

        }
        ps.SetParticles(particles, particles.Length);
    }
}

SeaParticel

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SeaParticle : MonoBehaviour {
    public ParticleSystem particleSystem;
    private ParticleSystem.Particle[] particlesArray;
    public Gradient colorGradient;
    public int seaResolution = 50; //每行粒子的数目
    public float spacing = 0.5f;//粒子之间的间隔
    public float noiseScale = 0.2f; //
    public float heightScale = 3f;
    public float noiseX;
    public float noiseY;
    // Use this for initialization
    void Start () {
        particleSystem = GetComponent<ParticleSystem>();
        particleSystem.loop = false;
        particlesArray = new ParticleSystem.Particle[seaResolution * seaResolution];
        particleSystem.maxParticles = seaResolution * seaResolution;
        particleSystem.Emit(seaResolution * seaResolution);
        particleSystem.GetParticles(particlesArray);
        for (int i = 0; i < seaResolution; i++)
        {
            for (int j = 0; j < seaResolution; j++)
            {

                float zPos = Mathf.PerlinNoise(i * noiseScale, j * noiseScale) * heightScale;
                particlesArray[i * seaResolution + j].position = new Vector3(i * spacing, zPos, j * spacing);
            }
        }
        particleSystem.SetParticles(particlesArray, particlesArray.Length);
    }

    // Update is called once per frame
    void Update () {
      for (int i = 0; i < seaResolution; i++)
        {
            for (int j = 0; j < seaResolution; j++)
            {

                float zPos = Mathf.PerlinNoise(i * noiseScale + noiseX, j * noiseScale + noiseY);
                //让粒子在x、z方向上波动
                float r = Random.Range(5, 10);
                particlesArray[i * seaResolution + j].color = colorGradient.Evaluate(zPos);

                //重新设置x,y的原因是为了让粒子波动起来
                particlesArray[i * seaResolution + j].position = new Vector3((i + zPos * r) * spacing, zPos * heightScale, (j + zPos * r)* spacing);
            }
        }
        particleSystem.SetParticles(particlesArray, particlesArray.Length);
        noiseX += Time.deltaTime;
        noiseY += Time.deltaTime;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36297981/article/details/80495404