Converting a prefab with collider then instantiating it at runtime with Unity.Physics

For prefabs in a scene we can add the ConvertToEntity and PhysicsShapeAuthoring components to convert a static mesh with collider to an entity with a physicscollider. However, if I’m converting a prefab in code then instantiating entities at runtime, how do I convert the collider to a physicscollider?
Here is what I’m currently doing (without Unity.Physics) - this all works fine.

Entity prefabEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(prefabs[i].gameObject, conversionSettings);

..
EntityArchetype entityArcheType = world.EntityManager.CreateArchetype(archetypeComponentTypeArray);

..
world.GetOrCreateSystem<MySystem>();

// create x entities from prefab in a loop
..
Entity entity = entityManager.Instantiate(prefabEntity);

// Add components
..

// SetComponentData
..

I’m aware of PhysicsShapeAuthoring component but that seems to require a ConvertToEntity component which doesn’t seem to fit my scenario. I “could” create a new PhysicsCollider and add it as a component but what I really want is to convert the existing collider to a PhysicsCollider.

This should all work as is. You don’t need PhysicsShapeAuthoring components on your GameObjects. If you had a GameObject with a Collider and a RigidBody component, adding the ConvertToEntity component in a scene would still result in a Entity with a PhysicsCollider etc.
This is all handled by the BaseLegacyColliderConversionSystem which converts the GameObject based Colliders to PhysicsColliders and should get called as part of the call to ConvertGameObjectHierarchy.

Are you seeing converted GOs without PhysicsColliders being added?

Without Unity.Physics installed I can say instantiate 5000 prefabs using ConvertGameObjectHierarchy etc. When I install Unity.Physics 0.2.4 I get 1 visible entity and the rest don’t render. They do appear in the Entity Debugger. On closer observation, they do have a PhysicsCollider component however the Entity Debugger throws hundreds of errors as I click on the entities.

InvalidCastException: Specified cast is not valid.
Unity.Properties.Reflection.ReflectedMemberProperty`2[TContainer,TValue].GetValue (TContainer& container) (at Library/PackageCache/com.unity.properties@0.6.2-preview/Runtime/Unity.Properties/Reflection/Properties/ReflectedMemberProperty.cs:24)
Unity.Properties.PropertyVisitor.VisitProperty[TProperty,TContainer,TValue] (TProperty property, TContainer& container, Unity.Properties.ChangeTracker& changeTracker) (at Library/PackageCache/com.unity.properties@0.6.2-preview/Runtime/Unity.Properties/PropertyVisitor.cs:54)
Unity.Properties.Reflection.ReflectedPropertyBag`1+PropertyProxy`2[TContainer,TProperty,TValue].Accept[TVisitor] (TContainer& container, TVisitor visitor, Unity.Properties.ChangeTracker& changeTracker) (at Library/PackageCache/com.unity.properties@0.6.2-preview/Runtime/Unity.Properties/Reflection/ReflectedPropertyBag.cs:19)
Unity.Properties.Reflection.ReflectedPropertyBag`1[TContainer].Accept[TVisitor] (TContainer& container, TVisitor visitor, Unity.Properties.ChangeTracker& changeTracker) (at Library/PackageCache/com.unity.properties@0.6.2-preview/Runtime/Unity.Properties/Reflection/ReflectedPropertyBag.cs:58)
Unity.Properties.PropertyContainer.Visit[TContainer,TVisitor] (TContainer& container, TVisitor visitor, Unity.Properties.ChangeTracker& changeTracker) (at Library/PackageCache/com.unity.properties@0.6.2-preview/Runtime/Unity.Properties/PropertyContainerVisit.cs:29)
Unity.Properties.PropertyVisitor.TryVisitContainerWithAdapters[TProperty,TContainer,TValue] (TProperty property, TContainer& container, TValue& value, Unity.Properties.ChangeTracker& changeTracker) (at Library/PackageCache/com.unity.properties@0.6.2-preview/Runtime/Unity.Properties/PropertyVisitor.cs:127)

Is there a way to reproduce what you are seeing that I could look at? For example, can you replicate your problem in the UnityPhysicsSamples project? (https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/UnityPhysicsSamples)

I couldn’t find a phyiscs sample that uses GameObjectConversionUtility.ConvertGameObjectHierarchy. However, I did notice two things of interest.

On U2019.2.0f1 with Entities 0.2.0 and Unity.Physics 0.2.4 I do get PhysicsCollider components (however only the first entity is rendered in scene).

On U2019.3.0f1 with Entities 0.3.0 and Unity.Physics 0.2.5 I do NOT get PhysicsCollider components (only 1 entity renders in scene).

However, I now get some additional info (seems like the newer version have better error information).

