I’m trying to move my character controller into ECS and everything is setup correctly, but I cannot figure out how to move the RayCast logic into ECS. Here’s my current approach, but it throws an error since I cannot call Schedule from inside a job.
[BurstCompile]
public struct MovementJob : IJobForEach<PhysicsMass, PhysicsVelocity, LocalToWorld, Translation, Movement, CharacterData>
{
[BurstCompile]
public void Execute(ref PhysicsMass mass, ref PhysicsVelocity vel, ref LocalToWorld localToWorld, ref Translation translation, [ReadOnly] ref Movement movement, [ReadOnly] ref CharacterData characterData)
{
...
using (NativeArray<RaycastHit> results = new NativeArray<RaycastHit>(1, Allocator.Temp))
{
NativeArray<SpherecastCommand> commands = new NativeArray<SpherecastCommand>(1, Allocator.Temp)
{
[0] = new SpherecastCommand(translation.Value, characterData.groundingRadius, -localToWorld.Up)
};
// Schedule the batch of sphere casts
JobHandle handle = SpherecastCommand.ScheduleBatch(commands, results, 1, default(JobHandle));
// Wait for the batch processing job to complete
handle.Complete();
// Copy the result. If batchedHit.collider is null, there was no hit
RaycastHit batchedHit = results[0];
if (batchedHit.collider != null)
{
//Logic goes here
}
// Dispose the buffers
commands.Dispose();
}
...
}
}
The only examples I’ve seen for RaycastCommand is using it’s own job and from the System passing all the positions and data it requires. Is there any way to use this with a IJobForEach?
[BurstCompile]
unsafe bool SphereCast(float3 from, float3 to, float radius, out ColliderCastHit hit)
{
CollisionFilter collisionFilter = new CollisionFilter()
{
BelongsTo = (1<<11), //Character
CollidesWith = ~(uint)(1<<11), //All but character
GroupIndex = 0
}
SphereGeometry sphereGeometry = new SphereGeometry() { Center = float3.zero, Radius = radius };
BlobAssetReference<Unity.Physics.Collider> sphereCollider = Unity.Physics.SphereCollider.Create(sphereGeometry, collisionFilter);
ColliderCastInput input = new ColliderCastInput()
{
Collider = (Unity.Physics.Collider*)sphereCollider.GetUnsafePtr(),
Orientation = quaternion.identity,
Start = from,
End = to
};
return collisionWorld.CastCollider(input, out hit);
}
[BurstCompile]
bool RayCast(float3 from, float3 to, out Unity.Physics.RaycastHit hit)
{
CollisionFilter collisionFilter = new CollisionFilter()
{
BelongsTo = (1<<11), //Character
CollidesWith = ~(uint)(1<<11), //All but character
GroupIndex = 0
}
RaycastInput input = new RaycastInput()
{
Start = from,
End = to,
Filter = collisionFilter
};
return collisionWorld.CastRay(input, out hit);
}
This when checking if grounded wouldn’t work with ray cast, but it works with sphere cast. Using the exact same from and to values. If I change the mask to use CollidesWith = ~0u, like on the link, then it detects collision with the character. Am I missing something?
Hello, You use the same from and to values but in one case, you use a ray, in the other you used a sphere. I think you have to take into consideration the sphere radius. your sphere may be hitting something because of it’s radius (schematicly, the center of the sphere did not hit anything but it’s surface did).
Even thought that would make sense, I’ve tested it with a massive distance and still returns nothing. I just gave up on the idea of using the RayCast since I never found any way to make it work.