3D游戏编程8--简单的粒子系统

粒子效果演示

效果演示

文件组合

文件组合

代码

ParticleHalo.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

/*
 因为做粒子效果要结合逻辑处理,所以除了简单的粒子效果,还加上了点击事件
 以及为了用协程,写了自动载入场景的功能
 顺便加了图片淡入淡出的效果,以及音效
 */

/*
 * 参考师兄代码,将此代码挂载到粒子系统上即可运行,另外需要自己设置背景之类的
 * 其中有些过期的方法,已经更正。
 */
public class ParticleHalo : MonoBehaviour {

    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;       // 时间
        }
    }

    public AudioSource darkSoulBGM;
    bool isExpand = false;
    public Image darkSoul;

    private ParticleSystem particleSysMain;  // 粒子系统
    private ParticleSystem.Particle[] particleArr;  // 粒子数组
    private CirclePosition[] circle; // 极坐标数组

    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;  // 游离范围

    private int tier = 10;  // 速度差分层数
    private float Yposition = 0f;
    // Use this for initialization
    void Start () {
        // 初始化粒子数组  
        particleArr = new ParticleSystem.Particle[count];
        circle = new CirclePosition[count];

        // 初始化粒子系统  
        particleSysMain = this.GetComponent<ParticleSystem>();
        var particleSys = particleSysMain.main;
        particleSys.startSpeed = 0;            // 粒子初始速度
        particleSys.startSize = size;          // 粒子初始大小 
        particleSys.loop = false;
        particleSys.maxParticles = count;      // 设置最大粒子量  
        particleSysMain.Emit(count);               // 发射粒子  
        particleSysMain.GetParticles(particleArr);

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

    void Update () {

        if(isExpand == true)
        {
            //这里处理了图片的淡入淡出
            Color test = darkSoul.color;
            test.a += 0.25f * Time.deltaTime;
            if (test.a > 0.5f)
            {
                test.a = 0.5f;
            }
            Yposition += Time.deltaTime;
            darkSoul.color = test;
        }

        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;

            //在这里改变半径大小就可以显示扩展效果
            if (isExpand == true)
            {
                if(circle[i].radius < 18.0f)
                {
                    circle[i].radius += Time.deltaTime * 4;
                }
            }

            // 粒子在半径方向上游离
            circle[i].time += Time.deltaTime;
            circle[i].radius += Mathf.PingPong(circle[i].time / minRadius / maxRadius, pingPong) - pingPong / 2.0f;

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

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

    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));
        }

        particleSysMain.SetParticles(particleArr, particleArr.Length);
    }
    private void OnGUI()
    {
        if(GUI.Button(new Rect(0, 0, 120, 30), "半径扩大"))
        {
            //播放BGM
            darkSoulBGM.Play();
            isExpand = true;
            //开始协程
            StartCoroutine(ReStart());
        }
        if(GUI.Button(new Rect(0, 30, 120, 30), "Reset"))
        {
            SceneManager.LoadScene("SampleScene");
        }
    }

    IEnumerator ReStart()
    {
        //七秒钟后载入SampleScene,但是颜色会变成浅黄色,感觉怪怪的
        yield return new WaitForSeconds(7.0f);
        SceneManager.LoadScene("SampleScene");
    }

}

资源

代码及视频演示

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值