-
In the game I'm working on you can walk inside spaceships while they're flying around. It should feel the same as if the ship was completely stationary. I've implemented player movement using CharacterVirtual but I'm having some problems getting it to work correctly. The CharacterVirtual as well as the ship's Body are in the same PhysicsSystem as all other objects, so the gravity vector can change if the ship is moving. I'm focusing on the case of a stationary but rotated ship at the moment. I'm calling SetUp() each frame, before calling the update function, with the correct up vector of the ship relative to the physics coordinate system. The gravity vector I'm passing in is also rotated to match the ship's down vector in the physics coordinate system. I'm also making sure that the vectors in ExtendedUpdateSettings (like mStickToFloorStepDown) are rotated accordingly. Should this be enough to support this kind of setup? The problems I'm having are largely related to jumping and gravity, both of which appear to lose strength as the up vector gets less aligned with the global up vector. Edit: I have now also tested the case of a ship that doesn't rotate but moves quite slowly (10m/s) and without acceleration. I can walk around for the most part, but I again get stuck where I wouldn't on a stationary ship, and I also sometimes get odd vertical position jumps. I already ruled out StickToFloor and WalkStairs by setting the vectors to zero. Any ideas? |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 4 replies
-
Hello, I tried to reproduce the issue, but as far as I can see everything works as intended. I've created #396 to be able to set the up vector in the CharacterVirtualTest. Can you repro your issue in that test? I haven't tested a fast moving 'ship' which is a far more tricky case. Because the simulation runs at a different time than the character itself, the character only sees an updated ship position, so if the ship moves fast enough the character can easily teleport halfway or entirely through a wall (tunnelling). If you get far enough into a wall it's difficult to determine what's inside and what's outside so you can indeed get stuck. I think you should probably add the delta position/rotation of the ship to the character before calling the update function so that the character movement becomes relative to the ship. If you need the acceleration of the ship to affect the character, I would express that by adding an extra velocity to the character. |
Beta Was this translation helpful? Give feedback.
-
B.t.w. rotating the character can also cause issues: If you do this without checking for collision, it is again possible that you rotate the character into geometry and if the geometry is complex enough and the intersection deep enough then it is possible that you get stuck (if the generated contacts have conflicting normals). |
Beta Was this translation helpful? Give feedback.
-
The character's movement happens completely relative to the moving ship. The ship's acceleration shouldn't affect the character, you can assume 100% perfect inertial compensators :) Here is the (simplified) code:
I've recorded a few short clips to show the actual problems I'm having. The working case, in a non-moving ship that is aligned with the coordinate space of the physics system: Now with the ship rotated by around 45 degrees around the z axis: Here's the ship rotated by 180 degrees: And with a moving ship: |
Beta Was this translation helpful? Give feedback.
-
Hello, I have the feeling that there's an issue with the velocity calculation:
GetLinearVelocity().GetY() will not return the vertical velocity when the ship is rotated, this will:
Also I don't see anything to fix up the character velocity when the ship has rotated during its update, so a better solution is probably:
Where previous_frame_up_vector can simply be gotten before you call JoltCharacter->SetUp(...). I'm assuming characterOffset is calculated after calling ExtendedUpdate by transforming the character position back relative to the ship and then storing it until the next frame? |
Beta Was this translation helpful? Give feedback.
-
To follow up on the velocity issue: it happens even if the ship is moving very slowly (1m/s). I end up being unable to walk up even a minor slope if it's going in the direction of ship movement. I've tracked this to CharacterVirtual::HandleContact(), which subtracts the contact's linear velocity from InVelocity. For the time being I can manage this by simply ignoring that velocity, but I wonder if some way of setting a kind of reference velocity to be added to relative_velocity, cancelling out the contact's velocity, could be useful there? |
Beta Was this translation helpful? Give feedback.
Hello,
I have the feeling that there's an issue with the velocity calculation:
GetLinearVelocity().GetY() will not return the vertical velocity when the ship is rotated, this will:
Also I don't see anything to fix up the character velocity when the ship has rotated during its update, so a better solution is probably:
Where previous_frame_up_vector can simply be gotten before you call JoltCharacter->SetUp(...).
I'm assumin…