Need help fixing the laser beam shining through the wall

  1. What do you want to achieve?
    I want my laser, not through a wall, it looks like laser cheating, I need you guys to help me fix this bug, it’s making me crazy
  2. What is the issue?
    Here is video about that bug:
    I dont want it not go though wall like this, it looking very bad

    Here is that bug, please help me it
  3. What solutions have you tried so far?
    I had trying to add more some script or deleted a bit script but it not working, here is what script have, please help edit it more or add more a bit script to remvoe this or guide me fix this on chat
    Control
wait(0)
local Tool = script.Parent
Handle = Tool.Handle
function Playerget()
	N=Tool.Parent.Name
	F=Game.Players:findFirstChild(N)
	return F
end
function NewLazer(Pos1,Pos2)
	P=Instance.new("Part")
	P.Name = "Lazer" 
	P.BrickColor = BrickColor.new("Persimmon")--Control the color here
	P.Transparency= 0.7
	P.Anchored = true 
	P.CanCollide = false
	P.CanTouch = false
	P.CanQuery = false
	P.CastShadow = false
	P.Material = Enum.Material.Neon
	P.formFactor = 0
	P.Size = Vector3.new(0.005,0.005,(Pos1-Pos2).magnitude) 
	P.CFrame = CFrame.new((Pos1+Pos2)/2,Pos1)+Vector3.new(0,0,0)
	M=Instance.new("BlockMesh")
	M.Scale = Vector3.new(0.03,0.03,1)
	M.Parent=P
	P.Parent = Tool.Spam
	return P
end
function Point(mouse)
	X = string.sub(mouse.Hit.X,1,4)
	Y = string.sub(mouse.Hit.Y,1,4)
	Z = string.sub(mouse.Hit.Z,1,4)
	Compile = Vector3.new(X,Y,Z)
	Lazer = NewLazer(Compile,Handle.Position)
	while true do	
		X = string.sub(mouse.Hit.X,1,4)
		Y = string.sub(mouse.Hit.Y,1,4)
		Z = string.sub(mouse.Hit.Z,1,4)
		Compile = Vector3.new(X,Y,Z)
		Lazer.Size = Vector3.new(1,1,(Compile-Handle.Position).magnitude) 
		Lazer.CFrame = CFrame.new((Compile+Handle.Position)/2,Compile)+Vector3.new(0,0,0)
		wait(0)
	end
end
function EQuip(mouse) 
	if(mouse~=nil)then
		Point(mouse)
	end
end
Tool.Equipped:connect(EQuip)

Cleaner

wait(0)
local Tool = script.Parent
function DeQuip()
	Spam=Tool.Spam:GetChildren()
	for i=1,#Spam do
		Spam[i]:Remove()
	end
end
Tool.Unequipped:connect(DeQuip)
1 Like

Here I was able to rewrite your script, I documented everything you possibly don’t know, I also merged both scripts you mentioned for simplicity. However, I am not able to test the code for other reasons I can’t explain here, so if you find any error please tell me and I’ll gladly help you.

The main reason why your script wasn’t working was that you weren’t raycasting (Raycasting | Roblox Creator Documentation)

local UserInputService = game:GetService("UserInputService") -- I prefer to use this over Mouse
local RunService = game:GetService("RunService") -- In order to replace the "while true do" loop which isn't the best option

local LaserRenderSteppedCon -- Saves the RunService loop here in case we need to disconnect it at any moment
local Laser -- Here we save the Laser object in case we need to destroy it at any moment

local Camera = workspace.CurrentCamera -- A camera will be needed
 
local Tool = script.Parent
local Handle = Tool.Handle
local Spam = Tool.Spam

local function Playerget() -- I recommend to index your functions locally, if you want to use the same function for many scripts, you can learn about ModuleScripts!
	local Character = Tool.Parent
	local Player = game:GetService("Players"):GetPlayerFromCharacter(Character)
	return Player
end

local function NewLazer(Pos1,Pos2)
	Laser = Instance.new("Part")
	Laser.Name = "Lazer" 
	Laser.BrickColor = BrickColor.new("Persimmon")--Control the color here
	Laser.Transparency= 0.7
	Laser.Anchored = true 
	Laser.CanCollide = false
	Laser.CanTouch = false
	Laser.CanQuery = false
	Laser.CastShadow = false
	Laser.Material = Enum.Material.Neon
	Laser.formFactor = 0
	Laser.Size = Vector3.new(0.005,0.005,(Pos1-Pos2).Magnitude) 
	Laser.CFrame = CFrame.new((Pos1+Pos2)/2,Pos1)+Vector3.new(0,0,0)
	
	local Mesh = Instance.new("BlockMesh")
	Mesh.Scale = Vector3.new(0.03,0.03,1)
	
	Mesh.Parent = Laser
	Laser.Parent = Spam
	
	return Laser
