How to make an empty character for player

As the title of this topic says, I am trying to make an empty character for players when they join. If you didnt understand, here is what I mean :

When a player joins, their character is loaded in the workspace with all the accessories in their character.

My goal is to not have that humanoid in their character at all.

Now you may suggest to have CharacterAutoLoads to false in Players. But that is basically just stops player from having character. That’s actually good but the problem comes about streaming. When streaming is enabled, the local scripts starts to malfunction and throw errors. When disabled, it works fine, but it reduced the game performance heavily.

image

I tried to make a startercharacter with just a humanoidrootpart in a model and put health and animate script with nothing blank code under StarterPlayer/StarterCharacterscripts, even though it worked, I see that roblox expects the character to have a humanoid and also there is a damage effect whenever I run the game.

image

All I want is access camera which only works when player has a character when streaming is enabled. Kindly help me :pray:

I couldnt find this topic in dev forum. If their is such a topic then forgive me for asking again and direct me to the correct solution for this to overcome

Disabling CharacterAutoLoads and creating a “proxy character” on the server to reference while updating its position to match the client’s character should work. However, this brute force method may lead to issues, particularly with replication. For example, the proxy character might not always sync perfectly with the client, leading to inconsistencies, such as lag or delayed position updates.

In the pseudocode below, we create a proxy character for each player when they join:

local Players = game:GetService("Players")
local Event: RemoteEvent -- Fake Event should fire to the client when the server has created the proxycharacter

local ROOT_PART_NAME = "HumanoidRootPart"
local PROXY_PARENT = nil -- Keeps the proxy in memory only, not in the game hierarchy

local proxyTemplate

-- Lazily creates the proxy character template on first use.
-- (You could pre-make this in the Explorer for better performance.)
local function CreateCharacterProxy(playerName: string)
	if not proxyTemplate then
		proxyTemplate = Instance.new("Model")
		proxyTemplate.Name = "ProxyCharacterTemplate"
		
		local root = Instance.new("Part")
		root.Name = ROOT_PART_NAME
		root.Parent = proxyTemplate
		
		local humanoid = Instance.new("Humanoid")
		humanoid.Parent = proxyTemplate
		
		proxyTemplate.Parent = script
	end
	
	local clone = proxyTemplate:Clone()
	clone.Parent = PROXY_PARENT
	clone.Name = playerName
	return clone
end

local function OnPlayerAdded(player: Player)
	local character = CreateCharacterProxy(player.Name)
end

Players.PlayerAdded:Connect(OnPlayerAdded)
2 Likes

I tried this method, but my goal is not to have a humanoid at all. I dont need health and stuff. Plus when I do you’re method, the player has a default damaged effect for some reason even though there is no humanoid for that character.

local cc=workspace.CurrentCamera
local plr=game:GetService("Players")
local lp=plr.LocalPlayer
local character=lp.Character or lp.CharacterAdded:Wait()
--you could just make local function
--and make singal to this function when player has character
--[[local function playerhascharacter()
if not character then
print("Can't Switch CurrentCamera to it's SubjectCamera to Player's Character due to Player has no Character")
else
cc.CameraSubject=character
end]]

-- this does only once (my guess)
if character then
cc.CameraSubject=character --(put whatever here)
end
--lp.CharacterAdded:Connect(playerhascharacter)

something like this ?

my-solution.rbxl (68.8 KB)
All scripts are in the ReplicatedStorage this may be overkill for what you want though.
I didnt do movement replication to the server since you may want to handle it a different way.

(sorry if not well commented)

1 Like

Nevermind, I did a work around. I set :

CharacterAutoLoad = false

Then, in the server script I put this :

game.Players.PlayerAdded:Connect(function(player)
	player.ReplicationFocus = workspace.CameraPart
end)

Now the floating player instance who has no character is located to where I want to be and the local scripts works just fine. But one issue still persist and is the UI. For some reason, StarterGUI doesnt load in the playerGUI. To solve this, you need to add a local script in Replicated First and then parent the ScreenGUI to the playerGUI. This is the sample local script located in ReplicatedFirst :

local player = game.Players.LocalPlayer
local playerGUI = player.PlayerGui
local GUI = script.ScreenGUI
local scriptUI = GUI.Background.LocalScript
task.wait(5)
GUI.Parent = playerGUI
scriptUI.Enabled = true

I also thank other devs for trying to help me out.