From 22ceafd0e2ecfd9451d8d8a484c92a85a3bcf190 Mon Sep 17 00:00:00 2001 From: FMsongX2 Date: Fri, 26 Jun 2026 00:54:13 +0900 Subject: [PATCH] Keep motion EndTime absolute and rescale correctly on speed change 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. --- .../Live2D/Cubism/Framework/Motion/CubismMotionLayer.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Assets/Live2D/Cubism/Framework/Motion/CubismMotionLayer.cs b/Assets/Live2D/Cubism/Framework/Motion/CubismMotionLayer.cs index e33dd319..af428d47 100644 --- a/Assets/Live2D/Cubism/Framework/Motion/CubismMotionLayer.cs +++ b/Assets/Live2D/Cubism/Framework/Motion/CubismMotionLayer.cs @@ -340,8 +340,14 @@ public void SetStateSpeed(int index, float speed) } var playingMotionData = _playingMotions[index]; + var previousSpeed = playingMotionData.Speed; playingMotionData.Speed = speed; - playingMotionData.EndTime = (playingMotionData.EndTime - Time.time) / speed; + + if (playingMotionData.EndTime >= 0.0f && previousSpeed > 0.0f) + { + playingMotionData.EndTime = Time.time + (playingMotionData.EndTime - Time.time) * previousSpeed / speed; + } + _playingMotions[index] = playingMotionData; _motionState.ClipMixer.SetSpeed(speed);