VR Expansion Plugin

Hey, I am struggling with HMD Camera access and render to texture support.

Is AcquireVRCamera the right way to do it? C
CreateCameraTexture2D gives me an empty texture.
GetVRCameraFrame fails when I plug an empty var to Target Render Target, and crashes unreal if I plug in an existing texture.

I’ve made sure my hmd front camera works properly outside of my project.

Any hints would be appreciated :slight_smile:

CreateCameraTexture2D generates an empty texture of the right format for the camera (size and format). You call that, then pass it in the GetVRCameraFrame.


AquireCamera - Save out the handle
ReleaseHandle when done

I could have automated this all into a component, but wanted to leave it open and just expose OpenVRs functions themselves.

First of all, thanks for this awesome plugin! :smiley:

I’ve got a question though: would it possible for 2 users to grab the same object in multiplayer? I’ve been messing around today a bit, but couldn’t find how to do it. I’ve seen that the default practice is to just “transfer” the object to the other player, when he tries to grab an object already held by someone.

You’d have to change the default BP implementation in the template and then either use the second player as a secondary attachment or run it with physics grips so they both apply forces instead of direct following.

(cut out the Already gripping check and drop logic, late updates would HAVE to be off, likely would want to turn off the defaulted center of mass setting as well)

Anything beyond that is up to you as there is no way of me knowing how you would want that to behave.

I have plans to setup something like this anyway eventually using gameplay tags to define an object as multigrippable, but its not a high priority.

There is also a lot of considerations to take into account with multiple players gripping, what behavior exactly are you trying to get?

Thanks for your explanation. I solved it in that way (except that I can not find the variable bSetToFoot but it is resolved anyway) and then I followed the tutorial. Thanks again for this great plugin and for this explanation. Great job

Apologies if this has been asked before, but I haven’t spotted a solution if it’s already been addressed: I’ve set up a damage-dealing volume using a conventional trigger-like structure using begin and end overlap, but the issue I’m facing is that the VRCharacter’s Capsule Component is registering overlap events, rather than the VRRootReference. What do I need to change to fix this?

Damage triggers look like the attached example.

The following code allows the VRRootReference to register damage events, but does not keep the capsule component from generating overlap events as well:

    : RightHandGun(nullptr)
    , LeftHandGun(nullptr)
     // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    GetCapsuleComponent()->bGenerateOverlapEvents = false;
    VRRootReference->bGenerateOverlapEvents = true;

What did I miss?

? What do you mean? The root reference IS the capsule component, I change the base class and provide a pointer to it so that accessing the functions are easier is all.


I was able to build a new project in 4.18 with the plugin, but I was hoping to use the example to understand how to use some of the features as I am pretty new to this.

However, I am not able to build the example project. I tried dropping in the binary plugins as well and switch engine versions from 4.17, 4.18, and 4.19. I can generate VS files, but I can’t build after that. Is there a known issue right now or am I doing it wrong?

Hmm. Maybe I have my character set up incorrectly, or I’m interpreting what I’m seeing incorrectly. What I"m observing is that if I draw a capsule at the CapsuleComponentLocation, and another at the VRLocation, the former appears at the center of the tracking volume, while the latter appears at the location of my HMD:

// draw capsule location & size
    const FVector& CapsuleComponentLocation{ GetCapsuleComponent()->GetComponentLocation() };
    const FRotator& CapsuleComponentRotation{ GetCapsuleComponent()->GetComponentRotation() };
        , CapsuleComponentLocation
        , GetCapsuleComponent()->GetScaledCapsuleHalfHeight()
        , GetCapsuleComponent()->GetScaledCapsuleRadius()
        , CapsuleComponentRotation.Quaternion()
        , FColor::White);

        , GetVRLocation()
        , VRRootReference->GetScaledCapsuleHalfHeight()
        , VRRootReference->GetScaledCapsuleRadius()
        , VRRootReference->GetComponentRotation().Quaternion()
        , FColor::Magenta);

So what’s happening is when the CapsuleComponentLocation overlaps a damage trigger, the player takes damage, even though the VRLocation is not overlapping the damage causer. So basically the player takes damage when the center of the tracking volume hits a hazard, rather than when their own perceived location does.

Am I thinking about this incorrectly?
Thanks for looking at this with me!

Mmmm, overlaps follow the VRLocation now, I changed how they behave around 4.16 or early 4.17 (sending the correct loc)? I did some testing just to be sure but all trigger volumes are working correctly for me off of the offset location, are you on an older build?

The rootcapsule IS the vrcapsule, I change its physics location and render transform to match the VR offset, the actors root location remains the same though, so things directly reading the root loc would be wrong.

Edit You are dereiving from VRCharacter and not BaseVRCharacter right? Because that would be a different story.

Thanks a lot for the suggestions (and sorry for my later reply)! I’ll try modifying the template project as you said tomorrow.

What I would like to achieve is a “collaborative work” thing, meaning 2 guys moving an object together from one point to another, like a heavy trunk that can’t be lifted by one guy alone. I imagine that there will be lots of problems with this, but just to be able to let 2 guys grab the same object would be a good start to work with!

Yeah you either need a custom grip and to define how it interacts like that then, or you need to run with physics grips which can allow for mutliple inputs.

Should be solvable.

Ahhh, I found what was going on. My motion controllers were still generating overlap events, and the usual posture from which I was testing caused the controller positions to coincide with the character origin often enough to produce a result that misled me. Removing collision and overlap generation from the controllers (we’re not grabbing anything in this game) seems to have fixed the issue. Thanks so much for looking at it with me!

Good to know!

By “physics grips” you mean like the “manipulation grip” type?

Manip and interactive with physics, though the latter needs some changes to work really well with it.

Alright, I’ll look into it, thanks again!

Patreon support here and I’ve lost my link to the discord invite. How do I get back into the discord chat channel?

I’m having a problem in multiplayer dropping a gripped object programmatically. In my character blueprint I have a function that will drop the specified held object from my hand. This is not using the normal routing because it is triggered via a menu, so not using grip release buttons. My blueprint calls CallCorrectDropSingleEvent and passes in the controller and grip parameters. It works on the client as expected and it works in stand-alone as expected, but the listen server doesn’t work.

I can see in the c++ code where it is failing, but having a hard time resolving the issue. The GripMotionControllerComponent: DropActor call is returning false after outputting the log message “VRGripMotionController drop function was called on the client side with a replicated grip”. I checked the condition that results in that message and found that my listen server is being detected as NM_Client. I don’t see how this is possible SinceTryDropSingle is a server RPC and the listen server execution path does indeed call through SinceTryDropSingle when debugging. There is no RPC to client after that, at least not that I can see.

To clarify, I’m not saying that I can’t drop gripped objects using the motion controller buttons. It is only when I call the CallCorrectDropSingleEvent from my own function that I run into problems.

What am I doing wrong?

Message me your discord tag

You totally sure that its not calling “TryDropSingleClient”? Server should never detect as a client

I can debug this easier when you enter discord after pming me your tag. Easier to share SS’s, i’ll check tomorrow for your message I am out
tonight with a severe cold.

My problem was in the implementation of a UI component. I had to go over with a fine tooth comb the various places where I’m spawning a UI actor and make sure the UI’s owner was set to the correct player. Somehow the UI was pointed to the remote other player instead of the local listen server player. Anyways, thanks for the response.