"Freeze to world" on constraints will always "bake offsets" if there are 0 sources
closed
Dor․
When setting up a (parent) constraint that is only meant to freeze an object to the world and otherwise return it to it's original location (i.e. back to the hand), doing so with 0 sources (as there's really no need for any sources) will cause the object to be offset instead of snap back, this behavior is gone if any source is added, even if the source/constraint weight is 0.
Repro:
- Add a parent constraint to an object that's placed on the hand, leave it with 0 sources
- Activate "Freeze to world"
- Move away from the object
- Disable "Freeze to world"
- Observe the object being unfrozen, but offset
Adding any source (with a transform) fixes this, regardless of weights.
Update: It appears to work in editor with 1 source but a weight set to 0 (so it's there but not used), but in game offsets are almost always still baked, which makes this even weirder.
Update 2: It works in game too, but if the object containing the constraint is off, and by a toggle it is turned on and at the same time turns "Freeze to world" off, but 1 frame later turns it on (2 keyframes), it seems not to function for some reason, but extending the animation so it's not 1 frame long and is instead 2 frames, with the 2nd keyframe duplicated (keyframe 0 = object on, freeze off, keyframe 1 and 2 = object on, freeze on) makes it work, I'm very confused as to why that makes a difference, it does not work if "keyframe 1" (the "middle" keyframe) is removed.
Log In
Dexvoid
updated the status to
closed
Sorry, but this behavior is intentional and changing it would regress existing content in VRChat.
If a constraint has no sources, then there's no information available to it about how it should be positioned, so it falls back to not constraining its target transform. In your repro steps, before activating Freeze to World in step 2, it's actually possible to move the constrained transform around manually in the scene in the SDK while in play mode, since the constraint has no reference for what it should be constraining that transform to.
This matches how Unity constraints behave. A Unity constraint with no sources acts differently to a Unity constraint with a single empty source, and VRChat constraints are built to match this as closely as possible. This is important for automatically converting Unity constraints to VRChat constraints when avatars are loaded in the client, as it means we can benefit from the performance boost of VRChat constraints without changing how the avatar behaves.
Dor․
Dexvoid
If a constraint has no sources, then there's no information available to it about how it should be positioned
I would have assumed it would have the same behavior as setting all source weights to 0 - use the "rest" values.Should I open a new canny for the weird issue in "update 2"? I have no idea why it requires a third keyframe, it's exactly the same as the second, but if the second is removed (so longer animation "0.033s", but just 2 keyframes) it won't work.
Dexvoid
Dor․
> I would have assumed it would have the same behavior as setting all source weights to 0 - use the "rest" values.
That may well be more intuitive, however vanilla Unity constraints behave differently between having no sources and all sources at a weight of zero, so VRC constraints are required to match that behavior.
> Should I open a new canny for the weird issue in "update 2"? I have no idea why it requires a third keyframe, it's exactly the same as the second, but if the second is removed (so longer animation "0.033s", but just 2 keyframes) it won't work.
Feel free to, though I feel we're getting into undefined behavior with this, since as above the expectation is that sources are defined to control where the constraint goes.
Dor․
Dexvoid There is a source set, the object being dropped has the constraint on it, the source is a dummy object on root/armature, when the toggle is off the object is off (which also turns off the constraint as a result), when turned on, the object is turned on, in the same keyframe (0) the constraint has "freeze to world" disabled, so that the object snaps back to the source, the next keyframe (1 frame later) has "freeze to world" re-enabled, expectation is that the object would be frozen again after snapping back, and it works perfectly fine in the editor, but in-game it never snaps back, so it stays at the same dropped location after the initial drop. Adding another keyframe (object on, freeze on, the same as the ending keyframe before) for some reason fixes that, simply extending the animation (removing the middle keyframe) does
not
.Dexvoid
Dor․ Thanks for the info, however we can't track issues out of replies to existing Canny reports. Please make a new one, ideally including an example avatar demonstrating the problem. Thanks very much.
Dor․
Dexvoid Opened canny https://feedback.vrchat.com/sdk-bug-reports/p/freeze-to-world-on-constraints-wont-turn-off-and-on-again-correctly-if-the-const
Hope it's clear enough (when referring to a specific keyframe I refer to it by index, not to be confused when I refer to the keyframe count)
StormRel
updated the status to
tracked