Help on making a ROBLOX game for VR

Help on making a ROBLOX game for VR I have looked everywhere but it just seems too outdated so I have been trying to make it myself but when i playtest it my character is stuck in the air and i spawn up high. This is the code:

local UIS = game:GetService("UserInputService")
local VRS = game:GetService("VRService")
local RS =  game:GetService("ReplicatedStorage")
local Run = game:GetService("RunService")
local SG = game:GetService("StarterGui")
local plr = game.Players.LocalPlayer
local char = script.Parent
local Cam =  game.Workspace.CurrentCamera
local RightHand = char:WaitForChild("Right Arm")
local LeftHand = char:WaitForChild("Left Arm")
local Head = char:WaitForChild("Head")
local Head2 = workspace.Head2
local RArm2 = workspace.RightArm2
local LArm2 = workspace.LeftArm2

-- VR Code --

if VRS.VREnabled == true then
	print(plr.Name.." has joined in VR")
	SG:SetCore("VRLaserPointerMode", 0)
	SG:SetCore("VREnableControllerModels", false)
	VRS:RecenterUserHeadCFrame()
	Cam.HeadScale = 1

	-- Controllers --

	VRS.UserCFrameChanged:Connect(function(thing, cframe)
		Head2.CFrame = VRS:GetUserCFrame(Enum.UserCFrame.RightHand)
		RArm2.CFrame = VRS:GetUserCFrame(Enum.UserCFrame.LeftHand)
		LArm2.CFrame = VRS:GetUserCFrame(Enum.UserCFrame.Head)

	end)

	-- Camera --

	Run.RenderStepped:Connect(function()
		Cam.HeadLocked = false
		Cam.CameraType = Enum.CameraType.Scriptable
	end)
end
5 Likes

Hello, I personally have not worked with VR development in *Roblox but I’ve done a bit of research over the years and I did play around with OpenXR on Unity which is what this integration is based on.

Try this code to see if it fixes your problem:

local UIS = game:GetService(“UserInputService”)
local VRS = game:GetService(“VRService”)
local RS = game:GetService(“ReplicatedStorage”)
local Run = game:GetService(“RunService”)
local SG = game:GetService(“StarterGui”)
local Workspace = game:GetService(“Workspace”)
local plr = game.Players.LocalPlayer
local char = script.Parent
local Cam = game.Workspace.CurrentCamera
local RightHand = char:WaitForChild(“Right Arm”)
local LeftHand = char:WaitForChild(“Left Arm”)
local Head = char:WaitForChild(“Head”)
local Head2 = workspace.Head2
local RArm2 = workspace.RightArm2
local LArm2 = workspace.LeftArm2

local function findSpawnLocation()
local spawnLocation = Workspace:FindFirstChild(“Spawn Location”)
if not spawnLocation then
local baseplate = Workspace:FindFirstChild(“Baseplate”)
if baseplate then
return baseplate.Position + Vector3.new(0, 3, 0)
end
else
return spawnLocation.Position
end
return Vector3.new(0, 10, 0)
end

if VRS.VREnabled == true then
SG:SetCore(“VRLaserPointerMode”, 0)
SG:SetCore(“VREnableControllerModels”, false)
VRS:RecenterUserHeadCFrame()
Cam.HeadScale = 1

VRS.UserCFrameChanged:Connect(function(thing, cframe)
    Head2.CFrame = VRS:GetUserCFrame(Enum.UserCFrame.RightHand)
    RArm2.CFrame = VRS:GetUserCFrame(Enum.UserCFrame.LeftHand)
    LArm2.CFrame = VRS:GetUserCFrame(Enum.UserCFrame.Head)
end)

Run.RenderStepped:Connect(function()
    Cam.HeadLocked = false
    Cam.CameraType = Enum.CameraType.Scriptable
end)

local spawnPos = findSpawnLocation()
char:SetPrimaryPartCFrame(CFrame.new(spawnPos))

