My goal is to stop my VR hand models (which are unanchored and networkowned by the client) from spazzing and teleporting when their cframe is modified each renderstep. The hands seem to start spazzing out and flying away sometimes coming back as if its fighting between some kind of constraint and the cframe set. Occasionally they will teleport along their upvector (this is confirmed) to and fro by a set random number each frame toggling. (what the heck is that???)
I tried changing the function to a physics step but the same thing happened again, I also compared it to a fully client sided anchored hand which worked completely perfect and points the blame at something network/physics based.
I provided videos of the hands spazzing and then acting completely normal in another instance and I have shown comments of the important parts of code (I know I threw in the entire program but I thought it would help for a full context).
Videos
Code
ALL CODE:
Server Sided VR Avatar Handler:
game.StarterGui:SetCore("VRLaserPointerMode", 0)
script.GiveAvatar.OnServerInvoke = function(player)
-- IMPORTANT BIT LOOK AT ME AND DOWN!
local bodygroup = Instance.new("Model")
bodygroup.Name = player.Name
bodygroup.Parent = game.Workspace
local head = game.ServerStorage.Head:Clone()
head.Parent = bodygroup
head.Name = "Head"
local lefthand = game.ServerStorage.LeftHand:Clone()
lefthand.Parent = bodygroup
lefthand.Name = "LeftHand"
local righthand = game.ServerStorage.RightHand:Clone()
righthand.Parent = bodygroup
righthand.Name = "RightHand"
bodygroup.PrimaryPart = head
lefthand.PrimaryPart:SetNetworkOwner(player)
righthand.PrimaryPart:SetNetworkOwner(player)
head:SetNetworkOwner(player)
return head,lefthand,righthand
-- END OF IMPORTANT BIT!
end
game.Players.PlayerAdded:Connect(function(player)
local vrenabled = game.ReplicatedFirst.VRQuery:InvokeClient(player)
if vrenabled then
player.CharacterAdded:Connect(function()
print("CharacterAdded")
player.Character:Destroy()
end)
player.CharacterAppearanceLoaded:Connect(function()
print("AppearanceLoaded")
player.Character:Destroy()
end)
end
end)
script.RemoveCharacter.OnServerEvent:Connect(function(player)
player.Character:Destroy()
player.CharacterAdded:Connect(function()
print("CharacterAdded")
player.Character:Destroy()
end)
player.CharacterAppearanceLoaded:Connect(function()
print("AppearanceLoaded")
player.Character:Destroy()
end)
end)
Client Sided VR Avatar Handler: (most of this is irrelevant, I specified what is not with comments)
game.ReplicatedFirst:RemoveDefaultLoadingScreen()
local uis = game:GetService("UserInputService")
local player = game.Players.LocalPlayer
local isvrenabled = false
local isdebugenabled = false
isvrenabled = uis.VREnabled
if player.Name == "Futuristic_Paladin" then
isvrenabled = true
isdebugenabled = true
end
if isvrenabled then
game.Workspace.VRAvatarScript.RemoveCharacter:FireServer()
print("Vrenabled")
game.StarterGui:SetCore("VRLaserPointerMode", 0)
game.StarterGui:SetCore("VREnableControllerModels", false)
local cam = Instance.new("Camera")
local playergui = player:WaitForChild("PlayerGui")
local debuggui = Instance.new("SurfaceGui")
debuggui.Face = Enum.NormalId.Top
debuggui.PixelsPerStud = 400
debuggui.Parent = playergui
debuggui.Name = "DebugGui"
debuggui.Enabled = true
debuggui.ClipsDescendants = true
debuggui.AlwaysOnTop = true
if player.Name == "Futuristic_Paladin" then
debuggui.Enabled = true
else
debuggui.Enabled = false
end
local keycode = script:WaitForChild("KeyCode")
local inputtype = script:WaitForChild("InputType")
local deltagui = script:WaitForChild("Delta")
local position = script:WaitForChild("Position")
local offsetlabel = script:WaitForChild("Offset")
local debuglabel = script:WaitForChild("Debug")
keycode.Parent = debuggui
inputtype.Parent = debuggui
deltagui.Parent = debuggui
position.Parent = debuggui
offsetlabel.Parent = debuggui
debuglabel.Parent = debuggui
local character
local root
local humanoid
local runservice = game:GetService("RunService")
-- IMPORTANT BIT LOOK AT ME AND DOWN!
local head,lefthand,righthand = game.Workspace.VRAvatarScript.GiveAvatar:InvokeServer()
local reallefthand = Instance.new("Part")
reallefthand.Parent = game.Workspace
reallefthand.Anchored = true
reallefthand.CanCollide = false
reallefthand.Size = Vector3.new(0.9,0.4,0.4)
reallefthand.Transparency = 0.5
local realrighthand = reallefthand:Clone()
realrighthand.Parent = game.Workspace
-- END OF IMPORTANT BIT BUT MORE FURTHER DOWN
local facepart = script.FacePart
facepart.Parent = game.Workspace
local facegui = facepart.FaceGui
debuggui.Adornee = righthand.HandSurface
game.Workspace.CurrentCamera:Destroy()
cam.Parent = game.Workspace
cam.Name = "VRCamera"
cam.CameraType = Enum.CameraType.Scriptable
game.Workspace.CurrentCamera = cam
cam.CFrame = CFrame.new(Vector3.new(0,5,0))
local lhcframe = CFrame.new(Vector3.new(1,-1,2))
local rhcframe = CFrame.new(Vector3.new(-1,-1,2))
local headcframe = CFrame.new(Vector3.new(10,5,0))
local headscale = 1
local offset = Vector3.new(0,0,0)
local orientation = Vector3.new(90,-90,0)
local offsetpart = Instance.new("Part")
local camrotation = 0
local currentrot = 0
local turnpersec = 3
offsetpart.Anchored = true
offsetpart.Orientation = orientation
offsetpart.Position = offset
local playerheight = 5
local function movehands(thedelta,hand)
local handthing
if hand == true then
handthing = lefthand
else
handthing = righthand
end
for _,hinge in pairs(handthing:GetDescendants()) do
if hinge:IsA("HingeConstraint") then
local hingevalue = hinge:FindFirstChildWhichIsA("NumberValue")
if hingevalue then
hinge.TargetAngle = hingevalue.Value * thedelta
hinge.ServoMaxTorque = 10000000
end
end
end
end
local leftdelta = 0
local rightdelta = 0
local cameraoffset = Vector3.new(0,0,0)
local clock = 0.02
local movemultiplier = 10
local debugpart = Instance.new("Part")
debugpart.Parent = game.Workspace
debugpart.Size = Vector3.new(1,1,1)
debugpart.Anchored = true
uis.InputChanged:Connect(function(input)
--[[
keycode.Text = tostring(input.KeyCode)
inputtype.Text = tostring(input.UserInputType)
position.Text = tostring(input.Position)
--]]
if input.KeyCode == Enum.KeyCode.Thumbstick1 then
local success, result = pcall(function()
cameraoffset = (cam.CFrame:ToWorldSpace(headcframe)).LookVector * movemultiplier * input.Position.Y * clock
cameraoffset = cameraoffset + ((headcframe:ToWorldSpace(cam.CFrame)).RightVector * movemultiplier * input.Position.X * clock)
cameraoffset = Vector3.new(cameraoffset.X,0,cameraoffset.Z)
end)
end
if input.KeyCode == Enum.KeyCode.Thumbstick2 then
if input.Position.X < 0.1 and input.Position.X > -0.1 then
camrotation = 0
else
camrotation = (input.Position.X * clock * -turnpersec)
end
end
end)
debugpartplace = false
uis.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.ButtonX then
debugpartplace = true
keycode.Text = "True"
end
if input.KeyCode == Enum.KeyCode.ButtonA then
uis:RecenterUserHeadCFrame()
end
end)
uis.InputEnded:Connect(function(input)
if input.KeyCode == Enum.KeyCode.ButtonX then
debugpartplace = false
keycode.Text = "False"
end
end)
runservice.RenderStepped:Connect(function(delta)
if currentrot > 360 then
currentrot = currentrot -360
end
if currentrot < -360 then
currentrot = currentrot + 360
end
clock = delta
-- IMPORTANT BIT LOOK AT ME AND DOWN!
cam.CFrame = cam.CFrame + cameraoffset
currentrot = currentrot + camrotation
cam.CFrame = CFrame.fromEulerAnglesXYZ(0,currentrot,0) + cam.CFrame.Position
if uis.VREnabled then
lhcframe = uis:GetUserCFrame(Enum.UserCFrame.LeftHand)
rhcframe = uis:GetUserCFrame(Enum.UserCFrame.RightHand)
headcframe = uis:GetUserCFrame(Enum.UserCFrame.Head)
if headcframe then
end
if rhcframe then
local righthandcframe = (cam.CFrame*CFrame.new(rhcframe.p*headscale))*CFrame.fromEulerAnglesXYZ(rhcframe:ToEulerAnglesXYZ())*offsetpart.CFrame
realrighthand.CFrame = righthandcframe + righthandcframe.LookVector * 0.1
position.Text = "R: "..tostring(righthand.PrimaryPart.CFrame)
end
if lhcframe then
local lefthandcframe = (cam.CFrame*CFrame.new(lhcframe.p*headscale))*CFrame.fromEulerAnglesXYZ(lhcframe:ToEulerAnglesXYZ())*offsetpart.CFrame
reallefthand.CFrame = lefthandcframe + lefthandcframe.LookVector * 0.1
inputtype.Text = "L: "..tostring(lefthand.PrimaryPart.CFrame)
end
end
lefthand:SetPrimaryPartCFrame(reallefthand.CFrame)
righthand:SetPrimaryPartCFrame(realrighthand.CFrame)
headcframe = uis:GetUserCFrame(Enum.UserCFrame.Head)
if headcframe then
head.CFrame = cam.CFrame:ToWorldSpace(headcframe)
end
-- END OF ALL IMPORTANT BITS!
facepart.CFrame = head.CFrame + head.CFrame.LookVector * 2
deltagui.Text = tostring(math.floor(1/clock))
facegui.FpsLabel.Text = tostring(math.floor(1/clock))
end)
end
Thanks for reading and responding! This is my first post I believe and although I am decently experienced in programming I make loads of mistakes, apologies if I did something stupid such as reposting or a simple 1 line bug or something.
EDIT: I figured out how to finally use the hide option yay.