fix: Section Speed Editor에서 본 곡선 없는 클립 length 0으로 표시되는 문제 수정
- Mixamo export 클립 등 m_FloatCurves만 있는 경우 bone transform 곡선이 없어 length가 0으로 계산되던 문제 수정 - bone 곡선이 없으면 m_StopTime을 기준으로 폴백하도록 effectiveLength 로직 추가
This commit is contained in:
@@ -54,18 +54,28 @@ public class AnimationSectionSpeedEditor : EditorWindow
|
||||
|
||||
// ── 클립 정보 (실제 키프레임 기반) ──
|
||||
float actualLength = GetActualLastKeyframeTime(clip);
|
||||
bool hasBoneCurves = actualLength > 0f;
|
||||
|
||||
// 본 트랜스폼 곡선이 없으면 m_StopTime을 기준으로 사용
|
||||
// (Mixamo export 클립 등 m_FloatCurves만 있는 경우)
|
||||
float effectiveLength = hasBoneCurves ? actualLength : clip.length;
|
||||
|
||||
EditorGUILayout.LabelField("Clip Info", EditorStyles.boldLabel);
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.LabelField("Length (keyframes)", $"{actualLength:F3}s");
|
||||
EditorGUILayout.LabelField("m_StopTime", $"{clip.length:F3}s");
|
||||
EditorGUILayout.LabelField("Length", $"{effectiveLength:F3}s");
|
||||
|
||||
if (Mathf.Abs(clip.length - actualLength) > 0.01f)
|
||||
if (hasBoneCurves && Mathf.Abs(clip.length - actualLength) > 0.01f)
|
||||
{
|
||||
EditorGUILayout.LabelField("m_StopTime", $"{clip.length:F3}s");
|
||||
EditorGUILayout.HelpBox($"m_StopTime({clip.length:F3}s)이 실제 키프레임 길이({actualLength:F3}s)와 다릅니다.\n" +
|
||||
"스피드 변경 시 실제 키프레임 길이를 기준으로 계산합니다.", MessageType.Warning);
|
||||
}
|
||||
else if (!hasBoneCurves)
|
||||
{
|
||||
EditorGUILayout.LabelField(" (본 곡선 없음, m_StopTime 기준)", EditorStyles.miniLabel);
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("Total Frames ({fps}fps)", $"{Mathf.Max(1, Mathf.FloorToInt(actualLength * fps))}");
|
||||
EditorGUILayout.LabelField("Total Frames ({fps}fps)", $"{Mathf.Max(1, Mathf.FloorToInt(effectiveLength * fps))}");
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
@@ -74,7 +84,7 @@ public class AnimationSectionSpeedEditor : EditorWindow
|
||||
fps = EditorGUILayout.IntField("FPS", fps);
|
||||
fps = Mathf.Max(1, fps);
|
||||
|
||||
int totalFrames = Mathf.Max(1, Mathf.FloorToInt(actualLength * fps));
|
||||
int totalFrames = Mathf.Max(1, Mathf.FloorToInt(effectiveLength * fps));
|
||||
|
||||
// ── 프레임 범위 ──
|
||||
EditorGUILayout.LabelField("Target Frame Range", EditorStyles.boldLabel);
|
||||
@@ -108,7 +118,7 @@ public class AnimationSectionSpeedEditor : EditorWindow
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// ── 타임라인 시각화 ──
|
||||
DrawTimeline(startTime, endTime, actualLength);
|
||||
DrawTimeline(startTime, endTime, effectiveLength);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
@@ -133,7 +143,7 @@ public class AnimationSectionSpeedEditor : EditorWindow
|
||||
// ── 미리보기 ──
|
||||
float newDuration = duration / speedMultiplier;
|
||||
float timeDelta = newDuration - duration;
|
||||
float newLength = actualLength + timeDelta;
|
||||
float newLength = effectiveLength + timeDelta;
|
||||
|
||||
EditorGUILayout.LabelField("Preview", EditorStyles.boldLabel);
|
||||
EditorGUI.indentLevel++;
|
||||
@@ -301,6 +311,7 @@ public class AnimationSectionSpeedEditor : EditorWindow
|
||||
float newDuration = duration / speedMultiplier;
|
||||
float timeDelta = newDuration - duration;
|
||||
float actualLength = GetActualLastKeyframeTime(clip);
|
||||
float effectiveLength = actualLength > 0f ? actualLength : clip.length;
|
||||
|
||||
Undo.RegisterCompleteObjectUndo(clip, $"Section Speed {speedMultiplier}x (frames {startFrame}~{endFrame})");
|
||||
|
||||
@@ -392,7 +403,7 @@ public class AnimationSectionSpeedEditor : EditorWindow
|
||||
}
|
||||
|
||||
// ── 5. m_StopTime 갱신 (SerializedObject로) ──
|
||||
float newStopTime = actualLength + timeDelta;
|
||||
float newStopTime = effectiveLength + timeDelta;
|
||||
var serializedClip = new SerializedObject(clip);
|
||||
SerializedProperty stopTimeProp = serializedClip.FindProperty("m_StopTime");
|
||||
if (stopTimeProp != null)
|
||||
@@ -433,7 +444,7 @@ public class AnimationSectionSpeedEditor : EditorWindow
|
||||
|
||||
Debug.Log($"[SectionSpeedEditor] {clip.name}: frames {startFrame}~{endFrame} → {speedMultiplier}x " +
|
||||
$"({duration:F3}s → {newDuration:F3}s) " +
|
||||
$"| clip: {actualLength:F3}s → {newStopTime:F3}s " +
|
||||
$"| clip: {effectiveLength:F3}s → {newStopTime:F3}s " +
|
||||
$"| curves: {modifiedCurves}, keyframes: {modifiedKeyframes}, skipped: {skippedCurves}" +
|
||||
$" | events: {(eventsModified ? "modified" : "none")}");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user