• Unity3D制作粒子系统


    任务

    阅读 “Unity制作神奇的粒子海洋!”。 

    http://www.manew.com/thread-47123-1-1.html

    参考 http://i-remember.fr/en 制作类似该网站效果。

    效果

    网站上的效果如下:

    可以看出就是里面一层粒子,和外面一层粒子以不同的速率向相反方向转动,下面为我制作出来的简单效果:

    制作过程

    新建粒子系统并设置

    新建一个粒子系统并且按照以下进行设置:

    编写代码

    首先创建粒子数组初始化,并且建立一个存储粒子属性的类:

     1 public class particleClass
     2     {
     3         public float radiu = 0.0f;
     4         public float angle = 0.0f;
     5         public particleClass(float radiu_, float angle_)
     6         {
     7             radiu = radiu_;
     8             angle = angle_;
     9         }
    10     }
    11 
    12     //创建粒子系统,粒子数组,粒子数目,声明粒子环的半径
    13     public ParticleSystem particleSystem;
    14     private ParticleSystem.Particle[] particlesArray;
    15     private particleClass[] particleAttr; //粒子属性数组
    16     public int particleNum = 10000;
    17     public float minRadius = 5.0f;
    18     public float maxRadius = 10.0f;
    19     public int Part = 2;
    20     public float speed = 0.1f;

    由于需要使得每一个粒子能够产生不同的轨迹,而不是全部在一个圆的边缘线上,因此需要随机产生半径

    同时粒子需要分散在各个部分,因此还需要随机产生角度

    粒子的角度和半径,便决定了它的位置,上面的粒子属性类保存的便是其角度与半径;

    但是如果观察仔细可以发现,网站上的粒子系统是粒子中间多,两边少的,也就是有点向中间聚集的,因此使用下面的方式来实现:

    1 // 随机产生每个粒子距离中心的半径,同时粒子要集中在平均半径附近  
    2             float midRadius = (maxRadius + minRadius) / 2;
    3             float minRate = Random.Range(1.0f, midRadius / minRadius);
    4             float maxRate = Random.Range(midRadius / maxRadius, 1.0f);
    5             float randomRadius = Random.Range(minRadius * minRate, maxRadius * maxRate);

    然后便是让粒子动起来,这个只需要在Update函数中让粒子分为两部分运动,一部分顺时针一部分逆时针,其中只需要修改粒子的角度即可;

     1     void Update()
     2     {
     3         //设置为两部分的粒子,一部分顺时针,一部分逆时针。
     4         for (int i = 0; i < particleNum; i++)
     5         {
     6             if (i % 2 == 0) particleAttr[i].angle += (i % Part + 1) * speed;
     7             else particleAttr[i].angle -= (i % Part + 1) * speed;
     8 
     9             //根据新的角度重新设置位置
    10             particleAttr[i].angle = particleAttr[i].angle % 360;
    11             float rad = particleAttr[i].angle / 180 * Mathf.PI;
    12             particlesArray[i].position = new Vector3(particleAttr[i].radiu * Mathf.Cos(rad), particleAttr[i].radiu * Mathf.Sin(rad), 0f);
    13         }
    14         particleSystem.SetParticles(particlesArray, particleNum);
    15     }

    这样,这个粒子系统就完成了,最终效果就出来啦~!还是很酷炫的!

    所有代码提供如下:

     1 using UnityEngine;
     2 using System.Collections;
     3 
     4 public class ParticleRotate : MonoBehaviour
     5 {
     6     public class particleClass
     7     {
     8         public float radiu = 0.0f;
     9         public float angle = 0.0f;
    10         public particleClass(float radiu_, float angle_)
    11         {
    12             radiu = radiu_;
    13             angle = angle_;
    14         }
    15     }
    16 
    17     //创建粒子系统,粒子数组,粒子数目,声明粒子环的半径
    18     public ParticleSystem particleSystem;
    19     private ParticleSystem.Particle[] particlesArray;
    20     private particleClass[] particleAttr; //粒子属性数组
    21     public int particleNum = 10000;
    22     public float minRadius = 5.0f;
    23     public float maxRadius = 10.0f;
    24     public int Part = 2;
    25     public float speed = 0.1f;
    26 
    27     void Start()
    28     {
    29         particleAttr = new particleClass[particleNum];
    30         particlesArray = new ParticleSystem.Particle[particleNum];
    31         particleSystem.maxParticles = particleNum;
    32         particleSystem.Emit(particleNum);
    33         particleSystem.GetParticles(particlesArray);
    34         for (int i = 0; i < particleNum; i++)
    35         {   //相应初始化操作,为每个粒子设置半径,角度
    36             //产生一个随机角度
    37             float randomAngle = Random.Range(0.0f, 360.0f);
    38 
    39             // 随机产生每个粒子距离中心的半径,同时粒子要集中在平均半径附近  
    40             float midRadius = (maxRadius + minRadius) / 2;
    41             float minRate = Random.Range(1.0f, midRadius / minRadius);
    42             float maxRate = Random.Range(midRadius / maxRadius, 1.0f);
    43             float randomRadius = Random.Range(minRadius * minRate, maxRadius * maxRate);
    44 
    45             //粒子属性设置
    46             particleAttr[i] = new particleClass(randomRadius, randomAngle);
    47             particlesArray[i].position = new Vector3(randomRadius * Mathf.Cos(randomAngle), randomRadius * Mathf.Sin(randomAngle), 0.0f);
    48         }
    49         //设置粒子
    50         particleSystem.SetParticles(particlesArray, particleNum);
    51     }
    52 
    53 
    54     void Update()
    55     {
    56         //设置为两部分的粒子,一部分顺时针,一部分逆时针。
    57         for (int i = 0; i < particleNum; i++)
    58         {
    59             if (i % 2 == 0) particleAttr[i].angle += (i % Part + 1) * speed;
    60             else particleAttr[i].angle -= (i % Part + 1) * speed;
    61 
    62             //根据新的角度重新设置位置
    63             particleAttr[i].angle = particleAttr[i].angle % 360;
    64             float rad = particleAttr[i].angle / 180 * Mathf.PI;
    65             particlesArray[i].position = new Vector3(particleAttr[i].radiu * Mathf.Cos(rad), particleAttr[i].radiu * Mathf.Sin(rad), 0f);
    66         }
    67         particleSystem.SetParticles(particlesArray, particleNum);
    68     }
    69 }

    总结

    感觉粒子系统能够做出很漂亮的东西啊,真的是增加界面效果,动作效果的神器,第一次打开I Remember的时候真的是被美到了,什么时候自己能够做到这样就好了。

  • 相关阅读:
    show proceslist时发现大量的sleep,有什么风险吗,该如何处理?
    监控MySQL的性能,应该主要观察那几个监控项?
    MySQL所有的压力都在一个CPU核心上,为什么会产生这种现象,改如何解决?
    大表,某列无索引,先需要查询该列,删除符合条件的记录,大约占40%数据量,请问有何更好的方案吗?
    MySQL DBA运维中那些动作属于危险性操作?
    云环境上自建MySQL,有哪些高可用实现方案?
    RDS上,MySQL实例中某张表数据小于tmp_table_size,但有查询时会报错临时空间满 The table '/data/mysql/zst/tmp/#sql_13975_23' is full. 原因可能是什么?
    MySQL误删除frm文件该怎么办?
    生产环境MySQL死锁如何监控及如何减少死锁发生的概率。
    MongoDB有哪些优秀特性及适合的场景是什么?
  • 原文地址:https://www.cnblogs.com/iamxiaoyubei/p/6828744.html
Copyright © 2020-2023  润新知