CFrame & Position on Server are inaccurate

So recently my weapon system broke. Positions and CFrames are absolutely inaccurate, making gun fire start from far away from a Attachment which I used server to get WorldPosition of an Attachment and other parts of gun using CFrame and Position. However they are way off than doing on client. Client has 100% accuracy in information such as CFrame and Position.

Before I would normally do this on Server:

grenade.CFrame = tool.Handle.CFrame

Rightnow I have to do this on Server but take Position information from Client:

script.Parent.Throw.OnServerEvent:Connect(function(Player, mousePosition, Spawn, SpawnCF)
grenade.CFrame = SpawnCF

Why Server has inaccurate information in terms of Position and CFrame? Is this an bug or an intended behavior change on Server in an update?

2 Likes

Are you making any changes to the weapon client-sided only? That’d be the key reason for this to be the result.

Any changes made locally are registered locally-only.

If you’re creating attachments locally, that could also contribute.

I’m not sure I fully understand your problem, but I hope this helps.

1 Like

All parts and attachments are server sided.

1 Like

Could you provide some code as well as further explanation as to what’s the issue? For me atleast, it’s a bit hard to assist you as I don’t have enough background information.

1 Like

When Server gets Position and CFrame

When Client gets Position and CFrame

Grenade is Server Sided, but uses Position and CFrame from different sources, one from Server and one from Client.

As results of the test, Server has inaccurate information while Client has accurate information about CFrame and Position

1 Like

Could you post your code?

-30chars-

Server Sided Position & CFrame

Script:

local tool = script.Parent
local config = tool:WaitForChild("Configuration")

function AngleOfReach(distance, altitude, velocity)
	local theta = math.atan((velocity^2 + math.sqrt(velocity^4 -196.2*(196.2*distance^2 + 2*altitude*velocity^2)))/(196.2*distance))
	if theta ~= theta then
		theta = math.pi/4
	end
	return(theta)
end

function Explode(part)
	local explosion = Instance.new("Explosion", workspace)
	explosion.Position = part.Position
	explosion.BlastRadius = config.ExplosionRadius.Value
	part:Destroy()
end

script.Parent.Throw.OnServerEvent:Connect(function(Player, mousePosition, Spawn, SpawnCF)
	Spawn = tool.Handle.Position
	SpawnCF = tool.Handle.CFrame
	local handlePos = Vector3.new(Spawn.X, 0, Spawn.Z)
	local mousePos = Vector3.new(mousePosition.X, 0, mousePosition.Z)
	local distance = (handlePos - mousePos).magnitude
	local altitude = mousePosition.Y - tool.Handle.Position.Y
	local angle = AngleOfReach(distance, altitude, config.GrenadeVelocity.Value)
	
	tool.Handle.Transparency = 1
	
	local grenade = tool.Handle:Clone()
	grenade.Parent = workspace
	grenade.Transparency = 0
	grenade.CanCollide = true
	grenade.CFrame = SpawnCF
	grenade.Velocity = (CFrame.new(Spawn, Vector3.new(mousePosition.X, Spawn.Y, mousePosition.Z)) * CFrame.Angles(angle, 0, 0)).lookVector * config.GrenadeVelocity.Value
	
	spawn(function()
		if config.ExplodeOnTouch.Value then
			grenade.Touched:Connect(function(hit)
				if hit.Parent ~= tool.Parent and hit.CanCollide then
					Explode(grenade)
				end
			end)
		else
			wait(config.FuseTime.Value)
			Explode(grenade)
		end
	end)
	
	wait(config.Cooldown.Value)
	
	tool.Handle.Transparency = 0
end)

Localscript:

local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
local Tool = script.Parent
local Handle = Tool:WaitForChild("Handle")
local Configuration = Tool:WaitForChild("Configuration")

local canThrow = true

Tool.Equipped:Connect(function()
	Mouse.Icon = "rbxasset://textures/GunCursor.png"
end)

Tool.Unequipped:Connect(function()
	Mouse.Icon = ""
end)

Tool.Activated:Connect(function()
	if canThrow then
		canThrow = false
		local throwAnimation = Player.Character:WaitForChild("Humanoid"):LoadAnimation(Tool:WaitForChild("ThrowAnimation"))
		throwAnimation:Play()
		throwAnimation.KeyframeReached:Connect(function(keyframe)
			if keyframe == "tick" then
				Handle:WaitForChild("Pin"):Play()
			elseif keyframe == "throw" then
				Tool:WaitForChild("Throw"):FireServer(Mouse.Hit.p, Handle.Position, Handle.CFrame)
				throwAnimation:Stop()
				Mouse.Icon = "rbxasset://textures/GunWaitCursor.png"
			end
		end)
		wait(Configuration:WaitForChild("Cooldown").Value)
		Mouse.Icon = "rbxasset://textures/GunCursor.png"
		canThrow = true
	end
end)

Client Sided Position & CFrame

Script:

local tool = script.Parent
local config = tool:WaitForChild("Configuration")

function AngleOfReach(distance, altitude, velocity)
	local theta = math.atan((velocity^2 + math.sqrt(velocity^4 -196.2*(196.2*distance^2 + 2*altitude*velocity^2)))/(196.2*distance))
	if theta ~= theta then
		theta = math.pi/4
	end
	return(theta)
end

function Explode(part)
	local explosion = Instance.new("Explosion", workspace)
	explosion.Position = part.Position
	explosion.BlastRadius = config.ExplosionRadius.Value
	part:Destroy()
end

script.Parent.Throw.OnServerEvent:Connect(function(Player, mousePosition, Spawn, SpawnCF)
	local handlePos = Vector3.new(Spawn.X, 0, Spawn.Z)
	local mousePos = Vector3.new(mousePosition.X, 0, mousePosition.Z)
	local distance = (handlePos - mousePos).magnitude
	local altitude = mousePosition.Y - tool.Handle.Position.Y
	local angle = AngleOfReach(distance, altitude, config.GrenadeVelocity.Value)
	
	tool.Handle.Transparency = 1
	
	local grenade = tool.Handle:Clone()
	grenade.Parent = workspace
	grenade.Transparency = 0
	grenade.CanCollide = true
	grenade.CFrame = SpawnCF
	grenade.Velocity = (CFrame.new(Spawn, Vector3.new(mousePosition.X, Spawn.Y, mousePosition.Z)) * CFrame.Angles(angle, 0, 0)).lookVector * config.GrenadeVelocity.Value
	
	spawn(function()
		if config.ExplodeOnTouch.Value then
			grenade.Touched:Connect(function(hit)
				if hit.Parent ~= tool.Parent and hit.CanCollide then
					Explode(grenade)
				end
			end)
		else
			wait(config.FuseTime.Value)
			Explode(grenade)
		end
	end)
	
	wait(config.Cooldown.Value)
	
	tool.Handle.Transparency = 0
end)

Localscript:

local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
local Tool = script.Parent
local Handle = Tool:WaitForChild("Handle")
local Configuration = Tool:WaitForChild("Configuration")

local canThrow = true

Tool.Equipped:Connect(function()
	Mouse.Icon = "rbxasset://textures/GunCursor.png"
end)

Tool.Unequipped:Connect(function()
	Mouse.Icon = ""
end)

Tool.Activated:Connect(function()
	if canThrow then
		canThrow = false
		local throwAnimation = Player.Character:WaitForChild("Humanoid"):LoadAnimation(Tool:WaitForChild("ThrowAnimation"))
		throwAnimation:Play()
		throwAnimation.KeyframeReached:Connect(function(keyframe)
			if keyframe == "tick" then
				Handle:WaitForChild("Pin"):Play()
			elseif keyframe == "throw" then
				Tool:WaitForChild("Throw"):FireServer(Mouse.Hit.p, Handle.Position, Handle.CFrame)
				throwAnimation:Stop()
				Mouse.Icon = "rbxasset://textures/GunWaitCursor.png"
			end
		end)
		wait(Configuration:WaitForChild("Cooldown").Value)
		Mouse.Icon = "rbxasset://textures/GunCursor.png"
		canThrow = true
	end
end)

May be a longshot given how long ago this was posted, but did you ever find a solution to this issue? Facing the same thing currently.

I don’t remember, this is really old.