Search Unity

PhysicsVelocity (lack of?) compatibility with netcode

Discussion in 'Physics for ECS' started by edalbeci, Jan 13, 2020.

  1. edalbeci

    edalbeci

    Joined:
    Jan 21, 2018
    Posts:
    36
    tl;dr I think installing netcode breaks PhysicsVelocity.

    I have a barebones Unity project, with one gameobject, one script, and 3 installed packages:

    1. The gameobject has "Physics Body" (gravity set to 0), "Physics Shape", and "Convert to Entity", as pictured in Fig. 1
    2. There's also only one script, `TestComponentSystem.cs`, in Fig. 2. In this script, I simply set `PhysicsVelocity.Linear` as it appears to be the recommended way to move rigidbodies.
    3. I've installed Entities@0.4.0, Havok@0.1.2, Hybrid Renderer@0.3.1, to obtain the list of packages in Fig. 3.

    As expected, hitting play gives a cube that's just floating to the right slowly (Fig. 4). However, if I install netcode@0.0.4, the project breaks (i.e., cube is now missing). This occurs without any other changes to the project -- I'm not importing or using netcode. This may be because I've misunderstood something critical, but seems like a weird artifact of just installing a package.

    Edit: I've added screenshots of the entities debugger before the netcode package is installed (Fig. 5) and after (Fig. 6)

    Context: I was originally trying to move a rigidbody "properly" after following the netcode getting started tutorial. Specifically, I wanted to avoid setting `Transform.Value` values and apply forces. In order to apply forces, I discovered I had to use `PhysicsWorld.ApplyInput` (as in the official UnityPhysics ApplyImpulse example). Setting `PhysicsVelocity.Linear` just didn't work, despite this approach proliferating the forums here.

    I'm now revisiting `PhysicsVelocity.Linear` because I would like to clamp the object's velocity. I kept simplifying until I got down to the case above, where netcode appears to render PhysicsVelocity useless.


    Fig. 1: cube setup


    Fig 2. `TestComponentSystem.cs`
    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Physics;
    3. using Unity.Mathematics;
    4.  
    5. public class TestComponentSystem : ComponentSystem
    6. {
    7.     protected override void OnUpdate()
    8.     {
    9.         Entities.ForEach((ref PhysicsVelocity velocity) =>
    10.         {
    11.             velocity.Linear = new float3(1, 0, 0);
    12.         });
    13.     }
    14. }
    Fig 3: list of packages in project

    Fig 4. screenshot of cube floating to the right


    Fig 5: entities debugger before netcode install


    Fig 6: entities debugger after netcode install

     
    Last edited: Jan 13, 2020
  2. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    Can you check whether in the Multiplayer > PlayMode Tools you have Client & Server set? If so, you need to set up spawning of a cube and which components should be added to the server/client cube etc. (as described in the Getting Started section of the NetCode manual)

    You can also disable setting up server and client as described in the NetCode manual.

    I'm not the biggest fan of it inserting itself into the play mode, exactly because of the issue you're having – it's unexpected.
     
  3. edalbeci

    edalbeci

    Joined:
    Jan 21, 2018
    Posts:
    36
    Ohh right, now I understand your play mode question in the original thread (direct link, for others). Thanks again for responding! Looks like "Client & Server" is set in Multiplayer > PlayMode, but your second sentence was spot-on, oops. I had to change "Convert to Entity" to netcode's "Conver to Client Server Entity". With that changed, the cube appears and floats to the right as desired/expected.

    However, to move one step closer to the Getting Started's `MoveCubeSystem`, I tried adding the system to `GhostPredictionSystemGroup`. Weirdly enough, this makes `PhysicsVelocity.Linear` dysfunctional again. The cube appears but does not float to the right. To be specific, I imported NetCode and added a directive (Fig. 1). What's maybe more perplexing, is the entity debugger appears to be empty. (Fig. 2) Once again, `PhysicsWorld.ApplyImpulse` works though.

    Edit: I noticed that changing to `UpdateAfter(...)` "works," in that setting `PhysicsVelocity.Linear` now works. However, the reverse is broken -- `PhysicsWorld.ApplyImpulse` doesn't work. This works for me, as between the two, I'd rather have `PhysicsVelocity.Linear` work. However, I don't understand what I've done and whether or not I've broken something.

    Fig. 1
    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Physics;
    3. using Unity.Mathematics;
    4. using Unity.NetCode;
    5.  
    6. [UpdateInGroup(typeof(GhostPredictionSystemGroup))]
    7. public class TestComponentSystem : ComponentSystem
    8. {
    9.     protected override void OnUpdate()
    10.     {
    11.         Entities.ForEach((ref PhysicsVelocity velocity) =>
    12.         {
    13.             velocity.Linear = new float3(1, 0, 0);
    14.         });
    15.     }
    16. }
    Fig 2.
     
    Last edited: Jan 13, 2020
  4. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    There's a dropdown at the top of the Entity Debugger, where you can now select the Server world and the Client worlds. Your systems are now probably in both until you tag them to be either running in the server and/or the client (see Getting Started also here).
     
    edalbeci likes this.
  5. edalbeci

    edalbeci

    Joined:
    Jan 21, 2018
    Posts:
    36
    Ahh darn, I will read the Getting Started more carefully. Thanks! Stuff is slowly making more sense with your help.
     
  6. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    My pleasure :) I completely worked through the Getting Started until I understood each piece. This helped immensely!
     
    edalbeci likes this.