Particle Attachment for AI
Attaching Particles to an AI
Fairly easy to attach particles to an AI once someone looks into the SDK for you :D
The particle will be attached to a bone, this gives you plenty of options as most AI have 20+ bones. The names of the bones can be found in the AI's md5 file which can be opened with notepad or wordpad. ie: pagan_female_mesh.md5mesh , usually the joint names are fairly obvious as the animators need to find that info easily. left_hand is obviously a bone in the left hand.
You'll need to create a particle effect using the Particle Editor. Once you have that you can add some info to your AI's def file. It's probably best if you want to add a fire particle to a pagan females hand that you copy her .def file and give it a new name, this way the pagan_female files won't get messed up.
There are probably 2 ways to go with the particle attachment:
- constantly emitted particle
- particle emitted at intervals.
Adding this line to your AI's entity def description (entityDef atdm:lantern_bot) will add a particle (bc_sparx) to the joint named smokestack.
"smokeParticleSystem1" "bc_sparx-smokestack"
Alternately you can add the particle named smokestack to the joint named smokestack by using this line
"smokeParticleSystem1" "smokestack"
The first option is probably best as you can reuse particles instead of making a new one to match the joint name. Either way you'll notice that the above lines contain smokeParticleSystem1. An AI can have multiple smokeParticleSystems attached. The Monster_Boss_Cyberdemon.def from D3 has 1-9, 2 are used for footsteps, the other seem to be permenately attached flame particles to his back and mouth.
OK, great you say. But I only want a steam puff coming from my steambot's smokestack everytime the top of the stack opens. (In this case it happens to be toward the end of each anim)
If so you'll need to add a line to your AI's model def description. This can also be found in the AI.def file (in this case lantern_bot.def). It will make a steampuff appear on the 31st frame at the smokestack joint. (you can also call things like footstep sounds, or alert sounds in this manner). Importing the model and animation into a 3d program are probably the easiest way to find a specifc frame, but you can also get it right by trial/error guessing. Most animations are around 30 frames, look for cycles. A bipeds walk anim is usually 2 steps (ie left foot, right foot) so a dust cloud coming from his right foot would be somewhere around frame 25, if it's late or early you can adjust until you get it close enough.
The benefit of using this method instead of a timing script is that you can match the particles timing to an AI's action even if something happens in time to mess up the sync.
anim walk models/md5/chars/steambots/lant_bot_walk.md5anim { frame 12 footstep frame 31 footstep frame 31 triggerSmokeParticle smokestack }
This is probably to be deleted soon, need to test self starting particles
I believe nothing other than "smokeParticleSystem1" "smokestack" is needed, they seem to start on their own, but if you want to start them you need to use above instruct
CODE /*
=========
idAI::SpawnParticles
=========
- /
void idAI::SpawnParticles( const char *keyName ) {
const idKeyValue *kv = spawnArgs.MatchPrefix( keyName, NULL ); while ( kv ) { particleEmitter_t pe;
idStr particleName = kv->GetValue();
if ( particleName.Length() ) {
idStr jointName = kv->GetValue(); int dash = jointName.Find('-'); if ( dash > 0 ) { particleName = particleName.Left( dash ); jointName = jointName.Right( jointName.Length() - dash - 1 ); }
SpawnParticlesOnJoint( pe, particleName, jointName ); particles.Append( pe ); }
kv = spawnArgs.MatchPrefix( keyName, kv ); }
}
That's probably Greek to you if you've never seen C++ before... So I'll explain it. Basically what it's doing is looking for a dash (-) in the value of the spawnarg. Everything left of the dash is the name of the particle. Everything to the right of the dash is the name of the joint (for our purposes, a joint just means a bone). If there's no dash, then the particle name is the same as the joint name - this is probably what's happening in your case. It's finding the bone named "smokestack", but it's also looking for a particle named "smokestack". Since it doesn't find such a particle, you get black squares.
So if you want a particle called myawesomeparticle to be (permanently!) emitted from the bone smokestack, you might use the following spawnarg:
"smokeParticleSystem1" "myawesomeparticle-smokestack"
So far so good, but it's not active yet (I think - you might want to test this yourself to be sure). So you need to use the triggerSmokeParticle frame command to turn it on. As you've discovered, this is placed within an "anim" block and takes this format:
frame [framenumber] [bonename]
Where [framenumber] is the frame number of the animation, and [bonename] is the name of the bone/joint on which to trigger particle effects. Note that all particle effects on that bone will be triggered, if you have more than one.