Different characters and scripts for VR and PC players

I wanted to make a script that VR and PC players have different scripts.
Pc doesn’t have any scripts but VR has 2 Scripts ( startercharacterscripts)
and they have different characters
can anyone help me? Thanks

1 Like
local UserInputService = game:GetService("UserInputService")

local isUsingVR = UserInputService.VREnabled
if isUsingVR then
	print("User is using a VR headset!")
else
	print("User is not using a VR headset!")
end

You could by default keep all character scripts disabled, then if they pass the check (provided in code) you can enable the VR/PC only scripts.

1 Like

ok thank you so much! now i try it

1 Like

but for the characters what can i do?

1 Like

and, the code would be like:

local UserInputService = game:GetService(“UserInputService”)

local isUsingVR = UserInputService.VREnabled
if isUsingVR then
script.Enabled = true
else
script.Enabled = false
end

?

2 Likes

Yes! Ideally you would have folders for individual platforms, then you can get the children of the folder and loop the descendants to enable scripts depending on the platform using the conditional I gave you.

I hope this helps!

1 Like

tysm! for the scripts i’m good, but i have to change the characters for VR and PC players

1 Like

What are you trying to achieve? Are you looking for a “Vr Hands” type approach for VR users?

1 Like

I’m trying to be that vr players have a locomotion ( that works only on one rig ) and pc players that have another rig

1 Like

I’m not sure how proficient at programming you are: but here’s what I would do:

  • Add a RemoteFunction to ReplicatedStorage
  • Add a LocalScript into StarterPlayerScripts with a function that gets the player’s device (VR or PC) and return the result
  • Connect the function to the RemoteFunction, that way the server can invoke the player’s client to get the device
  • Add your character models to the ServerStorage
  • Create a Script in ServerScriptService. When the player joins, invoke the RemoteFunction (with the player that joined as the argument)
  • The RemoteFunction should return the player’s device
  • You can then use additional logic on the server to load the character model depending on the device
  • Turn off AutoLoadCharacter on the Players service to prevent the wrong model loading

Right now, I’m writing this from my phone, so I’m not really able to test this, but this is how I would handle this. If you want to me clear anything up or answer any specific questions, please ask.
Good luck woth your project though, I’d love to see a proper locomotion game on Roblox.

i’m new at scripting, idk if i’m doing correctly.

Server Script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GetPlayerDevice = ReplicatedStorage:WaitForChild("GetPlayerDevice")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	player.AutoLoadCharacter = false

end)


Players.PlayerAdded:Connect(function(player)
	local device = GetPlayerDevice:InvokeClient(player)

	local characterModelsFolder = ServerStorage:WaitForChild("CharacterModels")
	local characterModel

	if device == "VR" then
		characterModel = characterModelsFolder:FindFirstChild("VRCharacter")
	elseif device == "PC" or device == "MOBILE" or device == "UNKNOWN" then
		characterModel = characterModelsFolder:FindFirstChild("PCCharacter")
	end

	if characterModel then
		local characterClone = characterModel:Clone()
		player.Character = characterClone
		characterClone.Parent = workspace
	end
end)

and in the localscript:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GetPlayerDevice = ReplicatedStorage:WaitForChild("GetPlayerDevice")
local UserInputService = game:GetService("UserInputService")
local isUsingVR = UserInputService.VREnabled


local function getDevice()
	if isUsingVR then
		return "VR"
	elseif UserInputService.TouchEnabled then
		return "Mobile"
	elseif UserInputService.MouseEnabled then
		return "PC"
	else
		return "Unknown"
	end
end

local player = game.Players.LocalPlayer
GetPlayerDevice.OnClientInvoke = getDevice

This looks about right, but you have some things that are incorrect.

Check your strings, your client returns “Mobile” but server checks for “MOBILE”

You should consider positioning the new character properly.

I’m not sure, but you should also be able to toggle automatic character respawning in the players properties without having to change it in runtime.

