Attach Character Collision Capsule to HMD (SteamVR)
I'm using an HTC Vive in SteamVR. I have managed to set up an empty character component with movement mapped to the motion controller thumbpads and a camera locked to the HMD, but I can't seem to get the collision capsule to follow the HMD since it is the blueprint root; it always stays in the center of the chaperone space. I've now rigged up a second collision capsule, as suggested here, and I am updating its position and half-height on each tick so that it stretches from the floor to the HMD location. This works well for interactions with physics objects (I can now push things around by walking into them), but my collision with the floor is still dictated by the original capsule in the center of my play space. This means that in order to walk off of a ledge, I have to be moving using the thumbstick; if I physically walk off the ledge I will hang in mid air. When walking up a ramp, my body capsule will just overlap the floor. I've attempted to disable collision on the root capsule, but this causes me to immediately fall through the floor... as far as I can tell this is happening because my body capsule is teleporting on each tick, and it's impossible to move a non-root component via sweep. Is there any way to attach the root capsule to the HMD in order to make interactions with the floor a bit more natural?
asked Aug 22 '16 at 03:28 AM in VR
After doing this all myself and getting subpar results, I found mordentral's VRExpansionPlugin which does proper multiplayer enabled collision out of the box. More info here: https://forums.unrealengine.com/development-discussion/vr-ar-development/89050-vr-expansion-plugin
I honestly can't recommend this enough, saved me a ton of time and effort.
answered Dec 13 '17 at 11:47 PM
Assuming you have this setup where the camera follows your HMD (note the scene node parenting your HMD camera)
The simplest method I know to get what you're looking is to use something like this function in you character BP (open image in a new tab to see full resolution)
We sample the camera relative location, null out the Z axis and get the delta with its old position. We add that delta vector to the collision position and subtract the same delta from the camera offset. Finally we update the old camera position as "OldPosition" member variable. That's it.
Here's the bp pastebin: https://blueprintue.com/blueprint/u-me1t6x/
You'll should be able to walk off ledges and push things around as expected.
Edit: updated to fix rotation, this is done by rotating our DeltaPos by the collision rotation (should only be yaw) but only when added to the collision component, don't rotate the delta for the camera offset.
The basic idea of the solution I came up with is to move the character on each tick towards the camera (or rather, a scene marker that is attached to the camera that is approximately where my neck is) and then update the VR origin scene component to keep the camera stationary. It's a bit tricky to set up, but works well.
Here is how I'm moving the character:
It is important to update the VR origin immediately after movement and before rendering, or you will get a lot of nauseating shaking. To do this I've bound a function to OnCharacterMovementUpdated like this:
UpdateSceneOffset looks like this:
For thumbstick movement, I'm just moving the VR origin in the direction I want to move. I'm basically just adding a vector to the world position of the scene, then clamping it within ~30 cm (this is an arbitrary number but it needs to be greater than 0) of the location that would cause the camera to always be stuck to the capsule. This prevents you from walking through walls. This vector is calculated like this:
And then moved like this, accounting for rotation because MoveComponentTo uses relative locations and physics sometimes causes the character to rotate and we don't want the camera to be affected:
I'm using MoveComponentTo because simply updating the location causes choppiness. Speed is controlled by a scalar applied to the thumbstick and (more critically) the delta on MoveComponentTo.
Update: Due to performance issues I moved this to C++. The relevant class can be found here.
Update2: Mordentral has a plugin available here that offers a much more robust solution to this problem.
You can have an dummy character for take place and update collision with the world . The dummy is follow the camera vr then keep the contrains between them like fixed distance or vector. You move in real world -> camera do offset -> then dummy follow -> if the dummy has collid and stop -> check the fix distance or the fix vector -> make the camera revert offset. It work for me.
answered Mar 09 '17 at 03:18 PM
The problem is that the camera is moving relative to the Actor (thus your actor doesn't move in World Space because the camera is inside the play space. Play space is effectively your Actor). Walking in the play space is moving the "Camera" and not the pawn / actor. That is how the Lock To HMD checkbox works, the engine is doing a very simple Query orientation and pose from an HMD if it is attached and that option is true. The collision capsule knows nothing of this. Sorry I don't have a better answer for you, this is actually making me wonder what happens when we go between Vive / Oculus.
One option is to always be moving the actor to keep you in the center of the play space but there are most likely a bunch of "gotchas" with that technique.
answered Sep 01 '16 at 06:49 PM
Follow this question
Once you sign in you will be able to subscribe for any updates here