ValveSoftware / steamvr_unity_plugin

SteamVR Unity Plugin - Documentation at: https://valvesoftware.github.io/steamvr_unity_plugin/
BSD 3-Clause "New" or "Revised" License
1.04k stars 258 forks source link

SteamVR_Actions broken after Scene reload #616

Open Noblauch opened 4 years ago

Noblauch commented 4 years ago

If you use the SteamVR interaction system in Unity and setup default parameters via SteamVR_Action_Boolean someAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("InteractUI"); the interaction system gets broken if you change the button type in the inspector to something other than the default value and then reload the scene in play mode. The problem persists until you restart Unity.

Use this script to see yourself:

using UnityEngine;
using UnityEngine.SceneManagement;
using Valve.VR;

public class InteractionBug : MonoBehaviour
{
    public SteamVR_Action_Boolean button = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("InteractUI");

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
            SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }
}

To Reproduce:

  1. Open a new Unity Project
  2. Import Steam VR
  3. Generate the default SteamVR Inputs
  4. Create a new Scene
  5. Delete the Main Camera
  6. Pull in the Player Prefab ( from SteamVR/InteractionSystem/Core/Prefabs )
  7. Add the provided Script to any GameObject in the scene
  8. Go to that GameObject and change the Button in the Inspector to something else as InteractUI
  9. Press play and observe any of the Hand scrips from the Player in scene
  10. Now press space to reload the scene
  11. Observe the Player Hands again and note that the Ui Interact Action has changed to whatever you selected in the provided script to at step 8
  12. The Ui Interact Action is now broken and can't be changed reversed to the original button and Unity must be restarted in order to do so

Or download this project I set up and just try it out (you can skip step 1 - 8 then) https://github.com/Noblauch/SteamVR_Interaction_Bug

Expected: The SteamVR_Input.GetAction("InteractUI") function only gets the defined (bound) button for the specific action and doesn't have the ability to actually change or destroy something.

It took me 2 days and overall ~19 hours at work to even figure out what the hell is going on. I really hope this gets fixed and some poor soul finds this post, so he doesn't need to commit -m "suicide"

My question now would still be how to initialize a button for the inspector because this way is breaking the system. However it's actually exactly done like that in the interaction system example scene.

Noblauch commented 4 years ago

Problems even more game breaking.

After hours upon hours of testing and ensuring there are even more problems along. The Input sytem is even more messed up than I anticipated.

