Hello, I am making a system of beams connecting between HumanoidRootPart and “closestPart” but I have a problem with beam attachment1 which is in Tween Position and in the loop. I want Attachemnt 1 to go from HumanoidRootPart to “closestPart” but its position is defined in a loop so something strange is going on with this attachment. Please help and sorry for a low details but I don’t know how to describe it. Maybe a short video will help.
Short video about issue:
local Player = game:GetService("Players").LocalPlayer
local HumanoidRootPart = Player.Character:WaitForChild("HumanoidRootPart")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Hacking = ReplicatedStorage.RemoteEvents:WaitForChild("Hacked")
local TweenService = game:GetService("TweenService")
local TweenInfo = TweenInfo.new(1)
local Beam = Instance.new("Beam")
local Attachment0 = Instance.new("Attachment")
local Attachment1 = Instance.new("Attachment")
local ProximityPrompt = Instance.new("ProximityPrompt")
local Info = Player:WaitForChild("PlayerInformation")
local DistanceValue = Info:WaitForChild("Distance")
local HoldingDuration = Info:WaitForChild("HoldingDuration")
local Cooldown = 5
local Debounce = true
RunService.Heartbeat:Connect(function()
if script.Equipped.Value == true and Debounce == true then
local closestMagnitude, closestPart = math.huge, nil
for _, parts in pairs(game.Workspace.Hackable:GetDescendants()) do
if parts.Name == "BasePart" then
local distance = (HumanoidRootPart.Position - parts.Position).Magnitude
if distance < closestMagnitude then
closestPart = parts --ISSUE STARTS HERE
Attachment1.Parent = closestPart
Attachment1.Position = HumanoidRootPart.Position
local PlrToBasePart = TweenService:Create(Attachment1, TweenInfo, {WorldPosition = Vector3.new(closestPart.Position.X, closestPart.Position.Y,closestPart.Position.Z)})
closestMagnitude = distance
Attachment0.Parent = HumanoidRootPart
ProximityPrompt.Parent = closestPart
Beam.Parent = HumanoidRootPart
Beam.Attachment0 = Attachment0
Beam.Attachment1 = Attachment1
PlrToBasePart:Play()
Beam.LightEmission = 1
Beam.LightInfluence = 1
Beam.Segments = 100
ProximityPrompt.Enabled = true
ProximityPrompt.HoldDuration = HoldingDuration.Value
ProximityPrompt.MaxActivationDistance = 70
ProximityPrompt.RequiresLineOfSight = false
ProximityPrompt.Style = "Custom"
ProximityPrompt.Exclusivity = Enum.ProximityPromptExclusivity.AlwaysShow
end
if closestMagnitude > DistanceValue.Value then
Beam.Attachment1 = nil
ProximityPrompt.Enabled = false
end
end
end
elseif script.Equipped.Value == false then
Beam.Attachment1 = nil
ProximityPrompt.Enabled = false
end
end)
Are you using TweenService to make the beam smoothly move to the target?
If I’m reading this correctly, it seems like you are creating and playing a tween every single frame.
In the video you’ve given, it looks like the attachment is struggling to tween to where it needs to be.
The problem is that the portion of the code that should be executed only once is being executed many times. I separated this code into two functions.
For it to work correctly it must first calculate which of the parts is closest and perform the action for only one of them (outside the loop).
I added a variable prevClosestPart to know when you are close to one part of the other or not close to any part. This way the functions I mentioned before will only be executed once.
I also changed the tween to work with CFrames. This way it is easier to do the calculations.
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Hacking = ReplicatedStorage.RemoteEvents:WaitForChild("Hacked")
local TweenService = game:GetService("TweenService")
local TweenInfo = TweenInfo.new(1)
local Beam = Instance.new("Beam")
local Attachment0 = Instance.new("Attachment")
local Attachment1 = Instance.new("Attachment")
local ProximityPrompt = Instance.new("ProximityPrompt")
--local Info = Player:WaitForChild("PlayerInformation") -- I commented this only for testing purposes
local DistanceValue = 20--Info:WaitForChild("Distance")
local HoldingDuration = 2--Info:WaitForChild("HoldingDuration")
local Cooldown = 5
local Debounce = true
function OnNear(closestPart)
Attachment1.Parent = closestPart
Attachment1.CFrame = closestPart.CFrame:ToObjectSpace(HumanoidRootPart.CFrame)
local PlrToBasePart = TweenService:Create(Attachment1, TweenInfo, {CFrame = CFrame.new()})
Attachment0.Parent = HumanoidRootPart
ProximityPrompt.Parent = closestPart
ProximityPrompt.Enabled = true
Beam.Parent = HumanoidRootPart
Beam.Attachment0 = Attachment0
Beam.Attachment1 = Attachment1
PlrToBasePart:Play()
Beam.LightEmission = 1
Beam.LightInfluence = 1
Beam.Segments = 100
ProximityPrompt.Enabled = true
ProximityPrompt.HoldDuration = HoldingDuration
ProximityPrompt.MaxActivationDistance = 70
ProximityPrompt.RequiresLineOfSight = false
ProximityPrompt.Style = "Custom"
ProximityPrompt.Exclusivity = Enum.ProximityPromptExclusivity.AlwaysShow
end
function OnFar()
Beam.Attachment1 = nil
ProximityPrompt.Enabled = false
end
local prevClosestPart = nil
RunService.Heartbeat:Connect(function()
if script.Equipped.Value == true and Debounce == true then
local closestMagnitude, closestPart = math.huge, nil
for _, parts in pairs(workspace.Hackable:GetDescendants()) do
if parts.Name == "BasePart" then
local distance = (HumanoidRootPart.Position - parts.Position).Magnitude
if distance < closestMagnitude and distance < DistanceValue then
closestPart = parts
closestMagnitude = distance
end
end
end
if closestPart then
if closestPart ~= prevClosestPart then
OnNear(closestPart)
prevClosestPart = closestPart
end
else
OnFar()
prevClosestPart = nil
end
elseif script.Equipped.Value == false then
Beam.Attachment1 = nil
ProximityPrompt.Enabled = false
end
end)