WL #962 PD 지시 5건 — ① 비수 주력 = 이펙트 1회(정면 사본 1개 · 이전 0.2 s 마다 6개가 겹쳐 같은 초승달 6연속이 되풀이) · 난사 시간 = 이펙트 1회 길이(프리팹 입자 분출 + 수명 자동 계산 1.16 s · 0.15 s 휘두름 · 배속 2.1) · 원본 숨김 2.1 s(끝 순간이동·이동 금지·무적)도 같은 시간(Skill_ShadowSlash 훅 1줄 InvisibleSeconds) · 판정 10회 고르게 · 판정 진단 = 판정은 10/10 나지만 피격 이펙트 칸 없음 + 넉백으로 더미가 이펙트 밖 3.4 m 까지 밀림 + 4 m 밖 빗나감 → 주력 스킬 피격 이펙트(WL_Hit_SwordSkill) · 넉백 끔(WLSkillHitFeel) · 판정 반경 4.0 m ② 월광 주력↔각성 교체(WLWeaponSkillTable · 칸 수치 유지) · 무자비한 일격 Slash Cracks 재질 빈칸(분홍) → Crack6bcg ③ 창 2타 찌르기 = FX_Blast 사본 WL_Impact_SpearBlast(찌를 때마다 · 0.35 s) ④ 오브 기본 공격 = FX_Shoot_Ice 사본(투사체 + 명중) ⑤ 마법책 = FX_Shoot_Card 사본(투사체 + 명중 · 원본 겉모습 분홍 후보 숨김)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-10-21 17:40:26 +09:00
parent 37b010fee7
commit c04cb8d20d
18 changed files with 153290 additions and 34 deletions

View File

@ -49,6 +49,7 @@ MonoBehaviour:
ColliderLayer: Actor
m_Pierce: 0
str_HitEffect:
str_HitEffect_CurPos:
m_ShowTimeOverEffect: 1
m_projectile: Projectile_BrutalSlash
projectileTime: 2
@ -125,6 +126,11 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6877057326494895805, guid: 8a02c4042c68dd244abad8cf394dab42,
type: 3}
propertyPath: 'm_Materials.Array.data[0]'
value:
objectReference: {fileID: 2100000, guid: 06ed439858d6b394eb2fbeda50f0ec16, type: 2}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
@ -159,12 +165,15 @@ MonoBehaviour:
ColliderLayer: Actor
m_Pierce: 0
str_HitEffect:
str_HitEffect_CurPos:
m_ShowTimeOverEffect: 1
m_Collider: {fileID: 0}
ColliderActiveDealyTime: 0
LoopTime: 1
Loop: 0
DelayTime: 0.1
ColliderActiveFrame: 2
OffDelayTime: 0
--- !u!65 &2663128934310353663
BoxCollider:
m_ObjectHideFlags: 0

View File

