Follow Transform Job lags behind.

Hello, I’ve just started with Job system.
I have a parallel transform job that simply make an object follow another object on certain distance.

[BurstCompile]
public struct FollowAtDistanceParallelTransformJob : IJobParallelForTransform
{
   public NativeArray<FollowAtDistanceData> FollowAtDistanceData;

   public void Execute(int index, TransformAccess transform)
   {
       float2 transformPosition2D = FollowAtDistanceData[index].Position.xz;
       float2 targetPosition2D = FollowAtDistanceData[index].TargetPosition.xz;

       float followDistance = FollowAtDistanceData[index].Distance;

       float distanceToTarget = math.distance(transformPosition2D, targetPosition2D);
       bool isTooFar = distanceToTarget > followDistance;

       if (isTooFar)
       {
           float3 direction = new float3(
               targetPosition2D.x,
               0,
               targetPosition2D.y
               );

           float3 pos = Float2Extensions.MoveTowards(
               transformPosition2D,
               targetPosition2D,
               distanceToTarget - followDistance
               ).ToX0Y();

           transform.position = pos;
           transform.rotation.SetLookRotation(direction);
       }
   }
}

Helper

    public static class Float2Extensions
    {
        public static float3 ToX0Y(this float2 v)
        {
            return new float3(v.x, 0, v.y);
        }

        public static float2 MoveTowards(float2 current, float2 target, float maxDistanceDelta)
        {
            return current + MoveTowardsDelta(current, target, maxDistanceDelta);
        }

        public static float2 MoveTowardsDelta(float2 current, float2 target, float maxDistanceDelta)
        {
            float2 toVector = target - current;

            float sqDist =
                toVector.x * toVector.x +
                toVector.y * toVector.y;

            if (sqDist == 0 || maxDistanceDelta >= 0 && sqDist <= maxDistanceDelta * maxDistanceDelta)
                return target;

            float dist = math.sqrt(sqDist);

            return new float2(
                toVector.x / dist * maxDistanceDelta,
                toVector.y / dist * maxDistanceDelta
                );
        }
    }

But it seems like the followers lag behind every time the target moves, especially the 2nd and 3rd follower.
I am not sure what went wrong.
8754970--1186387--upload_2023-1-25_11-9-46.png
Any help would be great, thanks!

This code is actually a port from the ECS version. It seems to be working well in ECS without any lagging behind issues. So I am confused what went wrong.

[BurstCompile]
public partial struct FollowAtDistanceJob : IJobEntity
{
    public TransformAspect.Lookup AllTransform;
    public EntityStorageInfoLookup EntityStorageInfoLookup;

    void Execute(Entity e, in FollowAtDistanceData followTarget)
    {
        bool hasNoTarget = !EntityStorageInfoLookup.Exists(followTarget.Target);
       
        if (hasNoTarget)
        {
            return;
        }

        TransformAspect transform = AllTransform[e];
        TransformAspect targetTransform = AllTransform[followTarget.Target];

        float3 targetPosition = targetTransform.Position;

        float2 transformPosition2D = transform.Position.xz;
        float2 targetPosition2D = targetPosition.xz;
       
        float distanceToTarget = math.distance(transformPosition2D, targetPosition2D);
        bool isTooFar = distanceToTarget > followTarget.Distance;

        if (isTooFar)
        {
            float3 direction = new float3(
                targetPosition2D.x,
                0,
                targetPosition2D.y
                );

            float3 delta = Float2Extensions.MoveTowardsDelta(
                transformPosition2D,
                targetPosition2D,
                distanceToTarget - followTarget.Distance
                ).ToX0Y();

            transform.TranslateWorld(delta);
            transform.LookAt(direction);
        }
    }
}

I thought it might be an order of operation bug. So I tried using IJobFor instead of IJobParallelForTransform.
Still encountering the same issue.

[BurstCompile]
public struct FollowAtDistanceJob : IJobFor
{
    public NativeArray<FollowAtDistanceData> FollowAtDistanceData;
    public NativeArray<FollowAtDistanceOutput> FollowAtDistanceOutput;

    public void Execute(int index)
    {
        float2 transformPosition2D = FollowAtDistanceData[index].Position.xz;
        float2 targetPosition2D = FollowAtDistanceData[index].TargetPosition.xz;

        float followDistance = FollowAtDistanceData[index].Distance;

        float distanceToTarget = math.distance(transformPosition2D, targetPosition2D);
        bool isTooFar = distanceToTarget > followDistance;

        float3 position = FollowAtDistanceData[index].Position;
        float3 direction = new float3(
            targetPosition2D.x,
            0,
            targetPosition2D.y
            );

        if (isTooFar)
        {
            position = Float2Extensions.MoveTowards(
                transformPosition2D,
                targetPosition2D,
                distanceToTarget - followDistance
                ).ToX0Y();
        }

        FollowAtDistanceOutput[index] = new FollowAtDistanceOutput
        {
            Position = position,
            Direction = direction
        };
    }
}

Need help!

If your ECS version works and the Job one doesn’t, maybe the problem is not in the job itself, but rather in how you are scheduling it. Maybe the input data is not being updated correctly into newly scheduled jobs or something.

I’ve decided not to use job for this specific case since I am in a deadline, and have not pursued it further since then since its working fine without any performance issues. I’ll re-investigate when I will need to come back to it.

Thanks for the reply!

1 Like