feat: 방어 시스템과 드로그 검증 경로 정리
- 애니메이션 이벤트 기반 방어/유지/해제 흐름과 HUD 피드백, 방어 디버그 로그를 추가했다. - 드로그 기본기1 테스트 패턴을 정리하고 공격 판정을 OnEffect 기반으로 옮기며 드로그 범위 효과의 타겟 레이어를 정상화했다. - 플레이어 퀵슬롯 테스트 세팅과 적-플레이어 겹침 방지 로직을 조정해 충돌 시 적이 수평 이동을 멈추고 최소 분리만 수행하게 했다.
This commit is contained in:
@@ -54,6 +54,9 @@ namespace Colosseum.Editor
|
||||
AnimationClip comboBasic1Hit1Clip0 = EnsureClipFromSource($"{AnimationsFolder}/Anim_Drog_콤보-기본기1_1_0.anim", $"{AnimationsFolder}/Anim_Drog_평타1R_0.anim");
|
||||
AnimationClip comboBasic1Hit1Clip1 = EnsureClipFromSource($"{AnimationsFolder}/Anim_Drog_콤보-기본기1_1_1.anim", $"{AnimationsFolder}/Anim_Drog_평타1R_1.anim");
|
||||
AnimationClip comboBasic1Hit2Clip = EnsureClipFromSource($"{AnimationsFolder}/Anim_Drog_콤보-기본기1_2_0.anim", LightCombo01BSourcePath, "A_MOD_SWD_Attack_LightCombo01B_RM_Neut");
|
||||
SetSingleOnEffectEvent(comboBasic1Hit1Clip0, -1f);
|
||||
SetSingleOnEffectEvent(comboBasic1Hit1Clip1, 0.30f);
|
||||
SetSingleOnEffectEvent(comboBasic1Hit2Clip, 0.28f);
|
||||
|
||||
AnimationClip comboBasic2Hit1Clip0 = EnsureClipFromSource($"{AnimationsFolder}/Anim_Drog_콤보-기본기2_1_0.anim", $"{AnimationsFolder}/Anim_Drog_평타2R_0.anim");
|
||||
AnimationClip comboBasic2Hit1Clip1 = EnsureClipFromSource($"{AnimationsFolder}/Anim_Drog_콤보-기본기2_1_1.anim", $"{AnimationsFolder}/Anim_Drog_평타2R_1.anim");
|
||||
@@ -971,6 +974,35 @@ namespace Colosseum.Editor
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정한 클립에 단일 OnEffect(0) 이벤트를 설정합니다. 음수 시간이면 이벤트를 비웁니다.
|
||||
/// </summary>
|
||||
private static void SetSingleOnEffectEvent(AnimationClip clip, float time)
|
||||
{
|
||||
if (clip == null)
|
||||
return;
|
||||
|
||||
if (time < 0f)
|
||||
{
|
||||
AnimationUtility.SetAnimationEvents(clip, Array.Empty<AnimationEvent>());
|
||||
EditorUtility.SetDirty(clip);
|
||||
return;
|
||||
}
|
||||
|
||||
float clampedTime = Mathf.Clamp(time, 0f, Mathf.Max(0f, clip.length - 0.01f));
|
||||
AnimationUtility.SetAnimationEvents(clip, new[]
|
||||
{
|
||||
new AnimationEvent
|
||||
{
|
||||
time = clampedTime,
|
||||
functionName = "OnEffect",
|
||||
intParameter = 0,
|
||||
},
|
||||
});
|
||||
|
||||
EditorUtility.SetDirty(clip);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 범위형 효과의 공통 판정 설정을 적용합니다.
|
||||
/// </summary>
|
||||
@@ -987,6 +1019,7 @@ namespace Colosseum.Editor
|
||||
serializedObject.FindProperty("targetTeam").enumValueIndex = (int)TargetTeam.Enemy;
|
||||
serializedObject.FindProperty("areaCenter").enumValueIndex = (int)areaCenter;
|
||||
serializedObject.FindProperty("areaShape").enumValueIndex = (int)areaShape;
|
||||
serializedObject.FindProperty("targetLayers").intValue = Physics.AllLayers;
|
||||
serializedObject.FindProperty("includeCasterInArea").boolValue = false;
|
||||
serializedObject.FindProperty("areaRadius").floatValue = areaRadius;
|
||||
serializedObject.FindProperty("fanOriginDistance").floatValue = fanOriginDistance;
|
||||
@@ -1173,7 +1206,8 @@ namespace Colosseum.Editor
|
||||
serializedObject.FindProperty("cooldown").floatValue = 0f;
|
||||
serializedObject.FindProperty("manaCost").floatValue = 0f;
|
||||
serializedObject.FindProperty("maxGemSlotCount").intValue = 0;
|
||||
serializedObject.FindProperty("triggeredEffects").arraySize = 0;
|
||||
serializedObject.FindProperty("castStartEffects").arraySize = 0;
|
||||
ConfigureTriggeredEffects(serializedObject, castStartEffects);
|
||||
|
||||
var clipObjects = new List<UnityEngine.Object>();
|
||||
if (clips != null)
|
||||
@@ -1187,17 +1221,6 @@ namespace Colosseum.Editor
|
||||
|
||||
SetObjectList(serializedObject, "animationClips", clipObjects);
|
||||
|
||||
var effectObjects = new List<UnityEngine.Object>();
|
||||
if (castStartEffects != null)
|
||||
{
|
||||
for (int i = 0; i < castStartEffects.Length; i++)
|
||||
{
|
||||
if (castStartEffects[i] != null)
|
||||
effectObjects.Add(castStartEffects[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SetObjectList(serializedObject, "castStartEffects", effectObjects);
|
||||
serializedObject.ApplyModifiedPropertiesWithoutUndo();
|
||||
skill.RefreshAnimationClips();
|
||||
|
||||
@@ -1205,6 +1228,40 @@ namespace Colosseum.Editor
|
||||
return skill;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 전달된 효과를 모두 Trigger Index 0의 애니메이션 이벤트 효과로 기록합니다.
|
||||
/// </summary>
|
||||
private static void ConfigureTriggeredEffects(SerializedObject serializedObject, IReadOnlyList<SkillEffect> effects)
|
||||
{
|
||||
SerializedProperty triggeredEffectsProperty = serializedObject.FindProperty("triggeredEffects");
|
||||
if (triggeredEffectsProperty == null)
|
||||
return;
|
||||
|
||||
var validEffects = new List<SkillEffect>();
|
||||
if (effects != null)
|
||||
{
|
||||
for (int i = 0; i < effects.Count; i++)
|
||||
{
|
||||
if (effects[i] != null)
|
||||
validEffects.Add(effects[i]);
|
||||
}
|
||||
}
|
||||
|
||||
triggeredEffectsProperty.arraySize = validEffects.Count > 0 ? 1 : 0;
|
||||
if (triggeredEffectsProperty.arraySize == 0)
|
||||
return;
|
||||
|
||||
SerializedProperty entryProperty = triggeredEffectsProperty.GetArrayElementAtIndex(0);
|
||||
entryProperty.FindPropertyRelative("triggerIndex").intValue = 0;
|
||||
SerializedProperty effectsProperty = entryProperty.FindPropertyRelative("effects");
|
||||
effectsProperty.arraySize = validEffects.Count;
|
||||
|
||||
for (int i = 0; i < validEffects.Count; i++)
|
||||
{
|
||||
effectsProperty.GetArrayElementAtIndex(i).objectReferenceValue = validEffects[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 드로그 보스 패턴 자산을 생성하거나 갱신합니다.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user