So I have a model I rigged with the “two bone IK” constraint, and I want to blend the weight value from 0 to 1 through a script i wrote. However, any modification of this value through script has not had any effect on the actual weight value. The only way I am able to change the weights of these components is through the inspector using the slider with my mouse. In fact I am not able to change any of the public setter values of the animation rigging package through scripts. Does anyone know how to modify these values? Thanks so much!
You have to access the data property of the constraint component. The data has all the properties you are looking for.
Hi @supersulu ,
For TwoBoneIKConstraint and any constraints implementing IRigConstraint
, you should be able to change your constraint weight by modifying TwoBoneIKConstraint.weight
.
Also, there are additional weights set in TwoBoneIKConstraintData (targetPositionWeight, targetRotationWeight and hintWeight) which you can retrieve like @danUnity_1 suggested in TwoBoneIKConstraint.data.
If this does not work, I would check the following:
- Are you animating your Rig? If so, make sure that your constraint weight is not animated if you intend to modify it through script.
- Make sure to modify the constraint weight in
Update
and notLateUpdate
. The latter will be done after animation has evaluated, and thus will not get picked up when evaluating constraint. - Make sure that targetPositionWeight and targetRotationWeight are not set to zero.
But it doesn’t do that @simonbz .
I’ve got a simple animation referencing the TwoBoneIKConstraint.Weight and it won’t budge. I’m sure I can script something to get a workaround going. Am I missing something? Seems like a bug?
EDIT:
the workaround is making a script that ref’s the constraint’s weight, changes its weight at runtime. Then animate the script’s weight property. Weird!
I’m also having trouble with this. I tried directly setting weights through script, and also through animations as mentioned above, but neither worked for me. The only thing that works is manually changing the weight via inspector within the editor at runtime.
Spent hours trying to debug this. It seems like something is resetting the weight right after I set it. I confirmed my weight change is persisted immediately after my code executes (e.g., following
leftHandIKRig.GetComponent().weight = 0;). However, somewhere between my code execution and the next frame update, the weight gets reset back to what it was before. I tried putting a breakpoint on the setter method in Rig.cs but nothing other than my script is invoking it. Is there any other way to reset that value? Would be nice to have a data breakpoint work with Unity (Something like Breakpoints | JetBrains Rider Documentation; if there’s a way to make this work please let me know).
Would appreciate any help resolving this issue.
Unity Version: 2020.19f1
Animation Rigging - 0.3.4 preview
I’ve upgraded from 2019.4.1f1 LTS recently if that makes any difference. Also on Burst 1.2.0-preview.12 if that matters; I didn’t upgrade to 1.3.9 yet as I’m seeing some warning that upgrading may break existing stuff.
EDIT: I managed to make it work by attaching a custom script directly to the Rig gameobject with a function that can change its weight, then invoking this function from my original external scope. Not sure why this works while manipulating the weight from an external scope doesn’t.
So:
Some External GameObject → ReferenceToRigGameObject.RigComponent.weight = newValue; => Doesn’t work.
Some External GameObject → ReferenceToRigGameObject.CustomRigWeightChangeScript.ChangeWeight(newValue); → this.gameObject.GetComponenet().weight = newValue; => works.
What am I missing here? Bug or my misunderstanding?
Can you submit a bug report using the Unity bug reporter for that? I’m not sure what doesn’t work for your use case, and we haven’t been able to reproduce a similar issue on our side.
Be it a bug or not, having a repro case will allow us to better answer you.
me too, multi aim constraint work with generic avatar but with humanoid it make my character fly away
and the two bone constraint ik does not work with both humanoid and generic avatar
I have a multi Parent Constraint rig I’m trying to change the weight of the sourceObject via script but it doesn’t allow me to change it, via animation I can
I’ve been facing the same problem.
Saving the target weight value and applying it on every Update() worked for me.
I have a Multi Aim Constraint and I’m adjusting the weight on the parent Rig script.
Hi, in order to change the weights of a WeightedTransformArray, you need to do the following:
var sources = parentConstraint.data.sourceObjects;
sources.SetWeight(0, x);
sources.SetWeight(1, y);
aimConstraint.data.sourceObjects = sources;
WeightedTransformArray is a struct. As such, calling sourceObjects will only retrieve a copy of the array. It needs to be set back in order for the weights to update.
How would you define the source object of a multi-aim constraint with c# please?
Similarly to how you set weights:
var sources = parentConstraint.data.sourceObjects;
sources.SetTransform(0, transform1);
sources.SetTransform(1, transform2);
aimConstraint.data.sourceObjects = sources;
However, be aware that this will not be applied at runtime. sourceObjects in MultiAim are used to build the constraint job. Modifying these transforms afterwards will not update the job.
Instead, consider building your constraint ahead of time and use weights to switch from transforms to transforms.
Thanks for getting back to me!
I had what I wanted working while setting it up, as the character being rigged and the target object were present in the scene at the time and dragging the source object from the hierarchy to the inspector was enough. Now, the character being rigged is instantiated and loses the references.
Your answer sounds like it’s not possible to instantiate and then assign.
I also tried adding a dummy object to the character, then on instantiate, have it reparent itself to the object I wanted as the source. That didn’t work either.
what is “aimConstraint” in your answer?
I had this before…
void Start()
{
player = GameObject.FindGameObjectWithTag("Player");
playerTarget = player.transform.Find("Root/Hips/Spine_01/Spine_02");
mac = GetComponent<MultiAimConstraint>();
var sources = mac.data.sourceObjects;
sources.SetTransform(0, playerTarget);
}
I see…adding mac.data.sourceObjects = sources;
at the end assigns the sources.
But this still won’t make the character aim at the player, right?
This has really knackered me for respawning! I can’t have the player as an instantiated prefab (either from scene or assets) on respawn, or else the ai loses reference of what to aim at. Disabling the player on death, moving to spawnpoint and re-enabling messes up the animation rigging positions and disabling the mesh renderers to move to spawn causes him to have seizures. I’m at a loss as to what to try next.
I’m experiencing the same issue where setting the Rig’s weight does not stick between updates. In my case, I am using a StateMachineBehaviour that sets the weight in the OnStateUpdate method.
I answered a similar question about Rig weights not so long ago:
https://discussions.unity.com/t/802978/8
Changing the rig weight in a StateMachineBehaviour is past the sync point where we read the scene value in the animation stream for Animation Rigging.
Like I’ve said, modified transform references in the aim constraint will not get picked up at runtime. At initialization, the Animation Rigging graph is built with the source transforms you’ve defined on the constraint and will not update automatically even if you change them.
Changing the constraint sources means you need to rebuild your animation rigging graph to account for these changes. Have a look at this response I gave on the subject not long ago:
https://discussions.unity.com/t/800894/3
This is old but I was having this problem recently as well, what ended up working for me, was either setting the weight constantly in an update method, or moving the weight changes to a Coroutine, and calling WaitForEndOframe() before setting the weights
private void DoStuff()
{
StartCoroutine(TransitionAnimationRigs());
}
private IEnumerator TransitionAnimationRigs()
{
yield return new WaitForEndOfFrame();
_weaponIdleRig.weight = 0;
}
Edit:
That turned out to be somewhat inconsistent when done for many characters, I did end up having to use update, but not constantly, I just primed the rigs to transition by setting a bool _haveRigsTransitioned to false, and calling Update to check:
{
TransitionRigs();
_haveRigsTransitioned = true;
}```
**so it only runs once, tested it for dozens of characters at the same time, and it seems good.**
Same issue for me:
namespace Animations
{
using UnityEngine;
using UnityEngine.Animations.Rigging;
public class AnimationEventsController : MonoBehaviour
{
private RightHandIkController _rightHandIk;
private WeaponPoseController _weaponPose;
private RigBuilder _rigBuilder;
void Start()
{
_rightHandIk = GetComponentInChildren<RightHandIkController>();
_weaponPose = GetComponentInChildren<WeaponPoseController>();
// _rigBuilder = GetComponent<RigBuilder>();
}
// animation event
void ThrowGrenade(float value)
{
_weaponPose.SetWeight(value);
_rightHandIk.SetWeight(value);
// _rigBuilder.Build(); works only after full rebuild
}
}
}
// RightHandIkController
public void SetWeight(float value)
{
_twoBoneIKConstrint.weight = value;
}
// WeaponPoseController
public void SetWeight(float value)
{
_multiPositionConstraint.weight = value;
}
How is it possible to avoid rebuild RigBuilder?
Animation rigging 1.0.3
Unity - 2020.3.16f1