Search Unity

Resolved AnimationJobBinder Update not updating job values.

Discussion in 'Animation Rigging' started by Ragueel, Apr 16, 2021.

  1. Ragueel

    Ragueel

    Joined:
    Jun 2, 2018
    Posts:
    39
    So I created my `AnimationJobBinder`, and I do some calculations in the update function and update the job's value.

    I have a job like this:
    Code (CSharp):
    1. public struct SampleJob : IWeightedAnimationJob
    2. {
    3.     public Vector3 somePos;
    4.  
    5.     public void ProcessAnimation(AnimationStream stream)
    6.     {
    7.         // Fancy stuff with somePos
    8.     }
    9.  
    10.     public void ProcessRootMotion(AnimationStream stream)
    11.     {
    12.     }
    13.  
    14.     public FloatProperty jobWeight { get; set; }
    15. }

    And AnimationJobBinder like this:
    Code (CSharp):
    1.  
    2.     public class SampleJobBinder : AnimationJobBinder<SampleJob, SampleData>
    3.     {
    4.         public override SampleJob Create(Animator animator, ref SampleData data, Component component)
    5.         {
    6.             // Some init
    7.             return new SampleJob
    8.             {
    9.                 somePos = Vector3.zero
    10.             };
    11.         }
    12.  
    13.         public override void Update(SampleJob job, ref SampleData data)
    14.         {
    15.             job.somePos = Vector3.one * Random.Range(-6f, 6f);
    16.         }
    17.  
    18.         public override void Destroy(SampleJob job)
    19.         {
    20.         }
    21.     }
    22.  
    Whenever I run this job's value is always zero. This means that `somePos` is always equal to the initial value. How can I update it in runtime?
     
  2. simonbz

    simonbz

    Unity Technologies

    Joined:
    Sep 28, 2015
    Posts:
    295
    Hi,

    The `Update` function in `AnimationJobBinder` is called with a copy of your job (all C# job containers are structs). Therefore, changing `somePos` in this instance will only modify the copy and not the job evaluated in the PlayableGraph.

    To change this value, you would need to register it in a NativeArray a little bit like so:

    Code (CSharp):
    1. public struct SampleJob : IWeightedAnimationJob
    2. {
    3.     public NativeArray<Vector3> somePos;
    4.     public void ProcessAnimation(AnimationStream stream)
    5.     {
    6.         // Fancy stuff with somePos[0]
    7.     }
    8.     public void ProcessRootMotion(AnimationStream stream)
    9.     {
    10.     }
    11.     public FloatProperty jobWeight { get; set; }
    12. }
    Code (CSharp):
    1.     public class SampleJobBinder : AnimationJobBinder<SampleJob, SampleData>
    2.     {
    3.         public override SampleJob Create(Animator animator, ref SampleData data, Component component)
    4.         {
    5.             // Some init
    6.             return new SampleJob
    7.             {
    8.                 somePos = new NativeArray<Vector3>(new Vector3[] {Vector3.zero}, Allocator.Persistent);
    9.             };
    10.         }
    11.         public override void Update(SampleJob job, ref SampleData data)
    12.         {
    13.             job.somePos[0] = Vector3.one * Random.Range(-6f, 6f);
    14.         }
    15.         public override void Destroy(SampleJob job)
    16.         {
    17.         }
    18.     }
     
    Ragueel likes this.
  3. tonycoculuzzi

    tonycoculuzzi

    Joined:
    Jun 2, 2011
    Posts:
    301
    Is there a better way to do this, besides using NativeArray? NativeArray isn't very readable. Shouldn't FloatProperty and similar work the same way?