Bullet Hole Decals
by Tim Heldna · 12/18/2005 (6:44 pm) · 32 comments
Bullet Hole Decals
I've decided to post this as a resource because I believe most people don't know that this function exists for projectiles.
Here's how to set it up:
N.B. I will be using the standard crossbow.cs script as a reference
In your weapon file go to the datablock ProjectileData(CrossbowProjectile) section and add this to the bottom of that datablock before the last };
Then directly above this datablock set up your decal data which should look something like this:
That's it, now when your projectile hits something it will leave a decal. You can adjust how long this decal lasts, max number of decals, and whether decals are enabled or disabled by going into starter.fps\client\prefs.cs and adjusting...
$pref::Decal::decalTimeout = "5000";
$pref::Decal::maxNumDecals = "256";
$pref::decalsOn = "1";
...accordingly.
Hope this is useful.
P.S. Make sure you're texture paths within the datablock DecalData are valid.
EDIT July 31st 2006 - Your weapon's projectile must have an explosion specified for decals to work!
E.g.
I've decided to post this as a resource because I believe most people don't know that this function exists for projectiles.
Here's how to set it up:
N.B. I will be using the standard crossbow.cs script as a reference
In your weapon file go to the datablock ProjectileData(CrossbowProjectile) section and add this to the bottom of that datablock before the last };
decals[0] = CrossbowDecal1; decals[1] = CrossbowDecal2; decals[2] = CrossbowDecal3; decals[3] = CrossbowDecal4; decals[4] = CrossbowDecal5; decals[5] = CrossbowDecal6;The whole thing should look like this:
datablock ProjectileData(CrossbowProjectile)
{
projectileShapeName = "~/data/shapes/crossbow/projectile.dts";
directDamage = 20;
radiusDamage = 20;
damageRadius = 1.5;
areaImpulse = 200;
explosion = CrossbowExplosion;
waterExplosion = CrossbowWaterExplosion;
particleEmitter = CrossbowBoltEmitter;
particleWaterEmitter= CrossbowBoltBubbleEmitter;
splash = CrossbowSplash;
muzzleVelocity = 100;
velInheritFactor = 0.3;
armingDelay = 0;
lifetime = 5000;
fadeDelay = 5000;
bounceElasticity = 0;
bounceFriction = 0;
isBallistic = false;
gravityMod = 0.80;
hasLight = true;
lightRadius = 4;
lightColor = "0.5 0.5 0.25";
hasWaterLight = true;
waterLightColor = "0 0.5 0.5";
[b]//Decal Data Start[/b]
decals[0] = CrossbowDecal1;
decals[1] = CrossbowDecal2;
decals[2] = CrossbowDecal3;
decals[3] = CrossbowDecal4;
decals[4] = CrossbowDecal5;
decals[5] = CrossbowDecal6;
[b]//Decal Data End[/b]
};Then directly above this datablock set up your decal data which should look something like this:
datablock DecalData(CrossbowDecal1)
{
sizeX = 0.05;
sizeY = 0.05;
textureName = "~/data/shapes/chaingun/textures/bullethole1";
};
datablock DecalData(CrossbowDecal2 : CrossbowDecal1)
{
textureName = "~/data/shapes/chaingun/textures/bullethole2";
};
datablock DecalData(CrossbowDecal3 : CrossbowDecal1)
{
textureName = "~/data/shapes/chaingun/textures/bullethole3";
};
datablock DecalData(CrossbowDecal4 : CrossbowDecal1)
{
textureName = "~/data/shapes/chaingun/textures/bullethole4";
};
datablock DecalData(CrossbowDecal5 : CrossbowDecal1)
{
textureName = "~/data/shapes/chaingun/textures/bullethole5";
};
datablock DecalData(CrossbowDecal6 : CrossbowDecal1)
{
textureName = "~/data/shapes/chaingun/textures/bullethole6";
};That's it, now when your projectile hits something it will leave a decal. You can adjust how long this decal lasts, max number of decals, and whether decals are enabled or disabled by going into starter.fps\client\prefs.cs and adjusting...
$pref::Decal::decalTimeout = "5000";
$pref::Decal::maxNumDecals = "256";
$pref::decalsOn = "1";
...accordingly.
Hope this is useful.
P.S. Make sure you're texture paths within the datablock DecalData are valid.
EDIT July 31st 2006 - Your weapon's projectile must have an explosion specified for decals to work!
E.g.
explosion = CrossbowExplosion;
About the author
Recent Blogs
• BCS Street props• Character Pack - Vince
• Recent Artwork
• Progress of our Weapon Pack
• Digital Speedometer
#2
12/19/2005 (4:48 am)
Quick question for anyone in the know, since this resource will be getting a lot of traffic for a while I'd assume and this is related. Does anyone know how to get decals working in TSE?
#3
12/19/2005 (1:55 pm)
Very cool, great resource. Do you have any suggestions on decal design? (Amount transparency, how to keep your bullet holes from appearing to have whitish outlines, etc)
#4
12/19/2005 (2:23 pm)
Make your texture full black after you've created the alpha channel, so you don't get any white outlines
#5
12/19/2005 (2:51 pm)
Well the outlines still exist the same way they did when I had the bullet hole decal semi-transparent. But if I zoom in they go away.
#6

