I'm creating a FPS, making guns, having no problems except for one thing. When I shoot it, how do I make it so that a bullet mark appears on the surface of the part shot at? I know you have to create a part, and insert a decal with the bullet mark, but how do I get to know which surface my bullet has hit? Just to let you know, I'm using Ray Casting, not some body velocity thing.
Please either tell me how to get the surface of the object, or write a simple example script which makes a bullet mark on a surface when the ray has collided with a Part.
Thank you very much if you could help. I'm not really asking for scripts, more like help.
You may be familiar with the first two return values of FindPartOnRay: the part it hit and the point of intersection. There is a third value that you're ignoring, which is the surface normal. The surface normal is a one-stud long vector which is perpendicular to the face of the object.
Here's a picture I drew to illustrate what I'm talking about.
As you can see, no matter the angle of the ray, as long as they hit the same surface, their surface normals will be parallel. This is useful because this determines which direction the bullet hole will be facing.
Now assuming that you've already casted the ray, this is one way of making bullet holes:
--Creating the bullet hole which will be cloned every time a hole needs to be made local bulletholepart = Instance.new("Part") bulletholepart.FormFactor = "Custom" bulletholepart.Size = Vector3.new(1, 1, 0.2) bulletholepart.Anchored = true bulletholepart.CanCollide = false bulletholepart.Transparency = 1 local bulletholedecal = Instance.new("Decal", bulletholepart) bulletholedecal.Face = "Front" -- you want it to be in front of the part for later bulletholedecal.Texture = "http://www.roblox.com/asset/?id=2078626" -- a bullet hole decal I found function shoot() -- TO-DO: cast the ray local hit, pos, normal = game.Workspace:FindPartOnRay(ray) -- If I hit a wall, then local bullethole = bulletholepart:Clone() bullethole.Parent = game.Workspace bullethole.CFrame = CFrame.new(pos, pos + normal) -- the most important part: this sets the CFrame of the bullethole so that it's nearly flush with the wall. game:GetService("Debris"):AddItem(bullethole, 10) -- automatically remove the bullet hole after 10 seconds -- TO-DO: do damage if it hits a player, etc. end
Take note that you will have to add the bullet holes to the ignore list or else the bullet holes will stack with each other -- I'll leave that up to you.