So I’m making a bot that will shoot in whatever direction it’s facing and I want the bot’s weapon to have some small spread. I came up with the code below to calculate the spread, however, regardless of the spread values or which direction the bot was facing the ray ended up veering off to the top left of where the barrel was facing.
-- Not the whole script, just the parts that are relevant to the raycast --
local bot = script.Parent;
local raycastParams = RaycastParams.new();
raycastParams.FilterDescendantsInstances = {bot};
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist;
raycastParams.IgnoreWater = false;
local randomObject = Random.new();
local minSpread = bot:GetAttribute("BulletMinSpread");
local maxSpread = bot:GetAttribute("BulletMaxSpread");
local range = bot:GetAttribute("BulletRange");
local function getRandomNumber(mini, maxi)
return randomObject:NextNumber(mini, maxi);
end
local directionCF = CFrame.new(Vector3.new(), barrel.CFrame.LookVector);
local spreadDirection = CFrame.fromOrientation(0, 0, getRandomNumber(0, math.pi * 2));
local spreadAngle = CFrame.fromOrientation(math.rad(getRandomNumber(minSpread, maxSpread)), 0, 0);
local direction = (directionCF * spreadDirection * spreadAngle).LookVector * range;
local result = workspace:Raycast(barrel.Position, direction, raycastParams);
I have a gut feeling it has something to do with directionCF and not having the right LookVector but I don’t know what else I should be using there instead.
Picture of what the ray looks like, highlighted part is the barrel:
There was 100 “shots” fired each time (using 1 min and 15 max spread that you provided for example)
They’re really sporadic. I’m not too experienced in this field, so I can’t really be of much help; but they appear to just spread out far too wide too quickly.
If this is of any help I’ll be surprised, but yeah I’m not 100% sure what it is honestly.
The main issue I’m having is the ray is always going to the same spot regardless of spread. Also, in my demo I had a large wall in front of the barrel to ensure the ray would hit it.
also don’t use deprecated terms. .position is deprecated and should be replaced favoring .Position
It’s bad, no at this point “bad” doesn’t describe it well enough anymore; It’s awful practice, even if you’re the only person who will ever see it. Although it seems like this may be snippet code so I’m not sure if you made it.
EDIT: Also, -range/2? you also have range defined elsewhere, no? so change the range parameter to “hitMagnitude” and pass through (barrel.Position - result.Position).Magnitude as the argument.
Then change -range / 2 to -hitMagnitude / 2
local beamTemplate = Instance.new("Part") -- good practice to avoid repetitive instancing
beamTemplate.BrickColor = BrickColor.new("Daisy orange")
beamTemplate.Material = "Neon"
beamTemplate.Transparency = 0.45
beamTemplate.Anchored = true
beamTemplate.CanTouch = false
beamTemplate.CanCollide = false
-- + all of these are constants, why set them for a new beam every single shot?
local function showRay(source, raycastResult)
local distance = (source.Position - raycastResult.Position).Magnitude
local beam = beamTemplate:Clone()
beam.Size = Vector3.new(0.025, 0.025, distance);
beam.CFrame = CFrame.new(source.Position, raycastResult.Position) * CFrame.new(0, 0, -distance/2);
beam.Parent = bot; -- you want these to, uh, get ignored, yeah?
game:GetService("Debris"):AddItem(beam, 1)
end
-- Changes: You pass the barrel as the first argument now, and results like before.