How do I loop casting a ray? I’m trying to loop a ray every second such that it can detect object that appears on the ray path while the object it moving.
What I want to achieve is:
When a player fires the gun, it will create a Bullet Part, the part will tween to where the user pointed at by using Raycasting and TweenService.
It will cast a ray and move the bullet to the shot direction every second.
I modified the code “Making a laser gun” from the Developer Hub for testing so far.
I also use TweenService to move the bullet part.
local beam = Instance.new("Part", workspace)
beam.BrickColor = BrickColor.new("Bright red")
beam.FormFactor = "Custom"
beam.Material = "Neon"
beam.Transparency = 0.25
beam.Anchored = true
beam.Locked = true
beam.CanCollide = false
beam.CFrame = CFrame.new(handle.CFrame.p - beam.CFrame.p)
local dir = mouse.Hit.p
delay(0,function()
while true do
local ray = Ray.new(beam.CFrame.p, dir*1)
local part, pos = workspace:FindPartOnRay(ray, player.Character, false, true)
local distance = (tool.Handle.CFrame.p - pos).magnitude
beam.Size = Vector3.new(0.3, 0.3, 2)
beam.CFrame = CFrame.new(beam.CFrame.p, pos)
local ti = TweenInfo.new(
distance * 0.05,
Enum.EasingStyle.Linear,
Enum.EasingDirection.Out,
0,
false,
0)
local goal = {
Position = pos
}
local tween = tweenser:Create(beam, ti, goal)
tween:Play()
if part ~= nil then
break
end
wait(1)
end
end)
This shooting direction is not accurate probably due to the variables stacking, but I just feel like there’s a better way to improve the entire code this looks like that it’s a “hacky” way to perform it, any thoughts?
I think the best thing to do would be to have the raycasting as a seperate loop.
I think you should do something like this (assuming you’re on a serverscript)
local Con
Con = RunService.Heartbeat:Connect(function()
if goalreachedsomethingsomething then
Con:Disconnect()
return
end
--shoot ray functions thing
end)
local previousPos = startPosition
RunService.Heartbeat:Connect(function()
–ray from previousPos to the current position
–if hit check distance
–if distance is too far, loop again, else disconnect
end)
I think I kinda solved it, however how do I replicate this to the server and such that it will be visible to others?
Firing the RemoteEvent 60 times a second doesn’t seems to be a right way.
delay(0,function()
local dir = (mouse.Hit.p - beam.CFrame.p).unit
local runService = game:GetService('RunService')
local Stepped
Stepped = runService.Stepped:Connect(function()
local ray = Ray.new(beam.CFrame.p, dir*1)
local part, pos = workspace:FindPartOnRay(ray, player.Character, false, true)
local dis = (beam.CFrame.p - pos).magnitude
beam.Size = Vector3.new(0.3, 0.3, 2)
beam.CFrame = CFrame.new(beam.CFrame.p, pos)
local ti = TweenInfo.new(
dis * 7/100,
Enum.EasingStyle.Linear,
Enum.EasingDirection.Out,
0,
false,
0)
local goal = {
Position = pos
}
local tween = tweenser:Create(beam, ti, goal)
tween:Play()
game.ReplicatedStorage.RemoteEvent:FireServer(dis*7/100, pos)
if part ~= nil then
Stepped:Disconnect()
if part.Parent:FindFirstChild("Humanoid") then
part.Parent.Humanoid:TakeDamage(10)
end
game:GetService("Debris"):AddItem(beam,1)
end
wait()
end)
end)
In my another game, I only use TweenService to tween the bullet, I use remote event to fire the server including the details of the bullet part, such as CFrame, ending point etc. However for this one, the ending point is different every second, how do I handle it for this one?