Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Convert PhysicsShapes components to PhysicsCollider manually

Discussion in 'Entity Component System' started by Plaximo, Jan 11, 2020.

  1. Plaximo

    Plaximo

    Joined:
    Oct 26, 2016
    Posts:
    8
    Hi,

    I'm having trouble to convert PhysicsShape components (MonoBehaviour authoring script) to a PhysicsCollider.(Entity world)

    I'm using the hybrid worklfow to convert my gameobjects to entities with the ConvertToEntity script.
    My simplified GameObject hierachy looks like this:
    • Enemy (Scripts: PhysicsBody, ConvertToEntity, MyConversionScript, Data)
      • Body (PhysicsShape, ...)
      • Left Arm (PhysicsShape, ..)
      • Right Arm (PhysicsShape, ...)
      • ...

    If I'm using the ConversionMode ConvertAndDestroy everything works fine. But with the ConversionMode ConvertAndInjectGameObject the ConvertToEntity script only stays in the attached GameObject, he doesn't touch his children. I have to do this cause I'm using a SkinnedMeshRenderer for animation, and it is currently not supported by dots.

    I have access to all the child PhysicsShape components inside my conversion script, how can I attach them to my Entity?

    Thanks.
     
  2. Plaximo

    Plaximo

    Joined:
    Oct 26, 2016
    Posts:
    8
    I found a solution.

    Basically you use a CompoundCollider to create the child colliders from the PhysicsShape components with the method CompoundCollider.Create(NativeArray<CompoundCollider.ColliderBlobInstance>)

    Code (CSharp):
    1.  
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Unity.Entities;
    5. using Unity.Transforms;
    6. using Unity.Physics;
    7. using Unity.Mathematics;
    8. using Unity.Physics.Authoring;
    9. using Unity.Collections;
    10.  
    11. ....
    12.  
    13. public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) {
    14.         ... My other components above
    15.  
    16.         // needed before manipulating PhysicsCollider
    17.         dstManager.AddComponent(entity, typeof(PhysicsCollider));
    18.         // Get all PhysicsShape components on the child GameObjects
    19.         PhysicsShapeAuthoring[] physicsShapeList = GetComponentsInChildren<PhysicsShapeAuthoring>();
    20.         int count = physicsShapeList.Length;
    21.         CompoundCollider.ColliderBlobInstance[] childColliderList = new CompoundCollider.ColliderBlobInstance[count];
    22.         for (int i = 0; i < count; i++) {
    23.             PhysicsShapeAuthoring physicsShape = physicsShapeList[i];
    24.             Quaternion colliderRotation = physicsShape.gameObject.transform.localRotation;
    25.             Vector3 colliderPosition = physicsShape.gameObject.transform.localPosition;
    26.             RigidTransform rigidTransform = new RigidTransform(colliderRotation, colliderPosition);
    27.             BoxGeometry boxGeometry = physicsShape.GetBoxProperties(); // I use only BoxColliders
    28.  
    29.             CompoundCollider.ColliderBlobInstance childCollider = new CompoundCollider.ColliderBlobInstance
    30.             {
    31.                 // This is the rotation and position of the collider
    32.                 CompoundFromChild = rigidTransform,
    33.                 // this is the shape of the collider
    34.                 Collider = Unity.Physics.BoxCollider.Create(boxGeometry)
    35.             };
    36.  
    37.             childColliderList[i] = childCollider;
    38.         }
    39.  
    40.         var childColliderNativeArray = new NativeArray<CompoundCollider.ColliderBlobInstance>(count, Allocator.Temp);
    41.         childColliderNativeArray.CopyFrom(childColliderList);
    42.         BlobAssetReference<Unity.Physics.Collider> collider = CompoundCollider.Create(childColliderNativeArray);
    43.         childColliderNativeArray.Dispose();
    44.  
    45.         var colliderComponent = new PhysicsCollider { Value = collider };
    46.         dstManager.SetComponentData(entity, colliderComponent);
    47.     }
    48.  
    49.  
    Next step would be how can I sync the colliders with the animations.