Using string checks for headshots is a quick but brittle solution that sacrifices technical rigor for ease of use. It’s a helpful starting point for S&box hobbyists, though professional systems usually require more reliable bone-tagging methods.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
Detect Headshots in the S&box Game EngineAdded:
In this sandbox tutorial, I'm going to show you how to detect shots on an NPC and also how to tell if that shot is a headshot. Let's get started. All right, so I'm working in the test bed project from Facepunch and if you don't have that, I'll leave a link in the description to where you can get it. In test bed, go into assets in the bottom, scenes, tests, and then double click on weapon lab and that'll bring up a tab up here. And if you hit play, you'll be able to run around and hit things and change your weapons. So, we want to start with a gun instead of the crowbar.
So, for you, the crowbar is going to be active. So, we're going to click on that under citizen and disable the crowbar and let's choose the MP4 and just make sure that's enabled. So, now when we come into the game, we can shoot things. Okay, so now we need an NPC target. I'm going to right click on the ground where I want to create him, choose create an empty.
We're going to call this NPC and then we're going to add component and search skinned and do model renderer skinned.
And then in the asset browser, we're going to choose models, citizen, and find citizen.vmdl and drag that into the model. And let's add a component called dresser to them, choose manual, drag in the model renderer skinned into the body target, and then click randomize and let's spin them 180° so that they're facing us. And if we press F to focus, here's our person. And I'm just going to randomize that one more time.
Perfect, a wrestler. This will be fun.
Okay, now if we save and we press play, we can shoot, but the bullets are passing right through. Why is that? So, that's because they're not a physics object yet. They're just a renderer. So, we have to add component and search physics and choose model physics. And then for the model, we're going to drag in the same model that we're using for the model renderer. Now, model physics is what makes a unit ragdoll, but it also gives them colliders all over their body. If we just start with motion enabled, they'll just collapse as a ragdoll and that's not what we want yet.
So, we can turn off motion enabled and And if we hit play, you can see now they're actually taking shots and there's little blood splatters. Okay, so now we want to track the damage that they're taking. So let's add component and we'll call this component hurt NPC, new component, save it. Okay, so we want to give them some health and we want this to be exposed to the editor. So we're going to make a property attribute. Let's make this a float which means that it's a decimal value, call it health and do our usual get set. And then we want some text to render their health. So we'll do another property.
Let's do text renderer and call this health text.
Get set. So we save that, go back into our editor.
Let's set the health to 100 and then on the NPC right click, choose create child, 3D object and then text. And we're going to bring this up. Let's flip this around also. We're going to clear this out this text out. And now if we go back to the NPC, grab text and drag it into health text, we can now set the text inside of the script. So I'm going to save with control S and now we need him to take damage. But since we already have a gun script, we're going to make use of that.
So if you click on the MP4, right click on test weapon and choose open test weapon.cs, we can see we actually have this super complicated script that does all of the heavy lifting for us. So we're going to find a method called shoot bullet. You can do that with control F and type shoot bullet and go down until we see its declaration. We know that this is the method declaration because it has the void return type in front of it. So essentially, this trace is how we detect what the bullet is colliding with. So we create a ray which is an origin and a direction. If you want to inspect this for yourself, you can click on forward ray and do F12 and then click on the type ray and do F12 again and we can see that it has an origin point and a direction. So this is essentially a point where the muzzle of the gun is and then the direction that it's firing. And then the trace is essentially grabbing any game objects that the ray collides with. So that's what the TR object is.
And then down here, it's saying the TR, which is the trace result, get the game object that it collided with, and it's going to be the first game object, and then get all the components on that game object, and then get all of the damageable components on that game object, and invoke on damage on them.
And so, this is how this is going to work.
In back in hurt NPC, do comma component.i damageable.
And this will tell you hurt NPC does not implement the interface member component i damageable on damage. So, now we need to implement that. We don't need on update. So, we're going to do void on damage in damage info info.
And we need to make this public. So, that it's using the method in i damageable. So, this is going to be invoked automatically if the trace result hits the hurt NPC because it is of type i damageable. So, let's take the health and subtract from it. Minus equals means subtract from the current value, and and assign the result back to health. And then we're going to do info.damage.
And then we want to display this. So, let's do health text.text equals health. And then this is currently a decimal, it's a float, and so we need to turn it into a string, which is a series of characters that can be displayed as text. And so, we're going to say two string open and close parentheses. Okay, so let's try this out. When we shoot him, nothing's happening. Why is that?
Well, that's because the i damageable component is on the hurt NPC, but whatever we're shooting is actually the body parts of the NPC. So, we have to get the parent, and I can show you how this works. If you go into test weapon, we can print out what's being damaged.
So, we want to log what's actually being hit. So, we'll do log.info, a dollar sign and double parentheses and double quotes, and then we'll say hit. And the dollar sign allows us to put variables inside of this string. And so, we're going to say tr game object, and the semicolon, and then let's go back to the game. And now, if we shoot, and then we press uh tilde to get our mouse back and go into console, you can see that the hit game object down here is spine. And that is not That is a child of the NPC, not the NPC itself. So, if we go back here, what we want to do is do damage to the root. So, I'm just going to change this and say game object.root.
And this finds the highest parent in the hierarchy and is going to hit that instead. And so, let's print that, too.
Game object.root. Save. Come back here.
And now, you can see, if I press tilde to get my mouse back, we're hitting the spine, but the root is the NPC. And look at that. He's actually taking damage.
There's our damage text. Okay?
So, now, we want him to actually die when he goes to zero health. So, let's make that happen. So, under hurt NPC, we're going to require component, which grabs a component that's already on this game object. And then, we'll do model physics.
And let's call this ragdoll.
Get set.
And now, we'll say, if health is less than or equal to zero, ragdoll.motionEnabled equals true. We go back to our game. We go back to our game. And now, when we shoot him down to zero health, he collapses. Cool. But, he wasn't really responding to those bullets. He didn't get like propelled backwards like his ragdoll does now that it's enabled. So, let's fix that.
If we go back into test weapon, you can see that we are actually applying a force to the hit position already.
However, this is happening before on damage is being called, which means that the ragdoll isn't enabled yet. So, we're going to grab all this, cut it, and paste it. And then, let's increase the amount of force just that we can really see this effect. And we'll save the code, and we'll go in. And now, we shoot him, and when he dies, he goes flying backwards and takes a bunch of damage.
Okay. So, let's clamp his health to be not less than zero. So, if he takes health beyond zero, let's just set this to zero.
And then, I actually also want to detect headshots. So, if we go back into test weapon, the damage is declared here. So, let's say var damage amount equals 10.
Um but, we want to see if it's actually hitting the head of the character. So, we'll do tr.gameobject name contains, and this is how we can search for a string, and let's say head.
And now, we're going to use a tertiary operator here. So, what this means is that if this evaluates to true, then we're going to use this value, and otherwise, use this value. So, this could be written with an if statement, but this is just nicer in one line. And then, we're going to pass damage amount into the damage info constructor. So, let's go back into the game, press play. And if I shoot him in the stomach, he takes 10 damage. It's 90. If I shoot him in the head, he takes 30 damage. It goes down to 60.
And now, we can see that he goes flying backwards. So, you can see that the impulse is actually being applied. Let me shoot him in the hand at the location that we are shooting. And that's all it takes. So, to summarize, on our NPC, we have the health and the health text, and we are implementing the IDamageable interface, which gives us this function, and it has to be public.
And this function, which gives us this method, and it has to be public. And this method is called inside of test weapon by saying, "Hey, did the thing that we hit, does its root object use the IDamageable component?" And if so, deal damage to it. And then, we just checked to see if the game object that it hit, not the root, but the actual game object that it hit, includes the word head. And you could use tags or something, which would probably be a better way to do that. And then after on damage is invoked, which turns on the ragdoll motion enabled if the health goes below zero, then we apply the impulse, and that gives us and that gives us this fantastic effect where we can shoot him and then just like that, I could shoot out his foot. So, very, very cool, nice and simple. Thanks for watching. I hope this was useful.
Related Videos
OpenHuman VS Hermes AI: Who Wins?
JulianGoldieSEO
285 views•2026-05-29
Long-Running Agents — Build an Agent That Never Forgets with Google ADK
suryakunju
142 views•2026-05-30
This computer is made from real human brain cells. And you can buy it.
Talktmsmedia
3K views•2026-05-28
BREAKING: Microsoft’s New Image Generating Model Beat Out GPT 1.5 and Nano Banana 2
aimmediahouse
122 views•2026-06-03
I Made the Same Anime Fight Scene in Every AI Video Generator
NobleGooseAnime
295 views•2026-05-30
Nvidia Bets Big On AI PCs | New Chip To Power Windows Laptops | Technology | AI Updates | N18S
cnnnews18
3K views•2026-06-01
I Tested NEW Opus 4.8 on Four Projects (Updated LLM Leaderboard)
AICodingDaily
298 views•2026-05-29
3D Platformer Update - NO CAPES
SolarLune
294 views•2026-05-30