end

local function CalculateRayHit()
	local MouseLocation = UserInputService:GetMouseLocation() -- Gets mouse location on the screen
	local ScreenRay = Camera:ScreenPointToRay(MouseLocation.X, MouseLocation.Y) -- Gets a ray based on where the mouse is aiming at
	
	local MouseHitResults = workspace:Raycast(ScreenRay.Origin, ScreenRay.Direction * 500) -- Where the mouse is hitting in the workspace 
	local MouseHit = (MouseHitResults and MouseHitResults.Position) or (ScreenRay.Origin + ScreenRay.Direction * 500) -- In case the ray doesn't hit anything, calculate a placeholder position
	
	local RayDirection = (MouseHit - Handle.Position).Unit * 1000 -- Direction calculated from the difference between MouseHit and the tool
	local RayResults = workspace:Raycast(Handle.Position, RayDirection) -- Ray based on RayDirection
	return (RayResults and RayResults.Position) or (Handle.Position + RayDirection) -- In case the ray doesn't hit anything, calculate a placeholder position
end

local function Point()
	
	local RayPosition = CalculateRayHit() -- Where the laser is hitting
	
	NewLazer(RayPosition, Handle.Position) -- Create laser
	
	if LaserRenderSteppedCon then -- Safety check
		LaserRenderSteppedCon:Disconnect()
		LaserRenderSteppedCon = nil
	end
	
	LaserRenderSteppedCon = RunService.RenderStepped:Connect(function() -- This starts a loop that changes the laser's position
		if not Laser then return end
		RayPosition = CalculateRayHit() -- Update the laser position
		
		Laser.Size = Vector3.new(1,1,(RayPosition - Handle.Position).Magnitude) 
		Laser.CFrame = CFrame.lookAt((RayPosition+Handle.Position)/2,RayPosition)
	end)
end

Tool.Equipped:Connect(Point)

Tool.Unequipped:Connect(function()
	if LaserRenderSteppedCon then -- Disconnects the loop since we are not going to use it anymore
		LaserRenderSteppedCon:Disconnect()
		LaserRenderSteppedCon = nil
	end
	
	if Laser then
		Laser:Destroy()
		Laser = nil
	end
	
	-- vv below is kept for compatibility, I don't know if you're using this for something else besides destroying the laser
	
	local SpamChildren = Spam:GetChildren()
	
	if #SpamChildren == 0 then return end
	
	for _, SpamItem in ipairs(SpamChildren) do
		SpamItem:Destroy()
	end
end)
1 Like

Spam it’s Model, it using for spam laser so it’s not working @Conejin_Alt
“Cleaner” and “Control” isn’t script together

I’m not sure what you mean, I’m sorry for that.

I guess if you want to keep your current script then you can simply replace these lines in the original Control script:

X = string.sub(mouse.Hit.X,1,4)
Y = string.sub(mouse.Hit.Y,1,4)
Z = string.sub(mouse.Hit.Z,1,4)
Compile = Vector3.new(X,Y,Z)

with this code snippet:

local Difference = (mouse.Hit - Handle.Position)
local RayResults = workspace:Raycast(Handle.Position, Difference.Unit * 1000)
local Compile
if RayResults then
	Compile = RayResults.Position
else
	Compile = mouse.Hit
end

Again, the main issue was that you were not raycasting between the mouse target and the handle origin point, the function would not detect if there was a wall in between and just update the laser without other checks.

I hope this helps, if you encounter another error please tell me.

Here, but it’s not working @Conejin_Alt


it looks like this
Screenshot (1328)
Can you tell me step by step to understand to do it easy please?

It’s really hard to help you when you are not providing enough information related to the errors, in order to see any errors in a script, check the menu ribbon in the application, click on VIEW tab, and click on Output, this should open a window that shows any errors in a script.


Obtained from View Tab | Roblox Creator Documentation

As I previously said, replacing the lines I highlighted in your script with the ones I provided to you should fix the issue you’re mentioning, from the screenshot you’re showing, you forgot to replace this part in the script:
image

To help you with that, here I wrote it for you in the script (and explained in the script):

