Unity3d Study Notes (9)--Particle halo

Source: Internet
Author: User
Tags cos emit

Refer to the halo effect on home page: http://i-remember.fr/en

Use Unity to make a similar Halo: (Back to the Advanced effect Oh ~)


You can observe that the halo has a minimum radius and a maximum radius, and that the middle part of the halo has more particles than the edge. Sharp-eyed can be found that the halo has at least 2 layers, the outer ring clockwise rotation, the inner ring counterclockwise rotation. In addition, each particle will wander, not in a straight circle.

That's how I designed it:

1. All particle motion is controlled by the program.

2. Use the parametric equation x = cos (t), y = sin (t) to calculate the particle position, where t is the angle.

3. Use the Pingpong function to let the particles wander in the radius direction.


Step One

Create a new empty object, rename it to Particlehalo, and then create a new empty sub-object underneath it and rename it to Clockwise_outer.


Select the child object and add the component->effects->particle System.


Step Two

Create a new C # script named Particlehalo.

Using unityengine;using system.collections;public class particlehalo:monobehaviour{    void Start ()    {    }    void Update ()    {    }}

Step Three

Define a new structure circleposition, which is used to record the current radius, angle and time of each particle, where time is required for free motion.

public class circleposition{Public    float radius = 0f, angle = 0f, time = 0f;    Public circleposition (float radius, float angle, float time)    {        This.radius = radius;   Radius        this.angle = angle;     Angle        this.time = time;       Time    }}
Declaring Particlehalo's private variables, particle systems and particles is a must, and circleposition corresponds to each particle and is therefore necessary.

    Private Particlesystem Particlesys;  Particle system    private particlesystem.particle[] Particlearr;  Particle array    private circleposition[] circle;//Polar array
Second, the number of particles, particle size, rotation of the maximum minimum radius, etc. also have to have.

    public int count = 10000;       Number of particles public    float size = 0.03f;      Particle size public    float Minradius = 5.0f;  Min. radius public    Float Maxradius = 12.0f;//maximum RADIUS public    bool clockwise = true;   Clockwise | counterclockwise public    FLOAT speed = 2f;        Speed public    float pingpong = 0.02f;  Free Range
