Correcting the end position of a beam move(?)

  1. What do you want to achieve?
    I want to move the beam to the mouse (or at least to appear like it’s on the mouse) while maintaining its locked length of ~100 studs and make it stopped by objects in between.

  2. What is the issue?
    The beam goes directly through any objects and the end of it is far from where the mouse is.

  3. What solutions have you tried so far?
    I haven’t found any solutions to this problem so I haven’t tried anything yet which is why I’m making this post.

Here’s the demo script I’m using to test this:

local function GetWorldPosition(BasePosition: Vector3, Position: Vector3|Vector2, length: number)
	local UnitRay = workspace.CurrentCamera:ScreenPointToRay(Position.X, Position.Y)
	local Result = workspace:Raycast(UnitRay.Origin, UnitRay.Direction * length)
	if Result then
		return Result.Position
	else
		return BasePosition + (UnitRay.Direction * length)
	end
end

local mouse = game.Players.LocalPlayer:GetMouse()
local range = 100
local beaming = false

game:GetService("UserInputService").InputEnded:Connect(function(key,busy)
	if busy then elseif key.KeyCode == Enum.KeyCode.F then
beaming = false
	end
end)

game:GetService("UserInputService").InputBegan:Connect(function(key,busy)
	if busy then elseif key.KeyCode == Enum.KeyCode.F then
		beaming = true
		local beam = game.ReplicatedStorage["Beam Holder"].a0:Clone()
		local beamattachment = Instance.new("Attachment")
		beam.Parent = game.Players.LocalPlayer.Character.LeftHand
		for i,v in pairs(beam:GetChildren()) do
			v.Attachment1 = beamattachment
		end
		beamattachment.Parent = game.Workspace.Terrain
		while beaming and wait() do
			local hitpos = mouse.Hit.Position
			if (hitpos-game.Players.LocalPlayer.Character.HumanoidRootPart.Position).magnitude > range then
				hitpos = GetWorldPosition(game.Players.LocalPlayer.Character.HumanoidRootPart.Position,game:GetService("UserInputService"):GetMouseLocation(),range)
			end
			beamattachment.WorldPosition = hitpos
		end
	end
end)

Do a raycast from the origin of the beam to where your mouse is, and make it stop at wherever it hits inbetween

How would I go about incorporating that to my current script?

local Player = game:GetService("Players").LocalPlayer
local Camera = workspace.CurrentCamera

local mouse = game.Players.LocalPlayer:GetMouse()
local range = 100
local beaming = false

game:GetService("UserInputService").InputEnded:Connect(function(key,busy)
	if busy then elseif key.KeyCode == Enum.KeyCode.F then
		beaming = false
	end
end)

game:GetService("UserInputService").InputBegan:Connect(function(key,busy)
	if busy then elseif key.KeyCode == Enum.KeyCode.F then
		beaming = true
		local beam = game.ReplicatedStorage["Beam Holder"].a0:Clone()
		local beamattachment = Instance.new("Attachment")
		beam.Parent = game.Players.LocalPlayer.Character.LeftHand
		for i,v in pairs(beam:GetChildren()) do
			v.Attachment1 = beamattachment
		end
		beamattachment.Parent = game.Workspace.Terrain
		while beaming and wait() do
			local hitpos = mouse.Hit.LookVector
			local IgnoreParams = RaycastParams.new()
			IgnoreParams.FilterType = Enum.RaycastFilterType.Blacklist
			local FilterList = {}
			for p, v in pairs(Player.Character:GetChildren()) do
				table.insert(FilterList, v)
			end
			IgnoreParams.FilterDescendantsInstances = FilterList
			local RayResult = workspace:Raycast(Player.Character.Head.Position, hitpos*range, IgnoreParams)
			
			if RayResult then
				hitpos = RayResult.Position
			else
				hitpos = hitpos*range+Player.Character.PrimaryPart.Position
			end
			beamattachment.WorldPosition = hitpos
		end
	end
end)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.