After a couple of tests, I kept having bullets go to a different place than the one I clicked, so I created this script where I tried a bunch of things to try and get the bullet to be accurate.
I tried both input.Position and UserInputService:GetMouseLocation(), ScreenPointToRay
instead of ViewportPointToRay
(I also tried changing the depth for both of those to various different numbers), and I tried subtracting the gui inset for all combinations. For the gui inset, I tested both Vector2.new(0, 36)
and GuiService:GetGuiInset()
.
I’m pretty sure it’s not because of the way I’m moving the bullets, because I tried a couple of different methods for that as well.
It’s not because of workspace:Raycast()
either, because I tried everything that I mentioned before with Ray.new()
and they had the same results.
tl;dr: I tried literally every combination of everything that I could think of that related to this, and I still don’t know why my bullets are offsetted. The name of this post is what I think is happening at this point.
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Camera = workspace.CurrentCamera
local zeroVector = Vector3.new()
local random = Random.new()
local tau = math.pi * 2
local bullet = script:WaitForChild("Bullet")
local bulletSpread = 0
local bulletSpeed = 90
local bulletCount = 0
local range = 400
local raycastParams = RaycastParams.new()
raycastParams.IgnoreWater = false
raycastParams.FilterDescendantsInstances = {Character}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
function randomOffset(vector, maxAngle)
local rand1 = random:NextNumber(0, tau)
local rand2 = random:NextNumber(math.cos(maxAngle / 1e3), 1)
local res = (CFrame.new(zeroVector, vector)
* CFrame.Angles(0, 0, rand1)
* CFrame.Angles(math.acos(rand2), 0, 0)
).LookVector
print(res:Dot(vector.Unit)) -- this always prints 1
-- since i set maxAngle to 0 for testing
return res
end
local function get3DPosition(screenPosition)
local oray = Camera:ViewportPointToRay(screenPosition.X, screenPosition.Y, 0)
return workspace:Raycast(oray.Origin, randomOffset(oray.Direction, bulletSpread) * range, raycastParams)
end
UserInputService.InputBegan:Connect(function(input, ignore)
if ignore then return end
if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
local raycastResult = get3DPosition(input.Position)
if not raycastResult then return end
local position = raycastResult.Position
local bullet = bullet:Clone()
bullet.Position = Character:GetPrimaryPartCFrame().Position + Vector3.new(4, 0, 4)
bullet.CFrame = CFrame.new(bullet.Position, position)
bullet.Anchored = true
bullet.Parent = workspace
bulletCount = bulletCount + 1
local startPosition = bullet.Position
local distance = (startPosition - position).Magnitude
local name = "RenderBullet" .. tostring(bulletCount)
RunService:BindToRenderStep(name, Enum.RenderPriority.Input.Value, function(deltaTime)
bullet.CFrame = bullet.CFrame + (bullet.CFrame.LookVector * deltaTime * bulletSpeed)
if (bullet.Position - startPosition).Magnitude >= distance then
bullet:Destroy()
RunService:UnbindFromRenderStep(name)
end
end)
end)
Player.CharacterAdded:Connect(function(newCharacter)
Character = newCharacter
end)
--// thanks for stopping by
btw the offset function isn’t related, I temporarily disabled that for testing.