Firing an effect at a place: the EmitAt calls
EnableEmitAt and AbsoluteEmitAt play an effect with its particles starting at a place you give. The emitter is not moved and not duplicated. Any number of plays of one emitter can run at once, and each has its own handle. Exercise 18 uses the call for the first time.
What the calls make possible:
- Sparks where a shot lands, from one emitter kept in the workspace.
- A whole explosion, grouped in a Model, played wherever the player points.
- A stream that starts at a character’s hand and stays with the hand.
- One burst with a larger count than the emitter was built with.
The two calls
Section titled “The two calls”| Call | item | Gives back |
|---|---|---|
Part_Icles:EnableEmitAt(item, origin, options?) | One emitter. Anything else is rejected with a message. | handle, duration |
Part_Icles:AbsoluteEmitAt(item, origin, options?) | An emitter, a stock ParticleEmitter, or a Part, Model or Attachment that holds emitters. | handle, duration |
options may be left out.
| Given back | What it is |
|---|---|
handle | The play handle for this one play. It is never nil. After a rejected call the handle controls nothing, and its Duration is 0. |
duration | The estimated length of this play in seconds, with the options counted in. nil means the play never ends. After a rejected call it is 0. The same number is at handle.Duration. |
local handle, duration = Part_Icles:AbsoluteEmitAt(sparks, position, { Count = 60 })The origin
Section titled “The origin”| You pass | Where particles start |
|---|---|
A CFrame | At its position, turned as the CFrame is turned. The emitter’s Direction turns with it. The place is fixed at the moment of the call. |
A Vector3 | At that position. The emitter keeps its own rotation. The place is fixed at the moment of the call. |
| A Part or MeshPart, Model, Attachment, Bone or the camera | Where that instance is at the moment each particle is made. An effect with a Delay or a Duration keeps starting particles at the instance as it moves. |
| Anything else | The call is rejected. See Messages in the Output window. |
If an instance given as the origin is gone when a particle is made, the place it had at the call is used.
The origin decides only where particles start. Particles in flight do not follow it. To make them follow, add the Link option.
What the item may be
Section titled “What the item may be”On this page a stock emitter is a ParticleEmitter, Trail or Beam that the plugin has not transformed.
item | What happens |
|---|---|
| An emitter made from a Part, Attachment or Model, in Emit mode | It plays at the origin. |
| An emitter in Animate mode | It plays where it is, as with EnableEmit. The Output window says so once. |
| An emitter made from a Beam, Trail, Light, Highlight, Sound, screen effect or ImageLabel | It plays where it is, as with EnableEmit. It has no position to move. The Output window says so once. |
| A Part, Model or Attachment that holds emitters | Every emitter inside plays at the origin. Each keeps its own offset from the pivot of the container, so the layout is kept. |
| Stock emitters inside such a container | They fire at the origin too, from a duplicate of the container. They are placed once, where the origin was at the call. They do not follow an origin that moves, and they are not linked. The duplicate is removed when they have finished, or after 60 seconds if they never do. |
| A stock ParticleEmitter | It fires at the origin. The size of its parent Part is kept, so an emitter that fills a box still fills it. |
| A stock Trail or Beam | It fires where it is. The origin is ignored. |
| A Folder, or any other instance without a position | The call is rejected, with a message. |
nil, or an instance with no parent | The call is rejected, with a message. |
The options
Section titled “The options”options is a table. Every entry may be left out.
| Option | Kind | If left out | What it does |
|---|---|---|---|
Count | Number | The emitter’s Emit count | The Emit count for this play. A value that is not a number is ignored. |
Delay | Number, seconds | The emitter’s Delay | The Delay for this play. |
Duration | Number, seconds, or text "min,max" | The emitter’s Duration | The Duration for this play. A range picks a random value. |
Link | Instance, or the text "camera" | The emitter’s own Link | Every emitter this call fires is linked to it, for this play. |
LinkMode | Text: "Follow", "Pivot", "Weld", "WeldWithoutRotation" or "RigidLocal" | "Weld" if Link is given. Otherwise the emitter’s own. | The Link Mode for this play. With no Link given, it changes the mode of the emitter’s own link for this play. Link describes each mode. |
EmitParent | Instance | The emitter’s Emit Into | Where the particles of this play are placed. |
UseFullOrigin | true or false | true | Set to false, only the position of the origin is used. Every emitter keeps its own rotation. A Vector3 origin always gives position only. |
LinkOverride | true or false | false | With Link: the origin is ignored. Particles start where the link is at that moment. A container closes onto the centre of the link. |
Persist | true or false | false | Writes Link, LinkMode and EmitParent onto the emitter for good, as SetLink and SetEmitParent do. |
ApplyToAll | true or false | false | With Persist on a container: writes them onto every emitter inside. LinkOverride with a Link does the same. With neither, Persist on a container writes nothing, and the three options are not used for the play either. |
IgnoreLink | true or false | false | The emitter’s own Link is not used for this play. A Link given in the options still applies. |
OriginResolver | A function that gives back a CFrame | None | Called each time a particle of the play is made. Its answer is the origin for that particle. Use it for an origin that moves and is not an instance, such as the mouse position during a Delay. If it gives back nil, the origin of the call is used. |
What the options reach:
| Options | Apply to | Do not apply to |
|---|---|---|
Count, Delay, Duration | The emitters the call fires directly | Stock ParticleEmitters. Emitters nested in a RenderTemplate. |
Without Persist, no option is written to the emitter. A play with a Duration leaves the emitter’s Enabled switch as it is.
Plays of one emitter run side by side. Each has its own Count, Delay and Duration, and each is stopped by its own handle.
An emitter in Animate mode is the exception. It has one cycle, and a play with a Duration switches its Loop on for that time.
The play handle
Section titled “The play handle”The handle acts on one play. Other plays of the same emitter, and the emitter itself, are not touched.
| Member | Gives back | What it does |
|---|---|---|
handle:Disable() | Nothing | Hard stop for this play. No more particles are made. Its particles in flight are removed at once. |
handle:SoftDisable() | Nothing | Soft stop for this play. No more particles are made. Those in flight finish their Lifetime. A looping Animate play finishes its cycle and does not start another. |
handle:SetTimescale(scale, duration?, permanent?) | Nothing | Sets the speed of this play’s particles, nested particles included. It covers particles in flight and those the play makes later. |
handle:GetParticles() | A list of instances | The particles of this play that are in flight. The list is empty when there are none. |
handle:GetPDatas() | A list of tables | The module’s own records for the same particles. Their layout is internal and can change with any version. Use handle:GetParticles() unless a record is needed. |
handle:IsAlive() | true or false | true while the play has a particle in flight or is still streaming. false during the Delay, before anything is made. |
handle.Active | true or false | The same answer as handle:IsAlive(), read as a value. |
handle:Wait() | The seconds waited | Waits until the play is over. |
handle.Duration | Seconds, or nil | The estimated length of the play. nil means it never ends. 0 on the handle of a rejected call. |
handle:SetTimescale follows the rules of Speed. A duration above 0 or permanent set to true must be given.
handle:Wait() waits for the play’s Duration, counted from the moment Wait is called. Call it straight after the play starts. After a stop call it returns as soon as nothing of the play is left. On a play that never ends it waits until a stop call is made and nothing of the play is left.
Stock emitters fired by the play are a special case.
| Member | With the stock emitters of the play |
|---|---|
handle:Disable() | The stock emitters placed by the play are removed at once. |
handle:SoftDisable() | The stock emitters placed by the play are left to finish. |
handle:SetTimescale | The particles of a stock ParticleEmitter are not affected. |
handle:GetParticles() | The particles of a stock ParticleEmitter are not instances and are not listed. |
Messages in the Output window
Section titled “Messages in the Output window”Each kind of message is written once in a session, not once for each call. <Api> is the name of the call. <full name> is the path of the instance.
| Message | Cause | Action |
|---|---|---|
[Part-Icles] <Api>: item is nil or has no parent; nothing emitted. | item is nil, or it has no parent. | Find the emitter with WaitForChild before the call. |
[Part-Icles] <Api>: origin must be a CFrame, a Vector3 or an instance with a position (got <type>); nothing emitted. | The origin is of another kind. | Pass a CFrame, a Vector3, a Part, a Model, an Attachment, a Bone or the camera. |
[Part-Icles] EnableEmitAt: <full name> is not a Part-Icle; use AbsoluteEmitAt for containers and raw emitters. Nothing emitted. | EnableEmitAt was given something that is not an emitter. | Pass one emitter, or call AbsoluteEmitAt. |
[Part-Icles] AbsoluteEmitAt: <full name> has no position; pass a Part / Model / Attachment / ParticleEmitter or a transformed item. Nothing emitted. | A Folder, or another instance without a position, was passed. | Group the emitters in a Model and pass the Model. |
[Part-Icles] EmitAt: <full name> emits in place: Animate-mode targets animate their own instance | The emitter is in Animate mode. It played where it is. | None, if that is wanted. Otherwise use an emitter in Emit mode. |
[Part-Icles] EmitAt: <full name> emits in place: <ClassName> has no position to move | The emitter is of a kind with no position. It played where it is. | None, if that is wanted. Otherwise use an emitter made from a Part, Attachment or Model. |
Part_Icles.Log.enabled = false silences these messages. See Limits and helpers.