I set the Hand GrabGripAction to none, because it breaks the game, I cannot use two buttons to pick things up, because obviously in 99% you need the few buttons for other features or systems. So I only have GrabPinchAction enabled. Everything worked again, until we tested every case, including scene reload. And here it happens again: Tons of errors spamming the console after reload: NullReferenceException: Object reference not set to an instance of an object Valve.VR.SteamVR_Action`2[SourceMap,SourceElement].get_Item (Valve.VR.SteamVR_Input_Sources inputSource) (at Assets/Imported/SteamVR/Input/SteamVR_Action.cs:42)

Every script that uses a SteamVR_Action_Boolean and is set to GrabGrip in the dropdown is now broken. I even tried to set the GrabGripAction on the hand to GrabGrip too, in hope it only breaks things if it's set to none. But then things are getting really strange, after scene reload scripts with GrabGrip buttons assigned change to GrabPinch and cant be set back. Everything is screwed up at this point. The deadline for shipping the software is next tuesday and our team is completely lost. I already wasted days upon days with this hacked together input system.

If anyone, anywhere has a dirty fix or anything... I'll take it!

zite commented 4 years ago

Sorry you've been having such issues with the plugin. Can you tell me what version of the plugin (top of the readme.txt) and what version of unity you're using?

zite commented 4 years ago

Thanks for the example project and detailed repro steps. I attempted to repro using your project but was unable to. When I reloaded the scene by hitting space bar it didn't revert the state of the action. I tried this with Unity 2019.2.0f1.

You may be having an issue with multiple player objects in your scene. If you go into the player prefab, SteamVRObjects, then [SteamVR] you'll see a checkbox for if you want to set the player to DoNotDestroy. Which in this case you probably don't. Let me know if this helps.

image

Noblauch commented 4 years ago

Hey zite, thanks for your reply and sorry for not checking back for some weeks! The software is now shipped and we ended up removing all default values used in our scripts to get it to work.

The Version of Steam VR is: SteamVR Unity Plugin - v2.5 (sdk 1.8.19) (you can also find the readme within the repo I provided)

The Unity Version I tested it on is 2019.2.8f1 running on Target Platform Windows x86_64. VR Headset is a HTC Vive Pro but it's reproducible without any VR devices attached.

I just got back to the project to test it with Do Not Destroy disabled, but the bug still occurs. I also re-downloaded my own repo to make sure there are no "issues" with my upload. You are right, the player should be destroyed on load, this is also the case in our program, I just forgot to change the settings there, but as it seems it doesn't make a difference (error still the same).

Here are the steps to reproduce if you use my repo (as I didn't mention them precisely):

  1. Press play and observe any of the Hand scrips from the Player in scene
  2. Press space to reload the scene
  3. Observe the Player Hands again and note that the Ui Interact Action has changed to \actions\default\in\GrabGrip (as I picked that button for demonstration on the Interaction Bug Script)
  4. If you exit play-mode try to repair the Hand scripts and change the Ui Interact Action back to \actions\default\in\InteractUI
  5. You won't be able to and need to restart Unity

I hope you are able to find what I mean. I still haven't found a way to setup default buttons in my scripts until now.

RedKrakenStudios commented 4 years ago

I am also having this (almost) exact issue. On scene reload only haptics are affected. Any script that uses haptics get the same "sourceMap" null error.

mecadiego113 commented 4 years ago

Any updates on this? This issue is broken our project when trying to go to a new scene or just reloading the current one.

levilansing commented 4 years ago

I believe I have this same or a related problem. However, in my case it used to work. The only things I can think of that I have changed since it worked are:

  1. Added 2 new action sets (but always keep default enabled)
  2. SteamVR updated itself recently. I'm on 1.11.13.
  3. Upgraded Unity from 2019.3.13 to 2019.3.14 (also tried upgrading again to 2019.3.15)

Now when i switch scenes, my hands stop tracking, the default action set claims to be enabled via a check in code, but the Unity UI now shows this:

image

And I can't run anymore because of it until I make a code change that causes Unity to recompile. then I can hit play again.

I'm using Unity 2019.3.15f1 and the latest SteamVR plugin, 2.5

levilansing commented 4 years ago

OK, so after fighting with this for 2 days, I think I have resolved my issues with the following:

First, I reverted to a single action set and removed default values in MonoBehaviours for action sets as @Noblauch mentioned, e.g., public SteamVR_ActionSet actionSet = SteamVR_Input.GetActionSet("default"); => public SteamVR_ActionSet actionSet; . This appeared to fix the issue!

Next I added my other action sets back in and my hands stopped tracking again after the SECOND scene load (Menu => Game => Menu*), however, the default action set didn't disappear from Unity anymore, so, progress.

After more experimentation I found that if I disabled all action sets before loading new scenes then the hands would work after loading. Maybe enabling a previously active action set just doesn't work after scene switching?

If this is the expected way to use action sets, it would be nice if disabling all action sets was done by SteamVR_LoadLevel automatically.

Kapunto commented 4 years ago

I experience a similar problem. After loading a scene a second time as @levilansing pointed out the actions are broken. It is not nesessary to load another scene. Directly reloading the scene already works. For me every script stays as it is and all the actions (dropdowns) seem fine but the routing is completly off. Also in die Inputs-Windows it shows a different behaviour. Pinch-Action is suddenly triggering Grip to but the Grip-Action isnt triggering anymore. I just encountered this problem so there isnt much more I know atm.

Edit: Strange is that the pose of hands is still working and hand pose is adjusting correctly to the different actions.

bigfoott commented 4 years ago

I'm having a similar issue. I have a scene using the [CameraRig] prefab and a scene using the Player prefab. When switching from player -> camerarig, my interaction breaks.

In the input live view, it looks like this before running: https://i.imgur.com/bXndxF8.png

Then after switching scenes: https://i.imgur.com/IvEOjKS.png

Then if i close and reopen the live view, I get this in the panel: https://i.imgur.com/QVyV2Fh.png

And this spam in the console: https://i.imgur.com/TfLRBsD.png

The actions file doesn't actually get changed, unity seems to think it does though.

It can be fixed by either regenerating the actions by changing an action and clicking save and generate, or by restarting unity.


Edit: Changed over to using a single action set and I'm no longer having any issues.

mynameisjohn commented 4 years ago

I just ran into the same issue, @Noblauch's fix worked for me. This is with SteamVR Unity Plugin - v2.5 (sdk 1.8.19). I have a single action set, which I think lessened some of the problems for me, but I still couldn't track hand position after reloading a scene.

@Noblauch should bill Steam for the hours... this asset is a bit of a mess. Still, the following change fixed it for me on SteamVR_Behaviour_Pose.cs line 17:

// Comment out the default value
public SteamVR_Action_Pose poseAction; // = SteamVR_Input.GetAction<SteamVR_Action_Pose>("Pose");

There's another one in SteamVR_ActivateActionSetOnLoad.cs, but I can get away with not changing that one because I've got a single action set (I think.)

Here are my symptom, in case this helps out anyone on Google:

  1. After re-loading (i.e loading the same scene twice (using SceneManager.LoadScene in my case), the previously working hand controllers are no longer tracked and sit at their initial position. I do see buttons being tracked, but I think that's because I'm manually subscribing to onStateUp/onStateDown messages instead of using SteamVR_Behavour_Boolean. I am using SteamVR_Behaviour_Pose, which I think is the source of the issue.
  2. I get the following error once per controller when the scene is loaded (so twice in my scene:)
    [SteamVR] No pose action set for this component
    UnityEngine.Debug:LogError(Object, Object)
    Valve.VR.SteamVR_Behaviour_Pose:Start() (at Assets/SteamVR/Input/SteamVR_Behaviour_Pose.cs:76)
  3. For both of my controller objects ((Controller (left), Controller (right)), all members of the SteamVR_Behaviour_Pose script (Pose Action, Input Source, Origin) are null or missing (which isn't the case in my Player prefab.) I see the following text in the SteamVR_Behaviour_Pose Editor component for each hand.
    Missing action: /actions/default/in/Pose
  4. I get an error every frame from an unknown object in the scene:
    NullReferenceException: Object reference not set to an instance of an object
    Valve.VR.SteamVR_Action`2[SourceMap,SourceElement].get_Item (Valve.VR.SteamVR_Input_Sources inputSource) (at Assets/SteamVR/Input/SteamVR_Action.cs:42)
    Valve.VR.SteamVR_Behaviour_Pose.UpdateHistoryBuffer () (at Assets/SteamVR/Input/SteamVR_Behaviour_Pose.cs:232)
    Valve.VR.SteamVR_Behaviour_Pose.SteamVR_Behaviour_Pose_OnUpdate (Valve.VR.SteamVR_Action_Pose fromAction, Valve.VR.SteamVR_Input_Sources fromSource) (at Assets/SteamVR/Input/SteamVR_Behaviour_Pose.cs:114)
    Valve.VR.SteamVR_Action_Pose_Source.CheckAndSendEvents () (at Assets/SteamVR/Input/SteamVR_Action_Pose.cs:699)
    Valve.VR.SteamVR_Action_Pose_Source.UpdateValue (System.Boolean skipStateAndEventUpdates) (at Assets/SteamVR/Input/SteamVR_Action_Pose.cs:592)
    Valve.VR.SteamVR_Action_Pose_Source_Map`1[Source].UpdateValues (System.Boolean skipStateAndEventUpdates) (at Assets/SteamVR/Input/SteamVR_Action_Pose.cs:403)
    Valve.VR.SteamVR_Action_Pose_Base`2[SourceMap,SourceElement].UpdateValues (System.Boolean skipStateAndEventUpdates) (at Assets/SteamVR/Input/SteamVR_Action_Pose.cs:245)
    Valve.VR.SteamVR_Input.UpdatePoseActions (System.Boolean skipSendingEvents) (at Assets/SteamVR/Input/SteamVR_Input.cs:334)
    Valve.VR.SteamVR_Input.UpdateVisualActions (System.Boolean skipStateAndEventUpdates) (at Assets/SteamVR/Input/SteamVR_Input.cs:317)
    Valve.VR.SteamVR_Input.OnPreCull () (at Assets/SteamVR/Input/SteamVR_Input.cs:302)
    Valve.VR.SteamVR_Behaviour.PreCull () (at Assets/SteamVR/Scripts/SteamVR_Behaviour.cs:219)
    Valve.VR.SteamVR_Behaviour.OnBeforeRender () (at Assets/SteamVR/Scripts/SteamVR_Behaviour.cs:189)
    UnityEngine.BeforeRenderHelper.Invoke () (at C:/buildslave/unity/build/Runtime/Export/Graphics/BeforeRenderHelper.cs:92)
    UnityEngine.Application.InvokeOnBeforeRender () (at C:/buildslave/unity/build/Runtime/Export/Application/Application.cs:318)
TMaloteaux commented 4 years ago

I have the same issue on my game. It is not happening when I load my scene a second time but it happens every third time.

StCost commented 3 years ago

Same issue. After changing any script and reloading scene, controllers are not tracked and any action doesn't work. Tried all suggestions in this topic, none of them helped.

EDIT: After half an hour I managed to solve this. I had to simply attach script SteamVR_Behaviour_Pose to my hands, which had SteamVR_Behaviour_Skeleton. Then define binding for Pose action. After doing all that my hands and actions are working fine after at least 5+ scene reloads.

Also [SteamVR] prefab still had doNotDestroy = true, so it wasn't an issue. image

Edit again: Poser is still broken. So after reload I cant use predefined hand poses.

ZnelArts commented 2 years ago

I am having a similar issue https://github.com/ValveSoftware/steamvr_unity_plugin/issues/1026

Has anybody been able to figure out how to fix this? [EDIT] There is a workaround for this issue and it is to avoid using defaults in your scripts