Search Unity

Official Unity Physics Discussion

Discussion in 'Physics for ECS' started by smcclelland, Mar 18, 2019.

Thread Status:
Not open for further replies.
  1. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    Have you checked out the 4a. Joints Parade demo in the example set? One thing to note at the minute is that due to limitations in the Game Object > Entity conversation system, constrained bodies need to have a parent/child relationship in the scene hierarchy.
    upload_2019-4-23_13-11-34.png

    If you want to setup a Joint in code check out the
    CreateJoint
    function in the BasePhysicsDemo.cs file.

    The Prismatic Joint currently does not limit rotation. All the joints are made up of smaller constraint atoms. For example, this if the code for CreatePrismatic (which you can dig into here
    : <your project>\Library\PackageCache\com.unity.physics@0.0.2-preview.1\Unity.Physics\Dynamics\Joint\Physics_Joint.cs)

    Code (CSharp):
    1.         public static BlobAssetReference<JointData> CreatePrismatic(float3 positionAinA, float3 positionBinB, float3 axisInB,
    2.             float minDistanceOnAxis, float maxDistanceOnAxis, float minDistanceFromAxis, float maxDistanceFromAxis)
    3.         {
    4.             CalculatePerpendicularNormalized(axisInB, out float3 perpendicular1, out float3 perpendicular2);
    5.             return Create(
    6.                 new MTransform(float3x3.identity, positionAinA),
    7.                 new MTransform(new float3x3(axisInB, perpendicular1, perpendicular2), positionBinB),
    8.                 new[]
    9.                 {
    10.                     Constraint.Planar(0, minDistanceOnAxis, maxDistanceOnAxis),
    11.                     Constraint.Cylindrical(0, minDistanceFromAxis, maxDistanceFromAxis)
    12.                 }
    13.             );
    14.         }
    If you create your own custom Prismatic you could add a further Constraint.Twist atom to limit rotation. The higher level Joint creation code is currently part of the UnityPhysicsExamples project e.g. see Assets\Demos\4. Joints\Scripts\Creators\PrismaticJoint.cs

    An extra Linear constraint atom could also be added with lower tweaked
    SpringFrequency
    and
    SpringDamping
    values so in the SoftJointDemo test.

    Alternative, the RaycastCar sample has a very basic spring/damper suspension applied based on a raycast hit which might be of use to you.
     
  2. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    The Limit DOF Joint you can download from in this response can let you lock to any plane. (Also see this response).
    LimitDOF.gif In this example, the Red cubes are locked to the plane whose normal cooresponds to the X axis, the green cubes are locked along the Y axis, and the Blue cubes along the Z axis. The yellow cubes are locked to the local Y axis of the sloped plane at the back rather then the global Y axis. For 2d Physics on X,Z you could local the Y Linear axis and the X,Z angular Axes. e.g.
    upload_2019-4-23_13-40-18.png
     
  3. microwest

    microwest

    Joined:
    Aug 27, 2013
    Posts:
    4
    I've been puzzled by this error for days. When i put physics entities in the hierarchy and execute rayCasting in a JobComponentSystem, everything works fine:). But when i spawned the same entities in runtime, the rayCasting JobSystem crashed. No compilation errors, just running crashed.:confused:

    crashed.JPG



    1. Spawning entities can be anywhere and here it's in a ComponentSystem.​
    void SpawnEntities(int count)
    {
    Entity entity;
    Vector2 circle;

    Entity EntityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(playerPrefab, World.Active);

    for (int i = 0; i < count; i++)
    {
    entity = PostUpdateCommands.Instantiate(EntityPrefab);
    circle = Random.insideUnitCircle * Range;

    Translation pos = new Translation()
    {
    Value = new float3(circle.x, 1, circle.y)
    };
    RayCastMove move = new RayCastMove()
    {
    targetPos = pos.Value,
    isHit = 0
    };

    PostUpdateCommands.SetComponent(entity, pos);
    PostUpdateCommands.SetComponent(entity, move);
    } PostUpdateCommands.DestroyEntity(EntityPrefab);
    }

    2. RayCasting is put in a JobComponentSystem.​
    [UpdateAfter(typeof(SpawnSystem))]
    public class RayCastSystem : JobComponentSystem
    {
    [BurstCompile]
    struct RayCastJob : IJobProcessComponentData<Translation, Rotation, RayCastMove>
    {
    [ReadOnly] public PhysicsWorld World;
    public void Execute([ReadOnly] ref Translation pos, [ReadOnly] ref Rotation rot, ref RayCastMove move)
    {
    float3 dirNormal = Math.normalize(Math.mul(rot.Value, new float3(0, 0, 1)));
    RaycastInput input = new RaycastInput()
    {
    Ray = new Ray()
    {
    Origin = pos.Value + dirNormal,
    Direction = dirNormal * 1.1f
    },
    Filter = new CollisionFilter()
    {
    CategoryBits = ~0u, // all 1s, so all layers, collide with everything
    MaskBits = ~0u,
    GroupIndex = 0
    }
    };
    RaycastHit hit = new RaycastHit();
    if (World.CastRay(input, out hit))
    {
    move.isHit = 1;
    }
    else
    move.isHit = 0;
    }
    }
    ... ....
    ... ....
    ... ....
    }

    • Editor console shows that : o_O
    The previously scheduled job RayCastSystem:RayCastJob reads from the NativeArray RayCastJob.Data.World.CollisionWorld.m_Bodies. You must call JobHandle.Complete() on the job RayCastSystem:RayCastJob, before you can deallocate the NativeArray safely.

    So i think when spawning physics entities, the BuildPhysicsWorld system should rebuild the dynamic bodies array and other stuff. But the raycast job conflicts with this. Is that true?:cool:

    and i did a little trick of delaying one frame to schedule the RayCastJob if spawning happened in this frame.:p

    void SpawnEntities(int count)
    {
    isSpawn = true;
    ... ...
    }
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
    ref bool isSpawn = ref World.Active.GetExistingManager<SpawnSystem>().isSpawn;
    if(isSpawn)
    {
    isSpawn = false;
    return inputDeps;
    }
    ... ...
    }

    Now things work like a charm.:D:p

    work.JPG

    • Questions:
    I hope DOTS Physics team will take note of this. Although my own tricks can fix it, is there should be an official way to update physics parameters when entities changed, without crashing other systems?

    As i know, adding or destroying entities in ECS by PostUpdateCommands will not disturb other correlated systems.​

    Or i used the DOTS physics the wrong way?o_O Let me know it.:)
     
    Last edited: Apr 23, 2019
    steveeHavok likes this.
  4. danyalmunir10

    danyalmunir10

    Joined:
    Feb 20, 2017
    Posts:
    1
    i am trying to figure from last 2 day how to receive trigger and collision event (like OnTriggerEnter/OnCollisionEnter) from new DOT physics. Haven't found any sample code for this, can anyone please guide me in right direction or provide piece of code for events.
     
  5. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    There is a triggers sample on the way.

     
    ElcolED, Cynicat and NotaNaN like this.
  6. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Thank you Very much that's the Response i was looking for!
    after adding your Scripts im getting a Compile error ( the BaseJoint class is missing ).

    and are you also planning for 2D Physics raycasts, i think it will be much more performant than 3D ones?

    im also having a bug when i build my game to Android devices if any entity collides with another the Game just crashes.
     
  7. newlife

    newlife

    Joined:
    Jan 20, 2010
    Posts:
    1,081
    steveeHavok thank you for your comprehensive reply. Im sorry again to ask a silly question, but how to create a custom prismatic joint? Where should I put the code?
     
  8. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    333
    I just realised that I never thanked you for helping out with that, sorry. Thanks, that was great. I did get my own implementation of that working before you posted it, but yours is neater so I stole it anyway.

    While I'm here I actually have a small documentation bug to report. The docs list the
    MaskBits
    and
    CategoryBits
    descriptions the wrong way around. That caused me problems for a few more minutes than I'm willing to admit. There's also a "too" that should be a "to" in
    MaskBits
    .
     
    Last edited: Apr 23, 2019
    steveeHavok likes this.
  9. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    333
    BaseJoint
    is part of the samples repo.
     
    steveeHavok and Opeth001 like this.
  10. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    333
    Joints are created as
    PhysicsJoint
    components. A
    PhysicsJoint
    has a
    BlobAssetReference<JointData>
    field that defines the joint's functionality. You can make a custom one of those with
    JointData.Create()
    by supplying constraints.

    Have a look at the attachment here for an example. https://forum.unity.com/goto/post?id=4449148#post-4449148
     
    steveeHavok likes this.
  11. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    333
    I had a similar scenario today where I needed to prevent a collider cast from hitting itself. I've used masking for now, but I would prefer to be able to ignore that collider.

    You say it's expensive, but what about providing a version of
    ClosestHitCollector
    and appropriate overloads that takes and ignores a single rigidbody index? That looks like it would only add a single
    int
    comparison per result as overhead. You could do the same with
    AllHitsCollector
    too for symmetry.

    The case of ignoring one single body, typically yourself, seems common and worth accommodating.
     
    steveeHavok likes this.
  12. Mr-Mechanical

    Mr-Mechanical

    Joined:
    May 31, 2015
    Posts:
    507
    @steveeHavok

    Is destruction/fracturing something that Havok or Unity Physics will eventually support?
     
  13. lijianfeng

    lijianfeng

    Joined:
    Sep 8, 2015
    Posts:
    54
    In order to make a RTS game,I need manual step the physics simulation,and automate render the world use physics bodies interpolation values,like position and rotation.How to reach that?
    Another question,how to roll back the world,do I need manual save all entities state and then recreate them to implement the rollback funtion?:cool:
     
  14. Cynicat

    Cynicat

    Joined:
    Jun 12, 2013
    Posts:
    290
    Well this is incredibly disappointing. Every project I have ever worked on from AAA to Indie that had physics has spent a massive chunk of their CPU time on computing physics and that's with a fully statefull system. Suddenly unity wants to switch their default to a system that is going to lack such a strong optimization? I know it's complex, i know it's not simple. But from where i'm sitting this looks like it makes unity physics useless for most production projects that aren't small demo games or determinism based multiplayer projects. Meaning the only option that is production viable for most games is behind a paywall now. This is a massive step down, despite Unity Physics other advantages.

    Physics is one of the things that sets your min CPU spec. It's not scalable without possibly breaking your game. It doesn't matter if you can simulate a crazy demo scene, it matters that you can run your game's physics on low end hardware. Unity physics needs to scale down to low end hardware. Most indies aren't building PS4 exclusives, their building games for people on cheap laptops, phones and 10 year old PCs.

    Physics sleeping has been the largest physics speedup in literally every project i have ever worked on with physics, how is this somehow not a priority for the default physics engine?

    I was really excited for Unity Physics. But I don't care about your other features if your going to quadruple my minspec. Unity Physics barely runs at 60fps on my work PC in even simple scenes. Complex scenes i'm lucky to get 30 fps. This is basically throwing all my performance gains from ECS in the trash along with some extra.

    We don't know how much havok is going to cost. But most indies don't have a licensing budget. Havok in the past has cost in the range of $10,000 and above to license, sometimes way above. while I assume it will be cheaper than that, I don't see it being in reach of most indies. Theres a big gap between what a professional studio can afford and what somebody making games in their spare time can afford.

    Anyway. Unity physics is amazing in a ton of ways but if it can't scale based on the current simulation I just don't see how this will be the solution they expect most developers to go with. =<
     
  15. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I believe Unity's waiting on some other bits before taking the almost literal brakes off.
     
  16. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    That's true but I think for the moment we can go through this by thinking about physics Entities as reusables, maybe if you don't need a wall to calculate physics into a far region from the player just move it and reuse it. I think a game can awesomely reduce Physics entities count like this.
     
  17. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,336
    That sounds like a lot of work, though. You're essentially describing writing your own culling system for physics objects.

    Stateless is starting to sound more and more like something that has huge drawbacks, and I really don't need rollback for any of the games I have made or are going to make. Hoping that the havoc license isn't prohibitively expensive.

    Sleeping should be a no-brainer to implement. You can thread as much as you want, and be as cache friendly as you want, you'll never get as fast as not running any code, which is what sleeping does.
     
  18. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    333
    We may not have automatic sleeping, but we can enable and disable physics on a per entity basis. It would be very simple to do something like disabling physics for objects with no velocity and then enabling it again on some event. We can get very fine grained control over sleep like mechanisms with this.

    Complex stacking is harder but you could build a system to accommodate it.

    What are some examples of situations where you would want sleeping, but think it would be prohibitively difficult to do manually?
     
  19. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Yes sure doing nothing is always better than processing some logic. But for the moment it's the only way I found of having as less as possible PhysicsBody running concurrently.
    And I don't think moving a bunch of Physics Bodies each time the player changes region is that havy.
     
  20. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    333
    Why are you moving them rather than destroying and making new ones? It sounds like you're doing pooling, which isn't often required with ECS.
     
  21. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Because I think moving thousands of entities containing a lot of data like collide, mesh.... Is always faster than creating new ones.
     
  22. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    But that's simply not true with ECS, it is one of the huge bonuses of it, you can keep things around and filter them or only keep exactly what you need, or even just create / destroy (which is not the same expense as with classic Unity).

    Doing pooling is maybe more overhead with ECS, depending.
     
    SamOld likes this.
  23. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    333
    Both ways should be lightning fast. You might get a tiny performance boost out of the pooling, but I doubt it's worth it unless you're really needing to optimise. The cost of the pooling algorithms could easily outweigh the savings. The pooling probably adds a lot of unneeded complexity to your code. It sounds like you need only a basic streaming setup.

    Big data like meshes won't be moved about anyway, unless each object has a unique mesh. That should be in shared component data, so it's basically free.

    [EDIT] This is one of the advantages of stateless. There's no first run cost to adding a new rigidbody. It's only as expensive as creating the entity.
     
    Opeth001 and hippocoder like this.
  24. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Yes but if u think about what is happening under the hood , creating them is an operation always done into the main thread, and at the end they will be moved to the position requested, or just don't waste time in main thread instantiating them and just move them.
     
  25. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    I don't really think that streaming a map can add overhead to the CPU. At the end this operation should not be done every frame, but just when the local player is reaching a certain location.
     
  26. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,776
    I would say "depends". For simple entities, where you got only bunch of data, may be faster to destroy and create.

    But when entities has bunch of relations structure, and /or some more complex algorithm, which is executed at creation, then making pooling may make sense.
     
    Opeth001 and SamOld like this.
  27. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    857
    Regarding the sleeping discussion and the proposal for a user created solution of removing/adding in the PhysicsVelocity after collision events to simulate this, why are collision events a toggleable feature? Are there performance hits with large/huge amounts of active rigidbodies creating collision events?
     
    Cynicat and SamOld like this.
  28. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    333
    @steveeHavok Would it be possible to build the broadphase in multiple stages? I would like to be able to do the following in a single frame.
    1. Run a physics query and conditionally create some new physics body entities.
    2. Run another physics query that includes my new entities, and then conditionally create some more.
    3. Step the physics of all bodies.
    This doesn't work at the moment, as queries can only detect things after
    BuildPhysicsWorld
    has built the broadphase. This only happens once per frame, so we can't do the changes in multiple waves like this.

    Would it be possible to tell the physics that I've just added these particular entities with colliders, and I want them to be added to the broadphase immediately? Then the above could look like this.
    1. [BuildPhysicsWorld]
    2. Run a physics query and conditionally create some new physics body entities.
    3. Force addition of new bodies.
    4. Run another physics query that includes my new entities, and then conditionally create some more.
    5. Force addition of new bodies.
    6. Step the physics of all bodies.
    I worry you may say that the broadphase needs to know how big it is to allocate memory, so this won't work performantly.
     
    steveeHavok likes this.
  29. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    That's the way I was trying to go. I copied the Burst exemple given in the documentation and added an entity to the signature then I try to get the entity matching the hit result ( also in the documentation example) and match it to the entity I added hopping I could filter it out but no luck for now. It seems that the entity index is the same (0) but the revision is not (0) for the entity I passed and (1) for the one I get from the hit...
     
  30. Cynicat

    Cynicat

    Joined:
    Jun 12, 2013
    Posts:
    290
    Couple problems with this. Entity spawning is MemCopy based. Meaning it has very little overhead. As in each entity has less overhead than calling most non-inlined functions. The performance difference is minimal and your opening yourself up to tons and tons of persistent state bugs for an optimization that does basically nothing in ECS. The overhead of calling even pure functions is higher than the spawn cost for ECS. You'll probably spend more overhead iterating over and setting the values that you will just emitting the entities yourself. You can also already construct entities on multiple threads, it's just the integration that is on the main thread. This also makes references unreliable. Because references to an entity won't be able to tell that you recycled an entity. If you wrap your references you will absolutely blow the tiny perf gain you got from this added complexity.

    This isn't to say it's impossible to get a perf win, but it would probably be super, super tiny, for a massive complexity jump and opening yourself to tons of bugs down the line.

    OOP systems often have tons of classes to allocate, constructors to run, other systems to call, inheritance trees to resolve etc... Plus each object is creating work for the garbage collector in future. And they are basically all exposed to persistant state bugs already. This is why pooling works in these contexts.

    As for object count. Most games already contain the minimum objects they can get away with. This is often tied to the streaming system already in place. Most production games get broken into chunks that can vary their detail level based on relevance. These can be sections of a level, or even a regular grid for open world games.
     
  31. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Creating new entities is not a free of charge operation, this is why Unity is adding the new async way of enitity instantiation.
    if we talk about some hundreds or few thousands of Entities that contain simple ComponentData yes you are perfectly right, but if we talk about 100k entities and containing a lot of Data reusing them is a good way of preventing the main thread from wasting time doing it again and again, constructing entities within multiple threads doesn't mean they are created in parallel or even faster, at the end it's just defering the work for a later moment within the main thread, it's just a way to let users directly send commands from jobs to the EntityManager rather than collecting the data again and do it from the main thread.
    and sincerely i dont see the diffrence of complexity between spawning or moving entities based on the Same list of requested entities, at the end ill just Query for all needed entities that belongs regions that are out of interest and simply move them, if there is not enought then ill instantiate new ones. i think it can be much faster than destroying 50K entites and create 60K new copies.
     
  32. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,267
    The fastest approach for physics culling would be to have a DisablePhysicsTag which could be added and removed in batch at the chunk level. BuildPhysicsWorld.cs would just need to add that tag to the None parts of the queries and everything would just work.

    The current fastest approach without modifying any packages that I am aware of is to have physics backup components that can be copied to and from so that disabling and enabling doesn't destroy the whole entity and you only pay the cost of the memcpy of the components rather than the initializations of the individual fields.
     
  33. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    333
    This is probably getting a bit too off topic for the physics thread. The relevant point is that it should be very fast to create and destroy physics bodies and colliders. Entity pooling is a separate discussion. I do think it's unlikely to be worthwhile (or even a net gain) in most cases, but we don't need to speculate here. If you're considering doing it, just try it both ways and measure the performance.

    Pooling does have a basic design problem - it breaks entity references. The moment you introduce pooling, you've given yourself a problem down the line if you ever might add another system that takes references to those entities.

    If we want to keep talking about pooling outside of the specific context of physics, I'd suggest making a dedicated thread for it.
     
    dzamani, Cynicat and NotaNaN like this.
  34. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    Check out this response. Note that the bug mentioned in the post was in the last preview release.
     
  35. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    The Build, Step and Export Physics World systems all have a FinalJobHandle's you may need to complete if using the same data. Step also has a FinalSimulationJobHandle and any systems which read the simulation results should depend on this.
     
  36. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    505
    Hello, I'm unsure if that bug is that same as the one (I guess it's a bug...) I'm experiencing, so I'll mention it.

    With two physics bodies colliding, at least one of them needs to be dynamic for a trigger to occur. When they are both kinematic, I cannot get a trigger to occur. This makes sense when you're only detecting collisions in order to apply physics forces, but I want to move my objects around as kinematic objects myself via code, but still query the physics engine for collisions/triggers that I can react to.

    Bug or feature? What is the recommended way to query for collisions? Should I be doing a bunch of collider casts myself manually or something? Would be nice if I didn't have to...
     
  37. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    So we've logged an issue to add options to ignore initial overlaps for ray and collider casts.
    As a hacky workaround, you can create your own custom verison of the ClosestHitCollector collector. Coincidentally, I was looking at something similar for the Mouse Pick Behavior. I wanted the mouse picking to optionally ignore Trigger Volumes in any demo without having to assign trigger filter information in every demo. There is a problem with the collector interface that has been logged and will need to be fixed. The rigid body index is not actually available at the time AddHit is called, so in a custom AddHit function the previous hit needs to be recorded and reassigned in TransformNewHits if the Rigid Body Index is to be ignored.
    Code (CSharp):
    1.     public struct ClosestHitWithIgnoreCollector : ICollector<RaycastHit>
    2.     {
    3.         public Entity EntityToIgnore;
    4.         public NativeSlice<RigidBody> Bodies;
    5.  
    6.         public bool EarlyOutOnFirstHit => false;
    7.         public float MaxFraction { get; private set; }
    8.         public int NumHits { get; private set; }
    9.  
    10.         private RaycastHit m_OldHit;
    11.         private RaycastHit m_ClosestHit;
    12.         public RaycastHit Hit => m_ClosestHit;
    13.  
    14.         public MousePickCollector(float maxFraction, NativeSlice<RigidBody> rigidBodies, int numDynamicBodies)
    15.         {
    16.             m_OldHit = default(RaycastHit);
    17.             m_ClosestHit = default(RaycastHit);
    18.             MaxFraction = maxFraction;
    19.             NumHits = 0;
    20.             IgnoreTriggers = true;
    21.             Bodies = rigidBodies;
    22.             NumDynamicBodies = numDynamicBodies;
    23.         }
    24.  
    25.         #region ICollector
    26.  
    27.         public bool AddHit(RaycastHit hit)
    28.         {
    29.             Assert.IsTrue(hit.Fraction < MaxFraction);
    30.             MaxFraction = hit.Fraction;
    31.             m_OldHit = m_ClosestHit;
    32.             m_ClosestHit = hit;
    33.             NumHits = 1;
    34.             return true;
    35.         }
    36.  
    37.         void CheckIsAcceptable(float oldFraction)
    38.         {
    39.             var isAcceptable = Bodies[m_ClosestHit.RigidBodyIndex].Entity != EntityToIgnore;
    40.             if (!isAcceptable)
    41.             {
    42.                 m_ClosestHit = m_OldHit;
    43.                 NumHits = 0;
    44.                 MaxFraction = oldFraction;
    45.                 m_OldHit = default(RaycastHit);
    46.             }
    47.         }
    48.  
    49.         public void TransformNewHits(int oldNumHits, float oldFraction, MTransform transform, uint numSubKeyBits, uint subKey)
    50.         {
    51.             m_ClosestHit.Transform(transform, numSubKeyBits, subKey);
    52.         }
    53.  
    54.         public void TransformNewHits(int oldNumHits, float oldFraction, MTransform transform, int rigidBodyIndex)
    55.         {
    56.             m_ClosestHit.Transform(transform, rigidBodyIndex);
    57.             CheckIsAcceptable(oldFraction);
    58.         }
    59.         #endregion
    60.     }
    61.  
    62.     ...
    63.  
    64.     var rayCastInput = new RaycastInput { Ray = Ray, Filter = CollisionFilter.Default };
    65.     var collector = new ClosestHitWithIgnoreCollector(1.0f, CollisionWorld.Bodies);
    66.     collector.IgnoreTriggers = IgnoreTriggers;
    67.     CollisionWorld.CastRay(rayCastInput, ref collector);
    68.     // you can't trust the return from castray if ignoring things in TransformNewHits
    69.     if (collector.MaxFraction < 1.0f)
    70.     {
    71.         ...
    72.     }
    73.  
    This is all nasty and will be fixed!.
     
    SamOld likes this.
  38. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    I was refering to the other response as an example of getting the collision event array.
    Its a bug that two Kinematic bodies are not adding collision events and we are looking into that. In the short term, you could try the
    Entities.World.Active.GetExistingSystem<BuildPhysicsWorld>().PhysicsWorldCalculateDistance
    function rather than casting, if you want to ignore velocities.
     
    Shinyclef likes this.
  39. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    I hear you, and this topic does seem to have brought up some good dicussion. While it may be out of scope for the core Unity Physics package, I do think we can represent the sleeping usecase functionality but at the demo level. The first priority for the core package would be looking at performance troubles on your simple scenes. Can you give me any details? For example, what are you aiming for minspec?
     
    Cynicat and SamOld like this.
  40. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    333
    This all sounds great, thanks.

    Is there any chance that we'll get the ability to filter collisions by entity archetype? I understand that collision layers make sense as a simple and very fast approach, but I often find myself using them to re-implement the same categorisation I have using entity queries.

    For the next bit of my prototype, I'm going to want to get all of the entities that are within a radius, have the
    UnitTag
    component, a
    Team
    shared component other than my own, have the
    LongRangeTag
    component, and do not have the
    StunnedTag
    component.

    Everything apart from the radius check, I can do with ECS queries. It would be very nice if I could fetch these as a single query.

    The best approaches that I know of now are creating a layer specifically for that query and using a system to assign the matching entities to that layer, using the spacial query to get all entities and then filtering them by archetype myself, or not using the physics at all and doing radius filtering myself.

    If archetypes could act like collision layers, this would be very easy.
     
  41. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    Maybe you can use the translation of your entities to check the radius kind of like it was done for the two stick shooter exemple.
     
  42. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    333
    Yes, that's what I meant by the third option, doing the radius filtering myself. That's easy to do, but it's linear with all matching entities in the scene so presents a performance problem. My situation is simple and I can do it that way because the numbers aren't large, but seeing as ECS is focused on large numbers and high performance, it's easy to imagine a scenario where this feature is very useful and the accelerated sublinear scaling is needed. It would similarly be much harder to filter this manually if the spacial query were more complex than a radius check.
     
  43. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    Hello,
    I tryied it but it seems that althouth the entity to ignered do is filtered out of the collector, the AddHit still return true.So this will say it had a hit even it was only the entity we want ignore.

    So for now we can trust the collector content but not the bool return of the RayCast.

    I got it to work with these modifications:

    1 ) Replace the MousePickCollector constructor by

    Code (CSharp):
    1.  
    2.             public ClosestHitWithIgnoreCollector(float maxFraction, NativeSlice<RigidBody> rigidBodies, Entity entityToIgnore)
    3.             {
    4.                 m_OldHit = default(RaycastHit);
    5.                 m_ClosestHit = default(RaycastHit);
    6.                 MaxFraction = maxFraction;
    7.                 NumHits = 0;
    8.                 Bodies = rigidBodies;
    9.                 EntityToIgnore = entityToIgnore;
    10.             }
    11.  
    2 ) cast your ray like so :
    Code (CSharp):
    1.  
    2.                         ClosestHitWithIgnoreCollector collector = new ClosestHitWithIgnoreCollector(1f,World.Bodies,entity);
    3.  
    4.                         if (World.CastRay(RaycastInput, ref collector))
    5.                         {
    6.                             if (collector.Hit.ColliderKey.Value != 0)
    7.                             {
    8.                                 // Do your stuff
    9.                             }
    10.                         }
    11.  
    12.  
     
    steveeHavok likes this.
  44. etiennepinchon

    etiennepinchon

    Joined:
    May 16, 2018
    Posts:
    8
    Hi everyone,

    I have an issue with Unity Physics, I would like to spawn 100 cubes with the physics components on them. However as soon as I am adding the physics code, the cubes are no longer rendered :(
    There is no error, just nothing on the scene. The entities are being created as I can see them in the entity debugger window.

    Could you please help me?
    Thanks!

    Here is my code:

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using Unity.Entities;
    5. using Unity.Mathematics;
    6. using Unity.Collections;
    7. using Unity.Transforms;
    8. using Unity.Jobs;
    9. using Unity.Burst;
    10. using Unity.Physics;
    11. using UnityEngine;
    12. using UnityEngine.Rendering;
    13. using Unity.Rendering;
    14. using Mesh = UnityEngine.Mesh;
    15. using Material = UnityEngine.Material;
    16.  
    17. public class CubeSpawner : MonoBehaviour
    18. {
    19.     public Mesh mesh;
    20.     public Material material;
    21.  
    22.     private void Start()
    23.     {
    24.  
    25.         float mass = 1f;
    26.         float3 linearVelocity = float3.zero;
    27.         float3 angularVelocity = float3.zero;
    28.  
    29.         EntityManager entityManager = World.Active.EntityManager;  
    30.      
    31.         NativeArray<Entity> entities = new NativeArray<Entity>(100, Allocator.Temp);
    32.         RenderMesh renderer = new RenderMesh {
    33.             mesh = mesh,
    34.             material = material,
    35.             subMesh = 0,
    36.             castShadows =  ShadowCastingMode.On,
    37.             receiveShadows = true
    38.         };
    39.         EntityArchetype chunkArchetype = entityManager.CreateArchetype(
    40.             typeof(LocalToWorld),
    41.             typeof(Translation),
    42.             typeof(Rotation),
    43.             typeof(RenderMesh),
    44.  
    45.             // physics
    46.             typeof(PhysicsCollider),
    47.             typeof(PhysicsMass),
    48.             typeof(PhysicsVelocity),
    49.             typeof(PhysicsDamping)
    50.         );
    51.         entityManager.CreateEntity(chunkArchetype, entities);
    52.  
    53.         unsafe {
    54.             for (int x = 0; x < 10; x++)
    55.             {
    56.                 for (int y = 0; y < 10; y++)
    57.                 {
    58.                     int idx = x + y * 10;
    59.                     entityManager.SetComponentData(entities[idx], new Translation { Value = new float3(x*2f, 5, y*2f) });
    60.                     entityManager.SetSharedComponentData(entities[idx], renderer);
    61.                  
    62.                     // Physics
    63.                     BlobAssetReference<Unity.Physics.Collider> boxCollider = Unity.Physics.BoxCollider.Create(float3.zero, quaternion.identity, new float3(1, 1, 1), 0.0f);
    64.                     Unity.Physics.Collider* colliderPtr = (Unity.Physics.Collider*)boxCollider.GetUnsafePtr();
    65.  
    66.                     entityManager.SetComponentData(entities[idx], new PhysicsCollider { Value = boxCollider });
    67.                     entityManager.SetComponentData(entities[idx], PhysicsMass.CreateDynamic(colliderPtr->MassProperties, 1f));
    68.                     float3 angularVelocityLocal = math.mul(math.inverse(colliderPtr->MassProperties.MassDistribution.Transform.rot), angularVelocity);
    69.                     entityManager.SetComponentData(entities[idx], new PhysicsVelocity()
    70.                     {
    71.                         Linear = linearVelocity,
    72.                         Angular = angularVelocityLocal
    73.                     });
    74.                     entityManager.SetComponentData(entities[idx], new PhysicsDamping()
    75.                     {
    76.                         Linear = 0.01f,
    77.                         Angular = 0.05f
    78.                     });
    79.                 }
    80.             }
    81.         }
    82.        
    83.     }
    84. }
    85.  
     
  45. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    The recommended approach is to create normal prefabs and use the conversion flow to create the entities that you can then instantiate.
    https://forum.unity.com/threads/new-subscene-converttoentity-workflows.638785/
     
  46. etiennepinchon

    etiennepinchon

    Joined:
    May 16, 2018
    Posts:
    8
    Thanks Joachim! So there is no way to make this work with code directly? Most of the code above is from one the get started examples of Unity Physics, does this mean that this is no longer supported?
    https://docs.unity3d.com/Packages/c...ing_started.html#creating-bodies-from-scratch
     
    Last edited: Apr 28, 2019
  47. foolmoron

    foolmoron

    Joined:
    Jun 22, 2013
    Posts:
    41
    How in the world do you get the physics category names window to show? I got it to pop up once but now I can't find it anywhere
     
  48. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    333
    There should be a PhysicsCategoryNames asset in the root of your Assets folder. It has an inspector that lets you edit them.

    If not, you can create a new one from the standard create menu.
     
  49. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    If you make a new project, there's no such asset out of the box, you have to make it yourself through the menu (Create->DOTS Physics->Physics Category Names). Also it's location doesn't matter, I keep mine in Settings folder atm.
     
  50. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    It is possible, but its definitely not the recommended approach. At minimum i would start with conversion flow for simplicity reasons and if for strange reasons i do not understand you absolutely need code based creation then you can always switch to it afterwards. This way you can compare the data of conversion vs your custom code.

    But the point is... Runtime components / data layout will change over time. Authoring representation is the only thing we can guarantee data stability on. Eg. new fields might get added, and if you don't initialize them correctly from code, then code might break when upgrading. And obviously it's just a lot more work to add & configure all the components correctly.
     
Thread Status:
Not open for further replies.