Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Unity Physics Discussion

Discussion in 'Data Oriented Technology Stack' started by smcclelland, Mar 18, 2019.

  1. SamOld

    SamOld

    Joined:
    Aug 17, 2018
    Posts:
    97
    The old manual versions seem to be what come up on google for most of the packages, I've fallen into that trap before. It seems like somebody at Unity needs to mess with some SEO stuff somewhere to prioritise the latest versions.
     
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    5,683
    Unfortunately they change constantly names and not realizing changing links to repositories. Which leads to broken links, which were once posted. These which wasn't broken, stay on top of search engine results, leading to outdated information, like docs.

    In fact, is better when link is broken, than not updated. Specially at current state of DOTS. Lesser of two evils.
     
  3. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    5,683
    Last edited: Aug 14, 2019
  4. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    5,683
  5. mnarimani

    mnarimani

    Joined:
    Mar 27, 2017
    Posts:
    212
    Hi. I get this error randomly in my console:
    Code (CSharp):
    1. TypeLoadException: Recursive type definition detected
    Code (CSharp):
    1. IndexOutOfRangeException: Index -1062612832 is out of range of '3' Length.
    2. Unity.Collections.NativeArray`1[T].FailOutOfRangeError (System.Int32 index) (at <8e57d4f652b945d9a17953823be083fc>:0)
    3. Unity.Collections.NativeArray`1[T].CheckElementReadAccess (System.Int32 index) (at <8e57d4f652b945d9a17953823be083fc>:0)
    4. Unity.Collections.NativeArray`1[T].get_Item (System.Int32 index) (at <8e57d4f652b945d9a17953823be083fc>:0)
    5. Unity.Physics.BoundingVolumeHierarchy.Refit (Unity.Collections.NativeArray`1[T] aabbs, System.Int32 nodeStartIndex, System.Int32 nodeEndIndex) (at Packages/com.unity.physics@0.2.0-preview/Unity.Physics/Collision/Geometry/BoundingVolumeHierarchyBuilder.cs:564)
    6. Unity.Physics.BoundingVolumeHierarchy+FinalizeTreeJob.Execute () (at Packages/com.unity.physics@0.2.0-preview/Unity.Physics/Collision/Geometry/BoundingVolumeHierarchyBuilder.cs:842)
    7. Unity.Jobs.IJobExtensions+JobStruct`1[T].Execute (T& data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, Unity.Jobs.LowLevel.Unsafe.JobRanges& ranges, System.Int32 jobIndex) (at <8e57d4f652b945d9a17953823be083fc>:0)
    What is the problem and how can I fix it?
     
  6. mnarimani

    mnarimani

    Joined:
    Mar 27, 2017
    Posts:
    212
    I'm using this code to run physics on Fixed Update:
    Code (CSharp):
    1. public class PhysicsRunner : MonoBehaviour
    2.     {
    3.         private BuildPhysicsWorld buildPhysicsWorld;
    4.         private StepPhysicsWorld stepPhysicsWorld;
    5.         private ExportPhysicsWorld exportPhysicsWorld;
    6.         private EndFramePhysicsSystem endFramePhysicsSystem;
    7.  
    8.         private void Awake()
    9.         {
    10.             buildPhysicsWorld = World.Active.GetOrCreateSystem<BuildPhysicsWorld>();
    11.             stepPhysicsWorld = World.Active.GetOrCreateSystem<StepPhysicsWorld>();
    12.             exportPhysicsWorld = World.Active.GetOrCreateSystem<ExportPhysicsWorld>();
    13.             endFramePhysicsSystem= World.Active.GetOrCreateSystem<EndFramePhysicsSystem>();
    14.         }
    15.  
    16.         private void FixedUpdate()
    17.         {
    18.             buildPhysicsWorld.Update();
    19.             stepPhysicsWorld.Update();
    20.             exportPhysicsWorld.Update();
    21.             endFramePhysicsSystem.Update();
    22.         }
    23.     }
    I have added [DisableAutoCreation] to systems. Can this break Unity Physics?
     
    macagu likes this.
  7. linfuqing

    linfuqing

    Joined:
    May 11, 2015
    Posts:
    40
    Hi,I need call physics systems by a custom timestep instead of fixedTime.Have any plan about this?
     
  8. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    5,683
    Checkout samples on github. There are 2 examples for variable and fixed times.
     
  9. linfuqing

    linfuqing

    Joined:
    May 11, 2015
    Posts:
    40
    I mean to change line 268 in BuildPhysicsWorld.cs and line 101 in StepPhysicsWorld.cs,how can i do?
    My physics package version is 0.2.0
     
  10. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    45
    How can I update a CollisionFilter on a PhysicsCollider from a system?
     
  11. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,395
    You can assign a new filter via ColliderPtr->Filter on the PhysicsCollider component.
     
  12. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    45
    Nope, doesn't work.

    Code (CSharp):
    1.         Entities.With(m_group).ForEach((Entity entity, ref SetExteriorFilterData setExteriorFilterData, ref PhysicsCollider physicsCollider) =>
    2.         {
    3.             physicsCollider.ColliderPtr->Filter = new CollisionFilter()
    4.             {
    5.                 BelongsTo = m_filters[0],
    6.                 CollidesWith = m_filters[1],
    7.                 GroupIndex = 0
    8.             };
    9.  
    10.             //chunkColliders[i] = collider;
    11.  
    12.             PostUpdateCommands.RemoveComponent<SetExteriorFilterData>(entity);
    13.  
    14.             var testComparer = new CollisionFilter()
    15.             {
    16.                 BelongsTo = m_filters[0],
    17.                 CollidesWith = m_filters[1],
    18.                 GroupIndex = 0
    19.             };
    20.  
    21.             if (physicsCollider.ColliderPtr->Filter.BelongsTo != testComparer.BelongsTo)
    22.             {
    23.                 Debug.LogError("Not same, " + physicsCollider.ColliderPtr->Filter.BelongsTo + ", " + testComparer.BelongsTo);
    24.             }
    25.         });
     
  13. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,707
    this works for me

    Code (CSharp):
    1.                 var collider = this.DstEntityManager.GetComponentData<PhysicsCollider>(entity);
    2.                 var filter = collider.Value.Value.Filter;
    3.                 filter.BelongsTo |= 1u << observersLayerBit;
    4.                 collider.Value.Value.Filter = filter;
    Via pointer should work as well but haven't tested.
     
  14. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    45
    Doesn't for me. It still keep it's original values.

    Code (CSharp):
    1.         Entities.With(m_group).ForEach((Entity entity, ref SetExteriorFilterData setExteriorFilterData, ref PhysicsCollider physicsCollider) =>
    2.         {
    3.             var filter = physicsCollider.Value.Value.Filter;
    4.  
    5.             PostUpdateCommands.RemoveComponent<SetExteriorFilterData>(entity);
    6.  
    7.             filter.BelongsTo = m_filters[0];
    8.             filter.CollidesWith = m_filters[1];
    9.  
    10.             physicsCollider.Value.Value.Filter = filter;
    11.  
    12.             var testComparer = new CollisionFilter()
    13.             {
    14.                 BelongsTo = m_filters[0],
    15.                 CollidesWith = m_filters[1],
    16.                 GroupIndex = 0
    17.             };
    18.  
    19.             if (physicsCollider.Value.Value.Filter.BelongsTo != testComparer.BelongsTo)
    20.             {
    21.                 Debug.LogError("Not same, " + physicsCollider.Value.Value.Filter.BelongsTo + ", " + testComparer.BelongsTo);
    22.             }
    23.         });
     
  15. Backes

    Backes

    Joined:
    Mar 22, 2018
    Posts:
    4
    I'm working on a project that have a terrain larger than the 10km that the default physics can handle. At the beginning, I've solved this problem using an origin offset. However, this solution have a limitation that the objects in the scene can't be farther than 10 km apart.

    From 2018.3, Unity give us the possibility to spawn others physics scenes. Then, I've worked on a solution that clusterise the objects in the scene, and for each cluster, I spawn a physics scene. However, before the Physics.Simulate, I must translate each object to the cluster centroid, process the physics step and then translate back to the world position. This translate process is consuming a lot of time. Maybe because it forces the physics to recalculate something in the broadphase.

    Does the new Unity Physics give us a way to avoid this translate overhead?
    How does the new Physics handle with large terrain's inaccuracy?
     
  16. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    45
    It seems I found the problem now. This works all fine on normal Colliders, but not on CompoundColliders, and I hope they change this.
     
  17. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,707
    That's interesting as I have not used any compound colliders yet. Looking at the source, I don't really understand why though. It's the exact same code for a CompoundCollider and any other collider when it comes to the filter. Unless you also need to go through the children colliders (Children) and set them as well but that doesn't seem to make sense looking at code.
     
    Last edited: Aug 27, 2019
  18. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    45
    Yeah. I finally found it once I copied the packet into my asset folder instead.

    In Physics_Collider.cs of the Collider struct.
    Code (CSharp):
    1.         public CollisionFilter Filter
    2.         {
    3.             get => m_Header.Filter;
    4.             set
    5.             {
    6.                 // Disallow changing the filter of composite types directly, since that is a combination of its children
    7.                 if(m_Header.CollisionType == CollisionType.Convex)
    8.                 {
    9.                     m_Header.Filter = value;
    10.                 }
    11.             }
    12.         }
    I guess I'll have to loop over the children and set their filter respectivly, but haven't found the code that would set the compound Collider therafter.
     
  19. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    45
    Diving into this feels soon a bit over my head, it seems I can either use
    Code (CSharp):
    1.         public unsafe bool GetChild(ref ColliderKey key, out ChildCollider child)
    2.         {
    3.             if (key.PopSubKey(NumColliderKeyBits, out uint childIndex))
    4.             {
    5.                 ref Child c = ref Children[(int)childIndex];
    6.                 child = new ChildCollider(c.Collider) { TransformFromChild = c.CompoundFromChild };
    7.                 return true;
    8.             }
    9.  
    10.             child = new ChildCollider();
    11.             return false;
    12.         }
    but I've yet to understand how ColliderKey works, or

    Code (CSharp):
    1.         public unsafe void GetLeaves<T>(ref T collector) where T : struct, ILeafColliderCollector
    2.         {
    3.             for (uint i = 0; i < NumChildren; i++)
    4.             {
    5.                 ref Child c = ref Children[(int)i];
    6.                 ColliderKey childKey = new ColliderKey(NumColliderKeyBits, i);
    7.                 if (c.Collider->CollisionType == CollisionType.Composite)
    8.                 {
    9.                     collector.PushCompositeCollider(new ColliderKeyPath(childKey, NumColliderKeyBits), new MTransform(c.CompoundFromChild), out MTransform worldFromCompound);
    10.                     c.Collider->GetLeaves(ref collector);
    11.                     collector.PopCompositeCollider(NumColliderKeyBits, worldFromCompound);
    12.                 }
    13.                 else
    14.                 {
    15.                     var child = new ChildCollider(c.Collider) { TransformFromChild = c.CompoundFromChild };
    16.                     collector.AddLeaf(childKey, ref child);
    17.                 }
    18.             }
    19.         }
    But requiring a collector that seems way too compelx for me to comprehend right now, looking at CompositeCompositeLeafCollector. It feels like fetching and modifying filters of Colliders should be trivial, maybe I'm missing something?
     
  20. Rory_Havok

    Rory_Havok

    Joined:
    Jun 25, 2018
    Posts:
    16
    Hello Jawsarn,
    The filter for a compound collider is expected to be a union of the filter of all of its child colliders. We test the filters all the way down to the leaves, so you must make sure both the compound and its children are set correctly. This happens automatically when baking the collider during the conversion pipeline.

    The problem is that the API isn't really designed for mutable colliders yet - some things are possible, some are awkward. We will tighten up the API contract in future versions. It seems you want to apply a filter to a compound and all of its children, so I would recommend:
    1. Cast it to CompoundCollider*
    2. Set its filter (it has a public setter in that API)
    3. Iterate its children using the "Children" enumerable, set the filter on those too
    4. If a child is itself a compound, repeat

    If you are working from the children upward instead, use CollisionFilter.CreateUnion() to merge any two filters, so just call it repeatedly to reduce any number of filters down to one and set that as the compound's filter.

    Rory (standing in for steveeHavok who is busy)
     
    Jawsarn likes this.
  21. Rory_Havok

    Rory_Havok

    Joined:
    Jun 25, 2018
    Posts:
    16
    Hello @Backes ,

    Can I ask how large your game world is?

    We haven't measured the behavior of Unity.Physics far from the origin yet but from experience I would guess that the behavior would degrade in a roughly similar way to PhysX, becuase it uses single precision floats. So I think you will still need to shift the physics world.

    However I do think Unity.Physics could _potentially_ make that use case easier/faster. The key thing is that the physics world is independent to the entity world, synchronized each frame via the BuildPhysicsWorld and ExportPhysicsWorld systems. So it should be fairly easy to modify the source to add an offset when we read the entity translations during BuildPhysicsWorld, and remove that offset when we apply them back in ExportPhysicsWorld. So the physics world be centered at a different position to the entity world. There would be practically no extra cost vs the normal physics step. Also you can simulate all your clustered worlds in parallel with each other - perhaps aside from ExportPhysicsWorld jobs which may need to be done in serial.

    Perhaps that is something we should offically support... But in the meantime we hope that users are comfortable modifying source to do things like this (and whenever we open up the github repo that will be easier).
     
    Last edited: Sep 7, 2019
    Backes likes this.
  22. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    45
    I tried this and I sadly dont' get it working correctly. My setup is simply one Dynamic Body with 3 cube child entities that I convert in the scene that all doesn't belong or collide with any layer, and a seperate static plane that belongs to layer 1, collides with 1. I get weird CollisionType, and filter values when I check debugger/log values (e.g. terrain CollisionType) and -535343 for groupIndex of filter. And the filter values set doesn't seem to presist in the next frame. Code below.

    Code (CSharp):
    1.     unsafe void SetChildFilter(ref CollisionFilter collisionFilter, CompoundCollider* collider)
    2.     {
    3.         foreach (var item in collider->Children)
    4.         {
    5.             Debug.Log("Filter before child: " + item.Collider->Filter.BelongsTo + ", " + item.Collider->Filter.CollidesWith + ", " + item.Collider->Filter.GroupIndex);
    6.             item.Collider->Filter = collisionFilter;
    7.             Debug.Log("Filter after child: " + item.Collider->Filter.BelongsTo + ", " + item.Collider->Filter.CollidesWith + ", " + item.Collider->Filter.GroupIndex);
    8.             if (item.Collider->CollisionType == CollisionType.Composite)
    9.             {
    10.                 SetChildFilter(ref collisionFilter, (CompoundCollider*)item.Collider);
    11.             }
    12.         }
    13.     }
    14.  
    15.     protected unsafe override void OnUpdate()
    16.     {
    17.         Entities.With(m_group).ForEach((Entity entity, ref PhysicsCollider physicsCollider) =>
    18.         {
    19.             physicsCollider.Value.Value.Filter = new CollisionFilter() { BelongsTo = 1, CollidesWith = 1, GroupIndex = 0 };
    20.  
    21.             var filterToSet = new CollisionFilter() { BelongsTo = 1, CollidesWith = 1, GroupIndex = 0 };
    22.  
    23.             SetChildFilter(ref filterToSet, (CompoundCollider*)physicsCollider.ColliderPtr);
    24.  
    25.         });
    26.     }
     
  23. linfuqing

    linfuqing

    Joined:
    May 11, 2015
    Posts:
    40
    Hi,I try the CCFixes.zip,it's not work for large timestep same as "hello world".
    Is it a temporary version for the static method "CharacterControllerUtilities.CollideAndIntegrate" ? and:
    Code (CSharp):
    1. public unsafe void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
    2.         {
    3.             float3 up = math.up();
    4.  
    5.             var chunkCCData = chunk.GetNativeArray(CharacterControllerComponentType);
    6.             var chunkCCInputData = chunk.GetNativeArray(CharacterControllerUserInputType);
    7.             var chunkCCInternalData = chunk.GetNativeArray(CharacterControllerInternalType);
    8.             var chunkPhysicsColliderData = chunk.GetNativeArray(PhysicsColliderType);
    9.             var chunkTranslationData = chunk.GetNativeArray(TranslationType);
    10.             var chunkRotationData = chunk.GetNativeArray(RotationType);
    11.  
    12.             DeferredImpulseWriter.BeginForEachIndex(chunkIndex);
    13.  
    14.             // Maximum number of hits character controller can store in world queries
    15.             const int maxQueryHits = 128;
    16.             var distanceHits = new NativeArray<DistanceHit>(maxQueryHits, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
    17.             var castHits = new NativeArray<ColliderCastHit>(maxQueryHits, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
    18.             var constraints = new NativeArray<SurfaceConstraintInfo>(4 * maxQueryHits, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
    19.  
    20.             for (int i = 0; i < chunk.Count; i++)
    21.             {
    22.                 var ccComponentData = chunkCCData[i];
    23.                 var ccInputData = chunkCCInputData[i];
    24.                 var ccInternalData = chunkCCInternalData[i];
    25.                 var collider = chunkPhysicsColliderData[i];
    26.                 var position = chunkTranslationData[i];
    27.                 var rotation = chunkRotationData[i];
    28.  
    29.                 // Collision filter must be valid
    30.                 Assert.IsTrue(collider.ColliderPtr->Filter.IsValid);
    31.  
    32.                 // Character step input
    33.                 CharacterControllerStepInput stepInput = new CharacterControllerStepInput
    34.                 {
    35.                     World = PhysicsWorld,
    36.                     DeltaTime = DeltaTime,
    37.                     Up = math.up(),
    38.                     Gravity = ccComponentData.Gravity,
    39.                     MaxIterations = ccComponentData.MaxIterations,
    40.                     Tau = c_DefaultTau,
    41.                     Damping = c_DefaultDamping,
    42.                     SkinWidth = ccComponentData.SkinWidth,
    43.                     ContactTolerance = ccComponentData.ContactTolerance,
    44.                     MaxSlope = ccComponentData.MaxSlope,
    45.                     RigidBodyIndex = PhysicsWorld.GetRigidBodyIndex(ccInternalData.Entity),
    46.                     CurrentVelocity = ccInternalData.LinearVelocity
    47.                 };
    48.  
    49.                 // Character transform
    50.                 RigidTransform transform = new RigidTransform
    51.                 {
    52.                     pos = position.Value,
    53.                     rot = rotation.Value
    54.                 };
    55.  
    56.                 // "Broad phase" (used both for checking support and actual character collide and integrate).
    57.                 MaxHitsCollector<DistanceHit> distanceHitsCollector = new MaxHitsCollector<DistanceHit>(
    58.                     stepInput.RigidBodyIndex, ccComponentData.ContactTolerance, ref distanceHits);
    59.                 {
    60.                     ColliderDistanceInput input = new ColliderDistanceInput()
    61.                     {
    62.                         MaxDistance = ccComponentData.ContactTolerance,
    63.                         Transform = transform,
    64.                         Collider = collider.ColliderPtr
    65.                     };
    66.                     PhysicsWorld.CalculateDistance(input, ref distanceHitsCollector);
    67.                 }
    68.  
    69.                 // Check support
    70.                 CheckSupport(stepInput, transform, ccComponentData.MaxSlope, distanceHitsCollector,
    71.                     ref constraints, out ccInternalData.SupportedState, out float3 surfaceNormal, out float3 surfaceVelocity);
    72.  
    73.                 // User input
    74.                 float3 desiredVelocity = ccInternalData.LinearVelocity;
    75.                 HandleUserInput(ccInputData, ccComponentData, stepInput.Up, surfaceVelocity, ref ccInternalData, ref desiredVelocity);
    76.  
    77.                 // Calculate actual velocity with respect to surface
    78.                 if (ccInternalData.SupportedState == CharacterSupportState.Supported)
    79.                 {
    80.                     CalculateMovement(ccInternalData.CurrentRotationAngle, stepInput.Up, ccInternalData.IsJumping,
    81.                         ccInternalData.LinearVelocity, desiredVelocity, surfaceNormal, surfaceVelocity, out ccInternalData.LinearVelocity);
    82.                 }
    83.                 else
    84.                 {
    85.                     ccInternalData.LinearVelocity = desiredVelocity;
    86.                 }
    87.  
    88.                 // World collision + integrate
    89.                 CollideAndIntegrate(stepInput, ccComponentData.CharacterMass, ccComponentData.AffectsPhysicsBodies > 0,
    90.                     collider.ColliderPtr, distanceHitsCollector, ref castHits, ref constraints,
    91.                     ref transform, ref ccInternalData.LinearVelocity, ref DeferredImpulseWriter);
    92.  
    93.                 // Write back and orientation integration
    94.                 position.Value = transform.pos;
    95.                 rotation.Value = quaternion.AxisAngle(up, ccInternalData.CurrentRotationAngle);
    96.  
    97.                 // Write back to chunk data
    98.                 {
    99.                     chunkCCInternalData[i] = ccInternalData;
    100.                     chunkTranslationData[i] = position;
    101.                     chunkRotationData[i] = rotation;
    102.                 }
    103.             }
    104.  
    105.             DeferredImpulseWriter.EndForEachIndex();
    106.         }
    it's not work in burst,and distanceHits,castHits,constraints not be disposed here.
     
  24. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    5,683
  25. astropuffin

    astropuffin

    Joined:
    May 16, 2015
    Posts:
    6
    I'm stuck on something which seems like it should be trivial: Raycast. I'm following the code samples (specifically https://docs.unity3d.com/Packages/com.unity.physics@0.2/manual/collision_queries.html) and I'm totally falling on my face. Here's my code:

    Code (CSharp):
    1. public class EntityManagerBehavior : MonoBehaviour {
    2.     [SerializeField] private EntityManager manager;
    3.     private void Awake() {
    4.         manager = World.Active.EntityManager;
    5.     }
    6.     private void Start() {
    7.         Temp(manager);
    8.     }
    9.     private void Temp(EntityManager m) {
    10.          var physicsWorld = World.Active.GetExistingSystem<BuildPhysicsWorld>().PhysicsWorld.CollisionWorld;
    11.          var e = m.CreateEntity();
    12.          m.AddComponentData(e, new Translation{Value = new float3(0,0,0)});
    13.          var spCollider = Unity.Physics.SphereCollider.Create(float3.zero, 1f);
    14.          m.AddComponentData(e, new PhysicsCollider {Value = spCollider});
    15.          m.AddComponentData(e, new Rotation{Value = quaternion.identity});
    16.          var input = new RaycastInput() {
    17.              Start = new float3(0,0,-2f),
    18.              End = new float3(0,0,2f),
    19.              Filter = CollisionFilter.Default
    20.          };
    21.          var bodiesLength = physicsWorld.NumBodies;
    22.          Debug.Log(bodiesLength);
    23.          var hit = physicsWorld.CastRay(input);
    24.          Debug.Log(hit);
    25.      }
    26.  }
    Result:
    Code (CSharp):
    1. 0
    2. False
    Why are there no bodies in my CollisionWorld? The documentation seems to imply that's automatically handled. Do I need to wait a simulation frame? Putting the Raycast in Update() doesn't seem to help.

    Physics package: 0.2.0
    Unity: 2019.2.0f1

    Note: I'm hoping to use a pure ECS framework rather than a hybrid.
     
    Last edited: Sep 2, 2019
  26. Ryetoast

    Ryetoast

    Joined:
    Mar 8, 2015
    Posts:
    40
    It appears that putting a physics shape on an entity breaks the entity debugger when looking at that entity =(
     
  27. Ryetoast

    Ryetoast

    Joined:
    Mar 8, 2015
    Posts:
    40
    Sort of, yes.

    You need to run your ray casts during the simulation update from a system that updates after BuildPhysicsWorld, otherwise it hasn't, as the name implies, built the physics world that you are trying to query against.

    A quick example looks something like this, but with correct function names and syntax:
    Code (CSharp):
    1. [UpdateAfter(typeof(BuildPhysicsWorld))]
    2. struct Raycaster : JobSystem {
    3.   RaycastJob {
    4.     CollisionWorld World;
    5.     void Execute () {
    6.       World.RayCast();
    7.      }
    8.   }
    9.  
    10.   BuildPhysicsWorld System;
    11.   OnCreate () {
    12.     System = Get<BuildPhysicsWorld>();
    13.   }
    14.  
    15.   OnUpdate (inputDeps) {
    16.     new RaycastJob {
    17.       World = System.PhysicsWorld.CollisionWorld
    18.     }.Schedule(this, JobHandle.Combine(System.LastJob, inputDeps)
    19.   }
    20. }
    I imagine if you want to do a non-jobified version you need to complete the LastJobHandle on the physics world in order to make sure it is ready for you.
     
  28. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,707
    Ryetoast likes this.
  29. Ryetoast

    Ryetoast

    Joined:
    Mar 8, 2015
    Posts:
    40
    I'm trying to do hit locations on a target, so my plan was originally make the parent have an invisible capsule for movement (physics body and shape) and then have children that are just shapes with an ecs component that applies a damage multiplier when it gets hit, and then forwards that damage on to its parent. This didn't work because it appears that the combined collider gets pushed up to the parent during conversion, and thus the multiplier doesn't getting applied since the hit never interacts with the child entity.

    Plan B was to make the hit location children have a body and shape, and make them kinematic. This doesn't work because they no longer attach to and follow the parent.
    (Edit: noticed this is called out in the editor, but there isn't a way to prevent the un-parenting or alternate suggestion)

    Any ideas on how I'm supposed to do something like this? (Visual aid in case I wasn't clear about what I was trying to do: http://i.imgur.com/LRDOBz7.png)
     
    Last edited: Sep 3, 2019
  30. Ryetoast

    Ryetoast

    Joined:
    Mar 8, 2015
    Posts:
    40
    I just tried making an entity and manually adding a PhysicsCollider from a conversion script to see if that would maintain the parent relationship.

    The visual elements of the collider only entities moved around fine, but for some reason the actual collider itself didn't stay synced with the position of the visuals... really strange.

    Isn't this whole thing "stateless" and recomputed each frame? Why would the position that the mesh renderer is using and the position of the physics collider not match up when the only physics related thing is the collider?

    For reference, here is my script that I'm creating the PhysicsCollider:
    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Mathematics;
    3. using Unity.Physics;
    4. using Unity.Physics.Authoring;
    5. using UnityEngine;
    6.  
    7. namespace Gamespace {
    8.  
    9.     namespace C {
    10.         struct HitLocation : IComponentData { public float DamageMultiplier; }
    11.     }
    12.  
    13.     [RequireComponent(typeof(CHealthChange))]
    14.     public class CHitLocation : MonoBehaviour, IConvertGameObjectToEntity {
    15.         public float DamageMultiplier = 1.0f;
    16.  
    17.         public PhysicsCategoryTags BelongsTo;
    18.         public PhysicsCategoryTags CollidesWith;
    19.  
    20.         void IConvertGameObjectToEntity.Convert (Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) {
    21.             dstManager.AddComponents(entity, new ComponentTypes(
    22.                 typeof(C.HitLocation),
    23.                 typeof(PhysicsCollider)
    24.             ));
    25.  
    26.             dstManager.SetComponentData(entity, new C.HitLocation { DamageMultiplier = DamageMultiplier });
    27.             dstManager.SetComponentData(entity, new PhysicsCollider {
    28.                 Value = Unity.Physics.BoxCollider.Create(
    29.                     float3.zero,
    30.                     quaternion.identity,
    31.                     transform.localScale,
    32.                     0.05f,
    33.                     new CollisionFilter {
    34.                         BelongsTo = BelongsTo.Value,
    35.                         CollidesWith = CollidesWith.Value
    36.                     },
    37.                     new Unity.Physics.Material {
    38.                         Flags = Unity.Physics.Material.MaterialFlags.IsTrigger
    39.                     }
    40.                 )
    41.             });
    42.         }
    43.     }
    44.  
    45. }
    46.  
     
  31. Ryetoast

    Ryetoast

    Joined:
    Mar 8, 2015
    Posts:
    40
    Figured out the answer to my own question... it's because the physics is directly using the Translation component, and not applying the LocalToWorld transform to it. Since it has a parent, the transform is a local/relative one that never changes, thus the collider stays in the same spot next to the world origin. This seems like a bug as all the other Unity systems respect the LocalToWorld.
     
  32. linfuqing

    linfuqing

    Joined:
    May 11, 2015
    Posts:
    40
    Which one should i choose between PhysicsTriggerEvent and PhysicsWorld.CalculateDistance from a performance perspective?
     
  33. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    45
    Yep, I think it's by current design and not really a bug. In the conversion system all physicBodies will be unparented automagically. But it enables to do some local physics if you layer and reparent it correctly, so it got that going :)
     
  34. lijianfeng

    lijianfeng

    Joined:
    Sep 8, 2015
    Posts:
    34
    How to set groupIndex of Filter of PhysicsCollider ?when I set it in job,it remain unchanged,so wired...:confused: here's my code:


    Code (CSharp):
    1. public void Execute(Entity entity, int index,[ReadOnly] ref RoleStateData roleState,ref PhysicsCollider collider)
    2.         {
    3.             var filter = collider.Value.Value.Filter;
    4.             filter.GroupIndex = -roleState.controllID;
    5.             collider.Value.Value.Filter = filter;
    6.             commandBuffer.RemoveComponent<SetGroupIndexTag>(index, entity);
    7.         }
     
    Last edited: Sep 4, 2019
  35. linfuqing

    linfuqing

    Joined:
    May 11, 2015
    Posts:
    40
    I get a very large value of velocity from SimplexSolver.Solve3d,is it a bug?
    upload_2019-9-3_21-47-48.png
     
  36. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,707
    Compound collider? You need to set all the children I believe.
     
  37. lijianfeng

    lijianfeng

    Joined:
    Sep 8, 2015
    Posts:
    34
    OMG!, I Instantiate some obj of the same entity prefab,so the reference to the the collider blobasset are same.
     
  38. astropuffin

    astropuffin

    Joined:
    May 16, 2015
    Posts:
    6
    Thanks @Ryetoast !
    For anyone following in my footsteps, here's a bare bones raycast with pure ECS.

    Code (CSharp):
    1. using Unity.Collections;
    2. using Unity.Entities;
    3. using Unity.Jobs;
    4. using Unity.Mathematics;
    5. using Unity.Physics;
    6. using Unity.Physics.Systems;
    7. using Unity.Transforms;
    8. using UnityEngine;
    9.  
    10. namespace YourNamespace {
    11.     public class RaycastBehavior : MonoBehaviour{
    12.         private EntityManager manager;
    13.         private PhysicsWorld physicsWorld;
    14.  
    15.         private void Awake() {
    16.             manager = World.Active.EntityManager;
    17.             physicsWorld = World.Active.GetExistingSystem<BuildPhysicsWorld>().PhysicsWorld;
    18.  
    19.             CreateRayCastTarget(manager, physicsWorld.CollisionWorld);
    20.         }
    21.  
    22.         private void Update() { if (Input.GetMouseButtonDown(0)) { RunRaycastQuery(); } }
    23.  
    24.         private struct RaycastJob : IJob {
    25.             public RaycastInput RaycastInput;
    26.             public NativeList<Unity.Physics.RaycastHit> RaycastHits;
    27.             [ReadOnly] public PhysicsWorld World;
    28.  
    29.             public void Execute() { World.CastRay(RaycastInput, ref RaycastHits); }
    30.         }
    31.  
    32.         private static void CreateRayCastTarget(EntityManager m, CollisionWorld c) {
    33.              var e = m.CreateEntity();
    34.              m.AddComponentData(e, new Translation{Value = new float3(0,0,0)});
    35.              var spCollider = Unity.Physics.SphereCollider.Create(float3.zero, 1f);
    36.              m.AddComponentData(e, new PhysicsCollider {Value = spCollider});
    37.              m.AddComponentData(e, new Rotation{Value = quaternion.identity});
    38.         }
    39.  
    40.         private  void RunRaycastQuery() {
    41.             ref var world = ref World.Active.GetExistingSystem<BuildPhysicsWorld>().PhysicsWorld;
    42.             Debug.Log($"bodies: {physicsWorld.Bodies}");
    43.             var input = new RaycastInput() {
    44.                 Start = new float3(0,0,-2f),
    45.                 End = new float3(0,0,2f),
    46.                 Filter = CollisionFilter.Default
    47.             };
    48.             var hits = new NativeList<Unity.Physics.RaycastHit>(Allocator.TempJob);
    49.             new RaycastJob {
    50.                 World = world,
    51.                 RaycastHits = hits,
    52.                 RaycastInput = input,
    53.             }.Schedule().Complete();
    54.             Debug.Log($"hits: {hits.Length}");
    55.             hits.Dispose();
    56.         }
    57.     }
    58. }
     
  39. Ryetoast

    Ryetoast

    Joined:
    Mar 8, 2015
    Posts:
    40
    So I manually set up a parent system for my hit locations, and now I ran into a new issue.

    I have entities that have physics shapes, but no physics body.
    I can successfully hit them when I use CollisionWorld.RayCast, however the resulting hit has a rigidbody index of -1, which means I have no way to get back the Entity that the raycast hit.

    I guess I could try sticking a kinematic or static body on it or whatever, but that seems like I'm jamming extra data on a thing for no reason, which is kinda counter ECS.

    Edit: I realized what I said doesn't make any sense, I was successfully hitting the hit locations, but for some reason my targeting raycast was failing, so something else weird is going on... I guess ignore this post for now?
     
    Last edited: Sep 4, 2019
  40. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    45
    I had similar problem to you, (you can see some page back in this thread). I didn't get changing filters of children to work for some strange reason, which is needed on compound collider (and modify the code so you are allowed to do this on compound colliders as well). What I do now is that I change layers on prefab and Convert for each different filter I need seperately, this also avoids the problem of blobasset being same.
     
  41. KingOscarV

    KingOscarV

    Joined:
    Apr 9, 2018
    Posts:
    1
    I'm having huge performance problem when I instantiate objects with the Physics Body and Physics Shape attached to them. I'm spawning them in using the "Spawn in random sphere" script (which is used in boid example). Whenever I hit play it takes like a minute to load the scene, once it's loaded though performance is fine. The problem hits about when I spawn around 1000 entities which shouldn't be a problem (I could without problem spawn 10k with the old rigidbody and collider system).
     
  42. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    8
    It does feel like a bug, the epsilon seems too small for this case. But just to verify, could you please post the inputs (up vector and 3 constraints as well) so that I can reproduce locally with a test case? Thanks!
     
  43. linfuqing

    linfuqing

    Joined:
    May 11, 2015
    Posts:
    40
    upload_2019-9-6_10-19-47.png
    I don't know what's the 'det' mean, for normalize the final pointVel I guess?
     
  44. linfuqing

    linfuqing

    Joined:
    May 11, 2015
    Posts:
    40
    BTW,sometime my character be moved a long distance when call SimplexSolver.Solve(but velocity is a normal value),is'it the same issue?
     
  45. linfuqing

    linfuqing

    Joined:
    May 11, 2015
    Posts:
    40
    Somewhat unrelated, the method "CharacterControllerUtilities.CollideAndIntegrate" has a bug after SimplexSolver.Solve which will drop through the terrain sometime.

    Original(start line 329 in CharacterControllerUtilities.cs from CCFixes.zip):
    Code (CSharp):
    1.  
    2.             float3 newDisplacement = newPosition - prevPosition;
    3.  
    4.             // Check if we can walk to the position simplex solver has suggested
    5.             MaxHitsCollector<ColliderCastHit> newCollector = new MaxHitsCollector<ColliderCastHit>(stepInput.RigidBodyIndex, 1.0f, ref castHits);
    6.             int newContactIndex = -1;
    7.  
    8.             // If simplex solver moved the character we need to re-cast to make sure it can move to new position
    9.             if (math.lengthsq(newDisplacement) > SimplexSolver.SimplexSolverEpsilon)
    10.             {
    11.                 float3 displacement = newDisplacement + gravityMovement;
    12.                 ColliderCastInput input = new ColliderCastInput()
    13.                 {
    14.                     Collider = collider,
    15.                     Orientation = orientation,
    16.                     Start = prevPosition,
    17.                     End = prevPosition + displacement * (1.0f + stepInput.ContactTolerance)
    18.                 };
    19.  
    20.                 world.CastCollider(input, ref newCollector);
    21.  
    22.                 for (int hitIndex = 0; hitIndex < newCollector.NumHits; hitIndex++)
    23.                 {
    24.                     ColliderCastHit hit = newCollector.AllHits[hitIndex];
    25.  
    26.                     bool found = false;
    27.                     for (int constraintIndex = 0; constraintIndex < numConstraints; constraintIndex++)
    28.                     {
    29.                         SurfaceConstraintInfo constraint = constraints[constraintIndex];
    30.                         if (constraint.RigidBodyIndex == hit.RigidBodyIndex &&
    31.                             constraint.ColliderKey.Equals(hit.ColliderKey))
    32.                         {
    33.                             found = true;
    34.                             break;
    35.                         }
    36.                     }
    37.  
    38.                     if (!found)
    39.                     {
    40.                         newContactIndex = hitIndex;
    41.                         break;
    42.                     }
    43.                 }
    44.             }
    45.  
    46.             // Move character along the newDisplacement direction until it reaches this new contact
    47.             if (newContactIndex >= 0)
    48.             {
    49.                 ColliderCastHit newContact = newCollector.AllHits[newContactIndex];
    50.  
    51.                 Assert.IsTrue(newContact.Fraction >= 0.0f && newContact.Fraction <= 1.0f);
    52.  
    53.                 integratedTime *= newContact.Fraction;
    54.                 newPosition = prevPosition + newDisplacement * newContact.Fraction;
    55.             }
    Modified:
    Code (CSharp):
    1.  
    2.                 float3 newDisplacement = newPosition - prevPosition;
    3.  
    4.                 // Check if we can walk to the position simplex solver has suggested
    5.                 MaxHitsCollector<ColliderCastHit> newCollector = new MaxHitsCollector<ColliderCastHit>(rigidBodyIndex, 1.0f, ref castHits);
    6.                 int newContactIndex = -1;
    7.  
    8.                 // If simplex solver moved the character we need to re-cast to make sure it can move to new position
    9.                 if (math.lengthsq(newDisplacement) > SimplexSolver.SimplexSolverEpsilon)
    10.                 {
    11.                     float3 displacement = newDisplacement + gravityMovement;
    12.                     ColliderCastInput input = new ColliderCastInput()
    13.                     {
    14.                         Collider = collider,
    15.                         Orientation = orientation,
    16.                         Start = prevPosition,
    17.                         End = prevPosition + displacement * (1.0f + contactTolerance)
    18.                     };
    19.                  
    20.                     world.CastCollider(input, ref newCollector);
    21.  
    22.                     float minFraction = float.MaxValue, fraction;
    23.                     for (int hitIndex = 0; hitIndex < newCollector.NumHits; hitIndex++)
    24.                     {
    25.                         ColliderCastHit hit = newCollector.AllHits[hitIndex];
    26.                         fraction = hit.Fraction;
    27.                         if (fraction < minFraction)
    28.                         {
    29.                             bool found = false;
    30.                             for (int constraintIndex = 0; constraintIndex < numConstraints; constraintIndex++)
    31.                             {
    32.                                 SurfaceConstraintInfo constraint = constraints[constraintIndex];
    33.                                 if (constraint.RigidBodyIndex == hit.RigidBodyIndex &&
    34.                                     constraint.ColliderKey.Equals(hit.ColliderKey))
    35.                                 {
    36.                                     found = true;
    37.                                     break;
    38.                                 }
    39.                             }
    40.  
    41.                             if (!found)
    42.                             {
    43.                                 minFraction = fraction;
    44.                                 newContactIndex = hitIndex;
    45.                             }
    46.                         }
    47.                     }
    48.                 }
    49.  
    50.                 // Move character along the newDisplacement direction until it reaches this new contact
    51.                 if (newContactIndex >= 0)
    52.                 {
    53.                     ColliderCastHit newContact = newCollector.AllHits[newContactIndex];
    54.  
    55.                     Assert.IsTrue(newContact.Fraction >= 0.0f && newContact.Fraction <= 1.0f);
    56.  
    57.                     integratedTime *= newContact.Fraction;
    58.                     newPosition = prevPosition + newDisplacement * newContact.Fraction;
    59.                 }
    60.  
     
    konsic likes this.
  46. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    1,494
    It’s matrix determinant

     
  47. linfuqing

    linfuqing

    Joined:
    May 11, 2015
    Posts:
    40
    but the matrix determinant is not:
    upload_2019-9-6_16-55-45.png
    and
    upload_2019-9-6_16-56-11.png
    they are not equal.

    I don't understand why need to pointVel /= det?
     
  48. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    8
    Hello folks,

    I won't quote individual replies since most of the latest ones are related to character controller.

    First, thanks @linfuqing for the info on the input to the simplex solver! It is definitely a problem, and the proper line should be
    float det = math.dot(r0, plane0);
    Can you check if this gives you better results? It could also be related to high movements you've seen with the character controller.

    Second, your suggested fix for CollideAndIntegrate seems correct. The code was assuming sorted hits, while that's not the case. So we do actually need closest unvisited hit, and the fraction manipulation you provided does the trick.

    I'll make sure both of these fixes end up in one of the next versions.
     
  49. Adam-Mechtley

    Adam-Mechtley

    Unity Technologies

    Joined:
    Feb 5, 2007
    Posts:
    191
    Hi folks! A new version of the physics package, 0.2.2, was released today. You can read the full set of changes here, but a few highlights include:
    • Collider Create() methods are now Burst compatible.
    • Mesh and convex conversion is now much faster.
    • Convex shapes now have wireframe previews in the scene at edit time
    • Fitting shapes to render geometry and/or generating automatic convex hulls now accounts for skinned meshes
    Please let us know if you encounter any major issues. Barring any critical issues that arise, our plan is for our next release to fall around Unite.
     

    Attached Files:

    Kender, Oblivionized and florianhanke like this.
  50. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,395
    In 0.2.2 was it intentional for the deprecated MeshCollider.Create to just silently fail?