so recently I posted a topic similar to this one except this time I’ve found a script that makes a part where the raycast is
please note that I have no idea what I’m doing I found this script from a tutorial on youtube:
local radius = 1
local function MakeRayVisible(ray)
local midpoint = ray.Origin + ray.Direction/2
local part = Instance.new("Part")
part.Parent = workspace
part.Anchored = true
part.CFrame = CFrame.new(midpoint, ray.Origin)
part.Size = Vector3.new(radius, radius, ray.Direction.Magnitude)
return part
end
local part = script.Parent
local Origin = part.Position
local direction = part.CFrame.LookVector*1000
local ray = Ray.new(Origin, direction)
MakeRayVisible(ray)
the issue is the part goes through the wall which is bad. Is there a way so the raycast doen’t go through the wall?
thanks
Just perform the raycast and take the length of the hit.Position - part.Position updated code:
local radius = 1
local function MakeRayVisible(ray)
local part = Instance.new("Part")
part.Anchored = true
local result = workspace:Raycast(ray.Origin, ray.Direction)
local len = ray.Direction.Magnitude
if result then
len = (ray.Origin - result.Position).Magnitude
end
part.Size = Vector3.new(radius, radius, len)
part.CFrame = CFrame.new(ray.Origin, ray.Direction) * CFrame.new(0, 0, -len*0.5)
part.Parent = workspace
return part
end
local part = script.Parent
local Origin = part.Position
local direction = part.CFrame.LookVector*1000
local ray = Ray.new(Origin, direction)
MakeRayVisible(ray)
ofcourse just check the ray each frame and destroy the previous one:
local RunService = game:GetService("RunService")
local radius = 1
local function MakeRayVisible(ray)
local part = Instance.new("Part")
part.Anchored = true
local result = workspace:Raycast(ray.Origin, ray.Direction)
local len = ray.Direction.Magnitude
if result then
len = (ray.Origin - result.Position).Magnitude
end
part.Size = Vector3.new(radius, radius, len)
part.CFrame = CFrame.new(ray.Origin, ray.Direction) * CFrame.new(0, 0, -len*0.5)
part.Parent = workspace
return part
end
do
local part = script.Parent
local lastRayPart = nil
RunService.Heartbeat:Connect(function()
if lastRayPart then
lastRayPart:Destroy()
end
local Origin = part.Position
local direction = part.CFrame.LookVector*1000
local ray = Ray.new(Origin, direction)
lastRayPart = MakeRayVisible(ray)
end)
end
You can also cast the ray and check if the hit is and Humanoid BodyPart
local function getPlayerHit(origin: Vector3, direction: Vector3): (Player, Humanoid)?
-- Create a whitelist with all players
local playerCharacters = {}
for _, player in ipairs(Players:GetPlayers()) do
if player.Character then
table.insert(playerCharacters, player.Character)
end
end
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Whitelist
params.FilterDescendantsInstances = playerCharacters
local result = workspace:Raycast(origin, direction, params)
if result then
local character, humanoid = result.Instance
--- Idk if this is necesery but just repeat get parent until we have the character
repeat
character = character.Parent
humanoid = character and character:FindFirstChild("Humanoid")
until character == nil or humanoid
if not character then
warn("Something went wrong did not find the player's character")
end
return Players:GetPlayerFromCharacter(character), humanoid
end
end
local origin = part.Position
local direction = part.CFrame.LookVector*1000
local player, humanoid = getPlayerHit(origin, direction)
if player then -- do something example
humanoid:TakeDamage(50)
end
local RunService = game:GetService("RunService")
---------- spot 1
local radius = 1
local function MakeRayVisible(ray)
local part = Instance.new("Part")
part.Anchored = true
part.BrickColor = BrickColor.new("Really red")
part.Material = "Neon"
part.CanCollide = false
--- spot 2
local result = workspace:Raycast(ray.Origin, ray.Direction)
local len = ray.Direction.Magnitude
if result then
len = (ray.Origin - result.Position).Magnitude
end
part.Size = Vector3.new(radius, radius, len)
part.CFrame = CFrame.new(ray.Origin, ray.Direction) * CFrame.new(0, 0, -len*0.5)
part.Parent = workspace
return part
end
------ spot 3
do
local Part = script.Parent
local lastRayPart = nil
RunService.Heartbeat:Connect(function()
if lastRayPart then
lastRayPart:Destroy()
end
local Origin = Part.Position
local direction = Part.CFrame.LookVector*1000
-----spot 4
local ray = Ray.new(Origin, direction)
lastRayPart = MakeRayVisible(ray)
end)
end
----------- spot 5
local function getPlayerHit(origin: Vector3, direction: Vector3): (Player, Humanoid)?
-- Create a whitelist with all players
local playerCharacters = {}
for _, player in ipairs(Players:GetPlayers()) do
if player.Character then
table.insert(playerCharacters, player.Character)
end
end
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Whitelist
params.FilterDescendantsInstances = playerCharacters
local result = workspace:Raycast(origin, direction, params)
if result then
local character, humanoid = result.Instance
--- Idk if this is necesery but just repeat get parent until we have the character
repeat
character = character.Parent
humanoid = character and character:FindFirstChild("Humanoid")
until character == nil or humanoid
if not character then
warn("Something went wrong did not find the player's character")
end
return Players:GetPlayerFromCharacter(character), humanoid
end
end
Do you want to check hits when the player pressed a button or just all the time?
The script is a ServerScript right otherwise you need some RemoteEvent instead.
local Debris = game:GetService("Debris")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local RAY_LIFETIME = 0.1
local RAY_RADIUS = 1
local RAY_COLOR = BrickColor.Red()
local RAY_TRANSPARENCY = 0.5
--- function to get player hit returns a player and humanoid
local function GetPlayerHit(origin: Vector3, direction: Vector3): (Player?, Humanoid?)
-- Create a whitelist with all players
local playerCharacters = {}
for _, player in ipairs(Players:GetPlayers()) do
if player.Character then
table.insert(playerCharacters, player.Character)
end
end
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Whitelist
params.FilterDescendantsInstances = playerCharacters
local result = workspace:Raycast(origin, direction, params)
if result then
local character, humanoid = result.Instance
--- idk if this is necesery but just repeat get parent until we have the character
repeat
character = character.Parent
humanoid = character and character:FindFirstChild("Humanoid")
until character == nil or humanoid
if not character then
warn("Something went wrong did not find the player's character")
end
return Players:GetPlayerFromCharacter(character), humanoid
end
end
local function DrawRay(origin: Vector3, direction: Vector3)
local part = Instance.new("Part")
part.Name = "Ray"
part.Anchored = true
local result = workspace:Raycast(origin, direction)
local len = (origin + direction).Magnitude
if result then
len = (origin - direction).Magnitude
end
part.Size = Vector3.new(RAY_RADIUS , RAY_RADIUS , len)
part.Material = Enum.Material.SmoothPlastic
part.BrickColor = RAY_COLOR
part.Transparency = RAY_TRANSPARENCY
part.CFrame = CFrame.new(ray.Origin, ray.Direction) * CFrame.new(0, 0, -len*0.5)
part.Parent = workspace
return part
end
--- Ray loop
do
local part = script.Parent
local lastRayPart
RunService.Heartbeat:Connect(function()
if lastRayPart then
lastRayPart:Destroy()
end
local origin = part.Position
local direction = part.CFrame.LookVector*1000
local rayPart = DrawRay(origin, direction)
--- Add the ray to debris to remove after a sertain amount of time
Debris:AddItem(rayPart, RAY_LIFETIME)
local player, humanoid = GetPlayerHit(origin, direction)
if player then -- do something example
humanoid:TakeDamage(50)
end
end)
end
local character, humanoid = result.Instance has the error UnbalancedAssignment: (31,3) Assigning 1 values to 2 variables initializes extra variables with nil; add 'nil' to value list to silence
part.CFrame = CFrame.new(ray.Origin, ray.Direction) * CFrame.new(0, 0, -len*0.5) has the error UnknownGlobal: (64,27) Unknown global 'ray'
if lastRayPart then has the error UninitializedLocal: (79,6) Variable 'lastRayPart' defined at line 75 is never initialized or assigned; initialize with 'nil' to silence
ServerScripts can also be inserted under any descendant of the workspace and the workspace itself So you can put it under your part.
local Debris = game:GetService("Debris")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local RAY_LIFETIME = 0.1
local RAY_RADIUS = 1
local RAY_COLOR = BrickColor.Red()
local RAY_TRANSPARENCY = 0.5
--- function to get player hit returns a player and humanoid
local function GetPlayerHit(origin: Vector3, direction: Vector3): (Player?, Humanoid?)
-- Create a whitelist with all players
local playerCharacters = {}
for _, player in ipairs(Players:GetPlayers()) do
if player.Character then
table.insert(playerCharacters, player.Character)
end
end
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Whitelist
params.FilterDescendantsInstances = playerCharacters
local result = workspace:Raycast(origin, direction, params)
if result then
local character, humanoid = result.Instance, nil
--- idk if this is necesery but just repeat get parent until we have the character
repeat
character = character.Parent
humanoid = character and character:FindFirstChild("Humanoid")
until character == nil or humanoid
if not character then
warn("Something went wrong did not find the player's character")
end
return Players:GetPlayerFromCharacter(character), humanoid
end
end
local function DrawRay(origin: Vector3, direction: Vector3)
local part = Instance.new("Part")
part.Name = "Ray"
part.Anchored = true
local result = workspace:Raycast(origin, direction)
local len = (origin + direction).Magnitude
if result then
len = (origin - direction).Magnitude
end
part.Size = Vector3.new(RAY_RADIUS , RAY_RADIUS , len)
part.Material = Enum.Material.SmoothPlastic
part.BrickColor = RAY_COLOR
part.Transparency = RAY_TRANSPARENCY
part.CFrame = CFrame.new(origin, direction) * CFrame.new(0, 0, -len*0.5)
part.Parent = workspace
return part
end
--- Ray loop
do
local part = script.Parent
local lastRayPart = nil
RunService.Heartbeat:Connect(function()
if lastRayPart then
lastRayPart:Destroy()
end
local origin = part.Position
local direction = part.CFrame.LookVector*1000
local rayPart = DrawRay(origin, direction)
--- Add the ray to debris to remove after a sertain amount of time
Debris:AddItem(rayPart, RAY_LIFETIME)
local player, humanoid = GetPlayerHit(origin, direction)
if player then -- do something example
humanoid:TakeDamage(50)
end
end)
end
thanks for all of your help and I’m sorry I’m an idiot but, it’s going through walls for some reason
sorry about all of the issues but I’m pretty sure that this will be the last one
Don’t worry happy to help here you go.
Added config vars at the top.
RAY_RADIUS → number | Ray thickness
RAY_COLOR → BrickColor. | color of part
RAY_TRANSPARENCY → number | Transparency [0 - 1].
RAY_INTERVAL → number | how many seconds to wait to shoot a ray set it 0 if you want all the time.
RAY_DURATION → number | how long the beam should shoot.
for a little test set both RAY_INTERVAL and RAY_DURATION to 1
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local RAY_RADIUS = 1
local RAY_COLOR = BrickColor.Red()
local RAY_TRANSPARENCY = 0.5
local RAY_INTERVAL = 0 -- Ray shoot interval in seconds set it to zero for no interval
local RAY_DURATION = 0 -- How long until we stop shooting
--- function to get player hit returns a player and humanoid
local function GetPlayerHit(origin: Vector3, direction: Vector3): (Player?, Humanoid?)
-- Create a whitelist with all players
local playerCharacters = {}
for _, player in ipairs(Players:GetPlayers()) do
if player.Character then
table.insert(playerCharacters, player.Character)
end
end
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Whitelist
params.FilterDescendantsInstances = playerCharacters
local result = workspace:Raycast(origin, direction, params)
if result then
local character, humanoid = result.Instance, nil
--- idk if this is necesery but just repeat get parent until we have the character
repeat
character = character.Parent
humanoid = character and character:FindFirstChild("Humanoid")
until character == nil or humanoid
if not character then
warn("Something went wrong did not find the player's character")
end
return Players:GetPlayerFromCharacter(character), humanoid
end
return nil, nil -- to silent the warning
end
local function DrawRay(origin: Vector3, direction: Vector3)
local part = Instance.new("Part")
part.Name = "Ray"
part.Anchored = true
local result = workspace:Raycast(origin, direction)
local len = (origin - (origin + direction)).Magnitude
if result then
len = (origin - result.Position).Magnitude
end
part.Size = Vector3.new(RAY_RADIUS, RAY_RADIUS , len)
part.Material = Enum.Material.SmoothPlastic
part.BrickColor = RAY_COLOR
part.Transparency = RAY_TRANSPARENCY
part.CFrame = CFrame.new(origin, direction) * CFrame.new(0, 0, -len*0.5)
part.Parent = workspace
return part
end
--- Ray loop
do
local part = script.Parent
local lastRayPart = nil
local timePassed = RAY_INTERVAL
RunService.Heartbeat:Connect(function(dt: number)
if lastRayPart and lastRayPart.Parent then -- if debris is to slow
lastRayPart:Destroy()
end
timePassed += dt
if timePassed < RAY_INTERVAL then -- Return if its not time yet
return
end
if timePassed > RAY_INTERVAL + RAY_DURATION then -- Reset the time passed after the duration has been reached
timePassed = 0
end
local origin = part.Position
local direction = part.CFrame.LookVector*1000
lastRayPart = DrawRay(origin, direction)
local player, humanoid = GetPlayerHit(origin, direction)
if player then -- do something example
humanoid:TakeDamage(50)
end
end)
end
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local RAY_RADIUS = 1
local RAY_COLOR = BrickColor.Red()
local RAY_TRANSPARENCY = 0.5
local RAY_INTERVAL = 0 -- Ray shoot interval in seconds set it to zero for no interval
local RAY_DURATION = 0 -- How long until we stop shooting
--- function to get player hit returns a player and humanoid
local function GetPlayerHit(origin: Vector3, direction: Vector3): (Player?, Humanoid?)
local result = workspace:Raycast(origin, direction)
if result then
local character, humanoid = result.Instance, nil
--- idk if this is necesery but just repeat get parent until we have the character
repeat
character = character.Parent
humanoid = character and character:FindFirstChild("Humanoid")
until character == nil or humanoid
if not character or not humanoid then
return
end
return Players:GetPlayerFromCharacter(character), humanoid
end
return nil, nil -- to silent the warning
end
local function DrawRay(origin: Vector3, direction: Vector3)
local part = Instance.new("Part")
part.Name = "Ray"
part.Anchored = true
local result = workspace:Raycast(origin, direction)
local len = (origin - (origin + direction)).Magnitude
if result then
len = (origin - result.Position).Magnitude
end
part.Size = Vector3.new(RAY_RADIUS, RAY_RADIUS , len)
part.Material = Enum.Material.SmoothPlastic
part.BrickColor = RAY_COLOR
part.Transparency = RAY_TRANSPARENCY
part.CFrame = CFrame.new(origin, direction) * CFrame.new(0, 0, -len*0.5)
part.Parent = workspace
return part
end
--- Ray loop
do
local part = script.Parent
local lastRayPart = nil
local timePassed = RAY_INTERVAL
RunService.Heartbeat:Connect(function(dt: number)
if lastRayPart and lastRayPart.Parent then -- if debris is to slow
lastRayPart:Destroy()
end
timePassed += dt
if timePassed < RAY_INTERVAL then -- Return if its not time yet
return
end
if timePassed > RAY_INTERVAL + RAY_DURATION then -- Reset the time passed after the duration has been reached
timePassed = 0
end
local origin = part.Position
local direction = part.CFrame.LookVector*1000
lastRayPart = DrawRay(origin, direction)
local player, humanoid = GetPlayerHit(origin, direction)
if player then -- do something example
humanoid:TakeDamage(50)
end
end)
end