3D游戏编程第八次作业

3D游戏编程第八次作业

  • 粒子光环
  • 运行截图
  • 具体实现

粒子光环

作业要求:

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

运行截图

3D游戏编程第八次作业_第1张图片

具体实现

本次作业比较简单, 三选一题目, 不用全部完成. 我选的是粒子光环题目, 因为实现完成后的效果比较好看. 下面就来一一进行粒子光环实现过程的分析.

首先要在Gameobject中添加Component
3D游戏编程第八次作业_第2张图片
然后新建C#脚本, 直接挂载到Gameobject上, 命名随意.
关键是脚本里面的内容, 其实关键点就几个而已, 一个是Particle System, 另外一个是粒子数组, 用来控制System中的粒子

private ParticleSystem particle_system;
private ParticleSystem.Particle[] particle_arr;

脚本声明的全部变量如下

public class ParticlePosition {
    public float radius = 0, theta = 0, target_radius = 0, animation_time = 0, speed = 0;
    public int speed_level = 0;
    public ParticlePosition(float radius, float theta, int level) {
        this.radius = radius;
        this.theta = theta;
        this.speed_level = level;
    }
}
private ParticleSystem particle_system;
private ParticleSystem.Particle[] particle_arr;
private ParticlePosition[] particle;
public int count = 20000;
public float min_radius = 5.0f;
public float max_radius = 12.0f;
public float theta_unit = Mathf.PI / (180 * 5);
public int direction = 1;
private float radius_unit = 0.008f;
private float small_min_radius = 3.0f;
private float small_max_radius = 6.0f;
private float position_now = 1;
private float time = 0;
private bool animation_start = false;

在Start中添加初始化代码, 比较简单, 用来初始化各个变量.

void Start() {
    particle_system = GetComponent(); // this particle_system
    particle_arr = new ParticleSystem.Particle[count]; // the number of particle
    particle = new ParticlePosition[count];

    particle_system.startSpeed = 0;         
    particle_system.startSize = 0.02f; // the size of particle
    particle_system.maxParticles = count; // the max count of particle
    particle_system.Emit(count); // initialize
    particle_system.GetParticles(particle_arr);
    particleInitial();
}

void particleInitial() {
    for (int i = 0; i < count; ++i) { 
        float midRadius = (max_radius + min_radius) / 2;
        float minRate = Random.Range(1.0f, midRadius / min_radius);
        float maxRate = Random.Range(midRadius / max_radius, 1.0f);
        float radius = Random.Range(min_radius * minRate, max_radius * maxRate);

        float theta = Random.Range(0.0f, 360.0f) / 180 * Mathf.PI;
        int choice = Random.Range(0, 3);
        int level = Random.Range(1, 6);
        particle[i] = new ParticlePosition(radius, theta, level);
        particle_arr[i].position = new Vector3(radius * Mathf.Cos(theta), 0f, radius * Mathf.Sin(theta));
    }
    particle_system.SetParticles(particle_arr, particle_arr.Length);
}

Update函数中则要对内外环以及外环动画进行控制. 我们的目标是内外环在不点击的情况下外环进行顺时针旋转, 内环进行逆时针旋转, 点击后从当前开始1.5s内是动画的执行时间, 不会再次接受点击事件. 所以Update函数内部主要进行旋转速度的控制(速度分为不同的等级, 以此来形成漂亮的旋转效果), 旋转方向的控制以及动画的执行效果, 代码比较容易, 在此不做过多讲解.

// Update is called once per frame
void Update() {
    if (animation_start && time < 1.5f) time += Time.deltaTime;
    if (time >= 1.5f) {
        animation_start = false;
        time = 0;
    }
    if (Input.GetMouseButtonDown(0)) {
        float temp_min_radius = 3.0f;
        float temp_max_radius = 6.0f;
        if (direction == 1 && time == 0) {
            if (position_now == 1) {
                temp_min_radius = 3.0f;
                temp_max_radius = 6.0f;
                position_now = 0;
            } else {
                temp_min_radius = min_radius;
                temp_max_radius = max_radius;
                position_now = 1;
            }
            for(int i = 0; i < count; ++i) {
                particle[i].animation_time = Random.Range(1.0f, 1.5f);
                float midRadius = (temp_max_radius + temp_min_radius) / 2;
                float minRate = Random.Range(1.0f, midRadius / temp_min_radius);
                float maxRate = Random.Range(midRadius / temp_max_radius, 1.0f);
                particle[i].target_radius = Random.Range(temp_min_radius * minRate, temp_max_radius * maxRate);
                particle[i].speed = (particle[i].radius - particle[i].target_radius) / particle[i].animation_time;
            }
        }
        animation_start = true;
    }
    for (int i = 0; i < count; i++) {
        if (direction == 1 && animation_start && particle[i].animation_time > time) {
            particle[i].radius -= particle[i].speed * Time.deltaTime;
        } else {
            if (direction == 1) particle[i].theta -= theta_unit * 0.3f * particle[i].speed_level;
            else particle[i].theta += theta_unit * 0.3f * particle[i].speed_level;
            float double_pi = Mathf.PI * 2;
            if (particle[i].theta < 0) particle[i].theta = double_pi;
            if (particle[i].theta > double_pi) particle[i].theta = 0;
        }
        particle_arr[i].position = new Vector3(particle[i].radius * Mathf.Cos(particle[i].theta), 0f, particle[i].radius * Mathf.Sin(particle[i].theta));
    }
    particle_system.SetParticles(particle_arr, particle_arr.Length);
}

你可能感兴趣的:(游戏)