制作光环

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

1、简单粒子制作

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

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

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

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

  • 可参考以前作业

参考了师兄的博客https://blog.csdn.net/simba_scorpio/article/details/51251126,这些代码就不再赘述了。师兄已经讲的很清楚了。

表示感谢

 

 

同时加入了自己的一些想法,扩展了几个功能,同时加入了奥运五环的元素。

 

不过由于有了师兄的代码,我的部分实现起来就比较简单了。

view.cs 控制界面,以及环的几个运动

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class View : MonoBehaviour
{
    public GameObject go1;
    public GameObject go2;
    public GameObject go3;
    public GameObject go4;
    public GameObject go5;

    private Vector3 vgo1;
    private Vector3 vgo2;
    private Vector3 vgo3;
    private Vector3 vgo4;
    private Vector3 vgo5;

    private bool gather;
    private bool rotating;
    private bool scaling;
    // Start is called before the first frame update
    void Start()
    {
        gather = false;
        vgo1 = go1.transform.position;
        vgo2 = go2.transform.position;
        vgo3 = go3.transform.position;
        vgo4 = go4.transform.position;
        vgo5 = go5.transform.position;
    }

    // Update is called once per frame
    void Update()
    {   if (gather)
        {
            go1.transform.position = Vector3.MoveTowards(go1.transform.localPosition, new Vector3(0f, 0f, 0f), Time.deltaTime * 1);
            go2.transform.position = Vector3.MoveTowards(go2.transform.localPosition, new Vector3(0f, 0f, 0f), Time.deltaTime * 1);
            go3.transform.position = Vector3.MoveTowards(go3.transform.localPosition, new Vector3(0f, 0f, 0f), Time.deltaTime * 1);
            go4.transform.position = Vector3.MoveTowards(go4.transform.localPosition, new Vector3(0f, 0f, 0f), Time.deltaTime * 1);
            go5.transform.position = Vector3.MoveTowards(go5.transform.localPosition, new Vector3(0f, 0f, 0f), Time.deltaTime * 1);
        }
        else
        {
            go1.transform.position = Vector3.MoveTowards(go1.transform.localPosition, vgo1, Time.deltaTime * 1);
            go2.transform.position = Vector3.MoveTowards(go2.transform.localPosition, vgo2, Time.deltaTime * 1);
            go3.transform.position = Vector3.MoveTowards(go3.transform.localPosition, vgo3, Time.deltaTime * 1);
            go4.transform.position = Vector3.MoveTowards(go4.transform.localPosition, vgo4, Time.deltaTime * 1);
            go5.transform.position = Vector3.MoveTowards(go5.transform.localPosition, vgo5, Time.deltaTime * 1);
        }
    }

    void OnGUI()
    {
        //大字体初始化
        GUIStyle bigStyle = new GUIStyle();
        bigStyle.normal.textColor = Color.white;
        bigStyle.fontSize = 30;

        if (GUI.Button(new Rect(0, 0, 100, 100), "旋转", bigStyle))
        {
            UnityEngine.Debug.Log("点击旋转");
            go1.GetComponent<Rotate>().rotating = !go1.GetComponent<Rotate>().rotating;
            go2.GetComponent<Rotate>().rotating = !go2.GetComponent<Rotate>().rotating;
            go3.GetComponent<Rotate>().rotating = !go3.GetComponent<Rotate>().rotating;
            go4.GetComponent<Rotate>().rotating = !go4.GetComponent<Rotate>().rotating;
            go5.GetComponent<Rotate>().rotating = !go5.GetComponent<Rotate>().rotating;
        }

        if (GUI.Button(new Rect(200, 0, 100, 100), "伸缩", bigStyle))
        {
            UnityEngine.Debug.Log("点击伸缩");
            go1.GetComponent<ParticleHalo>().scaling = !go1.GetComponent<ParticleHalo>().scaling;
            go2.GetComponent<ParticleHalo>().scaling = !go2.GetComponent<ParticleHalo>().scaling;
            go3.GetComponent<ParticleHalo>().scaling = !go3.GetComponent<ParticleHalo>().scaling;
            go4.GetComponent<ParticleHalo>().scaling = !go4.GetComponent<ParticleHalo>().scaling;
            go5.GetComponent<ParticleHalo>().scaling = !go5.GetComponent<ParticleHalo>().scaling;
        }
        if (GUI.Button(new Rect(400, 0, 200, 100), "聚散", bigStyle)) {
            UnityEngine.Debug.Log("聚散");
            gather = !gather;
        }
    }

}

 

控制光环旋转

Rotate.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rotate : MonoBehaviour
{
    public Transform tf;
    public int speed;
    public bool rotating = false;
    // Start is called before the first frame update
    void Start()
    {
        speed = 100;
    }

    // Update is called once per frame
    void Update()
    {
       if (rotating) tf.Rotate(Vector3.forward * speed * Time.deltaTime);
    }
}

 

控制光环的生成,同时控制光环的伸缩

ParticleHaro.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


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 class ParticleHalo : MonoBehaviour
{
    public ParticleSystem particleSys;  // 粒子系统
    private ParticleSystem.Particle[] particleArr;  // 粒子数组
    private CirclePosition[] circle; // 极坐标数组

    public int count = 10000;       // 粒子数量
    public float size = 0.1f;      // 粒子大小
    public float minRadius = 5.0f;  // 最小半径
    public float maxRadius = 9.0f; // 最大半径
    public bool clockwise = true;   // 顺时针|逆时针
    public float speed = 2f;        // 速度
    public float pingPong = 0.01f;  // 游离范围
    // Start is called before the first frame update
    public Gradient colorGradient;
    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);

        // 初始化梯度颜色控制器
        GradientAlphaKey[] alphaKeys = new GradientAlphaKey[5];
        alphaKeys[0].time = 0.0f; alphaKeys[0].alpha = 1.0f;
        alphaKeys[1].time = 0.4f; alphaKeys[1].alpha = 0.4f;
        alphaKeys[2].time = 0.6f; alphaKeys[2].alpha = 1.0f;
        alphaKeys[3].time = 0.9f; alphaKeys[3].alpha = 0.4f;
        alphaKeys[4].time = 1.0f; alphaKeys[4].alpha = 0.9f;
        GradientColorKey[] colorKeys = new GradientColorKey[2];
        colorKeys[0].time = 0.0f; colorKeys[0].color = Color.white;
        colorKeys[1].time = 1.0f; colorKeys[1].color = Color.white;
        colorGradient.SetKeys(colorKeys, alphaKeys);

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

    private int tier = 10;  // 速度差分层数

    private float time = 0;
    private bool jian = false;
    public bool scaling = false;
    void Update()
    {

        if (((int)time % 18) == 0 && scaling)
        {
            jian = false; 
            UnityEngine.Debug.Log("改变2");
        } else if (((int)time % 9) == 0 && scaling)
        {
            jian = true;
            UnityEngine.Debug.Log("改变1");
        }
        //增大和缩小半径范围
        if (jian && scaling)
        {
            minRadius = minRadius - 0.01f;
            maxRadius = maxRadius - 0.01f;
            
        } else if (scaling)
        {
            minRadius = minRadius + 0.01f;
            maxRadius = maxRadius + 0.01f;
        }
        if (scaling) time = time + Time.deltaTime;


        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;

            //particleArr[i].color = colorGradient.Evaluate(circle[i].angle / 360.0f);
        }

        RandomlySpread();   // 初始化各粒子位置
        particleSys.SetParticles(particleArr, particleArr.Length);
    }
}

  

posted @ 2020-12-09 00:21  woodx  阅读(226)  评论(0)    收藏  举报