end

If that does not fix your issue, I followed a project back in 2018, I don’t know when the last update was but it’s claimed to still be functional.

Nexus VR - Nexus VR Character Model by TheNexusAvenger

Best of luck.

3 Likes

I watched some of this and I think it might be valuable for learning vr development.

1 Like

I seem to spawn in the spawnpoint now but it seems like the world is locked to my head so when i move up the world also moves up so i cant look to the sky or down to the spawnpoint.

1 Like

Didn’t work for me probably because its too complicated for me so I’m just looking for a simple solution

1 Like

Hey @Fer_GameDeveloper, I am glad to hear some progress was made. I believe I made a mistake with the script when setting the CamHeadLock value to false. If the CamHeadLock is false, then the camera is not locked the the player’s head.

I did provide the updated script for you to try below this message so look for it and let me know if it helps.

I would definitely encourage you to look over the VR development documentation, I know reading the specifics can be very dry and it’s the least fun part of game development, but the more you know the more fun you find yourself having.

These are just “Tips” on building a better experience: VR Guidelines | Documentation - Roblox Creator Hub

This is the actual documentation for VR Development: VRService | Documentation - Roblox Creator Hub

Sometimes we have to do a bit of research and that means watching boring videos to find the information but that’s part of the fun in my opinion. Thanks to the video that @ppwwppw2 shared I was able to take the picture below it has a bit of context.

3 Likes

Thanks for responding! The code you provided did fix my main issue but now my other issue is just for the hands and head moving as the player moves. The hands and head move and rotate but dont move when the player moves. I’ve tried to lock the player in first person but with no success. I’m thinking of welding it but i think it will just stick to the players arms and head. Is there any way to fix this?

1 Like

The script I provided is incomplete, because although I could sit here and help you all night, and I mean that I definitely could, I would not be doing you any favors by just giving you the answers.

Let’s go over the first concept, you mentioned welding the arms to the controllers, and truthfully that’s an idea that in theory would work, you would be able to have the benefit of not having to script every single “grab” hand interaction since the object you’re grabbing could just be welded to the arm when grabbed, it would make for a cool experience seeing you characters arms as your own, and it would be the easiest way to go about it, but in order to do that you need to create proxies that would essentially be a representation of your controller identical in both orientation and position, and that’s just the tip of the iceberg because after you have those proxies, you would then need to update those proxies to match the real controllers, and weld them, but after all of that, you would still need to do the most important thing which is updating the CFrame of the player’s representation, and parts.

Now let’s review the alternative, look over the script I provided and I want you to look for the following:

Run.RenderStepped:Connect(function()

The function is one of the most important ones when creating a VR experience. In Unity developers use “void Update()” and I only bring that up because of the terminology, the word Update. We need to see what we are updating every frame. Run.RenderStepped runs every frame.

If we look at our script and locate Run.RenderStepped we see the following items on there:

    Cam.HeadLocked = true
    Cam.CameraType = Enum.CameraType.Scriptable
end)

local spawnPos = findSpawnLocation()
char:SetPrimaryPartCFrame(CFrame.new(spawnPos))

If we are keeping track of our problem, our problem is the head, and 2 arms that don’t seem to be Updated

It’s important to remember that any items that will be in constant motion, will need to be updated every frame, this can get resource intensive if you run everything the player sees using RunRenderStepped, so it’s important to plan your project accordingly.

If the play is to keep up with the player’s movements but you only update the camera, and not the arms, then your arms will stay behind since the only time we reference the player’s Primary Part CFrame is when we set CFrame.new to place the Player’s Primary part in spawnPos which is us running a function to location the Spawn Location, how is that function actually looking and finding the spawn location?

–First we declare the function findSpawnLocation

– Second we reference the location of the Spawn Location, followed by an if

– If we can’t find spawnLocationm then we look for the baseplate