function Point(mouse)
	local Difference = (mouse.Hit - Handle.Position) -- Difference between where the mouse is aiming at and the tool handle
	local RayResults = workspace:Raycast(Handle.Position, Difference.Unit * 1000) -- Performs a raycast that checks for anything in a line between the tool handle and the mouse position in a nutshell
	local Compile 
	if RayResults then -- If something was hit
		Compile = RayResults.Position -- The compiled position would be the hit position
	else -- Otherwise...
		Compile = mouse.Hit -- The compiled position would be where the mouse is aiming at simply, as there are no obstacles in between
	end
	Lazer = NewLazer(Compile,Handle.Position)
	while true do	
		if not Lazer or Lazer.Parent == nil then break end
		local Difference = (mouse.Hit - Handle.Position)
		local RayResults = workspace:Raycast(Handle.Position, Difference.Unit * 1000)
		local Compile
		if RayResults then
			Compile = RayResults.Position
		else
			Compile = mouse.Hit
		end
		Lazer.Size = Vector3.new(1,1,(Compile-Handle.Position).magnitude) 
		Lazer.CFrame = CFrame.new((Compile+Handle.Position)/2,Compile)+Vector3.new(0,0,0)
		task.wait()
	end
end

Reading most of your script, this is NOT the best way to go, I already tried to provide you a rewritten version of your script, for now, and also whenever you do anything related to scripting, always keep the Output window open because it can really help you with errors.

Now, again, if you find any other errors, tell me, but ALSO show me the errors that appear in the Output window.

Now not bug and can you tell me how to let people see the laser?, only they can see when using it, I want it everyone can see that laser like you explain this

It would be much better if you create another post regarding your new issue in order to keep this post clean and on-topic.

You could create a RemoteEvent (read more about this here: Remote Events and Functions | Roblox Creator Documentation) that sends the mouse.Hit position to the server whenever the player moves their mouse, in the server, you can create another RemoteEvent that, instead of receiving signals from clients, it fires the mouse input to everyone else, then the clients will create a laser on their end and process its position based on the mouse input obtained from the server.

The issue with the laser going through the wall may be related to the fact that the laser’s collision is turned off. You can turn on the collision for the laser by setting P.CanCollide to true. This will make the laser collide with the wall and prevent it from passing through.

Here is an updated version of the NewLazer function that includes the collision:

function NewLazer(Pos1,Pos2)
    P=Instance.new("Part")
    P.Name = "Lazer" 
    P.BrickColor = BrickColor.new("Persimmon")
    P.Transparency= 0.7
    P.Anchored = true 
    P.CanCollide = true  -- Turn on collision
    P.CanTouch = false
    P.CanQuery = false
    P.CastShadow = false
    P.Material = Enum.Material.Neon
    P.formFactor = 0
    P.Size = Vector3.new(0.005,0.005,(Pos1-Pos2).magnitude) 
    P.CFrame = CFrame.new((Pos1+Pos2)/2,Pos1)+Vector3.new(0,0,0)
    M=Instance.new("BlockMesh")
    M.Scale = Vector3.new(0.03,0.03,1)
    M.Parent=P
    P.Parent = Tool.Spam
    return P
end

Additionally, you may want to add a check to ensure that the laser doesn’t collide with the player’s own character. You can do this by checking if the laser’s collision group is set to Enum.CollisionGroup.Character. If it is, you can set the collision group to Enum.CollisionGroup.Custom to prevent the laser from colliding with the player’s character.

Here is an updated version of the NewLazer function that includes the collision group check:

function NewLazer(Pos1,Pos2)
    P=Instance.new("Part")
    P.Name = "Lazer" 
    P.BrickColor = BrickColor.new("Persimmon")
    P.Transparency= 0.7
    P.Anchored = true 
    P.CanCollide = true  -- Turn on collision
    P.CanTouch = false
    P.CanQuery = false
    P.CastShadow = false
    P.Material = Enum.Material.Neon
    P.formFactor = 0
    P.Size = Vector3.new(0.005,0.005,(Pos1-Pos2).magnitude) 
    P.CFrame = CFrame.new((Pos1+Pos2)/2,Pos1)+Vector3.new(0,0,0)
    M=Instance.new("BlockMesh")
    M.Scale = Vector3.new(0.03,0.03,1)
    M.Parent=P
    P.Parent = Tool.Spam
    
    -- Check collision group and set to Custom if it is Character
    if P.CollisionGroupId == Enum.CollisionGroup.Character then
        P.CollisionGroupId = Enum.CollisionGroup.Custom
    end
    
    return P
end

I hope this helps!

I had using it and it’s not working
it looks like this @HolisThaDev
Screenshot (1328)
Hecate 2 is tool subject

can you help me that plz, I dont know much about remoteevent, I only know about script

So did you know how to make beam from attachment1(From) in handle to attachment2(To) it’s look likes laser for easy and beam will connecting to 2 this attachment and it will moving follow mouse, Attachment2(To) will move follow mouse where it moving.