3D游戏作业:粒子系统
本次作业基本要求是三选一(可参考以前作业)
1、简单粒子制作
按参考资源要求,制作一个粒子系统,参考资源
使用 3.3 节介绍,用代码控制使之在不同场景下效果不一样
2、完善官方的“汽车尾气”模拟
使用官方资源资源 Vehicle 的 car, 使用 Smoke 粒子系统模拟启动发动、运行、故障等场景效果
3、参考 http://i-remember.fr/en 这类网站,使用粒子流编程控制制作一些效果, 如“粒子光环”
粒子流编程:
本次作业参考了 博客 https://blog.csdn.net/Eddie_Peng/article/details/80490772
实现效果:bilibili
粒子流——新膨胀光球
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Halo : MonoBehaviour {
public class Position
{
public float radius;
public float angle1;
public float angle2;
public Position(float r, float a,float b)
{
radius = r;
angle1 = a;
angle2 = b;
}
}
private ParticleSystem sys;
private ParticleSystem.Particle[] particals;
private Position[] positions;
public int num = 10000;
public float size = 0.3f;
public bool vary=true;
void Start () {
sys = this.GetComponent<ParticleSystem>();
particals = new ParticleSystem.Particle[num];
positions = new Position[num];
var main = sys.main;
main.startSpeed = 0;
main.startSize = size;
main.loop = false;
main.maxParticles = num;
sys.Emit(num);
sys.GetParticles(particals);
for (int i = 0; i < num; i++)
{
float radius=3f;
float angle1 = Random.Range(0f, 360f);
float radian1 = angle1 * 180 / Mathf.PI;
float angle2 = Random.Range(0f, 360f);
float radian2 = angle2 * 180 / Mathf.PI;
positions[i] = new Position(radius, angle1,angle2);
particals[i].position =
new Vector3(positions[i].radius * Mathf.Cos(radian2) * Mathf.Cos(radian1),
positions[i].radius * Mathf.Sin(radian2),
positions[i].radius * Mathf.Cos(radian2) * Mathf.Sin(radian1));
}
sys.SetParticles(particals, particals.Length);
}
void Update () {
if(vary==true)
{
for(int i=0;i<num;i++)
{
positions[i].radius-=0.01f;
}
if(positions[0].radius<=0.5){
vary=false;
}
}
else{
for(int i=0;i<num;i++)
{
positions[i].radius+=0.01f;
}
if(positions[0].radius>=3){
vary=true;
}
}
for (int i = 0; i < num; i++)
{
positions[i].angle1 = (positions[i].angle1 - Random.Range(0.5f,3f)) % 360f;
positions[i].angle2 = (positions[i].angle2 - Random.Range(0.5f,3f) + 180) % 360f - 180;
float radian1 = positions[i].angle1 / 180 * Mathf.PI;
float radian2 = positions[i].angle2 / 180 * Mathf.PI;
particals[i].position = new Vector3(positions[i].radius * Mathf.Cos(radian2) * Mathf.Cos(radian1),
positions[i].radius * Mathf.Sin(radian2),
positions[i].radius * Mathf.Cos(radian2) * Mathf.Sin(radian1));
}
sys.SetParticles(particals, particals.Length);
}
}
实验思路:
本次实验我选择了第三个任务,借鉴了上面的博客,原博客是实现两个粒子光环以实现黑洞的效果,我在学习其相关技巧基础上做了一些改变:1.由环变成球,从二维到三维 2.由静态变成动态,粒子球会膨胀收缩改变大小
实验过程:
仿照参考资料来设计一个位置类,方便粒子位置的变化,这里我有两个角度(参考博客只有一个),一个是x-z角(从0-360°),一个是y轴角(从-180到180),根据两个角我们可以确定球面上唯一一点。
设定粒子系统和粒子数组,位置数组并设定好相关变量,其中一定要用变量main,不能直接用sys.main(具体为啥我也没搞懂,事实告诉我一定要用main),其中num,size为粒子数目和大小。 emit函数用来发射粒子,particals来储存这些粒子。
初始化位置
我们随机生成两个角,然后根据这两个角求粒子坐标
x=cos(radian2)*sin(radian1)*radius
y=sin(radian2)*radius
z=cos(radian2)*cos(radian1)*radius
这里用到了空间几何的知识。
更新位置
vary变量用来记录当前是膨胀还是收缩,每个粒子的移动都是通过改变两个空间角实现的。
杂项
为了效果好看,我将天空盒设置成了黑色,并且从asset store下载了光辉粒子材质,最终实现了光球膨胀收缩的效果。