Move character locally?

I was wondering if there’s a way to efficiently move a players character without it replicating to the server?

Reason for this:
I want to have a customise room, that teleports the player to said room. However, if 50 players are all editing their characters, I don’t want all 50 characters overtop of each other. I also don’t want 50 rooms made, and assigning a room for each player. I also DO NOT want to create a dummy or clone of the character. I am using HumanoidDescription and thus require the actual Character model

I’ve tried setting the Network owner of the HRP to nil, however, that just teleports my player, then resets them back at spawn.

-- Client
script.Parent.Activated:Connect(function()
	if game.ReplicatedStorage.RemoteFunction:InvokeServer() then
		game.Players.LocalPlayer.Character:SetPrimaryPartCFrame(workspace.TeleportPoint.CFrame)
	end
end)

-- Server
game.ReplicatedStorage.RemoteFunction.OnServerInvoke = function(player)
	player.Character.HumanoidRootPart:SetNetworkOwner(nil)
	
	return true
end

ezgif.com-gif-maker
Client Teleport.rbxl (26.7 KB)

1 Like

Unfortunately due to network ownership teleportation replicates. So whether you want to or not you will have to clone it locally or create a separate room for each player. You can apply descriptions to NPC’s too.

You can’t do HumanoidDescription stuff via the client though, that’s the problem :confused:

Is that right? I swore I saw in a release note that Humanoid:ApplyDescription being able to be used locally was live.

1 Like
local HumanoidDescription = workspace.Dummy.Humanoid.HumanoidDescription

workspace.Dummy.Humanoid:ApplyDescription(HumanoidDescription)

Humanoid::ApplyDescription() can only be called by the backend server

https://developer.roblox.com/en-us/resources/release-note/Release-Notes-for-442 Says it’s pending :confused:

If it isn’t important that the humanoidrootpart teleports, you could teleport all the other bodyparts by changing Transform of the Root joint, which connects lowertorso to humanoidrootpart. If you change transform, the changes must be done every Stepped so that animations won’t override them. Camera updates should be done on RenderStepped. Here’s some example code. There’s a comment that tells where you can do the camera updates.

There are some problems with this, though. If the humanoidRootPart happens to move vertically for some reason, the visible character will move weirdly. Anchoring the humanoidrootpart causes movement problems after teleporting back for some reason.

startEdit should be called when you want to teleport to the customization room and stopEdit should be called when ypou want to teleport back.

local Players = game:GetService("Players")
local RunService = game:getService("RunService")
local ContextActionService = game:GetService("ContextActionService")

local FREEZE_ACTION = "FreezeMovement"


local plr = Players.LocalPlayer
local cam = workspace.CurrentCamera

local localCf
local steppedConn, renderSteppedConn
local movementEnums = Enum.PlayerActions:GetEnumItems()


local function sinkInput()
	return Enum.ContextActionResult.Sink
end

local function disableMovementControls()
	ContextActionService:BindAction(FREEZE_ACTION, sinkInput, false, unpack(movementEnums))
end

local function reEnableMovementControls()
	ContextActionService:UnbindAction(FREEZE_ACTION)
end

local function disconnectConns()
	steppedConn:Disconnect()
	renderSteppedConn:Disconnect()
	steppedConn, renderSteppedConn = nil, nil
end

local function stopEdit()
	print("stop editing")
	reEnableMovementControls()
	disconnectConns()
	local char = plr.Character
	if char then
		local hrp = char:FindFirstChild("HumanoidRootPart")
		if hrp then
			hrp.Anchored = false
		end
	end
end

local function getCharObjects()
	local char = plr.Character
	if not char then
		stopEdit()
		return
	end
	local lTorso, hum ,hrp = char:FindFirstChild("LowerTorso"), char:FindFirstChild("Humanoid"), char:FindFirstChild("HumanoidRootPart")
	if not (lTorso and hum and hrp) or hum.Health == 0 then
		stopEdit()
		return
	end
	local joint = lTorso:FindFirstChild("Root")
	if not joint then
		stopEdit()
		return
	end
	return hum, hrp, joint
end

local function onRenderStepped()
	local _, hrp = getCharObjects()
	if not hrp then
		return
	end
	
	-- update camera here
end

local function onStepped()
	local _, hrp, joint = getCharObjects()
	if not hrp then
		return
	end
	
	local relativeCf = hrp.CFrame:ToObjectSpace(localCf)
	joint.Transform = relativeCf*joint.Transform
end

local function startEdit() -- returns true if succeeded, otherwise returns false
	local hum, hrp = getCharObjects()
	if not hum then
		return false
	end
	
	disableMovementControls()
	localCf = CFrame.new(calculatePos(hum, hrp))
	
	steppedConn = RunService.Stepped:Connect(onStepped)
	renderSteppedConn = RunService.RenderStepped:Connect(onRenderStepped)
	return true
end
1 Like