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.
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
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.
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.