Client -> Server -> Client Issue

Hi,
So I’m having trouble firing back to the Client after I’ve already fired to the Server and declared an OnServerEvent. The purpose of this is because I want to move the character to a new position via the body position. The body position (as well as body gyro) is created and positioned in the Local script because I need to constantly check for the mouse’s position in order to rotate the character towards it, and for aiming purposes.
(You basically hold down E and you’re suspended in the air, and when you release, you will be in hit’s position.)
I want the new body position after it fires back to the client to be (hit) which is where the ray got intersected (it’s already defined, which is why I’m sending the position to the client).

I apologize for my messy code in advance I am extremely new to this lol.

Local Scr


local inputService = game:GetService("UserInputService")
local runService = game:GetService("RunService")

local Player = game:GetService("Players").LocalPlayer
local Char = Player.CharacterAdded:Wait()
local Mouse = Player:GetMouse()

local Remote = script:WaitForChild("RemoteEvent")

local Pressed = false
local Enabled = true
local Key = nil

local function coolDown()
	Enabled = true
end

local function bodyStationary()

	local BP = Instance.new("BodyPosition",Char.HumanoidRootPart)
	BP.MaxForce = Vector3.new(math.huge,math.huge,math.huge)
	BP.Position = Char.HumanoidRootPart.Position

	local BG = Instance.new("BodyGyro", Char.HumanoidRootPart)
	BG.P = 25000
	BG.MaxTorque = Vector3.new(math.huge,math.huge,math.huge)

	while Pressed == true do
		BG.CFrame = CFrame.new(Char.HumanoidRootPart.Position, Mouse.Hit.Position)
		runService.Heartbeat:Wait()
	end
	wait(0.5)
	BG:Destroy()
end

inputService.InputBegan:Connect(function(input, isTyping)
	if isTyping then return end

	if input.KeyCode == Enum.KeyCode.E and Enabled == true and Char:FindFirstChild("Pika") then
		Enabled = false
		Pressed = true
		Remote:FireServer("LightSword")
		Key = "E"
		bodyStationary()

	elseif input.KeyCode == Enum.KeyCode.E and not Char:FindFirstChild("Pika") then end
end)

inputService.InputEnded:Connect(function(input, isTyping)
	if isTyping then return end
		
	if input.KeyCode == Enum.KeyCode.E and Key == "E" then
		Pressed = false
		Key = nil
		script.RemoteEvent:FireServer("ERelease", Char.HumanoidRootPart.Position, Mouse.Hit.Position)
		delay(5,coolDown)
	end
end)
--Where problem is (1/2)
Remote.OnClientEvent:Connect(function(player, hit, text)
	if text == "BodyNewPos" then
		print("Does this work?")
		Char.HumanoidRootPart.BodyPosition.Position = hit
	end
end)

Server

local Player = game:GetService("Players")
local StarterPack = game:GetService("StarterPack")
local Remote = script.Parent
local debounce = false
local buttonDown = true
local MousePos1 = nil
local TorsoPos = nil
local char = nil


Remote.OnServerEvent:Connect(function(player,action,RightHand,MousePos)
	if action == "ERelease" then
		buttonDown = false
		TorsoPos = RightHand
		MousePos1 = MousePos
	end
	
	
	if action == "LightSword" and debounce == false then

		buttonDown = true
		char = player.Character
		
		local function rayCasting() 
			local rayParams = RaycastParams.new()
			rayParams.FilterType = Enum.RaycastFilterType.Blacklist
			rayParams.FilterDescendantsInstances = {workspace.Game, char}
			rayParams.IgnoreWater = false
			local hit = workspace:Raycast(TorsoPos, CFrame.new(TorsoPos,MousePos1).LookVector*25000, rayParams)
				if hit then
					return hit.Position
				else return nil
				end
		end
		
		debounce = true
		local An = Instance.new("Animation")
		An.AnimationId = "rbxassetid://11992916940"
		local SwordAnim = char.Humanoid:LoadAnimation(An)
		SwordAnim:Play()
		wait(1.35)
		SwordAnim:AdjustSpeed(0)

		while buttonDown == true do
			wait()
		end

		local hit = rayCasting(TorsoPos,MousePos1,char)
		if not hit or hit and (TorsoPos-hit).magnitude > 300 then
			hit = CFrame.new(TorsoPos,MousePos1) * CFrame.new(0,0,-300).Position
			char.HumanoidRootPart.CFrame = CFrame.new(hit)

		elseif hit or not hit and (TorsoPos-hit).magnitude < 300 then
			char.HumanoidRootPart.CFrame = CFrame.new(hit)

		end
		--Where problem occurs (2/2)
		Remote:FireClient(player, hit, "BodyNewPos")

		local Distance = (TorsoPos-hit).magnitude
		SwordAnim:AdjustSpeed(1)

		debounce = false
	end
end)
1 Like

