unity3d学习---粒子光环

摘要:粒子是粒子系统管理的基本单位。一般它是材料(Material)。材料包含两个内容,纹理(texture)、shader,分别负责形态、光照效果、两个方面。通常,粒子系统包含基础材料库供用户选择。粒子系统是模拟一些不确定、流动现象的技术。它采用许多形状简单且赋予生命的微小粒子作为基本元素来表示物体(一般由点或很小的多边形通过纹理贴图表示),表达物体的总体形态和特征的动态变化。如雨雪风云等现象。

本周作业:

本次作业基本要求是三选一

1、简单粒子制作

  • 按参考资源要求,制作一个粒子系统,参考资源
  • 使用 3.3 节介绍,用代码控制使之在不同场景下效果不一样

2、完善官方的“汽车尾气”模拟

  • 使用官方资源资源 Vehicle 的 car, 使用 Smoke 粒子系统模拟启动发动、运行、故障等场景效果

3、参考 http://i-remember.fr/en 这类网站,使用粒子流编程控制制作一些效果, 如“粒子光环”

  • 可参考以前作业

而且可以注意到unity已经给了我们一些标准的粒子系统,如果我们发现有近似可用的可以直接导入修改一下使用。其中导入标准粒子资源的方法:从菜单 Assets -> Import Package -> Particles 导入系统提供的粒子资源

这次完成的作业主要是参考师兄以前的作业实现了粒子流编程控制制作一些效果,并且增加了光束和闪光爆炸圈的一点小效果。其中大概设想的效果静态图如下所示:

          

这是gif图,还是使用编程来控制粒子最外两圈光环的效果,增加了从中心向四周散射光线的效果和普通光圈效果。


其中最外两层的关关主要是http://i-remember.fr/en 的效果。

实现思路:

观察效果发现光环由两层顺时针转动的环组成 

如下图,黑色圆环层粒子分布比较疏松范围广,红色圆环层密集而且有两个对称的缺口,并且红色顺时针转动速度较快 (其实下面那层黄色的粒子也真的好好看)


1.我们要首先定义新的结构CirclePosition,用来记录每个粒子的当前半径、角度和时间,其中时间是做游离运动需要的。

public class CirclePosition  
{  
    public float radius = 0f, angle = 0f, time = 0f;  
    public CirclePosition(float radius, float angle, float time)  
    {  
        this.radius = radius;   // 半径  
        this.angle = angle;     // 角度  
        this.time = time;       // 时间  
    }  
}

2.声明变量:粒子系统和粒子的活动的一些系数。声明ParticleHalo的私有变量,粒子系统和粒子是必须的,CirclePosition对应每个粒子,因此也是必须的。

    private ParticleSystem particleSys;  // 粒子系统  
    private ParticleSystem.Particle[] particleArr;  // 粒子数组  
    private CirclePosition[] circle; // 极坐标数组  
    private int tier = 10;  // 速度差分层数  
    //粒子的一些活动系数
    public int count = 10000;       // 粒子数量  
    public float size = 0.03f;      // 粒子大小  
    public float minRadius = 5.0f;  // 最小半径  
    public float maxRadius = 12.0f; // 最大半径  
    public bool clockwise = true;   // 顺时针|逆时针  
    public float speed = 2f;        // 速度  
    public float pingPong = 0.02f;  // 游离范围  

3.初始化设置,粒子活动由编程控制,所以记得要把粒子的初始速度设置为0。

    void Start () {
        // 初始化粒子数组  
        particleArr = new ParticleSystem.Particle[count];
        circle = new CirclePosition[count];

        // 初始化粒子系统  
        particleSys = this.GetComponent<ParticleSystem>();
        particleSys.startSpeed = 0;            // 粒子位置由程序控制  
        particleSys.startSize = size;          // 设置粒子大小  
        particleSys.loop = false;
        particleSys.maxParticles = count;      // 设置最大粒子量  
        particleSys.Emit(count);               // 发射粒子  
        particleSys.GetParticles(particleArr);

        RandomlySpread();   // 初始化各粒子位置  
    }

 4. RandomlySpread将所有的粒子随机分布在圆圈轨道上。

    void RandomlySpread()
    {
        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;

            // 随机每个粒子的游离起始时间  
            float time = Random.Range(0.0f, 360.0f);

            circle[i] = new CirclePosition(radius, angle, time);

            particleArr[i].position = new Vector3(circle[i].radius * Mathf.Cos(theta), 0f, circle[i].radius * Mathf.Sin(theta));
        }

        particleSys.SetParticles(particleArr, particleArr.Length);
    }

5.差分层实现粒子运动效果的多样性,并且引入pingppong函数来加强粒子效果(这一部分使用了Sin,Cos和PingPong等函数,最好先了解一下)。

	void Update () {
        for (int i = 0; i < count; i++)
        {
            if (clockwise)  // 顺时针旋转  
                circle[i].angle -= (i % tier + 1) * (speed / circle[i].radius / tier);
            else            // 逆时针旋转  
                circle[i].angle += (i % tier + 1) * (speed / circle[i].radius / tier);

            // 保证angle在0~360度  
            circle[i].angle = (360.0f + circle[i].angle) % 360.0f;
            float theta = circle[i].angle / 180 * Mathf.PI;

            particleArr[i].position = new Vector3(circle[i].radius * Mathf.Cos(theta), 0f, circle[i].radius * Mathf.Sin(theta));

            circle[i].time += Time.deltaTime;
            circle[i].radius += Mathf.PingPong(circle[i].time / minRadius / maxRadius, pingPong) - pingPong / 2.0f;
        }

        particleSys.SetParticles(particleArr, particleArr.Length);
    }

6.上面基本实现了我们的编程控制粒子光环,现在是来增加一些颜色,材质,光线等一些效果,达到上面我们想要实现的效果:

(1)其中inner表示内层的粒子光环,金黄色部分,guang是从中心向四周发射的光线,Ring是普通光环,outer是外层紫色光环。其中inner和outer粒子编程控制。

金黄的粒子光圈参数设置:


材质选择的是FireCloud,本身就是金黄色,蛮好看的。注意设置效果时间以及looping

(2)外层紫色光环设置大致相同,只是增加了一个颜色控制还有改变了粒子运动光环的半径大小还有粒子数目。但切记给这两个光环挂上我们的代码文本。

(3)光线的设置

               

                             也就是这样的一个效果。

首先自己做一个粒子材质,等一下挂在Renderer那里,具体做法:create material ->选择shader Particles/Additive ->选择合适的图片实现效果




(4)普通光圈的设置,大同小异,就是修改参数,每个人都可以实现自己想要的效果。


心得体会:这一块很有趣,参数一变效果就有很大差异,也是自己琢磨了好久尝试了好多种粒子光环,师兄的代码真的非常棒,效果也很好。粒子流编程控制可以加强。

最后:师兄的博客链接:师兄博客

视屏演示链接:视屏链接

猜你喜欢

转载自blog.csdn.net/tangyt77/article/details/80481010