Particlehalo need to set the parameters of the particle emitter at the beginning, because the motion of the particles is all implemented by the program, so remember to set the initial velocity of the particles to 0.

    void Start ()    {   //Initialize particle array        Particlearr = new Particlesystem.particle[count];        Circle = new Circleposition[count];        Initializes the particle system        Particlesys = this. Getcomponent<particlesystem> ();        particlesys.startspeed = 0;            Particle position by program control        particlesys.startsize = size;          Set particle size        Particlesys.loop = false;        Particlesys.maxparticles = count;      Sets the maximum particle amount        particlesys.emit (count);               Emission particles        particlesys.getparticles (particlearr);        Randomlyspread ();   Initialize each particle position    }

The Randomlyspread randomly distributes all the particles in the circle orbit.

 void Randomlyspread () {for (int i = 0; i < count; ++i) {//random radius of each particle from center, and hope that the particles are centered around the average radius flo            At 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);            Random angle of each particle float angle = random.range (0.0f, 360.0f);            Float theta = angle/180 * MATHF.PI;            Random start time of each particle randomly float = 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); }
OK, the script is mounted on the closkwise_outer, at this point you can try to run, the success of the words will appear such a picture:


Step Four

Well, how do we get the particles to spin? The simple idea is to gradually change the angle of the particles in the update function:

    void Update ()    {for        (int i = 0; i < count; i++)        {            if (clockwise)  //Clockwise rotation                circle[i].angle-= 0 .1f;            else            //counterclockwise rotation                circle[i].angle + = 0.1f;            Guaranteed angle in 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)); c14/>}        particlesys.setparticles (Particlearr, particlearr.length);    }
Run a bit, and you'll soon find out, a little fake! Especially when the particles are bigger and more obvious.

Yes, that's because we're adding the same increment for each particle angle, so it looks like a picture is spinning, not every particle moving.

To solve this problem, I let the particle angle increment not all the same, you need to add a differential layered variable tier:

    private int tier = ten;  Speed difference layered number    void Update ()    {for        (int i = 0; i < count; i++)        {            if (clockwise)  //clockwise rotation                Circle [I].angle-= (i% tier + 1) * (speed/circle[i].radius/tier);            else            //counterclockwise rotation                circle[i].angle + = (i% tier + 1) * (speed/circle[i].radius/tier);            Guaranteed angle in 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)); c16/>}        particlesys.setparticles (Particlearr, particlearr.length);    }
With this differential layered variable, all particles are divided into 10 camps, each with a different angle increment. I've also added a factor, which is associated with the radius of the particle, so that the smaller the angular increment of the particles farther away from the center, the slower the rotation. With this change, run again and find that the particle movement is less rigid.


Step five now the particles can be rotated, but still feel a bit rigid, why? The original is because the particles only in the angle of the change of the distinction, in the direction of the radius is still very uniform. Is there any way to make the radius of a particle move within the allowable range of fluctuations? Fortunately, Unity's MATHF class provides method Pingpong. Pingpong as the name suggests is the meaning of table tennis, table tennis is moving back and forth, so the pingpong function is to make the value in the range of changes, using the method specific reference API.

Add the following program to the Update method:

            The particles are upstream from            circle[i].time + = Time.deltatime in the radius direction;            Circle[i].radius + = Mathf.pingpong (Circle[i].time/minradius/maxradius, pingpong)-pingpong/2.0f;
and see if the effect is better:


Step Six

Now the particles are almost independent movement, the movement is no problem, the next is the light effect. How does the light effect manifest? Transparency is a good way to do this. You can use the gradient class with transparency. Add a new private variable to the Particlehalo class and initialize the gradient object in start.

    Public Gradient colorgradient;        void Start () {//Initialize particle array Particlearr = new Particlesystem.particle[count];        Circle = new Circleposition[count]; Initializes the particle system Particlesys = this.        Getcomponent<particlesystem> ();            particlesys.startspeed = 0;          Particle position by program control particlesys.startsize = size;        Set particle size Particlesys.loop = false;      Particlesys.maxparticles = count;               Sets the maximum particle amount particlesys.emit (count);        Emission particles particlesys.getparticles (Particlearr);        Initialize gradient color Controller 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 (); Initialize each particle position}
The particle's transparency is then changed in the update based on the particle's angle.

    Particlearr[i].color = Colorgradient.evaluate (circle[i].angle/360.0f);

Post-run Effects:


Step seven The last step, we only do the outer ring, inner ring and outer ring script is the same, just need to adjust the parameters. First, go back to the object hierarchy tree and create a new empty object under Particlehalo, named Anticlockwise_inner. Also add scripts ParticleHalo.cs and particle systems addcomponent->effects->particle system.


The inner ring is rotated counterclockwise, so the clockwise hook is removed, and the parameters are modified until the effect is satisfactory. In fact, you can also add a clockwise inner ring to make the circle more visible.




Advanced

Unity's own particles are not too much to force, such as not bright enough! Not glowing! When the particles are small, it becomes very dark, I believe you have found. There are two choices, either write shader yourself or use a third-party plugin. I used third-party plug-ins to Glow11 the current level and time limit, as mentioned in the section on making the solar system.

First import the GLOW11 plug-in, Assets->import Package->custom PACKAGE->GLOW11.

Add the GLOW11 component to main camera (found, actually the glow effect is generated on the camera), modify the particle system material particle system->render->material-> Default-material.


Now look at how it works:


Flash blind ... It was too bright and not very good ... Still like the hazy beauty.


Unity3d Study Notes (9)--Particle halo

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.