local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local Debris = game:GetService("Debris")

local localPlayer = Players.LocalPlayer

-- 원본 raycast 함수 보관 (무한 루프 방지용)
local originalRaycast = Workspace.Raycast

-- 궤적 이펙트를 그리는 보조 함수 (2초 유지)
local function drawTracer(startPos, endPos)
local attachment0 = Instance.new("Attachment")
attachment0.Position = startPos
attachment0.Parent = Workspace.Terrain

local attachment1 = Instance.new("Attachment")
attachment1.Position = endPos
attachment1.Parent = Workspace.Terrain

local beam = Instance.new("Beam")
beam.Attachment0 = attachment0
beam.Attachment1 = attachment1
beam.Width0 = 0.08
beam.Width1 = 0.08
beam.Color = ColorSequence.new(Color3.fromRGB(255, 215, 0)) -- 황금색 궤적
beam.FaceCamera = true
beam.Parent = Workspace.Terrain

Debris:AddItem(attachment0, 2)
Debris:AddItem(attachment1, 2)
Debris:AddItem(beam, 2)
end

-- [핵심] workspace:Raycast 함수를 전역적으로 변조 (Hooking)
Workspace.Raycast = function(self, origin, direction, userParams)
-- 기존 총기들이 쓰던 RaycastParams가 있으면 가져오고, 없으면 새로 생성
local raycastParams = userParams or RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude

-- 발사터 본인 캐릭터 강제 무시 리스트 삽입 (자신 통과)
local currentFilter = raycastParams.FilterDescendantsInstances or {}
if localPlayer.Character and not table.find(currentFilter, localPlayer.Character) then
table.insert(currentFilter, localPlayer.Character)
end
raycastParams.FilterDescendantsInstances = currentFilter

-- 변수 설정
local maxDistance = direction.Magnitude
local dirUnit = direction.Unit
local currentDistance = 0
local currentOrigin = origin

local finalResult = nil
local finalHitPosition = origin + direction

-- 모든 벽을 무제한으로 관통하며 플레이어(Humanoid)를 찾을 때까지 추적
while currentDistance < maxDistance do
local remainingDistance = maxDistance - currentDistance

-- 변조되지 않은 원본 레이캐스트 함수로 충돌 체크
local raycastResult = originalRaycast(Workspace, currentOrigin, dirUnit * remainingDistance, raycastParams)

if not raycastResult then
break
end

local hitInstance = raycastResult.Instance
local hitPosition = raycastResult.Position

currentDistance = currentDistance + (hitPosition - currentOrigin).Magnitude
finalHitPosition = hitPosition
finalResult = raycastResult -- 일단 맞은 결과 저장

-- 캐릭터(Humanoid)를 만났는지 검증
local character = hitInstance.Parent
local humanoid = character:FindFirstChildOfClass("Humanoid") or (character.Parent and character.Parent:FindFirstChildOfClass("Humanoid"))

if humanoid then
-- 플레이어를 찾았으므로 최종 결과로 확정하고 루프 종료
break
else
-- 캐릭터가 아니면 '무조건 벽'으로 간주하고 필터에 추가하여 관통 시킴
local updatedFilter = raycastParams.FilterDescendantsInstances
table.insert(updatedFilter, hitInstance)
raycastParams.FilterDescendantsInstances = updatedFilter

-- 충돌 지점 살짝 앞으로 레이 시작점 갱신
currentOrigin = hitPosition + (dirUnit * 0.05)
finalResult = nil -- 벽을 뚫었으므로 결과값은 일단 nil 처리 (다음 루프에서 적을 못찾으면 아무것도 안 맞은 걸로 반환)
end
end

-- 요청하신 2초 유지 총알 궤적을 화면에 생성
drawTracer(origin, finalHitPosition)

-- 기존 총기 스크립트들에게 최종 레이캐스트 결과값 반환 (데미지는 주지 않고 관통 판정만 넘김)
return finalResult
end

print("전역 모든 총알 벽 관통(월뱅) 시스템이 성공적으로 로드되었습니다.")

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: