How to properly set rotation and velocity? (DOTS Physics + NetCode)

Hello everyone,

For a game of mine, since it’s mainly just doing some 3D physics stuff that’s supposed to be playable in a multiplayer, I started to use the NetCode package, and thus the DOTS including the DOTS Physics.

As I figured out after a while, setting values directly like rotation or velocity causes visible issues like stuttering, which are resolved as soon as the code isn’t executed anymore. To give an example, I was able to replace the rotation freeze (setting the x and z rotation back to 0) by setting InverseInertia instead, but I still need to adjust e. g. velocity and rotation to implement the acceleration and steering. But if I do so by just calculating and assigning the values, the result is basically unusable (stuttering movement, floating above the ground, etc.).

The Code is contained in a ComponentSystem with the attributes [UpdateInWorld(UpdateInWorld.TargetWorld.ClientAndServer)] and [UpdateInGroup(typeof(GhostPredictionSystemGroup))]. The code in question:

this.Entities.ForEach((ref PhysicsVelocity velocity, ref CharacterBaseComponent character, ref PredictedGhostComponent prediction) =>
{
    if (GhostPredictionSystemGroup.ShouldPredict(tick, prediction))
    {
        if (character.isGrounded)
        {
            // positions.Add(translation.Value);
            var forward = character.forward;
            var groundNormal = character.groundNormal;
            // normals.Add(groundNormal);

            var dot = math.dot((float3)forward, (float3)groundNormal);
            var groundForward = forward - dot * groundNormal;
            var factor = -math.dot(groundForward, math.up());

            var acceleration = groundForward * factor * character.acceleration;
            velocity.Linear += acceleration * deltaTime;
        }
    }
});
this.Entities.ForEach((DynamicBuffer<CharacterInputCommand> inputBuffer, ref Rotation rotation, ref PhysicsVelocity velocity, ref CharacterBaseComponent character, ref PredictedGhostComponent prediction) =>
{
    if (GhostPredictionSystemGroup.ShouldPredict(tick, prediction))
    {
        CharacterInputCommand input;
        inputBuffer.GetDataAtTick(tick, out input);
        var steeringRotation = quaternion.AxisAngle(math.up(), input.horizontal * character.steeringSpeed);
        rotation.Value = math.mul(steeringRotation, rotation.Value);

        // speed adjustment after steering
        float3 forwardSpeed = velocity.Linear * math.dot(velocity.Linear, character.forward);
        velocity.Linear -= forwardSpeed;
        float3 rotatedVelocity = math.rotate(steeringRotation, forwardSpeed);
        velocity.Linear += rotatedVelocity * 0.25f + forwardSpeed * 0.75f;
    }
});

Regarding the first example: If I set the friction to 0+Minimum (instead of 1+Maximum as it is right now) and don’t accelerate the character manually (basically disable the first code snippet) but rather let the physics do this, and also disable the steering (2nd code snippet), then the movement is smooth as expected. But on the other hand, I’d still need to add enough “sideways friction” manually later on to get back to the desired behavior - e. g. by reducing the velocity - recreating the same issues I have right now.

What do I have to do to get the desired behavior?

1 Like

So your code seems fine, one should be able to change the PhysicsVelocity of any body and get the desired movement. I’m mostly concerned about the time when this is done - can you check that? Anywhere in between BuildPhysicsWorld and ExportPhysicsWorld would be completely ignored by physics.

Have you made any progress on this so far? What is your experience with NETCODE?

@MarksGames : I’ve abandoned this project for a long time now due to a lack of motivation - There are several issues regarding the physics, that probably only got introduced once the NetCode got added, so it felt like to much at once to deal with.
Right now, I started a network based project without Physics being involved in order to get a start with NetCode itself, which seems to work fine so far. Quite some time passed since you asked, so I guess you either tried to get your information somewhere else already, figured it out yourself, or gave up on it - I hope it’s not the latter one. I could try to help you, but this should not happen within this thread, and it would be more beneficial to you to create a new thread for this so more people (particularly more active people) could try to help you.

@petarmHavok : I’m sorry for the late response, and thank you for the attempt to narrow down the source of the issue. I’ll need to take another look at the project, but I wanted to take a longer route this time (hence this other NetCode project). I’ll respond again once I got around to take another look at that project.

1 Like

Hey guys I found a similar issue: Anyone else have PhysicsVelocity.Linear Randomly Decreasing and then Returning to Normal?

NetCode seems to be in a good-ish spot right now (able to handle a lot of cool stuff) but it seems to be broken with Physics.

Physics + NetCode PhysicsVelocity is currently broken. There does not seem to be a way to update PhysicsVelocity without it causing stuttering.

The “stuttering” has been pinpointed (in my post above) to random fluctuations in PhysicsVelocity.

FYI guys I found that if you don’t use PhysicsVelocity.Linear to make adjustments to velocity then NetCode + Physics is pretty workable

DOTS Multiplayer discussion page-6#post-6706921