- Home /
How to activate parent constraint via API the same way as Activate button does?
I am trying to call the same function as Activate button of the Parent Constraint component but it seems there's no such method in the API:
Guess the code is hidden in the component's editor script. Was trying to achieve the same result using SetTranslationOffset and SetRotationOffset which looked pretty straight forward but ended up with objects jump a bit when the function is called:
var positionDelta = parentConstraint.transform.position - source.position;
var rotationDelta = Quaternion.Inverse(source.rotation) * parentConstraint.transform.rotation;
parentConstraint.SetTranslationOffset(0, positionDelta);
parentConstraint.SetRotationOffset(0, rotationDelta.eulerAngles);
If you look at the decompiled editor script, you can see that these buttons call
ActivateAndPreserveOffset (for the activate button)
ActivateWithZeroOffset (for the zero button)
Both of these methods belong to the internal interface IConstraintInternal which ParentConstraint implements.
But sinse IConstraintInternal is... internal. It is not accessible to us (Without using reflection atleast).
I don't post this as an answer, because I don't know what these methods do exactly, and someone else might still know a way to do the same thing by using the methods/properties that are available to you.
Answer by Volgix · Feb 25, 2019 at 07:02 PM
So I had the same problem, and it seems like the 'jump' is due to the constraintTransform's world rotation (the bigger rotation the bigger gap).
This worked for me:
parentConstraint.SetTranslationOffset(0, Quaternion.Inverse(constraintTransform.rotation) * positionDelta);
Answer by AubreyH · May 24, 2019 at 01:53 PM
After you have added all your sources:
//This does the equivalent of pressing the "Activate" button
List<ConstraintSource> sources = new List<ConstraintSource>(constraint.sourceCount);
constraint.GetSources(sources);
for (int i = 0; i < sources.Count; i++)
{
Transform sourceTransform = sources[i].sourceTransform;
Vector3 positionOffset = sourceTransform.InverseTransformPoint( constrainedTransform.position);
Quaternion rotationOffset = Quaternion.Inverse(sourceTransform.rotation) * transform.rotation;
constraint.SetTranslationOffset(i, positionOffset);
constraint.SetRotationOffset(i, rotationOffset.eulerAngles);
}
//And remember to turn it on!
constraint.weight = 1f;//Master weight
constraint.constraintActive = true;
Actually Vlogix's answer solves the jump issue. Unity Team, how about adding examples to Parent Constraint API after 3 years of feature existence?:)
Answer by Defrag · Apr 10 at 01:54 AM
Something that's not addressed by the other comments so far: If there's scaling involved, you have to explicitly ignore it when transforming for your TranslationOffset. That is:
Matrix4x4 inverse = Matrix4x4.TRS(constraintTransform.position, constraintTransform.rotation, new Vector3(1,1,1)).inverse;
parentConstraint.SetTranslationOffset(0, inverse.MultiplyPoint3x4(parentConstraint.transform.position));
parentConstraint.SetRotationOffset(0, (Quaternion.Inverse(constraintTransform.rotation) * parentConstraint.transform.rotation).eulerAngles);