Search Unity

Question MultiAimConstraint - Changing Source Via Script?

Discussion in 'Animation Rigging' started by TragicallyCanadian, Jun 18, 2021.

  1. TragicallyCanadian

    TragicallyCanadian

    Joined:
    Mar 26, 2020
    Posts:
    39
    As the title suggestions, I am curious as to how one is able to change the source object of the Multi Aim Constraint via script? I can't seem to reference the source object via script. Am I missing something? Or is there some work around needed?

    Cheers!
     
  2. TragicallyCanadian

    TragicallyCanadian

    Joined:
    Mar 26, 2020
    Posts:
    39
  3. simonbz

    simonbz

    Unity Technologies

    Joined:
    Sep 28, 2015
    Posts:
    295
    Hi,

    When Animation Rigging builds its rig, it's creating a PlayableGraph with Animation C# Jobs that are evaluated by the Animator. However, a job does not refer to a transform directly, but will instead use transform handles (stream handles or scene handles) associated to transforms in the game object hierarchy. These will update when either animated, or modified by scripts, but changing a transform reference in a constraint will not update its handle counterpart.

    That is also the reason why constraint like MultiAimConstraint were built with multiple source objects in mind. By manipulating the weights, you can select which source object will drive your constraint and change from one transform to another.

    If you really need to instantiate a transform dynamically however, you'll need to rebuild the Animation Rigging graph for it to update with the new transform references. Something like this should work:

    Code (CSharp):
    1. var animator = GetComponent<Animator>();
    2. var rigBuilder = GetComponent<RigBuilder>();
    3.  
    4. animator.enabled = false;
    5. rigBuilder.Build();
    6. animator.enabled = true;
    7.  
     
  4. mrphilipjoel

    mrphilipjoel

    Joined:
    Jul 6, 2019
    Posts:
    61
    Thank you for the example on how to rebuild the graph.
    Can you give an example on how I could set the new transforms?
     
    hioctane likes this.
  5. MilitaryG

    MilitaryG

    Joined:
    Apr 26, 2021
    Posts:
    28
    this is how I was trying but failed:

    Code (CSharp):
    1.         multiAimConstraint = GetComponent<MultiAimConstraint>();
    2.         aimPoint = PlayerCamera.playerCamera.GetComponent<PlayerCamera>().aimPoint;
    3.  
    4.      
    5.         WeightedTransformArray sources = new WeightedTransformArray();
    6.         sources.Add(new WeightedTransform(aimPoint, 1f));
    7.         multiAimConstraint.data.sourceObjects = sources;
    8.  
    9.  
    10.         animator.enabled = false;
    11.         rigBuilder.Build();
    12.         animator.enabled = true;
    I ended making source aim point on whitch one I referenced through inspector

    and I'm making another object dinamically whitch finds that source aim point and changes position of the source aim point

    this work around works good for me
     
  6. kostiantynyeremenko

    kostiantynyeremenko

    Joined:
    Dec 8, 2022
    Posts:
    5
    I used a workaround. Instead of setting source transform in runtime i just moved existing source object in runtime:

    [SerializeField] private Transform _lookAtTarget;
    private void Update()
    {
    _lookAtTarget.position = Player.HeadTransform;
    }


    or just reparent it so not to use update:
    private void OnPlayerVisible()
    {
    _lookAtTarget.SetParent(Player.HeadTransform);
    }
     
  7. nishantoraon71

    nishantoraon71

    Joined:
    Dec 15, 2019
    Posts:
    1
    Code (CSharp):
    1.  
    2.         headWeightTransform = new WeightedTransform(targetIk,headLookWeight);
    3.      
    4.  
    5.  
    6.         WeightedTransformArray sources = new WeightedTransformArray();
    7.  
    8.         sources.Add(headWeightTransform);
    9.  
    10.         HeadMultiAimConstraint.data.sourceObjects = sources;
    11.  
    12.         anim.enabled = false;
    13.         rigBuilder.Build();
    14.         anim.enabled = true;
    15.        

    this will change your whole source Object array, whatever you add object in script will be there , make sure you don't Build the RigBuilder in every frame.. just a tip ;)