I’ve been struggling with this problem for several weeks now. When running the game in VR singleplayer, the input seems to work fine. However running it in netcode makes the inputs completely irresponsive, like the buttons simply aren’t triggering anything. This is weird because I also use the new unity input system for mouse/keyboard gameplay in the same project and that works in multiplayer and singleplayer. I’ve been trying a lot of things to no avail. The controller positions and head are tracking position and rotation, but not inputs.
The way I have it set up is the VR components are in the game scene before the game starts. When the player joins the game, the steam vr inputs will send positions and rotations to the netcode object, which has vr scripts stripped from it. The steam vr rig in the scene, local, is not receiving inputs. However running the scene without starting a netcode game makes it so the rig works. Here is my modified vr input script. I’m using valves open xr / steam vr package.
//======= Copyright (c) Valve Corporation, All rights reserved. ===============
using UnityEngine;
using UnityEngine.SceneManagement;
using Unity.Netcode;
using Valve.VR;
public struct ClickedEventArgs
{
public uint controllerIndex;
public uint flags;
public float padX, padY;
}
public delegate void ClickedEventHandler(object sender, ClickedEventArgs e);
public class SteamVR_TrackedController : NetworkBehaviour
{
public SteamVR_Input_Sources hand;
public uint controllerIndex;
public VRControllerState_t controllerState;
public bool triggerPressed = false;
public bool triggerClickedOnce = false;
public bool steamPressed = false;
public bool menuPressed = false;
public bool padPressed = false;
public bool padTouched = false;
public bool gripped = false;
public Animator handAnimator;
public SteamVR_Action_Boolean trigger = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("default", "Trigger");
public SteamVR_Action_Boolean grip = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("default", "GrabGrip");
public SteamVR_Action_Boolean menu = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("default", "Pause");
public SteamVR_Action_Boolean boost = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("default", "Boost");
public event ClickedEventHandler MenuButtonClicked;
public event ClickedEventHandler MenuButtonUnclicked;
public event ClickedEventHandler TriggerClicked;
public event ClickedEventHandler TriggerUnclicked;
public event ClickedEventHandler SteamClicked;
public event ClickedEventHandler PadClicked;
public event ClickedEventHandler PadUnclicked;
public event ClickedEventHandler PadTouched;
public event ClickedEventHandler PadUntouched;
public event ClickedEventHandler Gripped;
public event ClickedEventHandler Ungripped;
public GameObject pause;
public bool singlePlayer = true;
// Use this for initialization
protected virtual void Start()
{
if(pause == null)
{
pause = GameObject.Find("Pause");
if (pause != null)
pause.SetActive(false);
}
if (this.GetComponent<SteamVR_TrackedObject>() == null)
{
gameObject.AddComponent<SteamVR_TrackedObject>();
}
if (controllerIndex != 0)
{
this.GetComponent<SteamVR_TrackedObject>().index = (SteamVR_TrackedObject.EIndex)controllerIndex;
if (this.GetComponent<SteamVR_RenderModel>() != null)
{
this.GetComponent<SteamVR_RenderModel>().index = (SteamVR_TrackedObject.EIndex)controllerIndex;
}
}
else
{
controllerIndex = (uint)this.GetComponent<SteamVR_TrackedObject>().index;
}
}
public void SetDeviceIndex(int index)
{
this.controllerIndex = (uint)index;
}
public virtual void OnTriggerClicked(ClickedEventArgs e)
{
print("Trigger Clicked!!");
if (TriggerClicked != null)
TriggerClicked(this, e);
triggerClickedOnce = true;
if (Time.timeScale == 0)
{
SceneManager.LoadScene(0);
}
}
public virtual void OnTriggerUnclicked(ClickedEventArgs e)
{
if (TriggerUnclicked != null)
TriggerUnclicked(this, e);
}
public virtual void OnMenuClicked(ClickedEventArgs e)
{
if (MenuButtonClicked != null)
MenuButtonClicked(this, e);
if(Time.timeScale == 0)
{
Time.timeScale = 1;
pause.SetActive(false);
}
else
{
Time.timeScale = 0;
pause.SetActive(true);
}
}
public virtual void OnMenuUnclicked(ClickedEventArgs e)
{
if (MenuButtonUnclicked != null)
MenuButtonUnclicked(this, e);
}
public virtual void OnSteamClicked(ClickedEventArgs e)
{
if (SteamClicked != null)
SteamClicked(this, e);
}
public virtual void OnPadClicked(ClickedEventArgs e)
{
if (PadClicked != null)
PadClicked(this, e);
}
public virtual void OnPadUnclicked(ClickedEventArgs e)
{
if (PadUnclicked != null)
PadUnclicked(this, e);
}
public virtual void OnPadTouched(ClickedEventArgs e)
{
if (PadTouched != null)
PadTouched(this, e);
}
public virtual void OnPadUntouched(ClickedEventArgs e)
{
if (PadUntouched != null)
PadUntouched(this, e);
}
public virtual void OnGripped(ClickedEventArgs e)
{
if (Gripped != null)
Gripped(this, e);
}
public virtual void OnUngripped(ClickedEventArgs e)
{
if (Ungripped != null)
Ungripped(this, e);
}
public void UnclickTrigger()
{
triggerClickedOnce = false;
}
// Update is called once per frame
protected virtual void Update()
{
if(IsOwner || singlePlayer)
{
var system = OpenVR.System;
triggerPressed = trigger[hand].state;
triggerClickedOnce = trigger[hand].stateDown;
if (triggerClickedOnce)
{
if (Time.timeScale == 0)
{
SceneManager.LoadScene(0);
}
}
padPressed = boost[hand].state;
gripped = grip[hand].state;
if (handAnimator != null)
{
float gripVal = 0;
if (gripped)
{
gripVal = 1;
}
handAnimator.SetFloat("GrabState", gripVal);
}
if (menu[hand].stateDown)
{
if (Time.timeScale == 0)
{
Time.timeScale = 1;
pause.SetActive(false);
}
else
{
Time.timeScale = 0;
pause.SetActive(true);
}
}
if (system != null && system.GetControllerState(controllerIndex, ref controllerState, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VRControllerState_t))))
{
}
}
}
}