Constraint processing order does not follow component toggles
tracked
logi_9
It is expected that the Constraint component processes its dependencies in topological order when there are no cycles in the dependency graph. However, it seems that VRC Constraints cannot correctly handle changes in dependencies caused by toggling components, leading to cases where it fails to derive a consistent solution even when one exists.
In the sample avatar, there are four objects: Source, X, Y, and Z, all existing flatly. Source, X, and Z each have a child cube. Source is animated to be at X=-1 on even frames and at X=1 on odd frames. Each object has a Constraint component attached, and these components are controlled via animation so that the dependency changes as shown in the left diagram for the first two seconds after loading, and then to the right diagram thereafter.
Neither of these dependency sets contains cycles, and by processing them in topological order, all constraints can be satisfied (i.e., all cubes are positioned at the same location as Source). However, if the processing order is incorrect, one of the cubes may reference the previous frame's position, resulting in it being displayed at a different position from the other cubes.
In the sample avatar with automatic conversion, everything works as expected before switching dependencies, but after the switch, it seems that the correct order is not being maintained.
Unfortunately, Unity Constraints also exhibit a similar (but different a bit) issue, where the processing order is incorrect before the dependency switch but correct after the switch.
If accurate conversion from Unity Constraints is a priority, it would be beneficial to make VRC Constraints behave similarly to Unity Constraints. Otherwise, it would be ideal to process the dependencies in the correct order derived from the dependency graph. Could you please consider addressing this issue?
Sample Avatar: avtr_afc5ee48-560c-4ebf-8316-c74bc109e1a3
Log In
Dexvoid
tracked
Animating a source's weight to 0 will not break that constraint's dependency. The example you've given therefore contains a cyclic dependency of Z -> Y -> X -> Z which can be seen by overlapping your two diagrams.
We'll do what we can to replicate the requested behavior, but please note that cyclic dependencies between constraints are not recommended since they're undefined behavior as mentioned in Unity's own documentation on the subject: https://docs.unity3d.com/Manual/Constraints.html
This may take some time as it involves a degree of replicating what Unity is doing internally while keeping the system performant, so as an alternative, you could avoid the cyclic dependency entirely by using two constraints of the same type on the same game object and toggling between them. In your case, the single position constraint on Z could be split into two position constraints, one targeting Source and the other targeting Y. You'd then enable one and disable the other as needed instead of swapping the weights around. You will need to use VRChat constraints to do this, since Unity constraints don't allow multiple constraints of the same type on the same game object.
logi_9
Dexvoid Did you check the details of the sample avatar?
In the case where the issue occurs, I'm already attempting to control the dependencies by toggling the components' property
Enabled
. X
has both a Position Constraint (Pos) and a Parent Constraint (Par), with only the Position Constraint enabled in the left diagram and only the Parent Constraint enabled in the right diagram. In this situation, even considering sources with a weight of 0, I don't believe there is a cycle at any point in time. Is there something I might be missing?(Additionally, if dependencies can be controlled by toggling components, I believe it would be acceptable to consider sources with a weight of 0 as dependencies.)
Dexvoid
logi_9 Sorry for the confusion. I was offering a suggestion of splitting the position constraint on Z into two position constraints each with one source instead as a temporary solution to this problem.
You're correct that this setup triggers a fault when sorting VRChat constraints. The issue is tracked and is being investigated internally. We're aiming to allow this setup to behave in the same way it does with Unity constraints.
logi_9