#Raycast Bullet Visualization Calculations

1 messages · Page 1 of 1 (latest)

regal pasture
#

In the video one can see that when a raycastResult instance is found, then the visualized bullet calculates the raycast as if there isn't an instance. It looks like its endPos is behind the wall and its trying to reach it. But i want to have it that the endPos is at the mousePos. How can i do that?

#
local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera
local mouse = player:GetMouse()

local function mouseRaycast()
    local mousePos = userInputService:GetMouseLocation()
    local mouseRay = camera:ViewportPointToRay(mousePos.X, mousePos.Y)
    
    local raycastParams = RaycastParams.new()
    raycastParams.FilterDescendantsInstances = filteredObjects
    raycastParams.FilterType = Enum.RaycastFilterType.Exclude
    
    local raycastResult = workspace:Raycast(player.Character:FindFirstChild("Head").Position, mouseRay.Direction * 50, raycastParams)
    return raycastResult
end

local function visualizeBullet(startPos, endPos)
    local length = (endPos - startPos).Magnitude
    
    local bullet = Instance.new("Part")

    bullet.Size = Vector3.new(0.15, 0.15, length)
    bullet.CFrame = CFrame.lookAt(startPos, endPos) * CFrame.new(0, 0, -length / 2)
    
    bullet.Parent = workspace.RaycastFilter
    
    table.insert(filteredObjects, bullet)
    
    local transparencyTween = tweenService:Create(bullet, TweenInfo.new(0.5, Enum.EasingStyle.Linear), {Transparency = 1})
    transparencyTween:Play()
    
    transparencyTween.Completed:Connect(function()
        bullet:Destroy()
        table.remove(filteredObjects, table.find(filteredObjects, bullet))
    end)
end

userInputService.InputBegan:Connect(function(input, processed)
    if input.UserInputType == Enum.UserInputType.MouseButton1 then
        local raycastResult = mouseRaycast()
        
        local startPos = gun.Handle.Muzzle.Position
        if raycastResult then
            visualizeBullet(startPos, raycastResult.Position)
            
        else
            local mousePos = userInputService:GetMouseLocation()
            local mouseRay = camera:ViewportPointToRay(mousePos.X, mousePos.Y)
            local endPos = mouseRay.Origin + mouseRay.Direction * 50
            
            visualizeBullet(startPos, endPos)
        end
    end
end)
visual jewel
#

Use Mouse.Hit as your mousePos.

#

I mean as your endpos

#

Mouse.Hit is a Vector if i am not wrong

regal pasture
#

No that doesnt work

#

I think because it doesnt use the raycast

dusty urchin
#
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")

local player = Players.LocalPlayer
local camera = workspace.CurrentCamera
local mouse = player:GetMouse()

local CONFIG = {
  RAYCAST_DISTANCE = 1000,
  BULLET_SPEED = 0.5,
  BULLET_SIZE = 0.15
}

local filteredObjects = {}
local gun = -- put yor gun here

local function mouseRaycast()
  local mousePos = UserInputService:GetMouseLocation()
  local mouseRay = camera:ViewportPointToRay(mousePos.X, mousePos.Y)
  
  local raycastParams = RaycastParams.new()
  raycastParams.FilterDescendantsInstances = filteredObjects
  raycastParams.FilterType = Enum.RaycastFilterType.Exclude
  
  
  local raycastResult = workspace:Raycast(
    gun.Handle.Muzzle.Position, 
    mouseRay.Direction * CONFIG.RAYCAST_DISTANCE, 
    raycastParams
  )
  
  return raycastResult, mouseRay
end

local function visualizeBullet(startPos, endPos)
  local length = (endPos - startPos).Magnitude
  
  local bullet = Instance.new("Part")
  bullet.Shape = Enum.PartType.Block
  bullet.Material = Enum.Material.Neon
  bullet.CanCollide = false
  bullet.Size = Vector3.new(CONFIG.BULLET_SIZE, CONFIG.BULLET_SIZE, length)
  bullet.CFrame = CFrame.lookAt(startPos, endPos) * CFrame.new(0, 0, -length / 2)
  bullet.TopSurface = Enum.SurfaceType.Smooth
  bullet.BottomSurface = Enum.SurfaceType.Smooth
  
  bullet.Parent = workspace:FindFirstChild("RaycastFilter") or workspace
  
  table.insert(filteredObjects, bullet)
  
  local transparencyTween = TweenService:Create(
    bullet, 
    TweenInfo.new(CONFIG.BULLET_SPEED, Enum.EasingStyle.Linear), 
    {Transparency = 1}
  )
  
  transparencyTween:Play()
  
  transparencyTween.Completed:Connect(function()
    bullet:Destroy()
    table.remove(filteredObjects, table.find(filteredObjects, bullet))
  end)
end

#
  if processed then return end
  
  if input.UserInputType == Enum.UserInputType.MouseButton1 then
    local raycastResult, mouseRay = mouseRaycast()
    local startPos = gun.Handle.Muzzle.Position
    
    
    local endPos = mouseRay.Origin + mouseRay.Direction * CONFIG.RAYCAST_DISTANCE
    
    
    if raycastResult then
      endPos = raycastResult.Position
    end
    
    visualizeBullet(startPos, endPos)
  end
end)```
#

EndPos is always in mouseRay - Now it always calculates from the mouse direction
If there is a raycastResult, use its position (this is for hits)
Raycast from the weapon - Not from the head
Defined variables - I added UserInputService and TweenService
Improved structure - Centralized CONFIG
Input validation - Verifies processed data

regal pasture
#

the problem is that, when i have the cursor on an instance which is in the 50 studs range then the endPos is not on the cursors position - or my explaining skills just lack. in the the video one can see

regal pasture
regal pasture
#

lol fixed