Issue with raycasting on meshes
I’m trying to make a gun system for my upcoming game, only i’m stuck with this small issue accuring when firing at meshes or in this case the head of the character. I tried searching up solutions but couldn’t find one.
https://gyazo.com/576ce3f65f99f25d0fc344ff875b1f87
As you can see the gun detectes intersections outside of the mesh you can see which is expected because it’s in reality a normal part.
But it’s not ideal. I want the bulletholes on the mesh not on the part.
Btw I rather use surfacegui to show bulletholes for ClipsDescendants.
Serverscript inside gun model:
print("hi")
local worldPositionToGui = require(game:GetService("ServerScriptService").WorldPositionToGuiPosition)
local bulletHole = require(game:GetService("ServerScriptService").BulletHole)
local Debris = game:GetService("Debris")
local firerate = .1
local fireable = true
script.Parent.shot.OnServerEvent:Connect(function(player, character, mp2, ur2)
if fireable == true then
fireable = false
local MaxDistance = 50000 --Maximun distance the ray can go
script.Parent.Handle.pow:Play()
script.Parent.Handle.Flare.ParticleEmitter:Emit(100)
local raycastResult = bulletHole.raycastGun(player, character, script.Parent, mp2, ur2, MaxDistance)
if raycastResult then
if raycastResult.Instance.Parent:FindFirstChild("Humanoid") then
raycastResult.Instance.Parent:FindFirstChild("Humanoid").Health -= math.random(10,15)
bulletHole.setHole(raycastResult, true)
else
bulletHole.setHole(raycastResult)
end
bulletHole.addBeam(raycastResult, script.Parent.Handle)
else
bulletHole.addBeam()
end
task.wait(firerate)
fireable = true
end
end)
The modulescript with the name “BulletHole”
local bulletHole = {}
local Debris = game:GetService("Debris")
function bulletHole.raycastGun(player, character, gun, mp2, ur2, MaxDistance)
local dist = (character:FindFirstChild(gun.Name).Handle.Flare.WorldPosition - mp2)
local raycastparams = RaycastParams.new()
local direction = (mp2 - ur2.Origin).Unit * MaxDistance
raycastparams.FilterDescendantsInstances = gun.Parent:GetDescendants()
raycastparams.FilterType = Enum.RaycastFilterType.Exclude
local raycastResult = game:GetService("Workspace"):Raycast(ur2.Origin, direction, raycastparams)
return raycastResult
end
function bulletHole.checkGuiOnSurface(raycastResult, Surface)
local partInstances = raycastResult.Instance:GetDescendants()
for i, v in pairs(partInstances) do
if v.Name == "SurfaceGui" and v.Face == Surface then
return v
end
end
end
function bulletHole.checkFrameOnSurface(raycastResult, Surface)
local partInstances = raycastResult.Instance:GetDescendants()
for i, v in pairs(partInstances) do
if v.Name == "Frame" and v.Parent.Face == Surface then
return v
end
end
end
function bulletHole.addBeam(raycastResult, Handle, duration)
local beam = Handle.Beam
local part = Instance.new("Part")
if not duration then
duration = .1
end
part.Parent = workspace
part.Size = Vector3.new(1,1,1)
part.Position = raycastResult.Position
part.Anchored = true
part.Transparency = 1
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
Debris:AddItem(part, 2+duration) --to avoid the beam lasting longer than the added part.
local att = Instance.new("Attachment")
att.Parent = part
beam.Attachment1 = att
task.wait(duration)
beam.Attachment1 = nil
end
function bulletHole.setHole(raycastResult, bulletholeBlood)
local SCALE = 50
local worldPositionToGui = require(game:GetService("ServerScriptService").WorldPositionToGuiPosition)
local worldPosition = worldPositionToGui:WorldPositionToGuiPosition(raycastResult.Instance, raycastResult.Position)
local Surface = worldPosition[1] --the face you hit
local surfaceGui = bulletHole.checkGuiOnSurface(raycastResult, Surface)
local gunshotsIdBasedOnMaterials = require(script.Parent.BulletHoleSettings).gunshotsIdBasedOnMaterials
--If there is no surfacegui on that face, one will be added on that face.
if not surfaceGui then
surfaceGui = Instance.new("SurfaceGui")
surfaceGui.CanvasSize = Vector2.new( SCALE*worldPosition[2], SCALE*worldPosition[3] )
surfaceGui.Face = Surface
surfaceGui.Parent = raycastResult.Instance
surfaceGui.ClipsDescendants = true
surfaceGui.LightInfluence = 1
end
local bulletImage = Instance.new("ImageLabel")
local frame = bulletHole.checkFrameOnSurface(raycastResult, Surface)
--If there is no frame on that face, one will be added on that face.
if not frame then
local frame = Instance.new("Frame")
frame.Parent = surfaceGui
frame.ClipsDescendants = true
frame.BackgroundTransparency = 1
frame.Size = UDim2.new(1,0,1,0)
bulletImage.Parent = frame
end
if frame then
bulletImage.Parent = frame
end
bulletImage.Size = UDim2.new(0, 25, 0, 25) --standard size
bulletImage.Position = UDim2.new(worldPosition[4], 0, worldPosition[5], 0)
bulletImage.AnchorPoint = Vector2.new(0.5, 0.5)
bulletImage.ImageTransparency = .3 --standard ImageTransparency
bulletImage.BackgroundTransparency = 1
Debris:AddItem(bulletImage, 60)
math.randomseed(os.time())
local texture
if gunshotsIdBasedOnMaterials[raycastResult.Instance.Material] then
texture = gunshotsIdBasedOnMaterials[raycastResult.Instance.Material][math.random(1, 3)]
else
texture = gunshotsIdBasedOnMaterials.other[math.random(1, 3)]
end
if gunshotsIdBasedOnMaterials[raycastResult.Instance.Material] then -- if texture then
local size = gunshotsIdBasedOnMaterials[raycastResult.Instance.Material].size
local ImageTransparency = gunshotsIdBasedOnMaterials[raycastResult.Instance.Material].ImageTransparency
local BaseColor = gunshotsIdBasedOnMaterials[raycastResult.Instance.Material].BaseColor
bulletImage.Image = texture
bulletImage.Size = size --modified size
bulletImage.ImageTransparency = ImageTransparency --modified ImageTransparency
if BaseColor then
bulletImage.ImageColor3 = BaseColor
else
bulletImage.ImageColor3 = raycastResult.Instance.Color
end
else --if no texture/material then use 'other' textures
if bulletholeBlood then
bulletImage.Image = "rbxassetid://16241247312" or ""
bulletImage.ImageColor3 = Color3.fromRGB(255, 0, 0)
print(bulletImage.ImageColor3)
else
math.randomseed(os.time())
bulletImage.Image = gunshotsIdBasedOnMaterials.other[math.random(1,3)] or ""
bulletImage.Size = gunshotsIdBasedOnMaterials.other.size --modified size
bulletImage.ImageTransparency = gunshotsIdBasedOnMaterials.other.ImageTransparency
bulletImage.ImageColor3 = raycastResult.Instance.Color
end
end
end
return bulletHole
If you know any simple solution to this problem or know a link please post it here, thank you in advance.