Download

How to attach body to VR camera in 4.11

So I’ve got a player body that should basically always be below the camera, or the player can take a step over and see their headless torso. It should rotate with the camera on one axis only (left/right) but shouldn’t rotate up or down.

Since rotating the camera already rotates the player character left or right, all I really need is to keep the body always below the neck of the player. I could technically jump it to the proper offset from the location of the player camera every tick, but that seems unwieldy and a bit too brute force of an approach.

Just placing it under the camera gets it to rotate with the camera, so you can’t look down at your body without it angling away, and looking very silly indeed in shadows to boot.

What’d be the best way to accomplish this?

I’m trying to figure out something similar to this. I’d like some way for the root to stay attached to the camera some how. Making the camera be root messes up the controllers. I’d rather not have to treat my pawn as a 1x1 meter box that happens to contain the person playing the game.

If I’m following you correctly, you’re trying to achieve a similar affect to what I’ve already done.

I’ve rigged the character up so that as the camera changes, the mesh attempts to match the eyes (head bone + offset) to the same transform.

I did it using the FabrIK nodes in the characters animation Blueprint, feeding in the camera position each tick.

The basic problem is that if the person playing takes a step to the side, they step out of their body, and see it there.

So far, what I’ve done was actually used a spring arm, attached to the camera, and attached the body to that. On the arm, I checked “Inherit Yaw” only, leaving the other options unchecked, then I disabled the collision test and all the Lag options.

The player camera has “Follow HMD” enabled.

Now when the player steps side to side, the attached body mesh follows them along. Problem 1 solved.

Mostly.

One problem I am still having though is that there seems to be some sort of rotation offset happening, so when you turn side to side, you’re actually sweeping in an arc. Not quite sure of a fix for that yet.

This is what I did:

  1. Set Camera to use absolute world and rotation on begin play, and in the properties, **UNCHECK **“Lock to HMD”

  2. On Tick, if HMD is connected, AddWorldOffset on the camera, passing in the HMD device position.

  3. After moving the Camera component in Tick, get the delta from the newly set camera position to the actor position, then zero out the Z-component.

  4. Move your character (e.g., AddMovementInput) using this delta vector.

  5. Negate your delta vector, then call AddWorldOffset on the camera again (no Z-value here either).


Explaination of what’s happening:

Since we unlocked the camera from the HMD, we need to set its position every tick (AddWorldOffset in step #1). After moving the camera, we have an offset from the actor location to the camera component’s location. We then use this delta vector to move the player. Finally, we AddWorldOffset again on the camera with the negated delta vector, to move it back to its position relative to the player (otherwise it’s going to be offset by that delta vector).


Note that you want to do this and IK the head to the HMD position in the AnimBP.

You can just offset a the mesh (move it) by the cameras orientation forward vector instead so you don’t have to unlock the camera and then it is literally one step, you seem to have way to many motions going on there…

For my game, that wasn’t an option - I need the player actor to move when the camera does, which “Lock to HMD” doesn’t really seem to handle. Personally I also just don’t like the idea of moving around the components, but not the whole actor.

That is, unless Lock to HMD does move the whole actor, and not just the camera component, but that’s not what I was seeing in my tests.

If you’re just doing floating hands or arms, “Lock to HMD” and letting the camera component move around independently of the character actor is probably fine. For my case, nope.

Moving around the components is fine, that is how VR works you are moving the camera relative to the actors base position. You can still have any other components “follow” the hmd or sweep to it but running three separate location changes per tick is pretty wasteful, you could also get the difference (delta) without moving the camera first, saving you a step there.

If you aren’t running collision on the actor with the world then there isn’t a point to having them set up like that as far as I am aware, and if you are then when the actor collides with something then it will not be lined up with the camera anymore.

There’s no magical rulebook that says you have to do to it that way, nor would I follow it if there were, and doing it that way wasn’t suitable for my purposes. Nor do I like having the actor lay around while its components are flying around the map, it’s messy, and can probably result in weirdness if you ever rely on the base actor’s location for gameplay purposes.

Anyway, the method I provided will give those who want it to work this way something to go off, and is almost exactly the same as moving only the components, except that the actor moves to the camera.

I was going to add a threshold that when passed, causes the character to move to maintain the correct distance for neck/head/body.
This is based on a sit down experience rather then a standing up one.

I didn’t notice this reply earlier so sorry for the necro, but wanted to point out that if you are manually moving the camera in the Tick() to match the HMD that you are throwing out the late transform updates on the headset.

Yep, I know.

However, having tried both, there is no difference in comfort or movement latency.

Until there is a proper way to move the actor, it will have to do, because I’d rather work around this issue by fixing the actor movement than by hacking every other place in the engine that expects to deal with actors and not their components (e.g., EQS and many others).

Just like mordentral said: there is a magic rulebook, and it’s “late reprojection.”
Without that, your VR will be laggy.

If that is actually the case, then it’s more likely that you didn’t get late reprojection in either of the cases, and you’re just more-than-normal tolerant to lag.

Again, I don’t feel like hacking around EVERY place in the engine that requires the actor to be where the player is actually at. Which is a lot. If you feel like going through every system which deals with actors and not some random component inside said actor, more power to ya, but that’s a TON of unnecessary work vs just fixing actor movement in VR to work properly.

It’s fine to just deal with the components moving on their own if you’re making a tech demo with no real gameplay, but I already have many systems built and need it to work properly, rather than the half arsed way it works by default. If you don’t need that, good for you, doesn’t change my situation.

And again, zero difference between setting the camera every frame vs. “lock to HMD”. There’s literally no difference at all, late updates being ignored or not.

In sum, again, no, there is no magic rulebook. If you are religiously married to doing it the default way, that’s good for you, doesn’t change the fact that anyone else is free to do it properly if they need to or dislike the default, hackish way it works.

Besides, the correct fix for not getting late updates when not using Lock to HMD is to expose an event for “On Late Update” or something, or even to fix it so the engine can move the actor to the camera component (or gives an option to do so), not to build your whole game around that limitation.

Late updates are done on the rendering thread, you can’t expose it to a game thread event as they don’t run in sync. Although you could add a way to pass additional components to it that you want to be considered for the late transform modification, but that is what attaching currently is meant for, they specifically added late updating attached components to handle this situation.

If moving components they only deviate from the base position to a maximum of the chaperone bounds / play area as teleportation moves the zero point of the actor. You’ll never get the position of the HMD being many yards away from the zero point as it isn’t possible. That being said components don’t have to stay within a range of their base actor at all, an actor is like a struct that holds the components and allows you to work with them, they could be all the way across the level and it wouldn’t matter (I have a terrain system that handles an entire world off of one actor and components representing chunks of terrain, much like the built in terrain system).

Regardless you do what you want, if it’s working fine for you then more power to you. I just had some concerns I wanted to point out for others considering doing the same. Gamedev tends to have a lot of hacks to get around limitations and I don’t know what systems you have in place that require your specific work method.

Edit also yes I do get the irony since I made a plugin to specifically get around directly attaching actors to the motion controllers as they don’t sweep :rolleyes: