- Home /
PhysicsCollider not moving when setting Translation component [DOTS Physics]
I have a list of points and I want to Collider.CalculateDistance(PointDistanceInput)
on them. However, before that, I want to move the collider to a new position. Everything works fine but the problem is that the collider stays at the origin and not moving. Even the entity itself moves and its RenderMesh follows it to the new position. Any help is really appreciated. I've been trying to solve this issue for two days, but no luck!
protected override void OnUpdate()
{
Entity _meshColliderEntity = GetSingletonEntity<MeshColliderEntity_tag>();
if (_someCondition)
{
foreach (float3 position in _positions)
{
EntityManager.SetComponentData(_meshColliderEntity, new Translation { Value = position });
PhysicsCollider meshCollider = GetComponent<PhysicsCollider>(_meshColliderEntity);
foreach (float3 point in _points)
{
var pointDistanceInput = new PointDistanceInput
{
Position = point,
MaxDistance = 0.001f,
Filter = new CollisionFilter()
{
BelongsTo = 1u << 3,
CollidesWith = 1u << 2,
GroupIndex = 0
}
};
if (meshCollider.Value.Value.CalculateDistance(pointDistanceInput, out DistanceHit hit))
Debug.Log(hit.Position);
}
}
}
}
Answer by andrew-lukasik · Sep 12, 2021 at 04:09 PM
PhysicsCollider
will move once BuildPhysicsWorld
runs again. Your code doesn't work because PhysicsCollider
component has no access to this Translation
value you're changing here.
Also, you don't need to change positions to test that.
using Unity.Entities;
using Unity.Mathematics;
using Unity.Collections;
using Unity.Transforms;
using Unity.Physics;
[UpdateInGroup( typeof(FixedStepSimulationSystemGroup) )]
public class TestSystem : SystemBase
{
NativeArray<float3> _positions, _points;
protected override void OnCreate ()
{
_positions = new NativeArray<float3>( new float3[]{ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } , Allocator.Persistent );
_points = new NativeArray<float3>( new float3[]{ 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 } , Allocator.Persistent );
}
protected override void OnDestroy ()
{
if( _positions.IsCreated ) _positions.Dispose();
if( _points.IsCreated ) _points.Dispose();
}
protected override unsafe void OnUpdate ()
{
var positions = _positions;
var points = _points;
Entities
.WithReadOnly( positions ).WithNativeDisableParallelForRestriction( positions )
.WithReadOnly( points ).WithNativeDisableParallelForRestriction( points )
.WithAll<MyTag>()
.ForEach( ( in PhysicsCollider collider , in LocalToWorld transform ) =>
{
float3 transformPosition = transform.Position;
var colliderInfo = collider.Value.Value;
foreach( float3 p0 in positions )
foreach( float3 p1 in points )
{
float3 testPoint = transformPosition + ( p1 - p0 );
var pointDistanceInput = new PointDistanceInput{
Position = testPoint ,
MaxDistance = 0 ,
Filter = CollisionFilter.Default
};
if( colliderInfo.CalculateDistance(pointDistanceInput,out var hit) )
UnityEngine.Debug.Log("HIT");
else
UnityEngine.Debug.Log("MISS");
}
} )
.WithBurst()
.ScheduleParallel();
}
}
Thanks for your reply. Where in your code, you're moving the collider to a new position?
I barely know dots physics but from I can figure out you don't need to move a collider to do these tests at all. Collider position can be a temporary origin point too.
foreach( float3 p0 in positions )
foreach( float3 p1 in points )
float3 testPoint = transformPosition + ( p1 - p0 );
Oh, wait! I think I know what you mean. You're actually changing the point's position relative to the collider's position. I'll give it a try. Thanks.
Also, if you can convert those points into an AABB
then it will be much faster to calculate a distance between 2 bounds (backup link). As an early eli$$anonymous$$ation mechanism if nothing else.
Those points can't be AABB. They are individual points.