Are you confusing the camera’s position for the hit position?
i dont really know, mean all i am is sending the ray over so i have no clue
Can you at least label the things you’re printing out?
Also apparently you aren’t even printing the hit location, only the ray
Also also you can always just refer back to the demo I sent for guidance
The main thing im looking at is the bottom print, all im printing is the instance its hitting, (removed the other prints right now), i just thought it would hit the instance thats under the cursor but the spawn location is pretty far from the cursor and its still hitting it
Code
Server
local Tool = script.Parent
local Event = Tool.MainEvent
local Params = RaycastParams.new()
Params.FilterDescendantsInstances = {}
Params.FilterType = Enum.RaycastFilterType.Blacklist
local function OnEquipped()
local C = {}
local Holder = Tool.Parent
table.insert(C, Holder)
for i, v in ipairs(workspace.Ignored:GetChildren()) do
table.insert(C, v)
end
Params.FilterDescendantsInstances = C
end
local function Shoot(Player, ray)
local Rv = ray.Direction * 300
local Raycast = workspace:Raycast(ray.Origin, Rv, Params)
local HitPos = if Raycast then Raycast.Position else ray.Origin + Rv
local ShootFrom = Tool.Handle.Attachment.WorldPosition
local AimAt = HitPos - ShootFrom
local HitDetection = workspace:Raycast(ShootFrom, AimAt * 2, Params)
local ThingHit = if HitDetection then HitDetection.Instance else nil
local PosHit = if HitDetection then HitDetection.Position else HitPos
if ThingHit then
print(ThingHit)
end
end
Event.OnServerEvent:Connect(Shoot)
Tool.Equipped:Connect(OnEquipped)
Client
local Tool = script.Parent
local player = game.Players.LocalPlayer
local UIS = game:GetService("UserInputService")
local Event = Tool.MainEvent
local mouse = player:GetMouse()
script.Parent.Activated:Connect(function()
local ray = workspace.CurrentCamera:ViewportPointToRay(mouse.X, mouse.Y)
Event:FireServer(ray)
end)
Sorry if this isnt what you are asking for, dont really know what you mean here
Ah I see, I was talking about something else
The issue seems to stem from this:
Deriving the cursor position from
mouse
will respect the topbar offset, which is 36 pixels down, meaning that the ray will always be 36 pixels offset from the actual position. So you should’ve used UserInputService for this, which ignores the topbar offset.
Alright i switched it over to UIS and now uh
Idk cant really explain it in words so
Extremely confused now why the spawnlocation ceases to exist
Did you blacklist it from the raycast
Nope, it shouldn’t be blacklisted at all, and it hits once in the video not sure where i clicked for that though.
Try debugging it by spawning a temporary part on where the bullet should’ve hit and see if there’s anything wrong
Did this and saw the part spawning only in one area,
Apparently i didnt put the GetMouseLocation into the Activated function, so its all good now
Now, how would i create the bullet on the client so it doesnt look like its lagging behind like hell
When the player shoots, immediately create the clientsided bullet on their end (this means that the hitreg calculations will also need to be done on the client, but it will only be for GFX and has no actual effect on the bullet itself)
And for everyone else, the server will distribute the hitreg information and each client will create the tracer separately
You can once again refer back to the demo I sent for this, except that the demo doesn’t do what I just described in paragraph 1
So basically i gotta do everything thing i did on server, also on client?
Like FireAllClients?
Basically yeah
Well yes, but then it’s also going to fire back to the client who shot the bullet which will make it look like they shot twice
So you should instead manually fire the players
So Should i make it from scratch or can i just paste it over?
How would i do this?, never really did much else then firing all clients
You can paste it over, make changes to the variables if necessary
Use a for loop and exclude the caller
local players = game:GetService('Players')
OnServerEvent:Connect(function(player, ...)
for _, v in ipairs(players:GetPlayers()) do
if v ~= player then
remote:FireClient(v, ...)
Should work in theory
Alright ill get back to you in a bit, taking a small break to eat
Alright set up some code for replication and got the base code set up in the gun
Althought now not sure how to create the “Laser”
Also whats a good place to store settings for a player? Like checking if the player has other player’s bullets on or off, where would i store this?
Code
Server
local Tool = script.Parent
local Event = Tool.MainEvent
local Params = RaycastParams.new()
Params.FilterDescendantsInstances = {}
Params.FilterType = Enum.RaycastFilterType.Blacklist
local function OnEquipped()
local C = {}
local Holder = Tool.Parent
table.insert(C, Holder)
for i, v in ipairs(workspace.Ignored:GetChildren()) do
table.insert(C, v)
end
Params.FilterDescendantsInstances = C
end
local function Shoot(Player, ray)
local Rv = ray.Direction * 300
local Raycast = workspace:Raycast(ray.Origin, Rv, Params)
local HitPos = if Raycast then Raycast.Position else ray.Origin + Rv
local ShootFrom = Tool.Handle.Attachment.WorldPosition
local AimAt = HitPos - ShootFrom
local HitDetection = workspace:Raycast(ShootFrom, AimAt * 2, Params)
local ThingHit = if HitDetection then HitDetection.Instance else nil
local PosHit = if HitDetection then HitDetection.Position else HitPos
if ThingHit then
print(ThingHit)
end
for i, v in ipairs(game.Players:GetPlayers()) do
if v ~= Player and v then
Event:FireClient(v, "WhatEverDataINeedToSendToCreateTheBullet"))
end
end
end
Event.OnServerEvent:Connect(Shoot)
Tool.Equipped:Connect(OnEquipped)
Client
local Tool = script.Parent
local player = game.Players.LocalPlayer
local UIS = game:GetService("UserInputService")
local Event = Tool:WaitForChild("MainEvent")
local Params = RaycastParams.new()
Params.FilterDescendantsInstances = {}
Params.FilterType = Enum.RaycastFilterType.Blacklist
local function OnEquipped()
local C = {}
local Holder = Tool.Parent
table.insert(C, Holder)
for i, v in ipairs(workspace.Ignored:GetChildren()) do
table.insert(C, v)
end
Params.FilterDescendantsInstances = C
end
local function BulletGen(ray)
local Rv = ray.Direction * 300
local Raycast = workspace:Raycast(ray.Origin, Rv, Params)
local HitPos = if Raycast then Raycast.Position else ray.Origin + Rv
local ShootFrom = Tool.Handle.Attachment.WorldPosition
local AimAt = HitPos - ShootFrom
local HitDetection = workspace:Raycast(ShootFrom, AimAt * 2, Params)
local ThingHit = if HitDetection then HitDetection.Instance else nil
local PosHit = if HitDetection then HitDetection.Position else HitPos
if ThingHit then
print(ThingHit)
end
end
local function ClientBullet()
end
script.Parent.Activated:Connect(function()
local mouse = UIS:GetMouseLocation()
local ray = workspace.CurrentCamera:ViewportPointToRay(mouse.X, mouse.Y)
Event:FireServer(ray)
BulletGen(ray)
end)
script.Parent.Equipped:Connect(OnEquipped)
Event.OnClientEvent:Connect(ClientBullet)
I am just repeating myself at this point. You have the demo I sent and you can always just go in and have a look
Given two points, find the midpoint with the Lerp function, and then use CFrame.lookAt to orientate the tracer to look at one of the points. Then, set the Z component of the laser’s size to the magnitude of the displacement between the said two points. The X and Y components would be a constant which defines the thickness of the laser
Why should this be a setting? At what point would the player want to hide other player’s tracers in a game that’s all about shooting each other? It would just disadvantage them in the game as then they have no idea who’s shooting at them
You can use attributes to store the gun information. It replicates, so the server can also edit the gun configurations, and the client can make their own private changes to the visual aspects of the gun
Mb, kept forgetting you sent that
I see what you mean here, althougth yes i will do pvp, i was mainly thinking about PvE which wouldn’t really require other peoples bullets to be seen
Anyways i used the tutorial got it to work, although just as one final check theres nothing im doing wrong here?
Server
local Tool = script.Parent
local Event = Tool.MainEvent
local Params = RaycastParams.new()
Params.FilterDescendantsInstances = {}
Params.FilterType = Enum.RaycastFilterType.Blacklist
local function OnEquipped()
local C = {}
local Holder = Tool.Parent
table.insert(C, Holder)
for i, v in ipairs(workspace.Ignored:GetChildren()) do
table.insert(C, v)
end
Params.FilterDescendantsInstances = C
end
local function Shoot(Player, ray)
local Rv = ray.Direction * 300
local Raycast = workspace:Raycast(ray.Origin, Rv, Params)
local HitPos = if Raycast then Raycast.Position else ray.Origin + Rv
local ShootFrom = Tool.Handle.Attachment.WorldPosition
local AimAt = HitPos - ShootFrom
local HitDetection = workspace:Raycast(ShootFrom, AimAt * 2, Params)
local ThingHit = if HitDetection then HitDetection.Instance else nil
local PosHit = if HitDetection then HitDetection.Position else HitPos
if ThingHit then
print(ThingHit)
end
for i, v in ipairs(game.Players:GetPlayers()) do
if v ~= Player and v then
Event:FireClient(ShootFrom, PosHit)
end
end
end
Event.OnServerEvent:Connect(Shoot)
Tool.Equipped:Connect(OnEquipped)
Client
local Tool = script.Parent
local player = game.Players.LocalPlayer
local UIS = game:GetService("UserInputService")
local Event = Tool:WaitForChild("MainEvent")
local Bullet = workspace.Ignored.ClientBullet
local Debris = game:GetService("Debris")
-- For Easier Changing --
local BulletSize = 0.2
local BulletColor = Color3.new(1,1,0)
local RayLength = 300
-------------------------
local Params = RaycastParams.new()
Params.FilterDescendantsInstances = {}
Params.FilterType = Enum.RaycastFilterType.Blacklist
local function OnEquipped()
local C = {}
local Holder = Tool.Parent
table.insert(C, Holder)
for i, v in ipairs(workspace.Ignored:GetChildren()) do
table.insert(C, v)
end
Params.FilterDescendantsInstances = C
end
local function BulletGen(ray)
local Rv = ray.Direction * RayLength
local Raycast = workspace:Raycast(ray.Origin, Rv, Params)
local HitPos = if Raycast then Raycast.Position else ray.Origin + Rv
local ShootFrom = Tool.Handle.Attachment.WorldPosition
local AimAt = HitPos - ShootFrom
local HitDetection = workspace:Raycast(ShootFrom, AimAt * 2, Params)
local ThingHit = if HitDetection then HitDetection.Instance else nil
local PosHit = if HitDetection then HitDetection.Position else HitPos
local D = Bullet:Clone()
D.Color = BulletColor
D.Size = Vector3.new(BulletSize, BulletSize, (ShootFrom - PosHit).Magnitude)
D.CFrame = CFrame.lookAt(ShootFrom:Lerp(PosHit, .5), PosHit)
D.Parent = workspace.Ignored
Debris:AddItem(D, .2)
end
local function ClientBullet(From, To)
local ReplicatedBullet = Bullet:Clone()
ReplicatedBullet.Color = BulletColor
ReplicatedBullet.Size = Vector3.new(BulletSize, BulletSize, (From - To).Magnitude)
ReplicatedBullet.CFrame = CFrame.lookAt(From:Lerp(To, .5), To)
ReplicatedBullet.Parent = workspace.Ignored
Debris:AddItem(ReplicatedBullet, .2)
end
script.Parent.Activated:Connect(function()
local mouse = UIS:GetMouseLocation()
local ray = workspace.CurrentCamera:ViewportPointToRay(mouse.X, mouse.Y)
Event:FireServer(ray)
BulletGen(ray)
end)
script.Parent.Equipped:Connect(OnEquipped)
Event.OnClientEvent:Connect(ClientBullet)
I would suggest that you make the raycast rays longer, maybe at least 1 thousand given the size of the map for both raycasts (camera hit and hitreg)
This could definitely be simplified if you include Holder
inside the table constructor:
local C = {Tool.Parent}
Other than that, everything seems fine from just looking at it