- Home /
expanding ring velocity (ellipsoid particle emitter)
Hello! I add Ellipsoid particle emitter to my explosion, but it expanding not so fast how i want it. I already try change all values in inspector, but no one cant't change expanding ring velocity, it only allow change direction my ring.
Maybe anyone know some oter way how can i get it?
Unfortunately, the one variable that is not accessable through script is the Ellipsoid variable. This is a major pain! Try playing around with the Size Grow and Force settings in the particle animator.
The solution (though it will take longer to code) is most probably use a mesh emitter. If you are stuck I can look into making a ring mesh that can be expanded.
It's bad( Yes, i would be very glad, if you can write script ring mesh expanded, if it is not difficult for you of course))
I have submitted my answer ($$anonymous$$ $$anonymous$$ay)
Answer by AlucardJay · Jan 07, 2013 at 08:40 AM
Writing an expanding ring mesh script actually turned out to be a big project ! There is alot of technical stuff in here, if you are not familiar with procedural meshes, then it probably won't make much sense. Here's what you have to work with :
public var radiusBegin : float = 0.1;
public var radiusEnd : float = 5.0;
public var expandTime : float = 5.0;
public var ringWidth : float = 0.2;
public var segments : int = 60;
all that should be self-explanitory, start and finish radius, the time to take between the 2. Segments is how many points in the ring eg 12 would be like the numbers on a clock, 60 should be plenty of points to emit from.
EDIT :
now you can instantiate, the script will start as soon as it exists, and destroy itself at the end (after the particles have faded) :
// ring mesh emitter by Jason Kowalin (Jay Kay, alucardj) Jan 8th 2013
#pragma strict
public var radiusBegin : float = 0.1;
public var radiusEnd : float = 5.0;
public var expandTime : float = 5.0;
public var ringWidth : float = 0.2;
public var segments : int = 60;
private var theEmitter : ParticleEmitter;
private var isExpanding : boolean = false;
private var eTimer : float = 0.0;
private var eStep : float = 0.0;
function Start()
{
theEmitter = GetComponent( ParticleEmitter );
theEmitter.emit = false; // start with no particles emitted
StartMesh(); // build the ring
// - start ring from instantiation -
theEmitter.emit = true; // start emitting particles
isExpanding = true; // start expanding
eTimer = 0.0; // set timer to zero
eStep = ( radiusEnd - radiusBegin ) / expandTime; // calculate step for expanding ring
radiusInner = radiusBegin; // set the start radius
}
function Update()
{
if ( isExpanding )
{
ExpandRing();
}
}
function ExpandRing()
{
eTimer += Time.deltaTime; // update timer
if ( eTimer > expandTime ) // check if ring has finished expanding
{
isExpanding = false; // stop expanding
theEmitter.emit = false; // stop emitting
yield WaitForSeconds( theEmitter.maxEnergy + 0.5 ); // wait for last particles to fade
Destroy( gameObject );
}
// -- shouldn't have to change any of this code --
// update vertices
radiusInner += eStep * Time.deltaTime;
radiusOuter = radiusInner + ringWidth;
for (var i : int = 0; i < (segments + 1); i ++)
{
vertsInner[ i ] = new Vector3( posX[i], 0.0, posY[i] ) * radiusInner; // horizontal ring
vertsOuter[ i ] = new Vector3( posX[i], 0.0, posY[i] ) * radiusOuter;
}
vertsInner[ segments ] = vertsInner[0];
vertsOuter[ segments ] = vertsOuter[0];
verts = new Vector3[ ( segments + 1 ) * 2 ];
for (i = 0; i < segments + 1; i ++ )
{
verts[i] = vertsOuter[i];
verts[ i + segments + 1 ] = vertsInner[i];
}
mesh.vertices = verts;
// --
}
// ---- Don't change anything past this line !! ----
private var calcAngle : float;
private var posX : float[];
private var posY : float[];
private var radiusInner : float = 0.1;
private var radiusOuter : float = 2.0;
private var vertsInner : Vector3[];
private var vertsOuter : Vector3[];
private var mesh : Mesh;
private var uv : Vector2[];
private var verts : Vector3[];
private var tris : int[];
function StartMesh()
{
if ( !mesh )
{
mesh = new Mesh();
GetComponent(MeshFilter).mesh = mesh;
mesh.name = "ParticleMesh";
}
Construct();
}
function Construct()
{
var i : int = 0;
// ----
calcAngle = 0;
posX = new float[segments + 1];
posY = new float[segments + 1];
// Calculate Circle on X-Y
for (i = 0; i < segments + 1; i ++)
{
posX[i] = Mathf.Sin( calcAngle * Mathf.Deg2Rad );
posY[i] = Mathf.Cos( calcAngle * Mathf.Deg2Rad );
calcAngle += 360.0 / parseFloat(segments);
}
// ----
// Vertices
vertsInner = new Vector3[ ( segments + 1 ) ];
vertsOuter = new Vector3[ ( segments + 1 ) ];
var radiusInner : float = radiusBegin;
radiusOuter = radiusBegin + ringWidth;
for (i = 0; i < (segments + 1); i ++)
{
vertsInner[ i ] = new Vector3( posX[i], 0.0, posY[i] ) * radiusInner; // horizontal ring
vertsOuter[ i ] = new Vector3( posX[i], 0.0, posY[i] ) * radiusOuter;
}
vertsInner[ segments ] = vertsInner[0];
vertsOuter[ segments ] = vertsOuter[0];
verts = new Vector3[ ( segments + 1 ) * 2 ];
for (i = 0; i < segments + 1; i ++ )
{
verts[i] = vertsOuter[i];
verts[ i + segments + 1 ] = vertsInner[i];
}
// ----
// UVs
uv = new Vector2[verts.length];
for (i = 0; i < segments + 1; i ++ )
{
uv[i] = Vector2( 1.0 - (parseFloat(i) * (1.0 / segments)), 1.0 );
uv[ i + segments + 1 ] = Vector2( 1.0 - (parseFloat(i) * (1.0 / segments)), 0.0 );
}
// ----
// Triangles
tris = new int[ segments * 2 * 3 ];
var index : int = 0;
for (i = 0; i < tris.length / 6; i ++ )
{
tris[index + 0] = i;
tris[index + 2] = i + 1;
tris[index + 1] = i + segments + 1;
tris[index + 3] = i + 1;
tris[index + 5] = i + segments + 1 + 1;
tris[index + 4] = i + segments + 1;
index += 6;
}
// ----
// assign mesh
mesh.vertices = verts;
mesh.uv = uv;
mesh.triangles = tris;
mesh.RecalculateBounds();
mesh.RecalculateNormals();
}
// ----
// http://answers.unity3d.com/questions/375604/expanding-ring-velocity-ellipsoid-particle-emitter.html
Original answer :
everything runs from the update function. When LMB is pressed, the ring starts, expands and then finishes. SO to trigger the ring expanding, just replace if ( Input.GetMouseButtonDown(0) ) with whatever trigger you use to start the ring.
If you want a version that you can instantiate, then it automatically destroys itself, I can show you an edit for that, or I can upload a package with both versions for you to try. This was alot of fun !
Anyway, here is my wall of script :
// ring mesh emitter by Jason Kowalin (Jay Kay, alucardj) Jan 7th 2013
#pragma strict
public var radiusBegin : float = 0.1;
public var radiusEnd : float = 5.0;
public var expandTime : float = 5.0;
public var ringWidth : float = 0.2;
public var segments : int = 60;
private var theEmitter : ParticleEmitter;
private var isExpanding : boolean = false;
private var eTimer : float = 0.0;
private var eStep : float = 0.0;
function Start()
{
theEmitter = GetComponent( ParticleEmitter );
theEmitter.emit = false; // start with no particles emitted
StartMesh(); // build the ring
}
function Update()
{
if ( Input.GetMouseButtonDown(0) )
{
theEmitter.emit = true; // start emitting particles
isExpanding = true; // start expanding
eTimer = 0.0; // set timer to zero
eStep = ( radiusEnd - radiusBegin ) / expandTime; // calculate step for expanding ring
radiusInner = radiusBegin; // set the start radius
}
if ( isExpanding )
{
ExpandRing();
}
}
function ExpandRing()
{
eTimer += Time.deltaTime; // update timer
if ( eTimer > expandTime ) // check if ring has finished expanding
{
theEmitter.emit = false; // stop emmiting particles
isExpanding = false; // stop expanding
}
// -- shouldn't have to change any of this code --
// update vertices
radiusInner += eStep * Time.deltaTime;
radiusOuter = radiusInner + ringWidth;
for (var i : int = 0; i < (segments + 1); i ++)
{
//vertsInner[ i ] = new Vector3( posX[i], posY[i], 0.0 ) * radiusInner; // vertical ring
//vertsOuter[ i ] = new Vector3( posX[i], posY[i], 0.0 ) * radiusOuter;
vertsInner[ i ] = new Vector3( posX[i], 0.0, posY[i] ) * radiusInner; // horizontal ring
vertsOuter[ i ] = new Vector3( posX[i], 0.0, posY[i] ) * radiusOuter;
}
vertsInner[ segments ] = vertsInner[0];
vertsOuter[ segments ] = vertsOuter[0];
verts = new Vector3[ ( segments + 1 ) * 2 ];
for (i = 0; i < segments + 1; i ++ )
{
verts[i] = vertsOuter[i];
verts[ i + segments + 1 ] = vertsInner[i];
}
mesh.vertices = verts;
// --
}
// ---- Don't change anything past this line !! ----
private var calcAngle : float;
private var posX : float[];
private var posY : float[];
private var radiusInner : float = 0.1;
private var radiusOuter : float = 2.0;
private var vertsInner : Vector3[];
private var vertsOuter : Vector3[];
private var mesh : Mesh;
private var uv : Vector2[];
private var verts : Vector3[];
private var tris : int[];
function StartMesh()
{
if ( !mesh )
{
mesh = new Mesh();
GetComponent(MeshFilter).mesh = mesh;
mesh.name = "ParticleMesh";
}
Construct();
}
function Construct()
{
var i : int = 0;
// ----
calcAngle = 0;
posX = new float[segments + 1];
posY = new float[segments + 1];
// Calculate Circle on X-Y
for (i = 0; i < segments + 1; i ++)
{
posX[i] = Mathf.Sin( calcAngle * Mathf.Deg2Rad );
posY[i] = Mathf.Cos( calcAngle * Mathf.Deg2Rad );
calcAngle += 360.0 / parseFloat(segments);
}
// ----
// Vertices
vertsInner = new Vector3[ ( segments + 1 ) ];
vertsOuter = new Vector3[ ( segments + 1 ) ];
var radiusInner : float = radiusBegin;
radiusOuter = radiusBegin + ringWidth;
for (i = 0; i < (segments + 1); i ++)
{
//vertsInner[ i ] = new Vector3( posX[i], posY[i], 0.0 ) * radiusInner; // vertical ring
//vertsOuter[ i ] = new Vector3( posX[i], posY[i], 0.0 ) * radiusOuter;
vertsInner[ i ] = new Vector3( posX[i], 0.0, posY[i] ) * radiusInner; // horizontal ring
vertsOuter[ i ] = new Vector3( posX[i], 0.0, posY[i] ) * radiusOuter;
}
vertsInner[ segments ] = vertsInner[0];
vertsOuter[ segments ] = vertsOuter[0];
verts = new Vector3[ ( segments + 1 ) * 2 ];
for (i = 0; i < segments + 1; i ++ )
{
verts[i] = vertsOuter[i];
verts[ i + segments + 1 ] = vertsInner[i];
}
// ----
// UVs
uv = new Vector2[verts.length];
for (i = 0; i < segments + 1; i ++ )
{
uv[i] = Vector2( 1.0 - (parseFloat(i) * (1.0 / segments)), 1.0 );
uv[ i + segments + 1 ] = Vector2( 1.0 - (parseFloat(i) * (1.0 / segments)), 0.0 );
}
// ----
// Triangles
tris = new int[ segments * 2 * 3 ];
var index : int = 0;
for (i = 0; i < tris.length / 6; i ++ )
{
tris[index + 0] = i;
tris[index + 2] = i + 1;
tris[index + 1] = i + segments + 1;
tris[index + 3] = i + 1;
tris[index + 5] = i + segments + 1 + 1;
tris[index + 4] = i + segments + 1;
index += 6;
}
// ----
// assign mesh
mesh.vertices = verts;
mesh.uv = uv;
mesh.triangles = tris;
mesh.RecalculateBounds();
mesh.RecalculateNormals();
}
// ----
// http://answers.unity3d.com/questions/375604/expanding-ring-velocity-ellipsoid-particle-emitter.html
Woooow!!)) $$anonymous$$an, you awsome!! Thanks!!!) Well, yes, i create prefab(wawe), then i instantiate it by this code:
var wawe : GameObject; function Fire () { var mywawe = Instantiate (wawe, Vector3(transform.position.x,transform.position.y, transform.position.z) , Quaternion.identity);
mywawe.transform.parent = gameObject.transform; }
I'll be make experiments with you script, but if you can upload a package, wich would be works with my "instantiate script" - it will be greate!)
I have updated the answer with a second script for instantiation. I have also made a package : http://www.alucardj.net16.net/unityanswers/Ring$$anonymous$$eshEmitter.unitypackage
Open the scene Ring$$anonymous$$eshEmitterInstantiate and hit play. Now click the left, middle and right mouse buttons. These are all the same script, the Demo$$anonymous$$anager shows how to change the start and end radius and time when you instantiate :
clone = Instantiate( ring$$anonymous$$eshEmitterPrefab, Vector3.zero, Quaternion.identity );
cloneScript = clone.GetComponent( Ring$$anonymous$$eshEmitterInstantiate );
cloneScript.radiusBegin = 0.25;
cloneScript.radiusEnd = 5.0;
cloneScript.expandTime = 3.0;
Hope you like it. If I have done well, you can accept and vote my answer for some lovely lovely karma!
I previously made a straight line mesh when I first came across the problem of not being able to change the Ellipse Particle Emitter Ellipsoid vars, that's why I offered to do this (been there before!). But this has turned out very nice, shall be using it myself. Have Fun =]
Thank you, it looks very beautiful!) But it not exactly what i need, it's my fault, obviously i explain not so good.
i add image of the ring to my post - it's my ring, wich i use for now, it fit to me, but it expanding too slow (about 2,5 sec). I need, than it expanding about 0,5 - 1 sec
when you ring expanding for 3 sec - it looks good, but when i set 0,5 sec - it lose form of the ring, and looks like chaotic individual particles=(
It would be greate, if it looks like whole ring (like on my img), or a least it would be separate particles, but not lose form of the ring, when i set 0,5 sec and would be more like the whole ring(like on my img).
Sorry if i bothering you)
Fair enough, I understand now. But unfortunately that is the nature of particles, if you are moving the emitter that fast, then it will become a scattered mess. Normally a particle effect that only lasts a short time is a small effect like a muzzle flash or a bullet impact, very small particle. You want a large area. I strongly suggest just using an image. With the right image and shader, you can 'fake' the effect of a glowing moving ring. Really for this you should just use a plane and then increase the scale.
Hang on, I appreciate the gesture but if this is not what you are looking for then please Undo accept.
I am looking at a way to make a fast effect now =]