– if a baseplate is found, then we spawn at 0,3,0, but if a baseplate is not found, or a spawnlocation, the we spawn a whopping 0,10,0 which is fairly high.

local function findSpawnLocation()
local spawnLocation = Workspace:FindFirstChild(“Spawn Location”)
if not spawnLocation then
local baseplate = Workspace:FindFirstChild(“Baseplate”)
if baseplate then
return baseplate.Position + Vector3.new(0, 3, 0)
end
else
return spawnLocation.Position
end
return Vector3.new(0, 10, 0)
end

Now that we’ve taken this time to get a bit of understanding for the amount of time and effort it takes to figure out the issues and how to overcome them, I will share the last script I will be sending you.

Before you copy, and paste the script, take 10 minutes to look at the full script, look at the references so that you get an idea for the things you need to have in your game, and what they need to be named.

If you truly want to develop a game and love the idea of it, make this your best friend: VRService | Documentation - Roblox Creator Hub

Best of luck!

local UIS = game:GetService(“UserInputService”)
local VRS = game:GetService(“VRService”)
local Run = game:GetService(“RunService”)
local SG = game:GetService(“StarterGui”)
local Workspace = game:GetService(“Workspace”)
local plr = game.Players.LocalPlayer
local char = script.Parent
local Cam = Workspace.CurrentCamera
local RightHand = char:WaitForChild(“Right Arm”)
local LeftHand = char:WaitForChild(“Left Arm”)
local Head = char:WaitForChild(“Head”)
local Head2 = Workspace.Head2
local RArm2 = Workspace.RightArm2
local LArm2 = Workspace.LeftArm2

local function findSpawnLocation()
local spawnLocation = Workspace:FindFirstChild(“Spawn Location”)
if not spawnLocation then
local baseplate = Workspace:FindFirstChild(“Baseplate”)
if baseplate then
return baseplate.Position + Vector3.new(0, 3, 0)
end
else
return spawnLocation.Position
end
return Vector3.new(0, 10, 0)
end

if VRS.VREnabled == true then
SG:SetCore(“VRLaserPointerMode”, 0)
SG:SetCore(“VREnableControllerModels”, false)
VRS:RecenterUserHeadCFrame()
Cam.HeadScale = 1

local function updateVRComponents()
    Head2.CFrame = Cam.CFrame * VRS:GetUserCFrame(Enum.UserCFrame.Head)
    RArm2.CFrame = Cam.CFrame * VRS:GetUserCFrame(Enum.UserCFrame.RightHand)
    LArm2.CFrame = Cam.CFrame * VRS:GetUserCFrame(Enum.UserCFrame.LeftHand)
end

VRS.UserCFrameChanged:Connect(updateVRComponents)

Run.RenderStepped:Connect(function()
    Cam.HeadLocked = true
    Cam.CameraType = Enum.CameraType.Scriptable
    updateVRComponents()
end)

local spawnPos = findSpawnLocation()
char:SetPrimaryPartCFrame(CFrame.new(spawnPos))

end

2 Likes

Now the script you provided didn’t work for me, so I did some research with free models and found a way simpler solution which is this:

local VRS = game:GetService("VRService")
local SG = game:GetService("StarterGui")
local Run = game:GetService("RunService")
local Camera = workspace.CurrentCamera

if VRS.VREnabled == true then
	SG:SetCore("VRLaserPointerMode", 0)
	SG:SetCore("VREnableControllerModels", false)
	VRS:RecenterUserHeadCFrame()

	Run.RenderStepped:Connect(function()
		workspace.Head2.CFrame = Camera.CFrame * VRS:GetUserCFrame(Enum.UserCFrame.Head)
		workspace.RightArm2.CFrame = Camera.CFrame * VRS:GetUserCFrame(Enum.UserCFrame.RightHand)
		workspace.LeftArm2.CFrame = Camera.CFrame * VRS:GetUserCFrame(Enum.UserCFrame.LeftHand)
	end)
end
1 Like

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