when you are at home and you can use the computer can you send me the script? Idk how to fix it sorry .(

That’ll be in a while, so if no-one hops on in to help you effectively then as soon as I get home I’ll help ya out

ok! thank you so much! I wait :slight_smile:

For a new scripter, you did a good job interpreting my idea. The LocalScript is all correct. The player variable in unnecessary however, as it’s not used.

The only issues I see are with the Server Script.

  1. Remove the first Players.PlayerAdded. AutoLoadCharacter is a property of the Players service, not the player themselves. This also needs to be set in Studio, and can’t be edited via scripts.
    image

  2. Like @Chrobahh said, the spellings of the Server logic doesn’t match the result sent by the client. This is easy to fix, just change the “MOBILE” to “Mobile” and “UNKNOWN” to “Unknown”.

This is what the new code looks like:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GetPlayerDevice = ReplicatedStorage:WaitForChild("GetPlayerDevice")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
	local device = GetPlayerDevice:InvokeClient(player)

	local characterModelsFolder = ServerStorage:WaitForChild("CharacterModels")
	local characterModel

	if device == "VR" then
		characterModel = characterModelsFolder:FindFirstChild("VRCharacter")
	elseif device == "PC" or device == "Mobile" or device == "Unknown" then
		characterModel = characterModelsFolder:FindFirstChild("PCCharacter")
	end

	if characterModel then
		local characterClone = characterModel:Clone()
		player.Character = characterClone
		characterClone.Parent = workspace
	end
end)

While this works, there are a few other changes I would add to the script.

  • Naming the new character model to match the Player’s username
  • Moving the new character to a SpawnLocation
  • Adding respawning for when/if the player dies

That’s about it. Like I said, you did a very solid job on your own, well done. Here’s the script with the suggested changes:

Code with extra changes
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GetPlayerDevice = ReplicatedStorage:WaitForChild("GetPlayerDevice")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")

local function LoadCharacterModel(player, characterModel)
	local characterClone = characterModel:Clone()
	characterClone.Name = player.Name
	player.Character = characterClone
	characterClone.Parent = workspace
	characterClone.PrimaryPart.CFrame = workspace.SpawnLocation.CFrame + Vector3.new(0,2,0)

	characterClone.Humanoid.Died:Once(function()
		task.wait(game.Players.RespawnTime)
		LoadCharacterModel(player, characterModel)
	end)
end

Players.PlayerAdded:Connect(function(player)
	local device = GetPlayerDevice:InvokeClient(player)

	local characterModelsFolder = ServerStorage:WaitForChild("CharacterModels")
	local characterModel

	if device == "VR" then
		characterModel = characterModelsFolder:FindFirstChild("VRCharacter")
	elseif device == "PC" or device == "Mobile" or device == "Unknown" then
		characterModel = characterModelsFolder:FindFirstChild("PCCharacter")
	end

	if characterModel then
		LoadCharacterModel(player, characterModel)
	end
end)

It gives me 2 errors:
20:37:12.641 InvokeClient is not a valid member of RemoteEvent “ReplicatedStorage.GetPlayerDevice” - Server - Script:20
20:37:12.641 Stack Begin - Studio
20:37:12.641 Script ‘ServerScriptService.Script’, Line 20 - Studio - Script:20
20:37:12.641 Stack End - Studio
20:37:12.871 Players.Crisopeo.PlayerScripts.LocalScript:19: Expected identifier when parsing expression, got ‘=’ - Studio - LocalScript:19

The error Script:20 is because the GetPlayerDevice in ReplicatedStorage needs to be a RemoteFunction, not a RemoteEvent.

As for the LocalScript, could I please see that? It was working fine when I copied your old one.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GetPlayerDevice = ReplicatedStorage:WaitForChild("GetPlayerDevice")
local UserInputService = game:GetService("UserInputService")
local isUsingVR = UserInputService.VREnabled


local function getDevice()
	if isUsingVR then
		return "VR"
	elseif UserInputService.TouchEnabled then
		return "MOBILE"
	elseif UserInputService.MouseEnabled then
		return "PC"
	else
		return "UNKNOWN"
	end
end

local player = game.Players.LocalPlayer
GetPlayerDevice.OnClientInvoke = getDevice

and when i’m on vr it says:
20:41:45.977 ServerScriptService.Script:11: attempt to index nil with ‘CFrame’ - Server - Script:11
20:41:45.977 Stack Begin - Studio
20:41:45.977 Script ‘ServerScriptService.Script’, Line 11 - function LoadCharacterModel - Studio - Script:11
20:41:45.978 Script ‘ServerScriptService.Script’, Line 32 - Studio - Script:32
20:41:45.978 Stack End - Studio