Keep motion EndTime absolute and rescale correctly on speed change#95
Open
FMsongX2 wants to merge 1 commit into
Open
Keep motion EndTime absolute and rescale correctly on speed change#95FMsongX2 wants to merge 1 commit into
FMsongX2 wants to merge 1 commit into
Conversation
SetStateSpeed stored remaining duration ((EndTime - Time.time) / speed) into EndTime, which is an absolute timestamp everywhere else (set as StartTime + length/speed, compared against Time.time). The relative value lands in the past, so the motion ends immediately and the fade-out weight goes negative. Reachable via the public CubismMotionController.SetAnimationSpeed; triggers on any speed change, including speed == 1. Rebuild EndTime as Time.time + (EndTime - Time.time) * previousSpeed / speed so it stays absolute and rescales by remaining content time -- correct also when the motion already ran at a non-default speed (the prior form was exact only when the previous speed was 1). Guards: skip the rescale when EndTime is the -1 "no end" sentinel (MotionLength <= 0), and when the previous speed was 0 (paused) so the 0 * Infinity term does not produce NaN. speed == 0 paths are left unchanged from before.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
CubismMotionLayer.SetStateSpeed(reached via the publicCubismMotionController.SetAnimationSpeed) writes a relative value intoEndTime, which is an absolute timestamp everywhere else — set asStartTime + length / speedon play and read viaTime.time > EndTime. The relative value lands in the past, soTime.time > EndTimeis immediately true: the motion fires its end event at once, and its fade-out weight collapses to0(the now-negativeEndTime - timeis clamped byGetEasingSine), cutting the motion instead of playing it out. It triggers on any speed change, includingspeed == 1.Reproduction
Play a non-looping motion through
CubismMotionController, then callSetAnimationSpeed(0, index, 1.0f)(speed unchanged — a no-op):The API is public but no sample calls it, which is why this went unnoticed.
Fix
Rebuild
EndTimefrom the remaining content time, keeping it absolute:previousSpeedis the value being overwritten, so the rescale is correct for any prior speed, not only 1 —(EndTime - Time.time)is the wall-clock remaining under the old speed,* previousSpeedgives the remaining content time,/ speedconverts it to the new speed. TheEndTime == -1"no end" sentinel (MotionLength <= 0) is left untouched, and the rescale is skipped when the previous speed was0sospeed == 0(pause) paths stay unchanged instead of producingNaN.