I Don't know what to tell you c2, i don't seem to have the problem you describe.
One thing i do know is the smaller the image the better, i use 32 x 32 and that seems to work fine.
I attached a picture of one of my decals if it helps
12/20/2005 (4:06 am)

I Don't know what to tell you c2, i don't seem to have the problem you describe.
One thing i do know is the smaller the image the better, i use 32 x 32 and that seems to work fine.
I attached a picture of one of my decals if it helps
#7
12/20/2005 (3:44 pm)
Hmm your decal works fine. Will reference it when I make new ones. Thanks. :)
#8
12/23/2005 (4:27 pm)
every so often it shows a white box instead of the decal(im using the footprint for right now). Any ideas on this? sometimes its every other 10 or 2 or when ever...
#9
12/23/2005 (5:51 pm)
@Wesley: Sounds like one of your DecalData filepaths are incorrect.
#10
12/23/2005 (10:25 pm)
well then.. bad on my side
#11
That fits nicely into any options GUI. ;)
Here's a little piece of my options GUI after using the blood pool resource.
Hope it's useful here.
Ari
12/24/2005 (3:29 am)
Quote:
$pref::Decal::decalTimeout = "5000";
$pref::Decal::maxNumDecals = "256";
$pref::decalsOn = "1";
That fits nicely into any options GUI. ;)
Here's a little piece of my options GUI after using the blood pool resource.
Hope it's useful here.
new GuiCheckBoxCtrl(OP_DecalFX) {
profile = "GuiCheckBoxProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "9 181";
extent = "140 30";
minExtent = "8 2";
visible = "1";
variable = "$pref::Interior::ShowEnvironmentMaps";
text = "Decal FX";
groupNum = "-1";
buttonType = "ToggleButton";
helpTag = "0";
};
new GuiTextCtrl() {
profile = "GuiTextProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "215 145";
extent = "59 18";
minExtent = "8 2";
visible = "1";
lockMouse = "0";
text = "Max Decals:";
maxLength = "255";
helpTag = "0";
};
new GuiTextEditSliderCtrl() {
profile = "GuiDefaultProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "276 148";
extent = "67 16";
minExtent = "8 2";
visible = "1";
variable = "$pref::fxDecal::maxNumDecals";
lockMouse = "0";
maxLength = "255";
historySize = "0";
password = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
format = "%3.0f";
range = "0.000000 512.000000";
increment = "1";
};
new GuiTextCtrl() {
profile = "GuiTextProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "204 163";
extent = "70 18";
minExtent = "8 2";
visible = "1";
lockMouse = "0";
text = "Decal Timeout:";
maxLength = "255";
helpTag = "0";
};
new GuiTextCtrl() {
profile = "GuiTextProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "210 181";
extent = "64 18";
minExtent = "8 2";
visible = "1";
lockMouse = "0";
text = "Decal Offset:";
maxLength = "255";
helpTag = "0";
};
new GuiTextEditSliderCtrl() {
profile = "GuiDefaultProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "276 166";
extent = "67 16";
minExtent = "8 2";
visible = "1";
variable = "$pref::fxDecal::decalTimeout";
lockMouse = "0";
maxLength = "255";
historySize = "0";
password = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
format = "%3.0f";
range = "0.000000 300000.000000";
increment = "1000";
};
new GuiTextEditSliderCtrl() {
profile = "GuiDefaultProfile";
horizSizing = "right";
vertSizing = "bottom";
position = "276 184";
extent = "67 16";
minExtent = "8 2";
visible = "1";
variable = "$pref::fxDecal::decalOffset";
lockMouse = "0";
maxLength = "255";
historySize = "0";
password = "0";
tabComplete = "0";
sinkAllKeyEvents = "0";
format = "%3.3f";
range = "0.001000 0.100000";
increment = "0.001";
};Ari
#12
12/29/2005 (10:30 am)
Would this work on the player characters? I've been looking for away to apply red "holes" on the players when they get shot that do not disapear until they get health.
#13
No, it won't work on players. You can alter the head code to allow this the only problem being the decal applys itself to the bounding box. You can imagine how nasty it would look if you shot at a player and the decal was above & to the left of the players head floating in mid air.
Why don't you use the stock code in Torque to change the players texture based on damage. There's a couple of resources on how to change an objects texture through script. This way you could have say 5 different textures for a player, 1 (clean) base texture & 4 other textures which have varying amounts of red holes on them. When the player is healthy the base (clean) texture is used, when damage is at 80% the 2nd texture with 3 red holes is used, damage at 60% 3rd texture with 6 red holes is used and so on. Best of all no head code changes required.
If you want to see what i mean take a look at this resource.
Hope that helps
12/29/2005 (6:35 pm)
Alan,No, it won't work on players. You can alter the head code to allow this the only problem being the decal applys itself to the bounding box. You can imagine how nasty it would look if you shot at a player and the decal was above & to the left of the players head floating in mid air.
Why don't you use the stock code in Torque to change the players texture based on damage. There's a couple of resources on how to change an objects texture through script. This way you could have say 5 different textures for a player, 1 (clean) base texture & 4 other textures which have varying amounts of red holes on them. When the player is healthy the base (clean) texture is used, when damage is at 80% the 2nd texture with 3 red holes is used, damage at 60% 3rd texture with 6 red holes is used and so on. Best of all no head code changes required.
If you want to see what i mean take a look at this resource.
Hope that helps
#14
12/30/2005 (5:36 am)
Any possibility to use a decal to put spots in the highway?
#15
Thing is, I was thinking how 'modern' shooters do it where you can shoot them anywhere and that is where the entry wound (and corresponding exit wound) appear on the model. Abdomen, Chest, Head, arms, legs, and all the various combinations.
01/03/2006 (9:15 am)
Thanks Tim. I should have thought it through and realized it would end up hovering in the air.Thing is, I was thinking how 'modern' shooters do it where you can shoot them anywhere and that is where the entry wound (and corresponding exit wound) appear on the model. Abdomen, Chest, Head, arms, legs, and all the various combinations.
#16
-Stephen
01/09/2006 (7:37 pm)
Thankyou for this resource! I had the bulletholes working in my project but my HDD crashed so I lost everything. But now with this resource, I less thing I have to figure out.-Stephen
#17
That makes it much harder to create a model (unless you get the exporter to slice and dice your model automatically), but you get much more realism without having to recode major parts of TGE
01/11/2006 (7:17 am)
When you look at games like Soldier of Fortune (1 or 2), they have what they call the Ghoul rendering system for characters. I guess they split up a character in multiple parts (upper right arm, upper left arm, upper abdomen, etc...) and then they change the texture accordingly when they get shot.That makes it much harder to create a model (unless you get the exporter to slice and dice your model automatically), but you get much more realism without having to recode major parts of TGE
#18
Thanks,
David
01/11/2006 (7:20 am)
One other question : if I want to have footsteps in the snow, can I use this system, or do I use something else?Thanks,
David
#19
01/16/2006 (4:00 am)
Great Resource
#20
The player already has a decal system for footsteps. Look at the orc's footsteps and you'll notice he leaves a footprint impression on the ground which is set off by triggers within the movement animations.
Does this answer your question???
I can go into more detail if need be...
01/27/2006 (8:03 am)
@ David Janssens, The player already has a decal system for footsteps. Look at the orc's footsteps and you'll notice he leaves a footprint impression on the ground which is set off by triggers within the movement animations.
Does this answer your question???
I can go into more detail if need be...

Torque Owner Trenton Shaffer
Nice job.