Hey, hope you’re keeping well. You can use a RemoteFunction to do this. You can read up on them here.

You can use a RemoteFunction to do the following: Client → Server → Client

I’ve put together some code to show you how this could work. When the TextButton is pressed, a RemoteFunction is invoked from the client to the server and then back to the client. The result is that the message prints on both the server and the client.
Local Script

local Button = script.Parent --//  TextButton variable
local ReplicatedStorage = game:GetService("ReplicatedStorage") --//  ReplicatedStorage
local RemoteFunction = ReplicatedStorage:FindFirstChild("RemoteFunction") --//  RemoteFunction

function OnClick() --// Function that runs the code below when called
	local Invoke = RemoteFunction:InvokeServer() --//  Invoking the RemoteFunction
	print(Invoke) --// Printing whatever is returned from the server
end

Button.MouseButton1Click:Connect(OnClick) --// Calling the "OnClick" function above when the "Button" variable is clicked.

Server Script

local ReplicatedStorage = game:GetService("ReplicatedStorage") --//  ReplicatedStorage
local Function = ReplicatedStorage.RemoteFunction --//  RemoteFunction in ReplicatedStorage

local function InvokeFunction(Player) --//  Function
	local format = Player.Name.." has fired a RemoteFunction!" --//  Creating a format to print
	print(format) --//  Printing the format
	return format --//  Returning to the client
end


Function.OnServerInvoke = InvokeFunction --//  Calling the "InvokeFunction" function when the "RemoteFunction" is invoked.

Result:
image

Hope this helps!

1 Like

I can’t seem to get it to work. I want to pass values from the server to the client then execute a function on the client because the BodyPosition is created via the Local Script, and change the values with the ones passed from the Server Script. Do you know how I could do this? This is what I have right now but it doesn’t seem to work. (Also sorry for a late reply and I appreciate your help!)

Local Script

local function NewBodyPos(plr, hit, text)
	if text == "BodyNewPos" then
		print("Does this work?")
		Char.HumanoidRootPart.BodyPosition.Position = hit
	end
end
RemFunc.OnClientInvoke = NewBodyPos

Server

RemFunc:InvokeClient(player, hit, "BodyNewPos")

Hey! Thanks for your reply, don’t worry about how long it takes to reply, I check the DevForum quite regularly!

My apologies! I believe I picked you up wrong. Your code appears to be correct, however, can you just confirm if you are using more than one RemoteEvent, if you are, make sure you’re referencing it properly and if not, try add another RemoteEvent specifically for this function.

Let me know how you get on!

1 Like

Okay so I did add a second RemoteEvent and it’s still not working for some reason. It doesn’t error or anything, it just doesn’t do anything. I used the same code from the initial post but instead of using “Remote”, I added a second Remote and named it RemoteEvent2 and the variable “Remote2”. I also added a print after the FireClient and it prints so it’s not yielding or anything.

1 Like

Your issue looks like it’s being caused by having an unnecessary plr parameter in your function NewBodyPos in the LocalScript (the Server Script is fine from what I can see).

When handling a RemoteFunction on the client, you don’t need a parameter for the player since the code is already being run on that player’s machine.

This code should work:

local function NewBodyPos(hit, text)
	if text == "BodyNewPos" then
		print("Does this work?")
		Char.HumanoidRootPart.BodyPosition.Position = hit
	end
end
RemFunc.OnClientInvoke = NewBodyPos

Side note: Since you aren’t returning anything in your NewBodyPos function, you could probably replace the RemoteFunction with a RemoteEvent and it should work the exact same way.

Here’s the code for that if you choose to go that route:
LocalScript

local function NewBodyPos(hit, text)
	if text == "BodyNewPos" then
		print("Does this work?")
		Char.HumanoidRootPart.BodyPosition.Position = hit
	end
end
RemEvent.OnClientEvent:Connect(NewBodyPos)

Server Script

RemEvent:FireClient(player, hit, "BodyNewPos")
2 Likes

Oh my, yes that worked. Thanks so much! I had no idea you didn’t need the Player parameter in the local script. It literally says it on the developer page but I didn’t even notice. Thanks again!!!

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.