So I have a beam and attachments that are parented to the Humanoid Root Part but when I tried testing it in first person, it works but when you start jumping and moving, the beam starts glitching.
Code:
local attach0 = Instance.new("Attachment")
local attach1 = Instance.new("Attachment")
AimBeam.Attachment0 = attach0
AimBeam.Attachment1 = attach1
attach0.Parent = HumanoidRootPart
attach1.Parent = HumanoidRootPart
local function beamProjectile(gravity, initialVelocity, initialPosition, duration)
local c = 0.5 * 0.5 * 0.5
local p3 = 0.5 * gravity * duration * duration + initialVelocity * duration + initialPosition
local p2 = p3 - (gravity * duration * duration + initialVelocity * duration) / 3
local p1 = (c * gravity * duration * duration + 0.5 * initialVelocity * duration + initialPosition - c * (initialPosition + p3)) / (3 * c) - p2
local curve0 = (p1 - initialPosition).Magnitude
local curve1 = (p2 - p3).Magnitude
local b = Vector3.new(0, 1, 0) -- Set the beam direction to always point upward
local r1 = (p1 - initialPosition).Unit
local u1 = b:Cross(r1).Unit
local r2 = (p2 - p3).Unit
local u2 = b:Cross(r2).Unit
b = r1:Cross(u1).Unit
local cf1 = CFrame.new(initialPosition.X, initialPosition.Y, initialPosition.Z, r1.X, u1.X, b.X, r1.Y, u1.Y, b.Y, r1.Z, u1.Z, b.Z)
local cf2 = CFrame.new(p3.X, p3.Y, p3.Z, r2.X, u2.X, b.X, r2.Y, u2.Y, b.Y, r2.Z, u2.Z, b.Z)
return curve0, -curve1, cf1, cf2
end
local function createAndSetBeam(gravity, initialVelocity, initialPosition, endTime)
local t1 = endTime or 1
local curve0, curve1, cf1, cf2 = beamProjectile(gravity, initialVelocity, initialPosition, t1)
AimBeam.CurveSize0 = curve0
AimBeam.CurveSize1 = curve1
AimBeam.Segments = 100 * math.round(t1 * 3)
attach0.CFrame = HumanoidRootPart.CFrame:Inverse() * cf1 + Vector3.new(2.6, 1.5, -1.5)
attach1.CFrame = HumanoidRootPart.CFrame:Inverse() * cf2
end
local function aimTrajectory()
buttonDownConnection = RunService.RenderStepped:Connect(function(delta)
local endTime = 5
local direction = (mouse.Hit.Position - HumanoidRootPart.Position).Unit
local appliedVelocity = direction * projectileSpeed
createAndSetBeam(gravity, appliedVelocity, HumanoidRootPart.Position, endTime)
end)
end
local RunService = game:GetService("RunService")
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local HumanoidRootPart = character:WaitForChild("HumanoidRootPart")
local mouse = player:GetMouse()
mouse.TargetFilter = workspace
local tool = script.Parent
local Handle = tool:WaitForChild("Handle")
local AimBeam = Handle:WaitForChild("AimBeam")
local cooldown = 0.1
local currentTime = cooldown
local canThrow = true
local DataModule = require(script:WaitForChild("DataModule"))
local projectileSpeed = DataModule.ProjectileSpeed
local gravity = DataModule.EffectGravity
local buttonDownConnection
local attach0 = Instance.new("Attachment")
local attach1 = Instance.new("Attachment")
AimBeam.Attachment0 = attach0
AimBeam.Attachment1 = attach1
attach0.Parent = HumanoidRootPart
attach1.Parent = HumanoidRootPart
local function setButtonDownConnectionNil()
if buttonDownConnection then
buttonDownConnection:Disconnect()
buttonDownConnection = nil
end
end
local function resetAll()
setButtonDownConnectionNil()
AimBeam.Enabled = false
attach0:Destroy()
attach1:Destroy()
end
local function beamProjectile(gravity, initialVelocity, initialPosition, duration)
local c = 0.5 * 0.5 * 0.5
local p3 = 0.5 * gravity * duration * duration + initialVelocity * duration + initialPosition
local p2 = p3 - (gravity * duration * duration + initialVelocity * duration) / 3
local p1 = (c * gravity * duration * duration + 0.5 * initialVelocity * duration + initialPosition - c * (initialPosition + p3)) / (3 * c) - p2
local curve0 = (p1 - initialPosition).Magnitude
local curve1 = (p2 - p3).Magnitude
local b = Vector3.new(0, 1, 0) -- Set the beam direction to always point upward
local r1 = (p1 - initialPosition).Unit
local u1 = b:Cross(r1).Unit
local r2 = (p2 - p3).Unit
local u2 = b:Cross(r2).Unit
b = r1:Cross(u1).Unit
local cf1 = CFrame.new(initialPosition.X, initialPosition.Y, initialPosition.Z, r1.X, u1.X, b.X, r1.Y, u1.Y, b.Y, r1.Z, u1.Z, b.Z)
local cf2 = CFrame.new(p3.X, p3.Y, p3.Z, r2.X, u2.X, b.X, r2.Y, u2.Y, b.Y, r2.Z, u2.Z, b.Z)
return curve0, -curve1, cf1, cf2
end
local function createAndSetBeam(gravity, initialVelocity, initialPosition, endTime)
local t1 = endTime or 1
local curve0, curve1, cf1, cf2 = beamProjectile(gravity, initialVelocity, initialPosition, t1)
AimBeam.CurveSize0 = curve0
AimBeam.CurveSize1 = curve1
AimBeam.Segments = 100 * math.round(t1 * 3)
attach0.CFrame = HumanoidRootPart.CFrame:Inverse() * cf1 + Vector3.new(2.6, 1.5, -1.5)
attach1.CFrame = HumanoidRootPart.CFrame:Inverse() * cf2
end
local function aimTrajectory()
buttonDownConnection = RunService.RenderStepped:Connect(function(delta)
local endTime = 5
local direction = (mouse.Hit.Position - HumanoidRootPart.Position).Unit
local appliedVelocity = direction * projectileSpeed
createAndSetBeam(gravity, appliedVelocity, HumanoidRootPart.Position, endTime)
end)
end
mouse.Button1Down:Connect(function()
if canThrow and tool:IsDescendantOf(character) and tick() - currentTime >= cooldown then
AimBeam.Enabled = true
aimTrajectory()
end
end)
mouse.Button1Up:Connect(function()
if canThrow and tool:IsDescendantOf(character) and tick() - currentTime >= cooldown then
currentTime = tick()
local mouseHit = mouse.Hit.Position
local startPos = attach0.WorldPosition
script.ServerSender:FireServer(startPos, mouseHit)
setButtonDownConnectionNil()
AimBeam.Enabled = false
else
resetAll()
end
end)
tool.Destroying:Connect(function()
resetAll()
end)
humanoid.Died:Connect(function()
canThrow = false
resetAll()
end)
I don’t think the problem is from the mouse, I tried using the middle point of the screen and convert it to 3D space point but same results:
local function aimTrajectory()
buttonDownConnection = RunService.Stepped:Connect(function(delta)
local endTime = 5
local Vector = Vector2.new(workspace.CurrentCamera.ViewportSize.X / 2, workspace.CurrentCamera.ViewportSize.Y / 2 - (game:GetService("GuiService"):GetGuiInset().Y/2))
local mouseUnitRay = workspace.CurrentCamera:ScreenPointToRay(Vector.X, Vector.Y)
local direction = mouseUnitRay.Direction
local appliedVelocity = direction * projectileSpeed
createAndSetBeam(gravity, appliedVelocity, HumanoidRootPart.Position, endTime)
end)
end
The problem is not from your code it’s from the Roblox render system and I think you are right, in first person mode the mouse hit position does not change that fast while jumping because you are not moving the mouse you moving the character that’s why it’s late a little, it’s faster using RunService.Stepped but still not enough that’s why it glitchs sometimes, the same thing for this:
take a look at this simple script, it also keeps glitching in it:
local RunService = game:GetService("RunService")
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local HumanoidRootPart = character:WaitForChild("HumanoidRootPart")
local mouse = player:GetMouse()
local Beam = Instance.new("Beam",HumanoidRootPart)
local att0 = Instance.new("Attachment",HumanoidRootPart)
local att1 = Instance.new("Attachment",HumanoidRootPart)
Beam.Attachment0 = att0
Beam.Attachment1 = att1
Beam.FaceCamera = true
function Update()
att0.WorldPosition = HumanoidRootPart.CFrame.Position
att1.WorldPosition = mouse.Hit.p
end
RunService.RenderStepped:Connect(Update)
so the problem is from the engine and sadly you can’t do anything about it, your best option now is to just use RunService.Stepped it’s the fastest looping event available in Roblox.
Now I got it, I was wrong the mouse is not the problem it’s because in first person mode the HumanoidRootPart move with the camera so the two attachment inside of it move too in the same time your script keep updating the attachment position, I was able to solve it in this exemple by adding the second attachment into other part not the HumanoidRootPart
but when I did that in your code it glitch another way, you can test it by yourself if you want:
local RunService = game:GetService("RunService")
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local HumanoidRootPart = character:WaitForChild("HumanoidRootPart")
local mouse = player:GetMouse()
mouse.TargetFilter = workspace
local tool = script.Parent
local Handle = tool:WaitForChild("Handle")
local AimBeam = Handle:WaitForChild("AimBeam")
local cooldown = 0.1
local currentTime = cooldown
local canThrow = true
local DataModule = require(script:WaitForChild("DataModule"))
local projectileSpeed = DataModule.ProjectileSpeed
local gravity = DataModule.EffectGravity
local buttonDownConnection
local FakePart = Instance.new("Part",game.Workspace)
FakePart.Massless = true
FakePart.Anchored = true
FakePart.Size = Vector3.new(0.1,0.1,0.1)
FakePart.Transparency = 1
local attach0 = Instance.new("Attachment",HumanoidRootPart)
local attach1 = Instance.new("Attachment",FakePart)
AimBeam.Attachment0 = attach0
AimBeam.Attachment1 = attach1
local function setButtonDownConnectionNil()
if buttonDownConnection then
buttonDownConnection:Disconnect()
buttonDownConnection = nil
end
end
local function resetAll()
setButtonDownConnectionNil()
AimBeam.Enabled = false
attach0:Destroy()
attach1:Destroy()
end
local function beamProjectile(gravity, initialVelocity, initialPosition, duration)
local c = 0.5 * 0.5 * 0.5
local p3 = 0.5 * gravity * duration * duration + initialVelocity * duration + initialPosition
local p2 = p3 - (gravity * duration * duration + initialVelocity * duration) / 3
local p1 = (c * gravity * duration * duration + 0.5 * initialVelocity * duration + initialPosition - c * (initialPosition + p3)) / (3 * c) - p2
local curve0 = (p1 - initialPosition).Magnitude
local curve1 = (p2 - p3).Magnitude
local b = Vector3.new(0, 1, 0) -- Set the beam direction to always point upward
local r1 = (p1 - initialPosition).Unit
local u1 = b:Cross(r1).Unit
local r2 = (p2 - p3).Unit
local u2 = b:Cross(r2).Unit
b = r1:Cross(u1).Unit
local cf1 = CFrame.new(initialPosition.X, initialPosition.Y, initialPosition.Z, r1.X, u1.X, b.X, r1.Y, u1.Y, b.Y, r1.Z, u1.Z, b.Z)
local cf2 = CFrame.new(p3.X, p3.Y, p3.Z, r2.X, u2.X, b.X, r2.Y, u2.Y, b.Y, r2.Z, u2.Z, b.Z)
return curve0, -curve1, cf1, cf2
end
local function createAndSetBeam(gravity, initialVelocity, initialPosition, endTime)
local t1 = endTime or 1
local curve0, curve1, cf1, cf2 = beamProjectile(gravity, initialVelocity, initialPosition, t1)
AimBeam.CurveSize0 = curve0
AimBeam.CurveSize1 = curve1
AimBeam.Segments = 100 * math.round(t1 * 3)
attach0.CFrame = HumanoidRootPart.CFrame:Inverse() * cf1 + Vector3.new(2.6, 1.5, -1.5)
attach1.CFrame = FakePart.CFrame:Inverse() * cf2
end
local function aimTrajectory()
buttonDownConnection = RunService.RenderStepped:Connect(function(delta)
local endTime = 5
local direction = (mouse.Hit.Position - HumanoidRootPart.Position).Unit
local appliedVelocity = direction * projectileSpeed
createAndSetBeam(gravity, appliedVelocity, HumanoidRootPart.Position, endTime)
end)
end
mouse.Button1Down:Connect(function()
if canThrow and tool:IsDescendantOf(character) and tick() - currentTime >= cooldown then
AimBeam.Enabled = true
aimTrajectory()
end
end)
mouse.Button1Up:Connect(function()
if canThrow and tool:IsDescendantOf(character) and tick() - currentTime >= cooldown then
currentTime = tick()
local mouseHit = mouse.Hit.Position
local startPos = attach0.WorldPosition
script.ServerSender:FireServer(startPos, mouseHit)
setButtonDownConnectionNil()
AimBeam.Enabled = false
else
resetAll()
end
end)
tool.Destroying:Connect(function()
resetAll()
end)
humanoid.Died:Connect(function()
canThrow = false
resetAll()
end)
it’s because the script still updating the first attachment while it’s turning with the HumanoidRootPart and I don’t know how to solve it, taking the first attachment out of the HRP will make it glitch even more.