3D游戏做业:粒子系统

3D游戏做业:粒子系统

本次做业基本要求是三选一(可参考之前做业)

一、简单粒子制做

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

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

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

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

粒子流编程:

本次做业参考了 博客 https://blog.csdn.net/Eddie_Peng/article/details/80490772编程

实现效果:bilibili数组

粒子流——新膨胀光球dom

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.由静态变成动态,粒子球会膨胀收缩改变大小ide

实验过程:
仿照参考资料来设计一个位置类,方便粒子位置的变化,这里我有两个角度(参考博客只有一个),一个是x-z角(从0-360°),一个是y轴角(从-180到180),根据两个角咱们能够肯定球面上惟一一点。
在这里插入图片描述
在这里插入图片描述
设定粒子系统和粒子数组,位置数组并设定好相关变量,其中必定要用变量main,不能直接用sys.main(具体为啥我也没搞懂,事实告诉我必定要用main),其中num,size为粒子数目和大小。 emit函数用来发射粒子,particals来储存这些粒子。svg

初始化位置
在这里插入图片描述
咱们随机生成两个角,而后根据这两个角求粒子坐标
x=cos(radian2)*sin(radian1)*radius
y=sin(radian2)*radius
z=cos(radian2)*cos(radian1)*radius
这里用到了空间几何的知识。函数

更新位置
在这里插入图片描述
vary变量用来记录当前是膨胀仍是收缩,每一个粒子的移动都是经过改变两个空间角实现的。oop

杂项
为了效果好看,我将天空盒设置成了黑色,而且从asset store下载了光辉粒子材质,最终实现了光球膨胀收缩的效果。
在这里插入图片描述学习