@ -16,7 +16,7 @@ public class Skill_ShadowSlash : ProjectileBase
Show_InvisibleEffect();
//_data.shooter.Jump(2.1f, 1f, 10f, 1f, () =>
_data.shooter.Set_Invisible(2.1f, () =>
_data.shooter.Set_Invisible(WL.Combat.Weapon.WLShadowSlash.InvisibleSeconds(2.1f), () => // WL #962 숨김 시간 = 난사 시간(이펙트 1회 길이 · WLShadowSlash.json invisibleMatch · 끄면 원본 2.1 s)
{
OptionInfo.Ins.Set_PCMove(_data.shooter, true);
if (WL.Combat.Weapon.WLShadowSlash.SkipEnd(_data.shooter)) return; // WL #961 구르기로 캔슬된 시전 — 끝 대기 · 대상 뒤 순간이동 · 연기 · 카메라 돌리기 생략

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: aad0b1e7179a2484e80c555c0d3e3567
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -44,6 +44,15 @@
}
],
"skillHitFx": [
{
"classIds": [ 10202 ],
"skills": [ "Skill_ShadowSlash" ],
"prefab": "WL_Hit_SwordSkill",
"scale": 1.0,
"fit": 1.3,
"offsetCompensate": true,
"_note_962": "#962 PD 「비수 주력 사용 시 판정이 발생되지 않는다」 — 판정은 나지만(Play 실측 10/10) 비수(10201 · 10202)는 hitFx · skillHitFx 칸이 없어 맞아도 적 몸에 아무것도 안 떴다 → 주력(Skill_ShadowSlash)만 검 스킬 피격 이펙트 사본(WL_Hit_SwordSkill · 몸 높이 비례 fit 1.3 · 같은 몹 0.12 s 간격 skillHitMinInterval)"
},
{
"classIds": [
10101,
@ -304,6 +313,7 @@
"sweepFlip": false
},
{
"_note_962": "#962 PD 「창의 찌르기 이펙트를 Game VFX - Cartoon Skill Collection 의 FX_Blast 로」 — 2타 찌르기 6연타의 가림 이펙트(FX_Machine_Gun 사본 WL_Impact_SpearBurst · 0.9 s 1개)를 FX_Blast 사본 WL_Impact_SpearBlast 로 · 편집 모드 실측: 불꽃 줄기가 로컬 +X 로 뻗고 약 0.3 s 에 사라짐 → euler Y −90(+X → PC 정면) · 찌를 때마다(ShowEffect 6회 · minInterval 0.1) 1개씩 0.35 s · 자리 = PC 중심 + 정면 0.5 + 오른쪽 0.25 + 위 −0.1(창 끝 쪽으로 뻗음) · 방향 고정 · PC 회전 잠금(#943-⑤)은 그대로 · 배율 0.4(실제 약 0.25 · 길이 약 1.7 m 추정)",
"_note_940": "#940 PD 「창 2타 = 빠른 찌르기 연타 + 무기 부분을 FX_Machine_Gun 으로 가림」 — 사본 WL_Impact_SpearBurst(EricWang FX_Machine Gun · loop 끔 · 줄기 line/fire_line/trail 의 X·Y 기울기 0 = 지면 평행) · 이 이펙트는 총구 섬광이 로컬 +X 쪽, 탄 줄기는 −X 로 날아가는 2D 측면 연출(편집 모드 면 대면 렌더로 확인) → 로컬 X 를 PC 뒤쪽으로(euler -90,90,0: X→뒤 · Y→왼쪽 · Z→위 · XY 면 = 지면 평행) 두면 줄기가 적 쪽으로 난다 · 6연타 ShowEffect 중 첫 이벤트만 띄움(minInterval) · PC 를 따라감 · 1.0 초 뒤 풀 반환. 위치 = Play 실측(Sp940.Snap): 창 몸통 중심 = PC 기준 오른쪽 0.3 · 앞 0.3 · 발 위 0.37 m · 섬광 묶음 중심은 원점에서 로컬 (X 1.06 · Y 1.62 · Z -0.33) × 실제 배율만큼 벗어남(X→뒤 · Y→왼쪽이므로 세계 기준 뒤 0.385 · 왼쪽 0.59 · 아래 0.12) → forward/side/yOffset 은 「목표 + 벗어남」(실제 배율 0.363 = scale 0.6 × fallbackScale 0.55 × SizeFactor 1.1): forward 0.5 + 0.385 · side 0.3 + 0.59 · yOffset −0.15 + 0.12. 섬광 Fire_Flash 6개도 기울기 0 + Z 각 앞쪽 부채꼴(−35°~+40°) 로 고정(원본 3D 회전은 옆에서 보는 2D 연출용 · 위 카메라에선 빛줄기가 뒤를 봄)",
"classIds": [
10701
@ -311,34 +321,26 @@
"stages": [
2
],
"prefab": "WL_Impact_SpearBurst",
"scale": 0.6,
"euler": [
-90,
90,
0
],
"yOffset": -0.15,
"prefab": "WL_Impact_SpearBlast",
"scale": 0.4,
"euler": [ 0, -90, 0 ],
"yOffset": -0.1,
"calibrated": false,
"follow": true,
"forward": 0.885,
"side": 0.89,
"life": 0.9,
"minInterval": 0.9,
"life": 0.35,
"minInterval": 0.1,
"_note_944": "#944 창 모션이 Platform Spear 로 바뀌어 2타 연타 = 0.9 s(첫·마지막 ShowEffect 간격 0.75 s) → life 0.9 · minInterval 0.9(에이전트 실측 권고 · Play 미확인)",
"_note_941": "#941 PD 「창 공격 시 이펙트와 캐릭터 방향이 일치하게」 — alignWeapon: 매 프레임 창 소켓(손잡이 → 창끝 · 수평) 방향으로 돌리고 손잡이에서 길이 × alignFraction 자리에 둔다(forward/side 는 이때 안 씀 · massLocal 로 섬광 묶음 중심 보정)",
"alignWeapon": false,
"alignFraction": 0.55,
"massLocal": [
1.06,
1.62,
-0.33
],
"massLocal": [ 0, 0, 0 ],
"_note_943": "#943-⑤ PD 「타격하려는 방향을 고정한 채 … 이펙트가 캐릭터 방향에 따라 마구 바뀌면 안 됨」 — alignWeapon(창 방향 추종) 끄고 fixedDir: 띄우는 순간의 표적 방향으로 이펙트 방향 고정 + 공격 상태 동안 PC 회전 잠금(lockFacing · 타격 상자 Projectile_10101 도 같은 방향) · 자리 = PC 중심 + 정면 0.6 + 오른쪽 0.3 + 위 −0.15 − R × massLocal × 배율",
"fixedDir": true,
"lockFacing": true,
"alignForward": 0.6,
"alignSide": 0.3
"alignForward": 0.5,
"alignSide": 0.25
}
],
"groundFx": [

View File

@ -1,6 +1,7 @@
{
"enabled": 1,
"rules": [
{ "skill": "Skill_ShadowSlash", "pushScale": 0.05, "knockbackScale": 0.0, "staggerSeconds": 0.15, "_note_962": "#962 PD 「비수 주력 사용 시 판정이 발생되지 않는다」 — Play 실측: 판정은 나지만 맞을 때마다 원본 넉백 + 피격 밀기로 더미가 2 s 동안 1.0 → 3.4 m 밀려 제자리 난사 이펙트 밖으로 나가고 4.0 m 를 넘으면 빗나감 → 넉백 끔 · 밀기 × 0.05 · 맞을 때마다 경직 0.15 s(맞는 반응이 보이게)" },
{
"skill": "Skill_DashSlash",
"pushScale": 0.05,

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c01ad0a4907dcad4caad36f3b81c33c0
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d033295bb3548c24285e6ed30555d44a
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 27d0e12c2f6c0be41aeedec210970ef4
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1e72ebaf2bb45b94a8942a102709cb2c
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,11 +1,23 @@
{
"rules": [
{
"projectile": "Projectile_10303",
"hideNames": [ "Projectile" ],
"_note_962": "#962 PD 「마법책 이펙트를 Stylized Shoot & Hit Vol.2 의 FX_Shoot_Card 로」 — 마법책(9009 · 직업 10303) 기본 공격 투사체 Projectile_10303 의 원본 겉모습 Projectile(자식 5층 · Spiral 내장 셰이더 · Lightning 재질 빈칸 = 분홍 후보)을 숨기고 덧씌움 = FX_Shoot_Card_projectile 사본 WL_Fx_ShootCard(0.3) · 명중 = FX_Shoot_Card_hit 사본 WL_Fx_ShootCardHit(0.3 · 원본 Effect_Hit_10303 의 Lightning 도 재질 빈칸) · 같은 투사체를 쓰는 정령의 셉터(9005 · lineup 밖)도 같이 바뀐다",
"visual": "WL/Fx/WL_Fx_ShootCard",
"scale": 0.3,
"hitFx": "WL/Fx/WL_Fx_ShootCardHit",
"hitScale": 0.3,
"hitLife": 1.5
},
{
"projectile": "Projectile_10301",
"visual": "WL/WL_MagicBoltVisual",
"scale": 1.0,
"hitFx": "WL/Impact/WL_Hit_Staff",
"hitScale": 0.37,
"hideNames": [ "FX_Shoot_10_projectile" ],
"_note_962": "#962 PD 「오브의 기본 공격 이펙트를 Stylized Shoot & Hit Vol.2 의 FX_Shoot_Ice 로」 — 원본 투사체의 FX_Shoot_10_projectile(자식 3층)을 숨기고 덧씌움 = FX_Shoot_Ice_projectile 사본 WL_Fx_ShootIce(원본 FX_Shoot_10 과 같은 배율 0.3) · 명중 = 같은 세트 FX_Shoot_Ice_hit 사본 WL_Fx_ShootIceHit(0.3 · 이전 WL_Hit_Staff 0.37) · 이전 덧씌움 WL_MagicBoltVisual 은 파일만 남김",
"visual": "WL/Fx/WL_Fx_ShootIce",
"scale": 0.3,
"hitFx": "WL/Fx/WL_Fx_ShootIceHit",
"hitScale": 0.3,
"hitLife": 1.5
},
{

View File

@ -7,7 +7,7 @@
"keepHitBox": 1,
"fxPrefab": "WL/Fx/WL_Fx_DaggerMulti",
"fxScale": 0.85,
"fxDelay": 0.5,
"fxDelay": 0.0,
"fxForward": 0.45,
"fxYOffset": 0.0,
"fxLife": 2.5,
@ -17,21 +17,25 @@
"fxPrefabWidth": 5.26,
"hideOriginalFx": 1,
"slashStates": [ "attack", "DualBlades_Attack2" ],
"slashInterval": 0.2,
"slashInterval": 0.15,
"moveHold": 1,
"dodgeCancel": 1,
"fxEndAlign": 1,
"fxVisibleLife": 0.3,
"endHoldSeconds": 0.5,
"endIdle": 1,
"slashMatchFx": 1,
"invisibleMatch": 1,
"slashHitEven": 1,
"_note_962": "#962 PD 「비수 주력 사용 시 이펙트가 두 번 연속 재생되는 것 같다 → 이펙트는 한 번만 재생하고 모션을 이펙트에 맞춰」 · 「주력 사용 시 판정이 발생되지 않는데 왜 그런지 체크 · 수정」 — 이펙트 = 정면 사본 1개만(fxRepeatInterval 0 · 이전 = 0.5 s 부터 0.2 s 마다 6개가 겹쳐 같은 6연속 초승달이 되풀이) · 시전과 동시에(fxDelay 0) · 난사 시간 = 사본 1개가 보이는 시간(slashMatchFx · 입자 분출 0~0.75 s + 수명 0.3 = 1.05 s) · 휘두름 = 초승달 간격 0.15 s 마다(배속 2.1 = 휘두름마다 클립 0.32 s · #960 과 같은 길이) · 원본 숨김 2.1 s(이동 금지 · 무적 · 끝 대기 · 대상 뒤 순간이동)도 1.05 s 로(invisibleMatch · 훅 1줄) · 판정 10회를 1.05 s 에 고르게(slashHitEven) · 판정 진단(Play 실측 · 962_probe Q): 판정은 10/10 나지만 ① 비수 스킬 타격은 적 몸에 뜨는 피격 이펙트 칸이 없고 ② 맞을 때마다 더미가 약 0.25 m 씩 밀려 2 s 동안 1.0 → 3.4 m(이펙트 밖) ③ 4.0 m 를 넘으면 실제로 빗나감(4.5 m 조건 6/10) → 피격 이펙트 WLImpactFx skillHitFx(10202 · Skill_ShadowSlash) + 넉백 끔(WLSkillHitFeel) + 판정 반경 3.5 → 4.0 m(+ 몸 반지름 ≈ 원본 판정 상자 앞 4.4 m)",
"_note_961": "#961 PD 「주력 중 캐릭터가 움직이면 이펙트만 그 자리에 남음 → 못 움직이게 · 구르기로 캔슬하면 이펙트도 같이 소멸」 · 「이펙트 소멸 타이밍에 맞게 모션도 종료 · 최소 0.5 s 딜레이 후 공격」 — 이동 = 원본이 PCMove 를 끄지만 하네스 WASD · 가상패드가 Run_byJoystick 으로 움직였음 → moveHold(WLSkillCancel.HoldMove 2.0 s · 구르기는 됨) · 구르기 = 난사 · 반복 · 잔상 · 판정 멈춤 + 살아 있는 정면 사본 지움 · 정면 사본 반복을 0.3 s(초승달 보이는 시간) 일찍 끝내 마지막 이펙트가 난사 끝 2.0 s 에 함께 사라짐 · 끝난 뒤 0.5 s 공격 금지(IsStop 매 프레임 · 하네스 공격 키 IsHolding) · endIdle = 난사 끝(마지막 이펙트 소멸 2.0 s)에 바로 대기 동작(원본은 2.1 s 콜백에서 대기 · 그사이 마지막 휘두름이 이어짐) · 구르기 캔슬이면 원본 2.1 s 끝 처리(대기 · 대상 뒤 순간이동 · 연기 · 카메라 돌리기)를 건너뜀(Skill_ShadowSlash 훅 1줄 SkipEnd) · Play 실측(961_verify): ⓐ 이동 입력은 막혔는데(WASD 막힘 72 · 패드 0 m) 시전 중 0.65~1.06 m 전진 = 강제 재생하는 1·2타 클립의 공격 전진 표(AttackRootMotion) → 난사 중 Gate 차단(IsSlashing) ⓑ 사본 1개 = 초승달 6개를 0~0.75 s 에 나눠 뿜어 약 1.05 s 보임(fxVisibleLife 0.3 가정이 틀려 입자가 2.74 s 까지 남음) → 반복을 멈추는 1.7 s 에 살아 있는 사본의 분출도 멈춤(이미 나온 초승달 수명 0.3 s 만) = 2.0 s 에 함께 소멸",
"slashHits": 10,
"slashHitDelay": 0.1,
"slashHitRadius": 3.5,
"slashHitRadius": 4.0,
"slashHitRangeMul": 1.6,
"slashHitHalfAngle": 110,
"_note_960": "#960 PD 「비수 주력 스킬 공격 시 총 10회 타격이 가능하도록 애니메이션 재생 타이밍에 적절하게 판정」 · 「비수 공격 잔상 색 = 검은색」 — 원본 판정 = 시전 0.5 s 뒤 go_effect 가 0.1 s 간격 6회(Loop 6 · 난사와 무관) → 끄고(Loop 0) 난사 휘두름 틱 0.24 → 0.2 s(2.0 s 에 10번 휘두름 · 1.6 배속 exit 0.31 s 보다 짧음) 마다 0.1 s 뒤(1·2타 클립의 칼이 지나가는 순간) 1회씩 10회 = 원본 한 대 피해(1회 피해 그대로 → 총량 원본 6회의 10/6) · 범위 = PC 발 기준 3.5 m + 몸 반지름 · 대상 쪽 ±110°(맞을 때마다 더미가 밀려나 공격 범위 × 1.6 = 1.6 m 로는 10회 중 7회 · 2.5 m 로도 3.0 m 까지 밀려 빗나감 실측 · 원본 판정 상자는 앞 약 4.4 m 까지) · 판정 시각은 대기열(프레임 끊김에도 휘두름마다 1회) · 정면 사본 반복도 0.2 s(휘두름마다) · 잔상 색 teal → 검정(0,0,0,0.5)",
"slashSpeed": 1.6,
"slashSpeed": 2.1,
"slashSeconds": 2.0,
"fxMain": 1,
"fxPerSlash": 0,
@ -40,7 +44,7 @@
"fxSlashFraction": 0.6,
"fxSlashYOffset": 0.0,
"fxSlashFollow": 1,
"fxRepeatInterval": 0.2,
"fxRepeatInterval": 0,
"fxRepeatSeconds": 0,
"slashHardRestart": 1,
"slashGhosts": 1,

View File

@ -7,8 +7,8 @@
1029,바람쐐기,2,703406,화살 비,Skill_ArrowRain,archer_skill3,,6,18,0,10,7.0,Slow,WST:1003,Effect_Slow,5,M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref,,,,
1071,현자의 지팡이,1,703306,번개 소용 돌이,Skill_Hurricane,casting,skill_cast2,3,7,0,5,2.4,Burn,WST:1006,Effect_Burn,5,M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref,,,,
1071,현자의 지팡이,2,703305,운석 소환,Skill_MeteoStorm,casting,casting_end,6,18,0,10,8.0,Burn,WST:1006,Effect_Burn,5,M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref,,,,
1001,월광,1,703106,무자비한 일격,Skill_BrutalSlash,brutalslash,,3,6,0,5,2.8,Blood,WST:1001,Effect_Blood,6,M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref,,,,
1001,월광,2,703105,검기 분출,Skill_EnergySlash,energyslash,,6,16,0,8,6.2,Blood,WST:1001,Effect_Blood,8,M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref,,,,
1001,월광,1,703105,검기 분출,Skill_EnergySlash,energyslash,,3,6,0,8,2.8,Blood,WST:1001,Effect_Blood,8,M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref,,,,
1001,월광,2,703106,무자비한 일격,Skill_BrutalSlash,brutalslash,,6,16,0,5,6.2,Blood,WST:1001,Effect_Blood,6,M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref,,,,
1057,맹약,1,703303,에너지볼 난사,Skill_EnergyBall,casting,casting_end,3,7,0,10,3.6,Burn,WST:1005,Effect_Burn,5,M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref,,,,
1057,맹약,2,703301,블랙홀,Skill_BlackHole,casting,casting_end,6,18,0,10,7.5,Burn,WST:1005,Effect_Burn,5,M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref,,,,
9001,수호자의 철퇴,1,703505,십자 가르기,Skill_CrossSlash,crossslash,,3,6,0,2,2.4,Stun,,Effect_Stun,6,M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref,,,,

1 weapon_id weapon_name slot skill_id skill_name skill_class anim next_anim unlock_tier cool_s mp range_m dmg_ratio_base awaken2_extra fr_ref vfx src_cool_ref src wl_skill trigger dash_cast first_cast
7 1029 바람쐐기 2 703406 화살 비 Skill_ArrowRain archer_skill3 6 18 0 10 7.0 Slow WST:1003 Effect_Slow 5 M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref
8 1071 현자의 지팡이 1 703306 번개 소용 돌이 Skill_Hurricane casting skill_cast2 3 7 0 5 2.4 Burn WST:1006 Effect_Burn 5 M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref
9 1071 현자의 지팡이 2 703305 운석 소환 Skill_MeteoStorm casting casting_end 6 18 0 10 8.0 Burn WST:1006 Effect_Burn 5 M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref
10 1001 월광 1 703106 703105 무자비한 일격 검기 분출 Skill_BrutalSlash Skill_EnergySlash brutalslash energyslash 3 6 0 5 8 2.8 Blood WST:1001 Effect_Blood 6 8 M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref
11 1001 월광 2 703105 703106 검기 분출 무자비한 일격 Skill_EnergySlash Skill_BrutalSlash energyslash brutalslash 6 16 0 8 5 6.2 Blood WST:1001 Effect_Blood 8 6 M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref
12 1057 맹약 1 703303 에너지볼 난사 Skill_EnergyBall casting casting_end 3 7 0 10 3.6 Burn WST:1005 Effect_Burn 5 M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref
13 1057 맹약 2 703301 블랙홀 Skill_BlackHole casting casting_end 6 18 0 10 7.5 Burn WST:1005 Effect_Burn 5 M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref;weapon_id;weapon_name;fr_ref
14 9001 수호자의 철퇴 1 703505 십자 가르기 Skill_CrossSlash crossslash 3 6 0 2 2.4 Stun Effect_Stun 6 M:skill_id;skill_name;skill_class;anim;next_anim;range_m;awaken2_extra;vfx;src_cool_ref

View File

@ -64,6 +64,11 @@ namespace WL.Combat.Weapon
// fxEndAlign 1 = 정면 사본 반복을 fxVisibleLife(초승달 보이는 시간) 만큼 일찍 끝내 마지막 이펙트가 난사 끝에 함께 사라지게 · endHoldSeconds = 난사가 끝난 뒤 공격 금지(자동 전투 IsStop · 하네스 공격 키)
public int moveHold = 0, dodgeCancel = 0, fxEndAlign = 0;
public float fxVisibleLife = 0.3f, endHoldSeconds = 0f;
// #962 PD 「주력 이펙트가 두 번 연속 재생되는 것 같다 → 한 번만 재생하고 모션을 이펙트에 맞춰」 · 「주력 판정이 발생되지 않는다 → 원인 확인 · 수정」 —
// slashMatchFx 1 = 난사 시간 = fxDelay + 사본 1개가 보이는 시간(프리팹 입자계마다 시작 지연 + 마지막 분출 시각 + 수명의 최댓값 · FxDuration) ·
// invisibleMatch 1 = 원본 숨김(Set_Invisible 2.1 s = 이동 금지 · 무적 · 끝 대기 · 대상 뒤 순간이동)도 그 시간에 맞춤(원본 훅 1줄 InvisibleSeconds) ·
// slashHitEven 1 = 판정 slashHits 회를 난사 시간에 고르게(휘두름 수와 무관 · 그전엔 휘두름마다 1회 + 모자란 만큼 끝에 몰아서)
public int slashMatchFx = 0, invisibleMatch = 0, slashHitEven = 0;
public int endIdle = 0; // #961 1 = 난사가 끝나는 순간(= 마지막 이펙트 소멸) 대기 동작으로(원본은 0.1 s 뒤 2.1 s 콜백에서 대기 · 그사이 마지막 휘두름이 이어졌다)
}
@ -90,7 +95,7 @@ namespace WL.Combat.Weapon
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
static void Boot() { s_cfg = null; Casts = Shown = Scaled = Errors = 0; SlashLoops = SlashLeaks = FxShown = FxRepeats = FxSlashes = SlashGhostCount = SlashHits = SlashHitTargets = 0; DodgeCancels = EndHolds = EndSkips = EndIdles = FxStops = 0; s_holdActor = s_castShooter = s_slashActor = null; s_liveFx.Clear(); LastLog = SlashLog = FxRepeatLog = SlashHitLog = ""; }
static void Boot() { s_cfg = null; Casts = Shown = Scaled = Errors = 0; SlashLoops = SlashLeaks = FxShown = FxRepeats = FxSlashes = SlashGhostCount = SlashHits = SlashHitTargets = 0; DodgeCancels = EndHolds = EndSkips = EndIdles = FxStops = 0; s_holdActor = s_castShooter = s_slashActor = null; s_liveFx.Clear(); s_fxDur.Clear(); LastLog = SlashLog = FxRepeatLog = SlashHitLog = ""; }
public static string Describe() { return "casts " + Casts + " · shown " + Shown + " · scaled " + Scaled + " · err " + Errors + " · fx " + FxShown + "(반복 " + FxRepeats + ") · 잔상 " + SlashGhostCount + " · " + LastLog; }
@ -120,7 +125,7 @@ namespace WL.Combat.Weapon
if (c.fxMain != 0) Runner.StartCoroutine(CoFx(shooter, c, seq)); // #956 fxMain 0 = 정면 사본 없이 난사 사본(fxPerSlash)만
}
HitMode(skill, c); // #960 원본 6회 판정 끄기(slashHits > 0) / 되돌리기
if (c.moveHold != 0 && shooter is PCActor mh) WLSkillCancel.HoldMove(mh, Mathf.Max(0.1f, c.slashSeconds)); // #961 난사 동안 이동 입력 무시(구르기는 됨)
if (c.moveHold != 0 && shooter is PCActor mh) WLSkillCancel.HoldMove(mh, Mathf.Max(0.1f, SlashSec(c))); // #961 난사 동안 이동 입력 무시(구르기는 됨)
if (c.slashStates != null && c.slashStates.Length > 0 && !DSUtil.CheckNull(shooter) && shooter.m_animation != null) Runner.StartCoroutine(CoSlash(shooter, c, skill, seq)); // #955 · #960 휘두름마다 판정 · #961 구르기 캔슬 · 끝 공격 금지
if (c.slashGhosts != 0 && !DSUtil.CheckNull(shooter)) Runner.StartCoroutine(CoGhosts(shooter, c, seq)); // #959 난사 잔상
LastLog = "cast " + Casts + " · shown " + Shown + " · scaled " + Scaled;
@ -128,6 +133,41 @@ namespace WL.Combat.Weapon
catch (System.Exception ex) { Errors++; LastLog = "실패 — " + ex.Message; }
}
static readonly System.Collections.Generic.Dictionary<string, float> s_fxDur = new System.Collections.Generic.Dictionary<string, float>();
/// <summary>#962 이펙트 프리팹 1회가 보이는 시간 — 입자계마다 (시작 지연 + 마지막 분출 시각 + 수명 최댓값)의 최댓값(반복 입자계 · 끝없는 분출은 빼고 · 비율 분출은 duration). WL_Fx_DaggerMulti = 0.75 + 0.3 = 1.05 s.</summary>
public static float FxDuration(string path)
{
float v;
if (string.IsNullOrEmpty(path)) return 0f;
if (s_fxDur.TryGetValue(path, out v)) return v;
v = 0f; var p = Resources.Load<GameObject>(path);
if (p != null)
foreach (var ps in p.GetComponentsInChildren<ParticleSystem>(true))
{
var m = ps.main; if (m.loop) continue;
float delay = m.startDelay.mode == ParticleSystemCurveMode.Constant ? m.startDelay.constant : m.startDelay.constantMax;
float life = m.startLifetime.mode == ParticleSystemCurveMode.Constant ? m.startLifetime.constant : (m.startLifetime.mode == ParticleSystemCurveMode.TwoConstants ? m.startLifetime.constantMax : m.startLifetime.curveMultiplier);
var em = ps.emission; float last = -1f;
for (int i = 0; i < em.burstCount; i++) { var b = em.GetBurst(i); if (b.cycleCount <= 0) continue; last = Mathf.Max(last, b.time + (b.cycleCount - 1) * b.repeatInterval); }
if (em.rateOverTime.constantMax > 0f) last = Mathf.Max(last, m.duration);
if (last < 0f) continue;
v = Mathf.Max(v, delay + last + life);
}
s_fxDur[path] = v; return v;
}
/// <summary>#962 난사 시간 — slashMatchFx 면 fxDelay + 사본 1개가 보이는 시간(없으면 slashSeconds).</summary>
public static float SlashSec(WLShadowSlashJson c)
{
if (c.slashMatchFx != 0 && !string.IsNullOrEmpty(c.fxPrefab)) { float d = FxDuration(c.fxPrefab); if (d > 0.05f) return Mathf.Max(0f, c.fxDelay) + d; }
return c.slashSeconds;
}
/// <summary>#962 원본 Skill_ShadowSlash.Set 의 Set_Invisible(2.1 s) 인자 훅 — invisibleMatch 면 난사 시간으로(이동 금지 · 무적 · 끝 대기 · 대상 뒤 순간이동이 모션 끝에 함께).</summary>
public static float InvisibleSeconds(float orig)
{
try { var c = Cfg; if (c.enabled == 0 || c.invisibleMatch == 0) return orig; return Mathf.Max(0.2f, SlashSec(c)); }
catch (System.Exception) { return orig; }
}
public static int FxShown;
static WLShadowSlashRunner s_runner;
static WLShadowSlashRunner Runner { get { if (s_runner == null) { var go = new GameObject("[WL954] ShadowSlashFx"); go.hideFlags = HideFlags.HideAndDontSave; Object.DontDestroyOnLoad(go); s_runner = go.AddComponent<WLShadowSlashRunner>(); } return s_runner; } }
@ -136,7 +176,7 @@ namespace WL.Combat.Weapon
static System.Collections.IEnumerator CoFx(Actor shooter, WLShadowSlashJson c, int seq)
{
if (c.fxDelay > 0f) yield return new WaitForSeconds(c.fxDelay);
float t0 = Time.time - c.fxDelay, until = c.fxRepeatSeconds > 0f ? c.fxRepeatSeconds : c.slashSeconds; int n = 0;
float t0 = Time.time - c.fxDelay, until = c.fxRepeatSeconds > 0f ? c.fxRepeatSeconds : SlashSec(c); int n = 0;
if (c.fxEndAlign != 0) until = Mathf.Max(c.fxDelay + 0.01f, until - Mathf.Max(0f, c.fxVisibleLife)); // #961 마지막 초승달이 난사 끝에 함께 사라지게
while (true)
{
@ -182,7 +222,8 @@ namespace WL.Combat.Weapon
static System.Collections.IEnumerator CoGhosts(Actor shooter, WLShadowSlashJson c, int seq)
{
float t0 = Time.time; var col = c.slashGhostColor != null && c.slashGhostColor.Length >= 4 ? c.slashGhostColor : null;
while (Time.time - t0 < c.slashSeconds)
float sec = SlashSec(c);
while (Time.time - t0 < sec)
{
if (DSUtil.CheckNull(shooter) || shooter.IsDead() || s_cancelSeq == seq) yield break;
if (WLGhostStrike.LiveGhost(shooter, col, c.slashGhostHold, c.slashGhostFade)) SlashGhostCount++;
@ -240,7 +281,14 @@ namespace WL.Combat.Weapon
int hits = 0, targets = 0, scheduled = 0; var hitQ = new System.Collections.Generic.Queue<float>(4); var hitTimes = new System.Text.StringBuilder(); // #960 휘두름마다 판정 시각을 쌓는다(프레임 끊김으로 틱 둘이 한 프레임에 와도 빠지지 않게)
try
{
while (Time.time - t0 < c.slashSeconds)
float sec = SlashSec(c);
if (c.slashHitEven != 0 && c.slashHits > 0) // #962 판정 시각을 미리 고르게
{
float span = Mathf.Max(0.05f, sec - Mathf.Max(0f, c.slashHitDelay));
for (int k = 0; k < c.slashHits; k++) hitQ.Enqueue(t0 + Mathf.Max(0f, c.slashHitDelay) + k * span / c.slashHits);
scheduled = c.slashHits;
}
while (Time.time - t0 < sec)
{
if (DSUtil.CheckNull(shooter) || shooter.IsDead()) break; // CurAnim 조건은 뺀다(실측: 3회 만에 끊겨 원본 콤보 전이 Attack3→4(회전)·Jump 사슬이 이어졌다)
if (c.dodgeCancel != 0 && shooter.Get_CurAnim() == eAnim.Dodge) { canceled = true; break; } // #961 구르기 = 캔슬(강제 재생보다 먼저 봐서 구르기 동작을 덮지 않는다)