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. Nothke

    Nothke

    Joined:
    Dec 2, 2012
    Posts:
    112
    I think you might be missing the point of DOD. If "you must modify 4 components" you are maybe thinking in a very OOP way. There's no problem with that, my brain was in the same place.

    Whenever I need to "disable" systems on certain objects I look at the systems list in the Entity Debugger, it tells you which systems require which components to run. The point of ECS is to have as few systems running, so, if you don't need physics running on an entity you should remove the component that makes the physics run on that entity.

    StepPhysicsWorld system only requires PhysicsVelocity component to exist on the entity. PhysicsVelocity only contains the velocity vectors, which we don't need if we want the object to be static. You could say it's "transient data" that describes its dynamicness, doesn't describe any other property of the body. Mass and position data will still be preserved as they are in other components. Removing the PhysicsVelocity component from an entity will therefore effectively fix it.

    If you don't want everything to collide with it, you need to prevent BuildPhysicsWorld running on it as well. You can see in entity debugger that the second group requires the entity to NOT contain PhysicsVelocity (this is the query of the static collider group). In that case you'll need to remove the PhysicsCollider component too. Since PhysicsCollider only contains a reference to the collider (through the BlobAssetReference<Collider>), you could copy it to another component.

    (Of the top of my head) For example, a PickUpSystem would add a PickThisUpData component with an entity that will pick it up. This PickThisUpData is effectively a "tag" that exists for a single frame and marks the entity as ready to be picked up. Then a system called CopyColliderOnPickupSystem would require a PhysicsCollider and a PickThisUpData tag component, use EntityCommandBuffer to add a ColliderData component, copy PhysicsCollider's Value to PickedUpColliderData and remove PhysicsCollider. You could have a separate system that removes a PhysicsVelocity component from a PickThisUpData. At the end remove PickThisUpData from the entity so none of the systems above run on it. You could for sure run everything in a single system, but decoupling allows you to later add more systems for other components and you will surely need special cases considering it is a pick up behavior.

    Alternatively, you should also be aware that you can always override the data at any point between two systems by squeezing another system between. So, you could override the position/rotation after the physics step for example. Although as I said the point is to run the least amount of systems, so don't use this system if you have a lot of entities.
     
    Burlyduck likes this.
  2. CorneliusCornbread

    CorneliusCornbread

    Joined:
    Jun 21, 2017
    Posts:
    32
    I was having issues getting the joints workin within my own project. Despite it working in it's own project in the exact same Unity version.

    I ended up setting
    Code (CSharp):
    1. PhysicsMass.InverseInertia[0] = 0
    and
    Code (CSharp):
    1. PhysicsMass.InverseInertia[2] = 0
    . That ended up working perfectly. Thanks
     
    steveeHavok likes this.
  3. rileyoc

    rileyoc

    Joined:
    Sep 13, 2015
    Posts:
    7
    It looks like the Wreaking Havok talk is back up but unlisted. Here's the link to watch it:
     
  4. Ziboo

    Ziboo

    Joined:
    Aug 30, 2011
    Posts:
    356
    Thanks Nothke.

    That was actually the solution I had in mind.
    I was just not a huge fan of storing the collider.
    I just which we could have a new component in Unitty.Physics to tell the simulation to ignore a body. Like that I can keep all my components and don't need to store them for future reuse.
     
  5. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    I was debating on whether to add a
    PhysicsDisabled
    component tag to com.unity.physics\Unity.Physics\ECS\Components\PhysicsComponents.cs, then the Dynamic, Static and Joint entity queries in
    BuildPhysicsWorld
    could be tweaked to add

    None = new ComponentType[]
    {
    typeof(PhysicsDisabled)
    },


    I haven't tried this, but think it should work. Feels like a negative DO pattern, but also easier than adding/removing
    PhysicsJoint 
    or
    PhysicsVelocity
    and/or
    PhysicsCollider 
    components.
     
    lclemens and Nothke like this.
  6. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    Or open queries with allow write group flag and users can override this queries, exclude some things from them by their own components. Just thoughts in loud :)
     
    steveeHavok likes this.
  7. one_one

    one_one

    Joined:
    May 20, 2013
    Posts:
    621
    I'm trying to calculate the closest point between two colliders. Considering that there's no way to do that with the old physics system (unless I missed it somehow?) I thought I might try the new physics package for that job. However, since I only want to do a distance check and not simulate an entire physics world, I thought I'd use the methods built into the Collider structs. I have a couple of questions though:
    1. In the ColliderDistanceInput, is the RigidTransformation the transformation from one collider CS (the one where the distance check is called from as a member method) to the other's?
    2. Is there a convenient method for generating Physics.Colliders from UnityEngine.Colliders?
     
  8. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    651
    On your Physics Shape Authoring you have Collision Filters - so you can dissable "Collides With" Player.
    Then your Weapon won't collide with the player. Same has to be done to the player I guess --> Uncheck "Collides With" Weapon.
     
  9. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    1. Ultimately the query call hierarchy drops down something like SomeQuery( Collider* A, Collider* B, MTransform aFromB ). As you reach higher up the call stack Collider B is the Collider found in the Query Input struct and Collider A is the Collider that is calling the Query. Therefore, A->SomeQuery( Input{B,aFromB}, results ).
    A note on Transforms; we tend to use AFromB rather than BToA. The reason for this is that it is easier to read chains of calculations.
    e.g. if we wish to get AFromB and we have WorldFromA and WorldFromB then the code reads
        AFromB = math.mul(math.inverse(WorldFromA), WorldFromB)

    which scans left to right, whereas
        BToA = math.mul(math.inverse(AToWorld),BToWorld)

    involves some mental gymnastics.
    TLDR: the Transform is the Input collider's transform in the calling Collider's (or World's) local space. Clear as mud :)

    2. The LegacyColliderConversationSystem code has a bunch of functions you could copy into your own project and make use. (see Library\PackageCache\com.unity.physics@x.y.z\Unity.Physics.Hybrid\Conversion\LegacyColliderConversionSystem.cs)
     
  10. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    At runtime you can also set the group index of the Collision Filter on the Weapon and Player to some negative common number (i.e. if both groupIndex values are the same and negative, don't collide). We haven't exposed this in the editor right but a few folk are using it well.
    Also, here is a simple Keyframe Utility that I'll drop into Unity.Physics/Extensions/World/ComponentExtensions.cs for the next release:
    Code (CSharp):
    1.         public static void ApplyKeyframe(ref this PhysicsVelocity pv, PhysicsMass pm,
    2.             ref Translation t, ref Rotation r,
    3.             float3 desiredPosition, quaternion desiredRotation,
    4.             float deltaTime)
    5.         {
    6.  
    7.             float3 currentPosition = t.Value;
    8.             quaternion currentRotation = r.Value;
    9.  
    10.             float invDeltaTime = math.rcp(deltaTime);
    11.  
    12.             if(!desiredPosition.Equals(currentPosition))
    13.             {
    14.                 //float3 currentLinearVelocity = pv.Linear;
    15.                 float3 desiredLinearVelocity = (desiredPosition - currentPosition) * invDeltaTime;
    16.  
    17.                 pv.Linear = desiredLinearVelocity;
    18.             }
    19.  
    20.             if (!desiredRotation.Equals(currentRotation))
    21.             {
    22.                 float3 EstimateAnglesBetween(quaternion from, quaternion to)
    23.                 {
    24.                     float3 fromImag = new float3(from.value.x, from.value.y, from.value.z);
    25.                     float3 toImag = new float3(to.value.x, to.value.y, to.value.z);
    26.  
    27.                     float3 angle = math.cross(fromImag, toImag);
    28.                     angle -= to.value.w * fromImag;
    29.                     angle += from.value.w * toImag;
    30.                     angle += angle;
    31.                     return math.dot(toImag, fromImag) < 0 ? -angle : angle;
    32.                 }
    33.              
    34.                 //float3 currentAngularVelocity = pv.GetAngularVelocity(pm, r);
    35.                 float3 desiredAngularVelocity = EstimateAnglesBetween(currentRotation, desiredRotation) * invDeltaTime;
    36.  
    37.                 pv.SetAngularVelocity(pm, r, desiredAngularVelocity);
    38.             }
    39.         }
     
    John_Leorid likes this.
  11. Chebn

    Chebn

    Joined:
    Oct 25, 2019
    Posts:
    9
    Just a quick question on Physics Simulation with Mobile devices, when playing with Gravity and Velocity, is it expected to have to set Application.targetFrameRate to 60 for mobile devices (iOS in my case)? Looks like everything behaves normally in the editor but once I push a build to my phone, everything halves unless I explicitly set the target FPS to 60. This is not true for the regular MonoBehaviour RigidBodies. A simple test scene with a Box + MonoBehaviour RigidBody and a Subscene with a Box + Physics Shape shows the gravity difference (but only on the phone, not editor)
     
  12. craftsmanbeck

    craftsmanbeck

    Joined:
    Nov 20, 2010
    Posts:
    40
    My searches have come up empty, but with the Unity Physics package, the time to enter play mode dramatically longer. Like, I have a simple scene with a cube that gets converted to ECS, takes 3-4 seconds to enter play mode. Import Unity Physics package, same scene with no changes takes over 10 seconds. Add a physics body, scene now takes over 30 seconds to enter play mode. Remove Unity Physics package, back down to 3 seconds.
    Is this a known issue and I'm just inept at searching, or?
     
    lclemens and twobob like this.
  13. crysicle

    crysicle

    Joined:
    Oct 24, 2018
    Posts:
    95
    Could there be an option for terrain collider's collision/physics information to be derived only from Native<float> heights, heightmap resolution, and scale without needing to convert it through Terrain.Init()? That would make massive improvements to runtime heightmap manipulation.

    At the moment i can manipulate 9kk heightmap data on the GPU and send about 1kk heightmap data back to the CPU while still running at around 90 FPS on my rig. Conversion for just 66,049 heightmaps with TerrainCollider.Create() causes 40+ms spikes, which means that for most hardware, you could barely manipulate 50k heightmaps each frame even with multithreading. If, however, the physics logic could just use the former data for all it's calculations, the number of heightmaps you could manipulate during runtime could be cranked into the stratosphere.
     
  14. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    Cause DOTS Physics playbacks in SimulationSystemGroup which moved from fixed time step loop to default update loop for some reasons (you can read about that in dots forum), It will be in fixed loop in future, but no yet.
     
    Chebn likes this.
  15. PartyBoat

    PartyBoat

    Joined:
    Oct 21, 2012
    Posts:
    97
    I know this is a big ask, but would it be possible for Unity Physics to be renamed before it hits 1.0?

    As of right now the title "Unity Physics" is too generic and renders any kind of internet search on the subject maddeningly impossible. It doesn't matter what it's called, although a unique word or acronym would be preferred (e.g. something like "DOTS" or "Havok"). Please consider this before it's too late or your users will be forever frustrated with old PhysX-related information obscuring their search results. Changing this now will save countless hours in lost productivity over the coming years.
     
    DoN2kcz, Egad_McDad, lclemens and 4 others like this.
  16. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,780
    While I could agree generally, that calling Unity Physics may become confusing. But not for DOTS users. Rather for average Joe, using PhysX.

    Anyone using DOTS physics, would probably recognize straight away, what refers to DOTS whats to Havok and what to PhysX.

    But that may not be necessary true, for someone who don't know about DOTS as an example.
     
  17. PartyBoat

    PartyBoat

    Joined:
    Oct 21, 2012
    Posts:
    97
    The problem isn't not being able to recognize which physics system the information relates to; the problem is not being able to easily find information on what you intended to look for. The term "Unity Physics" is so broad that searching for it in Google returns results on everything physics related.

    For example, say I want to find information about how to approach a character controller in Unity Physics. If I search for "Unity Physics character controller" the results are useless. Even with quotes around "Unity Physics" to search for that exact phrase the results are still terrible. In this case there are actually forum posts and examples out there with information that is relevant, you just can't find it through a search engine. This is a massive issue for information sharing and discovery.
     
  18. Rory_Havok

    Rory_Havok

    Joined:
    Jun 25, 2018
    Posts:
    70
    This is due to the collider construction jobs being marked synchronous for Burst. These jobs take a few seconds to compile. In return the colliders get built much faster. Unity plan to cache the Burst compiled jobs, when that happens these will not be compiled every time you press play. In the meantime you could opt to change to the source to remove the sync attribute from those jobs.
     
    Last edited: Oct 28, 2019
    KwahuNashoba and craftsmanbeck like this.
  19. mpforce1

    mpforce1

    Joined:
    Apr 4, 2014
    Posts:
    34
  20. linfuqing

    linfuqing

    Joined:
    May 11, 2015
    Posts:
    166
    hi,why I get rigidBodyIndex =-1 when CastRay?
    %FDTFUY7Y(Z[2`C}ETPV@{J.png
     
  21. astropuffin

    astropuffin

    Joined:
    May 16, 2015
    Posts:
    7
    @Rory_Havok Thank you for your help! I finally succeeded at this after coming back from vacation. For those following in my footsteps, Here's what I was trying to do:
    Now that I know how to do it, it feels obvious, but I spent a long time trying to understand @Rory_Havok 's hints of help. Here's my working unit test that updates an entity with physics, with tons of comments to explain why I'm doing each step.
    Code (CSharp):
    1. using System.Collections;
    2. using NUnit.Framework;
    3. using Unity.Entities.Tests;
    4. using Unity.Mathematics;
    5. using Unity.Physics;
    6. using Unity.Physics.Extensions;
    7. using Unity.Physics.Systems;
    8. using Unity.Transforms;
    9. using UnityEngine.TestTools;
    10. using SphereCollider = Unity.Physics.SphereCollider;
    11.  
    12. namespace Tests.UnityScripts {
    13.     public class MotionTest :ECSTestsFixture {
    14.  
    15.         [UnityTest]
    16.         public IEnumerator ShouldUpdateTranslationOnPhysicsUpdate() {
    17.             var e = m_Manager.CreateEntity();
    18.             // This entity will require a number of components in order to for the physics engine to treat it as a dynamic object:
    19.             // Translation, Rotation, PhysicsCollider, PhysicsVelocity, PhysicsMass
    20.  
    21.             // Translation
    22.             m_Manager.AddComponentData(e, new Translation{Value = float3.zero});
    23.             // Rotation
    24.             m_Manager.AddComponentData(e, new Rotation{Value = quaternion.identity});
    25.             // Collider
    26.             var spCollider = SphereCollider.Create(float3.zero, 1f);
    27.             m_Manager.AddComponentData(e, new PhysicsCollider {Value = spCollider});
    28.             // Add a non-zero linear Velocity
    29.             m_Manager.AddComponent<PhysicsVelocity>(e);
    30.             m_Manager.SetComponentData(e, new PhysicsVelocity{Angular = float3.zero, Linear = new float3(1,1,1)});
    31.             // Mass
    32.             m_Manager.AddComponent<PhysicsMass>(e);
    33.             m_Manager.SetComponentData(e, PhysicsMass.CreateDynamic(MassProperties.UnitSphere, 1f));
    34.  
    35.             // Now that we have a viable entity, run the simulation. You need 3 things: BuildPhysicsWold, StepPhysicsWorld, and ExportPhysicsWorld.
    36.  
    37.             // Create a buildPhysicsWorld. This system prepares the physics simulation. Literally "builds the physics world"
    38.             var buildPhysicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>();
    39.             var physicsWorld = buildPhysicsWorld.PhysicsWorld;
    40.             // "Run" the buildPhysicsWorld. This populates the physics world from the entities.
    41.             buildPhysicsWorld.Update();
    42.  
    43.             // Create a stepPhysicsWorld. This is the system that runs the simulation.
    44.             var stepPhysicsWorld = World.GetOrCreateSystem <StepPhysicsWorld>();
    45.             // Get a reference to the simulation object within the stepPhysicsWorld.
    46.             var simulation = stepPhysicsWorld.Simulation;
    47.             // construct the simulation parameters.
    48.             var stepInput = new SimulationStepInput {
    49.                 World = physicsWorld, // Reference the physicsWorld created by the buildPhysicsWorld
    50.                 TimeStep = 1f, // one second. This is pretty large.
    51.                 ThreadCountHint = PhysicsStep.Default.ThreadCountHint,
    52.                 NumSolverIterations = PhysicsStep.Default.SolverIterationCount,
    53.                 Gravity = new float3(0,-10,0), // approximately 1G
    54.                 SynchronizeCollisionWorld = true
    55.             };
    56.             // Pass the step parameters to the simulation step
    57.             simulation.Step(stepInput);
    58.             // Actually run the simulation
    59.             stepPhysicsWorld.Update();
    60.             // Create the exportPhysicsWorld. This will take the results of your simulation and "export" it back to your entities.
    61.             var exportPhysicsWorld = World.GetOrCreateSystem<ExportPhysicsWorld>();
    62.             // "Run" the export
    63.             exportPhysicsWorld.Update();
    64.  
    65.             // The entities should now have updated values!
    66.             Assert.AreNotEqual(float3.zero, e.GetPosition());
    67.             // Be good and dispose of your disposable objects.
    68.             simulation.Dispose();
    69.             // yield for the next frame
    70.             yield break;
    71.         }
    72.     }
    73. }
    I hope this proves useful for others, and perhaps can inform the "official" documentation in the future.
     
    Last edited: Oct 29, 2019
  22. rileyoc

    rileyoc

    Joined:
    Sep 13, 2015
    Posts:
    7
    This was mentioned in the Havok talk. My understanding is that the speculative collision detection gathers speculative contacts on upcoming edges with normals that face towards your object instead of aligning with the nearby faces. I think the solution is to detect those edge normals and correct them manually to align with the adjacent faces. Alternatively, the Havok backend already has a robust solution to this that can be enabled.
     
    steveeHavok likes this.
  23. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    Do you have a custom collector? If you have a custom collector, and the ray has hit a compound collider, then at the point that AddHit is called the rigid body index will be -1 (because reasons that will be fixed!). If you ignore the hit at that point the index could be set as the query moves up the compound hierarchy. The mouse pick behavior needs to do this hack as well. Basically with a custom collector that ignores hits, you need to double check you don't have a -1 index as well. We do plan on fixing this.
     
  24. mpforce1

    mpforce1

    Joined:
    Apr 4, 2014
    Posts:
    34
    Hi, do you know how I can do this edge detection? The API is a bit difficult to understand and work with. As said in my thread, I can get ModifyNarrowphaseContactsBehaviour working as it was intended but I'm unsure how I could use the data available at that point to figure out what counts as an edge or at least modify the normal to something more appropriate for the angle of the mesh at the contact point. In that example, they modify the contact normal to be up rather than towards the ball, but that results in objects not being slowed down on sloped surfaces.

    Regarding Havok Physics, we need to use the Unity Physics implementation because it offers cross-platform determinism which I think Havok doesn't offer.
     
  25. rileyoc

    rileyoc

    Joined:
    Sep 13, 2015
    Posts:
    7
    Gotcha, I haven't tried this myself so I don't know exactly what information is provided but hopefully somebody here can help.
     
  26. eterlan

    eterlan

    Joined:
    Sep 29, 2018
    Posts:
    177
    Hi everyone, I have a big problem with physics package..
    physics package ver 0.2.4
    unity ver 2019.3.07b
    Once I download it, all my converted game object doesn't rendered by its translation any more. The translation component works normally by the way.
    The mesh component is in child of my converted game objects, is that the reason?
    After I delete the package, everything works fine.
    Is it a bug or intended?

    --- Edit ---
    OK it's not a bug, I figure it out. This Physics package collects every existing collider(old) in conversion stage, then disconnect it with its parent entity and throw it into a big array to query. After that, the disconnected entity is a lonely collider, and wouldn't move with parent entity now. What I do is just remove the built-in box collider, then everything works fine.
     
    Last edited: Oct 31, 2019
  27. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    one_one, Gruguir, Nothke and 4 others like this.
Thread Status:
Not open for further replies.