ArgumentNullException: A valid BlobAssetStore must be passed to construct a BlobAssetComputationContext
Parameter name: blobAssetStore
Unity.Entities.BlobAssetComputationContext`2[TS,TB]..ctor (Unity.Entities.BlobAssetStore blobAssetStore, System.Int32 initialCapacity, Unity.Collections.Allocator allocator) (at Library/PackageCache/com.unity.entities@0.3.0-preview.4/Unity.Entities.Hybrid/GameObjectConversion/BlobAssetComputationContext.cs:31)
Unity.Physics.Authoring.BeginColliderConversionSystem.OnUpdate () (at Library/PackageCache/com.unity.physics@0.2.5-preview/Unity.Physics.Hybrid/Conversion/BeginColliderConversionSystem.cs:14)
Unity.Entities.ComponentSystem.InternalUpdate () (at Library/PackageCache/com.unity.entities@0.3.0-preview.4/Unity.Entities/ComponentSystem.cs:102)
Unity.Entities.ComponentSystemBase.Update () (at Library/PackageCache/com.unity.entities@0.3.0-preview.4/Unity.Entities/ComponentSystemBase.cs:301)
Unity.Entities.ComponentSystemGroup.OnUpdate () (at Library/PackageCache/com.unity.entities@0.3.0-preview.4/Unity.Entities/ComponentSystemGroup.cs:109)
UnityEngine.DebugLogHandler:LogException(Exception, Object)
Unity.Entities.Conversion.JournalingUnityLogger:LogException(Exception, Object) (at Library/PackageCache/com.unity.entities@0.3.0-preview.4/Unity.Entities.Hybrid/GameObjectConversion/JournalingUnityLogger.cs:50)
UnityEngine.Debug:LogException(Exception)
Unity.Debug:LogException(Exception) (at Library/PackageCache/com.unity.entities@0.3.0-preview.4/Unity.Entities/Stubs/Unity/Debug.cs:19)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.3.0-preview.4/Unity.Entities/ComponentSystemGroup.cs:113)
Unity.Entities.ComponentSystem:InternalUpdate() (at Library/PackageCache/com.unity.entities@0.3.0-preview.4/Unity.Entities/ComponentSystem.cs:102)
Unity.Entities.ComponentSystemBase:Update() (at Library/PackageCache/com.unity.entities@0.3.0-preview.4/Unity.Entities/ComponentSystemBase.cs:301)
Unity.Entities.GameObjectConversionUtility:Convert(World) (at Library/PackageCache/com.unity.entities@0.3.0-preview.4/Unity.Entities.Hybrid/GameObjectConversion/GameObjectConversionUtility.cs:147)
Unity.Entities.GameObjectConversionUtility:ConvertGameObjectHierarchy(GameObject, GameObjectConversionSettings) (at Library/PackageCache/com.unity.entities@0.3.0-preview.4/Unity.Entities.Hybrid/GameObjectConversion/GameObjectConversionUtility.cs:229)

5247836--524135--phycol1_u201920_entities020_phy024.png 5247836--524138--phycol2_u201930_entities030_phy025.png

I have resolved the errors messages with the following:

// In my monobehaviour

private BlobAssetStore blobAssetStore;

private void ConvertPrefabs()
{
  ..
  blobAssetStore = new BlobAssetStore();
  GameObjectConversionSettings conversionSettings = GameObjectConversionSettings.FromWorld(world, blobAssetStore);
  ..
  // more here..
}

private void OnDestroy()
{
  // Dispose of the BlobAssetStore, else we're get a message:
  // A Native Collection has not been disposed, resulting in a memory leak.
  if (blobAssetStore != null) { blobAssetStore.Dispose(); }
}

I’m not sure if OnDestroy() is the correct place to dispose of the blobAssetStore but seems to work.

The only way I could get the prefabs to render with Unity.Physics 0.2.5 installed was to add another collider to the parent gameobject of the prefabs.

How can I get this to work with colliders in the children but not the parent? Without Unity.Physics installed it works fine (howbeit without PhysicsCollider components).

4 Likes

Update – Looks like NetCode is waiting for the Entities patch, as related in this thread

I’m not using ConvertGameObjectHierarchy but I’m seeing this same issue – for me I’ve actually removed both the Unity Physics collider from the prefab in (it’s converted automatically using the Ghost generation code from the multiplayer package). I also had an old school collider on a child plane GO that was being converted in the scene by a parent ConvertToClientServerEntity component – however I removed this too and am still getting the “ArgumentNullException: A valid BlobAssetStore must be passed to construct a BlobAssetComputationContext” – even upon restarting my editor. Seems there’s just something wrong here.

Thank you for this!
I was struggling with that memory leak, I’m not familiar with BlobAssetStore and only now getting to know it!

2 Likes