Search Unity

Question Follow Transform Job lags behind.

Discussion in 'C# Job System' started by Gekigengar, Jan 25, 2023.

  1. Gekigengar

    Gekigengar

    Joined:
    Jan 20, 2013
    Posts:
    738
    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.
    Code (CSharp):
    1. [BurstCompile]
    2. public struct FollowAtDistanceParallelTransformJob : IJobParallelForTransform
    3. {
    4.    public NativeArray<FollowAtDistanceData> FollowAtDistanceData;
    5.  
    6.    public void Execute(int index, TransformAccess transform)
    7.    {
    8.        float2 transformPosition2D = FollowAtDistanceData[index].Position.xz;
    9.        float2 targetPosition2D = FollowAtDistanceData[index].TargetPosition.xz;
    10.  
    11.        float followDistance = FollowAtDistanceData[index].Distance;
    12.  
    13.        float distanceToTarget = math.distance(transformPosition2D, targetPosition2D);
    14.        bool isTooFar = distanceToTarget > followDistance;
    15.  
    16.        if (isTooFar)
    17.        {
    18.            float3 direction = new float3(
    19.                targetPosition2D.x,
    20.                0,
    21.                targetPosition2D.y
    22.                );
    23.  
    24.            float3 pos = Float2Extensions.MoveTowards(
    25.                transformPosition2D,
    26.                targetPosition2D,
    27.                distanceToTarget - followDistance
    28.                ).ToX0Y();
    29.  
    30.            transform.position = pos;
    31.            transform.rotation.SetLookRotation(direction);
    32.        }
    33.    }
    34. }
    Code (CSharp):
    1.     public static class Float2Extensions
    2.     {
    3.         public static float3 ToX0Y(this float2 v)
    4.         {
    5.             return new float3(v.x, 0, v.y);
    6.         }
    7.  
    8.         public static float2 MoveTowards(float2 current, float2 target, float maxDistanceDelta)
    9.         {
    10.             return current + MoveTowardsDelta(current, target, maxDistanceDelta);
    11.         }
    12.  
    13.         public static float2 MoveTowardsDelta(float2 current, float2 target, float maxDistanceDelta)
    14.         {
    15.             float2 toVector = target - current;
    16.  
    17.             float sqDist =
    18.                 toVector.x * toVector.x +
    19.                 toVector.y * toVector.y;
    20.  
    21.             if (sqDist == 0 || maxDistanceDelta >= 0 && sqDist <= maxDistanceDelta * maxDistanceDelta)
    22.                 return target;
    23.  
    24.             float dist = math.sqrt(sqDist);
    25.  
    26.             return new float2(
    27.                 toVector.x / dist * maxDistanceDelta,
    28.                 toVector.y / dist * maxDistanceDelta
    29.                 );
    30.         }
    31.     }
    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.
    upload_2023-1-25_11-9-46.png
    Any help would be great, thanks!
     
    Last edited: Jan 25, 2023
  2. Gekigengar

    Gekigengar

    Joined:
    Jan 20, 2013
    Posts:
    738
    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.
    Code (CSharp):
    1. [BurstCompile]
    2. public partial struct FollowAtDistanceJob : IJobEntity
    3. {
    4.     public TransformAspect.Lookup AllTransform;
    5.     public EntityStorageInfoLookup EntityStorageInfoLookup;
    6.  
    7.     void Execute(Entity e, in FollowAtDistanceData followTarget)
    8.     {
    9.         bool hasNoTarget = !EntityStorageInfoLookup.Exists(followTarget.Target);
    10.        
    11.         if (hasNoTarget)
    12.         {
    13.             return;
    14.         }
    15.  
    16.         TransformAspect transform = AllTransform[e];
    17.         TransformAspect targetTransform = AllTransform[followTarget.Target];
    18.  
    19.         float3 targetPosition = targetTransform.Position;
    20.  
    21.         float2 transformPosition2D = transform.Position.xz;
    22.         float2 targetPosition2D = targetPosition.xz;
    23.        
    24.         float distanceToTarget = math.distance(transformPosition2D, targetPosition2D);
    25.         bool isTooFar = distanceToTarget > followTarget.Distance;
    26.  
    27.         if (isTooFar)
    28.         {
    29.             float3 direction = new float3(
    30.                 targetPosition2D.x,
    31.                 0,
    32.                 targetPosition2D.y
    33.                 );
    34.  
    35.             float3 delta = Float2Extensions.MoveTowardsDelta(
    36.                 transformPosition2D,
    37.                 targetPosition2D,
    38.                 distanceToTarget - followTarget.Distance
    39.                 ).ToX0Y();
    40.  
    41.             transform.TranslateWorld(delta);
    42.             transform.LookAt(direction);
    43.         }
    44.     }
    45. }
     
  3. Gekigengar

    Gekigengar

    Joined:
    Jan 20, 2013
    Posts:
    738
    I thought it might be an order of operation bug. So I tried using IJobFor instead of IJobParallelForTransform.
    Still encountering the same issue.
    Code (CSharp):
    1. [BurstCompile]
    2. public struct FollowAtDistanceJob : IJobFor
    3. {
    4.     public NativeArray<FollowAtDistanceData> FollowAtDistanceData;
    5.     public NativeArray<FollowAtDistanceOutput> FollowAtDistanceOutput;
    6.  
    7.     public void Execute(int index)
    8.     {
    9.         float2 transformPosition2D = FollowAtDistanceData[index].Position.xz;
    10.         float2 targetPosition2D = FollowAtDistanceData[index].TargetPosition.xz;
    11.  
    12.         float followDistance = FollowAtDistanceData[index].Distance;
    13.  
    14.         float distanceToTarget = math.distance(transformPosition2D, targetPosition2D);
    15.         bool isTooFar = distanceToTarget > followDistance;
    16.  
    17.         float3 position = FollowAtDistanceData[index].Position;
    18.         float3 direction = new float3(
    19.             targetPosition2D.x,
    20.             0,
    21.             targetPosition2D.y
    22.             );
    23.  
    24.         if (isTooFar)
    25.         {
    26.             position = Float2Extensions.MoveTowards(
    27.                 transformPosition2D,
    28.                 targetPosition2D,
    29.                 distanceToTarget - followDistance
    30.                 ).ToX0Y();
    31.         }
    32.  
    33.         FollowAtDistanceOutput[index] = new FollowAtDistanceOutput
    34.         {
    35.             Position = position,
    36.             Direction = direction
    37.         };
    38.     }
    39. }
    Need help!
     
  4. gilzoide

    gilzoide

    Joined:
    Oct 7, 2015
    Posts:
    30
    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.
     
  5. Gekigengar

    Gekigengar

    Joined:
    Jan 20, 2013
    Posts:
    738
    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!
     
    gilzoide likes this.