Does anyone have any idea how this is achieved? Because by the looks of it, the beam is resizes depending on the distance it has reached, meaning the ray API is used. But would this mean hundreds of rays are being fired to figure out the distance of the beam as well as acting as a damager? I have a feeling if I did this it would not be healthy for the server to deal with.
Furthermore, there is a particle at the end of the ray which suggests there is a dummy part at the hit position at the end of the ray to emit the particles.
Well, only thing I have in mind right now is raycasting + particle effects. You can also use UnbindAction and ContextActionService if you want to trigger it that way.
By the looks of it, the size of the beam part (yellow neon cylinder) depends on how far the target is. For example, if a player shoots the beam at a part 10 studs away, then the beam part coming out of the hand is 10 studs long. This is constantly updating as the player changes the distance of their target.
Would it be wise to fire hundreds of rays within let’s say, 10 to 15 seconds?
No, raycasting is very cheap. If you’re worried about it, you could have the server tell each client to do the raycasting and rendering of the cylinder.
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
local Character = Player.Character or Player.CharacterAdded:Wait()
-- Placeholders
local Part
local Ray
UserInputService.InputBegan:Connect(function(InputObject, GameProcessed)
if InputObject.UserInputType == Enum.UserInputType.MouseMovement then
Part:Destroy()
local Ray = Ray.new(Character.RightHand.CFrame.p, (mouse.Hit.p - Character.RightHand.CFrame.p).unit * 300)
local Part = Instance.new("Part")
local FoundPart, Position = workspace:FindPartOnRay(Ray, Character, false, true)
local Distance = (tool.Handle.CFrame.p - position).magnitude
Part.Size = Vector3.new(0.3, 0.3, distance)
Part.CFrame = CFrame.new(Character.RightHand.CFrame.p, position) * CFrame.new(0, 0, -Distance / 2)
Part.Parent = workspace
end
end)
That’s the purpose of this thread if you read it first before posting; finding out how this was done.
Getting the player’s mouse doesn’t really say anything about accomplishing this. Yes, it gets the mouse but what then? You’ll need to include a lot more than that.
No worries, perfect reply thank you! So far this looks like it’s all a client thing, of course will cause security ramifications. Would it be stressful on the server to request where the mouse position be within renderstepped? Or should it be vice versa, the client sends to the server the mouse position, and then once the server does all that fancy calculations with rays, use FireAllClients to render the beam effect? Note that this will be alongside the the ray creation.
You can utilize remotes in order to do this, but the replication is up to you. It’s just an example.
However, constantly firing a remote can cause some network problems so I would definitely recommend only allowing it to be fired when it is enabled.
I would recommend doing everything visual on the server, to improve UX since there will be a delay if you wait for the server to respond. What we can do, is handle damage on the server since that is what is mostly able to be exploited when having things handled on the client.
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Player = Players.LocalPlayer
local UserInputService = game:GetService("UserInputService")
local Mouse = Player:GetMouse()
local Held = false
local Character = Player.Character
local Beam = Instance.new("Beam")
Beam.Segments = 1
Beam.Width0 = 1
Beam.Width1 = 1
Beam.Color = ColorSequence.new(Color3.new(1, 0, 0))
Beam.FaceCamera = true
local attachment0 = Instance.new("Attachment")
local attachment1 = Instance.new("Attachment")
Beam.Attachment0 = attachment0
Beam.Attachment1 = attachment1
Beam.Parent = workspace.Terrain
attachment0.Parent = workspace.Terrain
attachment1.Parent = workspace.Terrain
Beam.Enabled = false
repeat wait() until Character
local BodyGyro = Instance.new("BodyGyro", Character.HumanoidRootPart)
UserInputService.InputBegan:Connect(function(inputObject,chatting)
if chatting then return end
if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
Beam.Enabled = true
Held = true
while Held do
BodyGyro.MaxTorque = Vector3.new(0,math.huge,0)
BodyGyro.CFrame = CFrame.new(Character.HumanoidRootPart.CFrame.p, Mouse.Hit.p)
BodyGyro.P = 1e9
local RightHand = Character:FindFirstChild("RightHand")
attachment0.Position = RightHand.Position
attachment1.Position = Mouse.Hit.p
wait()
end
end
end)
UserInputService.InputEnded:Connect(function(inputObject)
if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
Held = false
Beam.Enabled = false
end
end)
Wow I never thought about using a beam, certainly reduces the stress as a part is no longer needed to simulate the beam. However, just at a glance, wouldn’t the beam penetrate parts? Seeing as there’s no way to tell the beam to stop at a certain range when something if between the player and the mouse position.