Why does generating multiple rays from the same starting point result in teleporting parts coming one after the other?

Hey, I’m currently working on a cannon that uses raycasting to determine the bullet trajectory. I’m attempting to code for a canister shot (basically a shotgun shell) for the cannon, and I’m doing so by repeating individual raycasts (with inaccuracy once I get this figured out), but for some reason the bullets keep on landing one after the other.
Below is the example I’m talking about.
https://gyazo.com/c21fb9243ce27eeeb172d70891922a6f
And below is the code; half of this is basically irrelevant lol, I think it has something to do with the raycasts. But I don’t know what’s wrong.

	for i=1,3 do
		coroutine.resume(coroutine.create(function()
			local StartTick = tick()
			local newpart = Instance.new("Part")
			local InaccuracyFactor = Vector3.new(math.random(-20,20)/10,math.random(-20,20)/10,math.random(-20,20)/10)
			local Velocity = (Muzzle.CFrame.LookVector)
			--print(Muzzle.CFrame:VectorToObjectSpace(Muzzle.CFrame.LookVector))
			--print(Muzzle.CFrame:VectorToObjectSpace(InaccuracyFactor))
			newpart.Anchored = true
			newpart.Name = "CanisterBall"
			newpart.CanCollide = false
			newpart.Size = Vector3.new(1,1,1)
			newpart.Shape = "Ball"
			newpart.Color = Color3.fromRGB(27, 42, 53)
			newpart.Material = "Metal"
			newpart.Orientation = Muzzle.Orientation 
			newpart.Parent = workspace
			newpart.Position = Cannon.Muzzle.Position
			repeat
				local ray = Ray.new(OriginPoint,Velocity)
				local hit,position, thingy = workspace:FindPartOnRayWithIgnoreList(ray, {Cannon, newpart})
				newpart.Position = position
				if hit then 
					print(hit:GetFullName())
					if hit.Name ~= "CanisterBall" then
						newpart:Destroy()
						print("kk canister destroyed")
					end
				end
			Velocity = Velocity - Vector3.new(0,.05,0)
			OriginPoint = OriginPoint + Velocity
			wait(1)
			until tick() - StartTick >= 100
		end))
		end

Maybe it has something to do with the referenced raycast position? Maybe the rays are hitting each other as they are created? How would I account for this problem?

Without reading too much into it, I believe this is your problem. I would make a new folder or model in Workspace, parent the CanisterBalls to this model, and then add the model to the ignore list in your code.

I think I got two reasons why:

I don’t know if 1 is 1 second, I mean that the for do is firing every second.

Maybe the most obvious, you can use a spawn function for that, for example (Correct me if I’m wrong, I don’t know if I wrote the function correctly):

spawn(function()
    wait(1)
    print("This is printed later")
end)
print("Believe it or not, I'm printed first")

Thanks for reading.

Even if I tried parenting the canisterballs to the model, it still produces the same result.
(quite legitimately the same code except for lines 1,2 and the line corresponding with the ray)

local CanisterModel = Instance.new("Model", workspace)
CanisterModel.Name = "CanisterModel"
for i=1,3 do
		coroutine.resume(coroutine.create(function()
			local StartTick = tick()
			local newpart = Instance.new("Part", CanisterModel)
			local InaccuracyFactor = Vector3.new(math.random(-20,20)/10,math.random(-20,20)/10,math.random(-20,20)/10)
			local Velocity = (Muzzle.CFrame.LookVector)
			--print(Muzzle.CFrame:VectorToObjectSpace(Muzzle.CFrame.LookVector))
			--print(Muzzle.CFrame:VectorToObjectSpace(InaccuracyFactor))
			newpart.Anchored = true
			newpart.Name = "CanisterBall"
			newpart.CanCollide = false
			newpart.Size = Vector3.new(1,1,1)
			newpart.Shape = "Ball"
			newpart.Color = Color3.fromRGB(27, 42, 53)
			newpart.Material = "Metal"
			newpart.Orientation = Muzzle.Orientation 
			newpart.Position = Cannon.Muzzle.Position
			repeat
				local ray = Ray.new(OriginPoint,Velocity)
				local hit,position, thingy = workspace:FindPartOnRayWithIgnoreList(ray, {Cannon, newpart, CanisterModel})
				newpart.Position = position
				if hit then 
					print(hit:GetFullName())
					if hit.Name ~= "CanisterBall" then
						newpart:Destroy()
						print("kk canister destroyed")
					end
				end
			Velocity = Velocity - Vector3.new(0,.05,0)
			OriginPoint = OriginPoint + Velocity
			wait(1)
			until tick() - StartTick >= 100
		end))
		end

I don’t know if 1 is 1 second, I mean that the for do is firing every second.
I’m pretty sure it fires instantaneously, if you look at the video clip it shows all three shots being generated at the same time.

And for the spawn function; would I replace the coroutine.resume(coroutine.create etc etc)) with spawn()? How would I use it? Frankly I’m unfamiliar with using spawn

Sorry, but what is coroutine? Same as you in not very familiarized with coroutine.
By the way, everything inside spawn is not yielded.

Also, another solution would be using Tween Service, that move stuff smoothly.

Essentially it allows a script to perform multiple tasks without having to wait for each one to finish. For example if you had two while true do loops,

while true do
   blankblankblank
end

while true do
   yayyayyay
end

only the first would run, but with coroutines you can run both. But anyway, I still need help on this, hehe.

Oh, I think it’s the same thing as Spawn.

As I have seen, in the for i=1,3 do, 3 is the times it’s fired, I guess.

1 Like

You wrote it perfect, but that wouldn’t be the issue. He is using coroutines, which are a more complicated way of doing, for the most part, the same thing as spawn.

Interesting. I’m sorry I couldn’t be of more help.

I don’t think this will fix it, but you may consider replacing OriginPoint = OriginPoint + Velocity to OriginPoint = position, just in case it finds something not on the ignore list but ignores it later in the if block. It will also be a easier to type and infinitesimally more efficient. In other words, if you have the variable that tells you the exact current position, you might as well use it. It’s up to you of course.

1 Like