[WL] #939~#942 피격 이펙트 교체(검 SlashHitBlue · 활 PinkSlashHit · 박힌 화살 제거) · 창 2타 찌르기 6연타 + 기계총 가림(창 방향 추종) · 피격 이펙트 몸 앞(카메라 쪽) · 시전 뒤 이동해도 지팡이 주력·활 각성 유지(lockUntilFire)
- WLImpactFx: swingFx follow/forward/side/life/minInterval/alignWeapon/massLocal · WLWeaponFollowFx · TowardCamera(hitTowardCamera) · 풀 반환은 끄기 전 Update - CombatAnimMapping 10701 Attack2~2f(속도 3 · 타격 3회) → pcanim_spear.controller · Spearman@Attack2_S 서브클립 - 사본 WL_Hit_Sword/SwordSkill(SlashHitBlue) · WL_Hit_Bow(PinkSlashHit) · WL_Impact_SpearBurst(FX_Machine Gun · loop 끔 · 줄기·섬광 평탄화) - WLSkillCancel: lockUntilFire(Skill_Hurricane · Skill_ArrowRain) · noSkip += Skill_Hurricane - 피격 카메라 쪽 당김: WLProjectileHitFx · WLSkillVfx hit · WLGreatWave · WLBladeStorm Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
c421d272fc
commit
9202f9c8fe
|
|
@ -733,7 +733,7 @@ ModelImporter:
|
|||
functionName: Move
|
||||
data:
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0.1
|
||||
floatParameter: 0.05
|
||||
intParameter: 0
|
||||
messageOptions: 0
|
||||
- time: 0.44
|
||||
|
|
@ -840,14 +840,7 @@ ModelImporter:
|
|||
functionName: Move
|
||||
data:
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0.1
|
||||
intParameter: 0
|
||||
messageOptions: 0
|
||||
- time: 0.44
|
||||
functionName: Projectile
|
||||
data: Projectile_10101
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0
|
||||
floatParameter: 0.05
|
||||
intParameter: 0
|
||||
messageOptions: 0
|
||||
transformMask: []
|
||||
|
|
@ -897,7 +890,7 @@ ModelImporter:
|
|||
functionName: Move
|
||||
data:
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0.1
|
||||
floatParameter: 0.05
|
||||
intParameter: 0
|
||||
messageOptions: 0
|
||||
- time: 0.44
|
||||
|
|
@ -911,6 +904,163 @@ ModelImporter:
|
|||
maskType: 0
|
||||
maskSource: {instanceID: 0}
|
||||
additiveReferencePoseFrame: 0
|
||||
- serializedVersion: 16
|
||||
name: Attack2d_S_10701
|
||||
takeName: Take 001
|
||||
internalID: -5059006814000262888
|
||||
firstFrame: 33
|
||||
lastFrame: 46
|
||||
wrapMode: 0
|
||||
orientationOffsetY: 0
|
||||
level: 0
|
||||
cycleOffset: 0
|
||||
loop: 0
|
||||
hasAdditiveReferencePose: 0
|
||||
loopTime: 0
|
||||
loopBlend: 0
|
||||
loopBlendOrientation: 1
|
||||
loopBlendPositionY: 1
|
||||
loopBlendPositionXZ: 0
|
||||
keepOriginalOrientation: 1
|
||||
keepOriginalPositionY: 1
|
||||
keepOriginalPositionXZ: 1
|
||||
heightFromFeet: 0
|
||||
mirror: 0
|
||||
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
|
||||
curves: []
|
||||
events:
|
||||
- time: 0
|
||||
functionName: LookAtTarget
|
||||
data:
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0
|
||||
intParameter: 0
|
||||
messageOptions: 0
|
||||
- time: 0.32
|
||||
functionName: ShowEffect
|
||||
data: Effect_Slash_10101_2
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0
|
||||
intParameter: 1
|
||||
messageOptions: 0
|
||||
- time: 0.38
|
||||
functionName: Move
|
||||
data:
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0.05
|
||||
intParameter: 0
|
||||
messageOptions: 0
|
||||
transformMask: []
|
||||
maskType: 0
|
||||
maskSource: {instanceID: 0}
|
||||
additiveReferencePoseFrame: 0
|
||||
- serializedVersion: 16
|
||||
name: Attack2e_S_10701
|
||||
takeName: Take 001
|
||||
internalID: 6234510843852800090
|
||||
firstFrame: 33
|
||||
lastFrame: 46
|
||||
wrapMode: 0
|
||||
orientationOffsetY: 0
|
||||
level: 0
|
||||
cycleOffset: 0
|
||||
loop: 0
|
||||
hasAdditiveReferencePose: 0
|
||||
loopTime: 0
|
||||
loopBlend: 0
|
||||
loopBlendOrientation: 1
|
||||
loopBlendPositionY: 1
|
||||
loopBlendPositionXZ: 0
|
||||
keepOriginalOrientation: 1
|
||||
keepOriginalPositionY: 1
|
||||
keepOriginalPositionXZ: 1
|
||||
heightFromFeet: 0
|
||||
mirror: 0
|
||||
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
|
||||
curves: []
|
||||
events:
|
||||
- time: 0
|
||||
functionName: LookAtTarget
|
||||
data:
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0
|
||||
intParameter: 0
|
||||
messageOptions: 0
|
||||
- time: 0.32
|
||||
functionName: ShowEffect
|
||||
data: Effect_Slash_10101_2
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0
|
||||
intParameter: 1
|
||||
messageOptions: 0
|
||||
- time: 0.38
|
||||
functionName: Move
|
||||
data:
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0.05
|
||||
intParameter: 0
|
||||
messageOptions: 0
|
||||
- time: 0.44
|
||||
functionName: Projectile
|
||||
data: Projectile_10101
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0
|
||||
intParameter: 0
|
||||
messageOptions: 0
|
||||
transformMask: []
|
||||
maskType: 0
|
||||
maskSource: {instanceID: 0}
|
||||
additiveReferencePoseFrame: 0
|
||||
- serializedVersion: 16
|
||||
name: Attack2f_S_10701
|
||||
takeName: Take 001
|
||||
internalID: -6788666626592393668
|
||||
firstFrame: 33
|
||||
lastFrame: 46
|
||||
wrapMode: 0
|
||||
orientationOffsetY: 0
|
||||
level: 0
|
||||
cycleOffset: 0
|
||||
loop: 0
|
||||
hasAdditiveReferencePose: 0
|
||||
loopTime: 0
|
||||
loopBlend: 0
|
||||
loopBlendOrientation: 1
|
||||
loopBlendPositionY: 1
|
||||
loopBlendPositionXZ: 0
|
||||
keepOriginalOrientation: 1
|
||||
keepOriginalPositionY: 1
|
||||
keepOriginalPositionXZ: 1
|
||||
heightFromFeet: 0
|
||||
mirror: 0
|
||||
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000
|
||||
curves: []
|
||||
events:
|
||||
- time: 0
|
||||
functionName: LookAtTarget
|
||||
data:
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0
|
||||
intParameter: 0
|
||||
messageOptions: 0
|
||||
- time: 0.32
|
||||
functionName: ShowEffect
|
||||
data: Effect_Slash_10101_2
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0
|
||||
intParameter: 1
|
||||
messageOptions: 0
|
||||
- time: 0.38
|
||||
functionName: Move
|
||||
data:
|
||||
objectReferenceParameter: {instanceID: 0}
|
||||
floatParameter: 0.05
|
||||
intParameter: 0
|
||||
messageOptions: 0
|
||||
transformMask: []
|
||||
maskType: 0
|
||||
maskSource: {instanceID: 0}
|
||||
additiveReferencePoseFrame: 0
|
||||
isReadable: 1
|
||||
meshes:
|
||||
lODScreenPercentages: []
|
||||
|
|
|
|||
|
|
@ -80,10 +80,10 @@ AnimatorState:
|
|||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Attack2c
|
||||
m_Speed: 1.5
|
||||
m_Speed: 3
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: -1702032561837743134}
|
||||
- {fileID: 6867887696765296130}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
|
|
@ -346,6 +346,28 @@ AnimatorStateTransition:
|
|||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1101 &-5049265843962658925
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions: []
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -1457214211898673553}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.15
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 1
|
||||
m_HasFixedDuration: 0
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1102 &-4643384778099596019
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
|
|
@ -354,7 +376,7 @@ AnimatorState:
|
|||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Attack2b
|
||||
m_Speed: 1.5
|
||||
m_Speed: 3
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: -6303488384549399601}
|
||||
|
|
@ -458,6 +480,56 @@ AnimatorState:
|
|||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1102 &-2630414053381351969
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Attack2f
|
||||
m_Speed: 3
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: 3733479137453790388}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: -6788666626592393668, guid: 53058ef486fc88f49820c30b8ca9e674,
|
||||
type: 3}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1101 &-2463007587306551008
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions: []
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -2630414053381351969}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.15
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 1
|
||||
m_HasFixedDuration: 0
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1102 &-1818568085792577103
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
|
|
@ -466,7 +538,7 @@ AnimatorState:
|
|||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Attack2
|
||||
m_Speed: 1.5
|
||||
m_Speed: 3
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: 1829211669066088794}
|
||||
|
|
@ -486,28 +558,34 @@ AnimatorState:
|
|||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1101 &-1702032561837743134
|
||||
AnimatorStateTransition:
|
||||
--- !u!1102 &-1457214211898673553
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions: []
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -4047895833455868784}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.15
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 1
|
||||
m_HasFixedDuration: 0
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
m_Name: Attack2e
|
||||
m_Speed: 3
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: -2463007587306551008}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: 6234510843852800090, guid: 53058ef486fc88f49820c30b8ca9e674,
|
||||
type: 3}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1102 &-1383661589576729455
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
|
|
@ -2246,6 +2324,15 @@ AnimatorStateMachine:
|
|||
- serializedVersion: 1
|
||||
m_State: {fileID: -7785429122263097812}
|
||||
m_Position: {x: 80, y: 100, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 53093606317774197}
|
||||
m_Position: {x: 115, y: 165, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: -1457214211898673553}
|
||||
m_Position: {x: 150, y: 230, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: -2630414053381351969}
|
||||
m_Position: {x: 185, y: 295, z: 0}
|
||||
m_ChildStateMachines: []
|
||||
m_AnyStateTransitions: []
|
||||
m_EntryTransitions: []
|
||||
|
|
@ -2310,6 +2397,34 @@ AnimatorStateMachine:
|
|||
m_ExitPosition: {x: 300, y: 60, z: 0}
|
||||
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
|
||||
m_DefaultState: {fileID: 110211406}
|
||||
--- !u!1102 &53093606317774197
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Attack2d
|
||||
m_Speed: 3
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: -5049265843962658925}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: -5059006814000262888, guid: 53058ef486fc88f49820c30b8ca9e674,
|
||||
type: 3}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1102 &146044103495546524
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
|
|
@ -2696,6 +2811,28 @@ AnimatorState:
|
|||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1101 &3733479137453790388
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions: []
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -4047895833455868784}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.15
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 1
|
||||
m_HasFixedDuration: 0
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1101 &4622039596610312686
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
|
|
@ -2878,6 +3015,28 @@ AnimatorStateTransition:
|
|||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1101 &6867887696765296130
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions: []
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 53093606317774197}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.15
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 1
|
||||
m_HasFixedDuration: 0
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1102 &8500637094174956195
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
|
|
|
|||
|
|
@ -1368,7 +1368,7 @@ MonoBehaviour:
|
|||
floatParameter: 0
|
||||
- classId: 10701
|
||||
note: "\uCC3D \xB7 Spear(WL 10701) \u2192 Spearman Attack2_S(1\uD0C0) \xB7 \uCC0C\uB974\uAE30
|
||||
\uAD6C\uAC04 \xD73(2\uD0C0) \xB7 Attack1(3\uD0C0) (#840 \uC7AC\uBC30\uC5F4)"
|
||||
\uAD6C\uAC04 \xD73(2\uD0C0) \xB7 Attack1(3\uD0C0) (#840 \uC7AC\uBC30\uC5F4 \xB7 #940 2\uD0C0 = \uCC0C\uB974\uAE30 6\uC5F0\uD0C0 \uC18D\uB3C4 3 \xB7 \uD0C0\uACA9 3)"
|
||||
controllerPathOverride: Assets/Res_Addr/Animations/pcanim_spear.controller
|
||||
enabled: 1
|
||||
states:
|
||||
|
|
@ -1411,7 +1411,7 @@ MonoBehaviour:
|
|||
createIfMissing: 0
|
||||
firstFrame: 33
|
||||
lastFrame: 46
|
||||
speed: 1.5
|
||||
speed: 3
|
||||
events:
|
||||
- functionName: LookAtTarget
|
||||
time: 0
|
||||
|
|
@ -1433,7 +1433,7 @@ MonoBehaviour:
|
|||
normalizedTime: 0.38
|
||||
stringParameter:
|
||||
intParameter: 0
|
||||
floatParameter: 0.1
|
||||
floatParameter: 0.05
|
||||
- functionName: Projectile
|
||||
time: 0
|
||||
useNormalized: 1
|
||||
|
|
@ -1449,7 +1449,7 @@ MonoBehaviour:
|
|||
createIfMissing: 1
|
||||
firstFrame: 33
|
||||
lastFrame: 46
|
||||
speed: 1.5
|
||||
speed: 3
|
||||
events:
|
||||
- functionName: LookAtTarget
|
||||
time: 0
|
||||
|
|
@ -1471,14 +1471,7 @@ MonoBehaviour:
|
|||
normalizedTime: 0.38
|
||||
stringParameter:
|
||||
intParameter: 0
|
||||
floatParameter: 0.1
|
||||
- functionName: Projectile
|
||||
time: 0
|
||||
useNormalized: 1
|
||||
normalizedTime: 0.44
|
||||
stringParameter: Projectile_10101
|
||||
intParameter: 0
|
||||
floatParameter: 0
|
||||
floatParameter: 0.05
|
||||
- stateName: Attack2c
|
||||
sourceFbxPath: Assets/ExplosiveLLC/Spearman Warrior Mecanim Animation Pack/Animations/Spearman@Attack2_S.FBX
|
||||
subClipName: Attack2c_S_{CID}
|
||||
|
|
@ -1487,7 +1480,7 @@ MonoBehaviour:
|
|||
createIfMissing: 1
|
||||
firstFrame: 33
|
||||
lastFrame: 46
|
||||
speed: 1.5
|
||||
speed: 3
|
||||
events:
|
||||
- functionName: LookAtTarget
|
||||
time: 0
|
||||
|
|
@ -1509,7 +1502,7 @@ MonoBehaviour:
|
|||
normalizedTime: 0.38
|
||||
stringParameter:
|
||||
intParameter: 0
|
||||
floatParameter: 0.1
|
||||
floatParameter: 0.05
|
||||
- functionName: Projectile
|
||||
time: 0
|
||||
useNormalized: 1
|
||||
|
|
@ -1517,6 +1510,106 @@ MonoBehaviour:
|
|||
stringParameter: Projectile_10101
|
||||
intParameter: 0
|
||||
floatParameter: 0
|
||||
- stateName: Attack2d
|
||||
sourceFbxPath: Assets/ExplosiveLLC/Spearman Warrior Mecanim Animation Pack/Animations/Spearman@Attack2_S.FBX
|
||||
subClipName: Attack2d_S_{CID}
|
||||
sourceClipName:
|
||||
incomingExitTime: 0.9
|
||||
createIfMissing: 1
|
||||
firstFrame: 33
|
||||
lastFrame: 46
|
||||
speed: 3
|
||||
events:
|
||||
- functionName: LookAtTarget
|
||||
time: 0
|
||||
useNormalized: 1
|
||||
normalizedTime: 0
|
||||
stringParameter:
|
||||
intParameter: 0
|
||||
floatParameter: 0
|
||||
- functionName: ShowEffect
|
||||
time: 0
|
||||
useNormalized: 1
|
||||
normalizedTime: 0.32
|
||||
stringParameter: Effect_Slash_10101_2
|
||||
intParameter: 1
|
||||
floatParameter: 0
|
||||
- functionName: Move
|
||||
time: 0
|
||||
useNormalized: 1
|
||||
normalizedTime: 0.38
|
||||
stringParameter:
|
||||
intParameter: 0
|
||||
floatParameter: 0.05
|
||||
- stateName: Attack2e
|
||||
sourceFbxPath: Assets/ExplosiveLLC/Spearman Warrior Mecanim Animation Pack/Animations/Spearman@Attack2_S.FBX
|
||||
subClipName: Attack2e_S_{CID}
|
||||
sourceClipName:
|
||||
incomingExitTime: 0.9
|
||||
createIfMissing: 1
|
||||
firstFrame: 33
|
||||
lastFrame: 46
|
||||
speed: 3
|
||||
events:
|
||||
- functionName: LookAtTarget
|
||||
time: 0
|
||||
useNormalized: 1
|
||||
normalizedTime: 0
|
||||
stringParameter:
|
||||
intParameter: 0
|
||||
floatParameter: 0
|
||||
- functionName: ShowEffect
|
||||
time: 0
|
||||
useNormalized: 1
|
||||
normalizedTime: 0.32
|
||||
stringParameter: Effect_Slash_10101_2
|
||||
intParameter: 1
|
||||
floatParameter: 0
|
||||
- functionName: Move
|
||||
time: 0
|
||||
useNormalized: 1
|
||||
normalizedTime: 0.38
|
||||
stringParameter:
|
||||
intParameter: 0
|
||||
floatParameter: 0.05
|
||||
- functionName: Projectile
|
||||
time: 0
|
||||
useNormalized: 1
|
||||
normalizedTime: 0.44
|
||||
stringParameter: Projectile_10101
|
||||
intParameter: 0
|
||||
floatParameter: 0
|
||||
- stateName: Attack2f
|
||||
sourceFbxPath: Assets/ExplosiveLLC/Spearman Warrior Mecanim Animation Pack/Animations/Spearman@Attack2_S.FBX
|
||||
subClipName: Attack2f_S_{CID}
|
||||
sourceClipName:
|
||||
incomingExitTime: 0.9
|
||||
createIfMissing: 1
|
||||
firstFrame: 33
|
||||
lastFrame: 46
|
||||
speed: 3
|
||||
events:
|
||||
- functionName: LookAtTarget
|
||||
time: 0
|
||||
useNormalized: 1
|
||||
normalizedTime: 0
|
||||
stringParameter:
|
||||
intParameter: 0
|
||||
floatParameter: 0
|
||||
- functionName: ShowEffect
|
||||
time: 0
|
||||
useNormalized: 1
|
||||
normalizedTime: 0.32
|
||||
stringParameter: Effect_Slash_10101_2
|
||||
intParameter: 1
|
||||
floatParameter: 0
|
||||
- functionName: Move
|
||||
time: 0
|
||||
useNormalized: 1
|
||||
normalizedTime: 0.38
|
||||
stringParameter:
|
||||
intParameter: 0
|
||||
floatParameter: 0.05
|
||||
- stateName: Attack3
|
||||
sourceFbxPath: Assets/ExplosiveLLC/Spearman Warrior Mecanim Animation Pack/Animations/Spearman@Attack1.FBX
|
||||
subClipName: Attack3_S_{CID}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0eda445e0da615240b665d3520bdd2b8
|
||||
guid: b045b4c9da72b1f44ac7a72a916693e5
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5f30f9a67194e8046aa88d000ef33761
|
||||
guid: 8951081eddb29cc44bd9b735a9bbb96e
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a0d786a009561ff41b2158114e70f619
|
||||
guid: b511e0a9c336908459c2fc3d8be6d6fc
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 978527634d822e34bbb34ddf9543ac06
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -4,6 +4,11 @@
|
|||
"sizeFactorMin": 0.5,
|
||||
"sizeFactorMax": 3.0,
|
||||
"bodyCenterFraction": 0.5,
|
||||
"_note_941": "#941 PD 「피격 이펙트는 몬스터보다 상단에 보여야 해」 — 피격 이펙트(hitFx · skillHitFx · 투사체별 명중 · 방패 치기 · 대검)를 몸 중심에서 카메라 쪽으로 (몸 너비 × 0.6 · 0.5~1.5 m) × hitTowardCamera 만큼 당긴다(화면 위치는 그대로 · 0 = 끔)",
|
||||
"hitTowardCamera": 1.0,
|
||||
"hitTowardWidthMul": 0.6,
|
||||
"hitTowardMin": 0.5,
|
||||
"hitTowardMax": 1.5,
|
||||
"flyingGap": 0.1,
|
||||
"profileWarmup": true,
|
||||
"profileSeconds": 2.5,
|
||||
|
|
@ -15,7 +20,7 @@
|
|||
],
|
||||
"prefab": "WL_Hit_Sword",
|
||||
"scale": 1.0,
|
||||
"fit": 1.3,
|
||||
"fit": 1.7,
|
||||
"offsetCompensate": true
|
||||
},
|
||||
{
|
||||
|
|
@ -47,7 +52,7 @@
|
|||
"skills": [],
|
||||
"prefab": "WL_Hit_SwordSkill",
|
||||
"scale": 1.0,
|
||||
"fit": 1.5,
|
||||
"fit": 1.9,
|
||||
"offsetCompensate": true
|
||||
},
|
||||
{
|
||||
|
|
@ -242,6 +247,37 @@
|
|||
"emitter": "slash_add",
|
||||
"radiusFit": 1.68,
|
||||
"sweepFlip": false
|
||||
},
|
||||
{
|
||||
"_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
|
||||
],
|
||||
"stages": [
|
||||
2
|
||||
],
|
||||
"prefab": "WL_Impact_SpearBurst",
|
||||
"scale": 0.6,
|
||||
"euler": [
|
||||
-90,
|
||||
90,
|
||||
0
|
||||
],
|
||||
"yOffset": -0.03,
|
||||
"calibrated": false,
|
||||
"follow": true,
|
||||
"forward": 0.885,
|
||||
"side": 0.89,
|
||||
"life": 1.0,
|
||||
"minInterval": 0.8,
|
||||
"_note_941": "#941 PD 「창 공격 시 이펙트와 캐릭터 방향이 일치하게」 — alignWeapon: 매 프레임 창 소켓(손잡이 → 창끝 · 수평) 방향으로 돌리고 손잡이에서 길이 × alignFraction 자리에 둔다(forward/side 는 이때 안 씀 · massLocal 로 섬광 묶음 중심 보정)",
|
||||
"alignWeapon": true,
|
||||
"alignFraction": 0.55,
|
||||
"massLocal": [
|
||||
1.06,
|
||||
1.62,
|
||||
-0.33
|
||||
]
|
||||
}
|
||||
],
|
||||
"groundFx": [
|
||||
|
|
|
|||
|
|
@ -28,7 +28,11 @@ namespace WL.Combat.Impact
|
|||
public sealed class WLSwingFxRule { public int[] classIds; public int[] stages; public string prefab; public float scale = 1f; public float[] euler; public float yOffset; public bool calibrated = true; public string emitter = ""; public float radiusFit = 1f; public bool sweepFlip; public float fallbackScale = 0.55f;
|
||||
public float minFacing;
|
||||
// #932 PD 「대검 1타는 모션을 내려치기로 바꾸지 말고 대각선 베기하면서 이펙트만 좀 더 잘보이게」 — 1 = 기울임 축을 호의 현(시작 → 끝 선 · 면 법선 × 이등분) 으로: 베는 방향(대각선)은 그대로 두고 초승달 가운데만 카메라 쪽으로 펼친다 · maxTilt = 최대 각(도)
|
||||
public int facingAxis; public float maxTilt = 40f; } // #928 0 보다 크면 초승달 면 법선과 시선의 |cos| 이 이 값보다 작을 때(카메라에서 면이 얇게 보일 때) 면을 카메라 쪽으로 그 값까지만 기울인다(피벗 고정)
|
||||
public int facingAxis; public float maxTilt = 40f; // #928 0 보다 크면 초승달 면 법선과 시선의 |cos| 이 이 값보다 작을 때(카메라에서 면이 얇게 보일 때) 면을 카메라 쪽으로 그 값까지만 기울인다(피벗 고정)
|
||||
// #940 PD 「창 2타 연타 때 무기 부분을 FX_Machine_Gun 으로 가려」 — calibrated 0 전용: follow = PC 에 붙여 따라감 · forward = PC 정면 거리(m) · life = 켜 둘 초(0 = 프리팹 길이) · minInterval = 같은 PC·단계의 ShowEffect 가 이 초 안에 또 오면 새로 띄우지 않고 궤적만 막는다(6연타 이벤트 → 이펙트 1개)
|
||||
public bool follow; public float forward; public float side; public float life; public float minInterval; // side = PC 오른쪽 거리(m)
|
||||
// #941 PD 「창 공격 시 이펙트와 캐릭터 방향이 일치하게」 — alignWeapon = 매 프레임 무기 소켓(손잡이 → 무기 끝) 방향에 맞춰 돌리고 손잡이에서 alignFraction 만큼 간 자리에 둔다(forward/side 는 안 씀) · massLocal = 프리팹 로컬 단위의 보이는 묶음 중심(원점 보정 · Play 실측)
|
||||
public bool alignWeapon; public float alignFraction = 0.5f; public float[] massLocal; }
|
||||
/// <summary>지면 충격파. tipContact = 칼끝이 지면(contactHeight 이내)에 닿는 프레임·자리에서 재생(단계 안에서 minDrop 이상 올라갔다 내려올 때) · 못 잡으면 timeout 뒤 최저점(fallbackHeight 이내)에.</summary>
|
||||
/// <summary>#900 frontOnly = PC 정면 쪽 접점만 인정(해머 1타 내려치기 — 뒤로 휘두를 때 등 뒤 지면 접점을 건너뛴다 · 2026-10-17 실측 −0.8 m).</summary>
|
||||
public sealed class WLGroundFxRule { public int[] classIds; public int stage; public string prefab; public float scale = 1f; public float forward; public bool tipContact = true; public float contactHeight = 0.15f; public float minDrop = 0.35f; public float timeout = 1.5f; public float fallbackHeight = 0.5f; public bool frontOnly; }
|
||||
|
|
@ -45,6 +49,8 @@ namespace WL.Combat.Impact
|
|||
public bool enabled = true;
|
||||
public float referenceHeight = 1f, sizeFactorMin = 0.5f, sizeFactorMax = 3f;
|
||||
public float bodyCenterFraction = 0.5f; // 몸 중심 높이 = 발 + 키 × 이 값
|
||||
// #941 PD 「피격 이펙트는 몬스터보다 상단에 보여야 해(몬스터에게 가려지기 때문)」 — 피격 이펙트를 몸 중심에서 카메라 쪽으로 (몸 너비 × hitTowardWidthMul · hitTowardMin~Max m) × hitTowardCamera 만큼 당겨 몸 앞에 그린다(화면 위치는 그대로) · 0 = 끔
|
||||
public float hitTowardCamera = 1f, hitTowardWidthMul = 0.6f, hitTowardMin = 0.5f, hitTowardMax = 1.5f;
|
||||
public float flyingGap = 0.1f; // #921 몸 그림 바닥이 발보다 이만큼(m) 넘게 높으면 떠 있는 몹 — 몸 중심 = 지금 그림(bounds) 가운데(오르내려도 정중앙) · 0 = 끔
|
||||
public bool profileWarmup = true; // 프리팹 프로필 실측(끄면 구 방식 배치)
|
||||
public float profileSeconds = 2.5f; // 프로필 실측 길이
|
||||
|
|
@ -138,6 +144,17 @@ namespace WL.Combat.Impact
|
|||
}
|
||||
public static Vector3 BodyCenter(Actor a) { return a == null ? Vector3.zero : GetBodyBox(a).center; }
|
||||
|
||||
/// <summary>#941 피격 이펙트를 몸 앞(카메라 쪽)에 두는 이동량 — 카메라가 없으면 0. 다른 피격 경로(방패 치기 · 대검 · 투사체별 명중)도 같은 식을 쓴다.</summary>
|
||||
public static Vector3 TowardCamera(Vector3 at, float bodyWidth)
|
||||
{
|
||||
var s = S; if (s == null || s.hitTowardCamera <= 0f) return Vector3.zero;
|
||||
var cam = Camera.main; if (cam == null) return Vector3.zero;
|
||||
var d = cam.transform.position - at; if (d.sqrMagnitude < 1e-4f) return Vector3.zero;
|
||||
float m = Mathf.Clamp(bodyWidth * s.hitTowardWidthMul, s.hitTowardMin, s.hitTowardMax) * s.hitTowardCamera;
|
||||
return d.normalized * m;
|
||||
}
|
||||
public static Vector3 TowardCamera(Actor a) { if (a == null) return Vector3.zero; var bb = GetBodyBox(a); return TowardCamera(bb.center, bb.width); }
|
||||
|
||||
public static float SizeFactor(Actor actor)
|
||||
{
|
||||
var s = S; if (actor == null || s == null || s.referenceHeight <= 0f) return 1f;
|
||||
|
|
@ -177,9 +194,10 @@ namespace WL.Combat.Impact
|
|||
float scale; string how;
|
||||
if (fit > 0f && prof != null && prof.extent > 1e-3f) { scale = scale0 * fit * bb.height / prof.extent; how = "fit"; }
|
||||
else { scale = scale0 * SizeFactor(target); how = "legacy"; }
|
||||
Vector3 pos = bb.center - (prof != null && offsetCompensate ? prof.centerOffset * scale : Vector3.zero);
|
||||
var toCam = TowardCamera(bb.center, bb.width); // #941 몸 앞(카메라 쪽)
|
||||
Vector3 pos = bb.center - (prof != null && offsetCompensate ? prof.centerOffset * scale : Vector3.zero) + toCam;
|
||||
if (Play(prefab, pos, Quaternion.identity, scale) == null) return false;
|
||||
LastHit = kind + " " + prefab + " → " + target.name + " (" + why + ") " + how + " scale=" + scale.ToString("F3") + " body h=" + bb.height.ToString("F2") + " w=" + bb.width.ToString("F2") + " center=" + bb.center.ToString("F2") + " feet=" + target.Get_position().ToString("F2");
|
||||
LastHit = kind + " " + prefab + " → " + target.name + " (" + why + ") " + how + " scale=" + scale.ToString("F3") + " body h=" + bb.height.ToString("F2") + " w=" + bb.width.ToString("F2") + " center=" + bb.center.ToString("F2") + " toCam=" + toCam.magnitude.ToString("F2") + " feet=" + target.Get_position().ToString("F2");
|
||||
LastLog = LastHit;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -265,7 +283,7 @@ namespace WL.Combat.Impact
|
|||
var r = s.swingFx[i];
|
||||
if (r == null || !Contains(r.classIds, cls) || (r.stages != null && r.stages.Length > 0 && !Contains(r.stages, stage))) continue;
|
||||
var tf = pc.transform;
|
||||
Quaternion rot; Vector3 pos; float scale; string how;
|
||||
Quaternion rot; Vector3 pos; float scale; string how; bool cal_used = false;
|
||||
SwingCalibration cal = null;
|
||||
var prof = r.calibrated ? Profile(r.prefab, r.emitter) : null;
|
||||
if (r.calibrated && SlashTrailSettings.Instance != null) cal = SlashTrailSettings.Instance.FindCalibration(cls, ev.stringParameter);
|
||||
|
|
@ -290,23 +308,35 @@ namespace WL.Combat.Impact
|
|||
}
|
||||
Vector3 pivotW = tf.position + tf.rotation * cal.pivot;
|
||||
pos = pivotW - rot * (prof.sweepCenter * scale) + Vector3.up * r.yOffset;
|
||||
SwingCalibrated++; how = "cal tilt=" + tilt.ToString("F0") + " axis=" + axis.ToString("F2") + " bis=" + bW.ToString("F2") + " sweep=" + cal.sweepDeg.ToString("F0") + (positive ? "+" : "-") + " tipR=" + cal.tipRadius.ToString("F2") + " pivot=" + pivotW.ToString("F2") + " effR=" + prof.sweepRadius.ToString("F2");
|
||||
SwingCalibrated++; cal_used = true; how = "cal tilt=" + tilt.ToString("F0") + " axis=" + axis.ToString("F2") + " bis=" + bW.ToString("F2") + " sweep=" + cal.sweepDeg.ToString("F0") + (positive ? "+" : "-") + " tipR=" + cal.tipRadius.ToString("F2") + " pivot=" + pivotW.ToString("F2") + " effR=" + prof.sweepRadius.ToString("F2");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (r.minInterval > 0f) // #940 연타 이벤트 묶음 — 첫 이벤트만 띄우고 나머지는 궤적만 막는다
|
||||
{
|
||||
long key = ((long)pc.GetInstanceID() << 4) | (long)(stage & 15); float last;
|
||||
if (s_swingAt.TryGetValue(key, out last) && Time.time - last < r.minInterval) { SwingThrottled++; LastSwing = "swing throttled stage " + stage; return true; }
|
||||
s_swingAt[key] = Time.time;
|
||||
}
|
||||
rot = tf.rotation * (r.euler != null && r.euler.Length >= 3 ? Quaternion.Euler(r.euler[0], r.euler[1], r.euler[2]) : Quaternion.identity);
|
||||
scale = r.scale * r.fallbackScale * SizeFactor(pc);
|
||||
pos = pc.Get_Center_position() + Vector3.up * r.yOffset;
|
||||
how = "legacy(" + (cal == null ? "no-cal" : prof == null ? "no-profile" : !prof.sweepValid ? "no-sweep" : "cal-kind") + ")";
|
||||
pos = pc.Get_Center_position() + tf.forward * r.forward + tf.right * r.side + Vector3.up * r.yOffset;
|
||||
how = "legacy(" + (cal == null ? "no-cal" : prof == null ? "no-profile" : !prof.sweepValid ? "no-sweep" : "cal-kind") + ")" + (r.follow ? " follow" : "");
|
||||
}
|
||||
if (Play(r.prefab, pos, rot, scale) == null) return false;
|
||||
var inst = Play(r.prefab, pos, rot, scale); if (inst == null) return false;
|
||||
if (r.follow) inst.transform.SetParent(tf, true); // #940 PC 를 따라간다(풀 반환 때 WLImpactOneShot 이 원래 부모로 되돌린다)
|
||||
if (r.life > 0f) { var os = inst.GetComponent<WLImpactOneShot>(); if (os != null) os.OverrideLife(r.life); }
|
||||
var fw = inst.GetComponent<WLWeaponFollowFx>(); // #941 무기 방향 추종
|
||||
if (r.alignWeapon && !cal_used) { if (fw == null) fw = inst.AddComponent<WLWeaponFollowFx>(); if (fw.Arm(pc, r, scale)) how += " alignWeapon"; else how += " alignWeapon(no-socket)"; }
|
||||
else if (fw != null) fw.Disarm();
|
||||
SwingShown++; LastSwing = "swing " + r.prefab + " stage " + stage + " " + how + " scale=" + scale.ToString("F3"); LastLog = LastSwing;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int SwingTilted;
|
||||
public static int SwingTilted, SwingThrottled;
|
||||
static readonly Dictionary<long, float> s_swingAt = new Dictionary<long, float>(); // #940 (PC, 단계) → 마지막으로 띄운 시각
|
||||
|
||||
/// <summary>#928 PD 「대검 1타 공격이 보는 방향에 따라서 너무 얇게 보여서 … 어느 방향에서 보더라도 검기처럼 보이게」 —
|
||||
/// 초승달 면 법선 n 과 시선(Camera.main)의 |cos| 이 minFacing 보다 작으면 n 을 시선 쪽(가까운 쪽 부호)으로 그 값이 될 만큼만 돌리는 회전(축 = n × 시선 · 가장 작은 회전) · deg = 돌린 각.
|
||||
|
|
@ -597,7 +627,7 @@ namespace WL.Combat.Impact
|
|||
{
|
||||
if (s_root == null) { var r = new GameObject("WL_ImpactFx"); Object.DontDestroyOnLoad(r); s_root = r.transform; }
|
||||
go = Object.Instantiate(p, s_root); go.name = prefab; go.SetActive(false);
|
||||
if (go.GetComponent<WLImpactOneShot>() == null) go.AddComponent<WLImpactOneShot>();
|
||||
var one = go.GetComponent<WLImpactOneShot>(); if (one == null) one = go.AddComponent<WLImpactOneShot>(); one.home = s_root;
|
||||
if (list == null) { list = new List<GameObject>(4); s_pool[prefab] = list; }
|
||||
list.Add(go);
|
||||
}
|
||||
|
|
@ -614,6 +644,36 @@ namespace WL.Combat.Impact
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>#941 궤적 교체 이펙트를 매 프레임 무기 소켓 방향(손잡이 → 무기 끝 · 수평)에 맞춘다 — 창 2타 기계총 가림처럼 PC 정면이 아니라 무기가 향한 쪽으로 쏘게. 자리 = 손잡이 + 방향 × 길이 × alignFraction + 위 yOffset − R × massLocal × 배율.</summary>
|
||||
public sealed class WLWeaponFollowFx : MonoBehaviour
|
||||
{
|
||||
Transform _socket; Vector3 _tipLocal, _mass; Quaternion _base; float _scale, _frac, _yOff; PCActor _pc; bool _armed;
|
||||
public static int Frames; public static string LastLog = "";
|
||||
public bool Arm(PCActor pc, WLSwingFxRule r, float scale)
|
||||
{
|
||||
_pc = pc; _scale = scale; _frac = r.alignFraction; _yOff = r.yOffset;
|
||||
_base = r.euler != null && r.euler.Length >= 3 ? Quaternion.Euler(r.euler[0], r.euler[1], r.euler[2]) : Quaternion.identity;
|
||||
_mass = r.massLocal != null && r.massLocal.Length >= 3 ? new Vector3(r.massLocal[0], r.massLocal[1], r.massLocal[2]) : Vector3.zero;
|
||||
_armed = WLImpactRunner.SocketTip(pc, out _socket, out _tipLocal);
|
||||
if (_armed) Apply();
|
||||
return _armed;
|
||||
}
|
||||
public void Disarm() { _armed = false; }
|
||||
void OnDisable() { _armed = false; }
|
||||
void LateUpdate() { if (_armed) Apply(); }
|
||||
void Apply()
|
||||
{
|
||||
if (_socket == null || _pc == null) { _armed = false; return; }
|
||||
Vector3 hilt = _socket.position, tip = _socket.TransformPoint(_tipLocal);
|
||||
Vector3 d = tip - hilt; float len = d.magnitude; d.y = 0f;
|
||||
if (d.sqrMagnitude < 1e-4f) d = _pc.transform.forward; d.Normalize();
|
||||
var rot = Quaternion.LookRotation(d, Vector3.up) * _base;
|
||||
Vector3 pos = hilt + d * (len * _frac) + Vector3.up * _yOff - rot * (_mass * _scale);
|
||||
transform.SetPositionAndRotation(pos, rot); Frames++;
|
||||
LastLog = "align hilt=" + hilt.ToString("F2") + " tip=" + tip.ToString("F2") + " dir=" + d.ToString("F2") + " pos=" + pos.ToString("F2");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>PC 에 붙는 러너 — 콤보 단계 진입 뒤 칼끝(WeaponTrailDriver) 높이를 추적해 지면 접점에서 충격파를 띄운다.</summary>
|
||||
public sealed class WLImpactRunner : MonoBehaviour
|
||||
{
|
||||
|
|
@ -725,6 +785,8 @@ namespace WL.Combat.Impact
|
|||
public sealed class WLImpactOneShot : MonoBehaviour
|
||||
{
|
||||
ParticleSystem[] _ps; float _life = -1f, _offAt;
|
||||
public Transform home; // #940 풀 루트 — follow 로 PC 에 붙었던 것을 꺼질 때 되돌린다
|
||||
public void OverrideLife(float sec) { if (sec > 0f) _offAt = Time.time + sec; } // #940 규칙의 life(초)
|
||||
void OnEnable()
|
||||
{
|
||||
if (_ps == null)
|
||||
|
|
@ -742,7 +804,8 @@ namespace WL.Combat.Impact
|
|||
for (int i = 0; i < _ps.Length; i++) { _ps[i].Clear(true); _ps[i].Play(true); }
|
||||
_offAt = Time.time + _life;
|
||||
}
|
||||
void Update() { if (Time.time >= _offAt) gameObject.SetActive(false); }
|
||||
// #940 follow 로 PC 에 붙었던 것은 끄기 전에 풀 루트로 되돌린다(OnDisable 안 SetParent 는 「already being activated or deactivated」 오류 — Play 실측 7건)
|
||||
void Update() { if (Time.time >= _offAt) { if (home != null && transform.parent != home) transform.SetParent(home, false); gameObject.SetActive(false); } }
|
||||
}
|
||||
|
||||
/// <summary>맞은 투사체를 몸 중심까지 조준 비행시킨 뒤 피격 이펙트와 함께 끈다(지팡이 마법 투사체).</summary>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,13 @@
|
|||
],
|
||||
"noSkip": [
|
||||
"Skill_ArrowRain",
|
||||
"Skill_FatalBlow"
|
||||
"Skill_FatalBlow",
|
||||
"Skill_Hurricane"
|
||||
],
|
||||
"_note_942": "#942 PD 「마법사 주력 스킬 … 플레이어가 이동해도 발동 된 스킬이 끊겨선 안돼 … 활 각성 스킬도 동일」 — Play 실측(CastMove): 시전 0.4~0.6 초 뒤 이동하면 발동 이벤트(SkillFired) 전에 시전 동작이 Run 으로 끊겨 투사체가 아예 안 나왔다(스킬발사 +0) → lockUntilFire = 발동까지만 이동·구르기 입력 무시(상한 holdMaxSeconds) · 발동 뒤 이동은 자유 · 투사체는 noSkip(Skill_Hurricane 추가 · Skill_ArrowRain 기존)으로 끝까지 유지",
|
||||
"lockUntilFire": [
|
||||
"Skill_Hurricane",
|
||||
"Skill_ArrowRain"
|
||||
],
|
||||
"holdMove": [
|
||||
"Skill_DashSlash"
|
||||
|
|
|
|||
|
|
@ -366,6 +366,7 @@ namespace WL.Combat.Weapon
|
|||
if (!s_hitPrefabs.TryGetValue(_c.hitFx, out prefab) || prefab == null) { prefab = Resources.Load<GameObject>(_c.hitFx); s_hitPrefabs[_c.hitFx] = prefab; }
|
||||
if (prefab == null) { WLBladeStorm.LastLog = "히트 이펙트 없음 " + _c.hitFx; return; }
|
||||
var at = a.Get_Center_position(); var d = at - from; d.y = 0f; if (d.sqrMagnitude < 1e-4f) d = _pc.transform.forward;
|
||||
at += WL.Combat.Impact.WLImpactFx.TowardCamera(a); // #941 몸 앞(카메라 쪽)
|
||||
var go = Instantiate(prefab, at, Quaternion.LookRotation(d) * prefab.transform.rotation);
|
||||
foreach (var ps in go.GetComponentsInChildren<ParticleSystem>(true)) { var m = ps.main; m.scalingMode = ParticleSystemScalingMode.Hierarchy; }
|
||||
go.transform.localScale = prefab.transform.localScale * Mathf.Max(0.01f, _c.hitFxScale);
|
||||
|
|
|
|||
|
|
@ -522,7 +522,7 @@ namespace WL.Combat.Weapon
|
|||
{
|
||||
f.hits++; f.last = now; WLGreatWave.Hits++;
|
||||
if (f.hits > WLGreatWave.MaxHitsOnOne) WLGreatWave.MaxHitsOnOne = f.hits;
|
||||
WLGreatWave.Spawn(c.hitFx, a.Get_Center_position(), Quaternion.LookRotation(_dir), c.hitFxScale, c.hitFxLife);
|
||||
WLGreatWave.Spawn(c.hitFx, a.Get_Center_position() + WL.Combat.Impact.WLImpactFx.TowardCamera(a), Quaternion.LookRotation(_dir), c.hitFxScale, c.hitFxLife); // #941 몸 앞(카메라 쪽)
|
||||
}
|
||||
}
|
||||
// 밀기 — 최대 횟수 전인 동안 앞머리와 함께(보스 제외 · 내비 위)
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ namespace WL.Combat.Weapon
|
|||
GameObject p;
|
||||
if (!s_prefabs.TryGetValue(prefab, out p) || p == null) { p = Resources.Load<GameObject>(prefab); s_prefabs[prefab] = p; }
|
||||
if (p == null) return false;
|
||||
var go = Instantiate(p, WL.Combat.Impact.WLImpactFx.BodyCenter(target), p.transform.rotation);
|
||||
var go = Instantiate(p, WL.Combat.Impact.WLImpactFx.BodyCenter(target) + WL.Combat.Impact.WLImpactFx.TowardCamera(target), p.transform.rotation); // #941 몸 앞(카메라 쪽)
|
||||
go.transform.localScale = p.transform.localScale * (scale * WL.Combat.Impact.WLImpactFx.SizeFactor(target));
|
||||
Destroy(go, Mathf.Max(0.2f, life));
|
||||
Shown++;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ namespace WL.Combat.Weapon
|
|||
public string[] noSkip = new string[0]; // 이동 · 구르기로 끊겨도 이펙트를 남기는 스킬
|
||||
public string[] holdMove = new string[0]; // #911 발동 뒤 공격 이펙트(이 PC 의 원본 스킬 투사체)가 끝날 때까지 이동 입력 무시 · 구르기는 허용(= 스킵)
|
||||
public string[] endWithMotion = new string[0]; // #914 스킬 동작이 입력 없이 끝나면(대기로) 그 스킬 이펙트도 바로 끈다 — 남은 이펙트 때문에 서 있지 않게
|
||||
public string[] lockUntilFire = new string[0]; // #942 시전 뒤 첫 발동(SkillFired)까지 이동 · 구르기 입력 무시(holdMaxSeconds 상한) — 발동 뒤엔 자유(투사체는 noSkip 으로 유지) · PD 「플레이어가 이동해도 발동 된 스킬이 끊겨선 안돼」(실측: 이동이 발동 이벤트 전에 시전 동작을 끊어 투사체가 아예 안 나왔다)
|
||||
public int holdUntilFire = 1; // 1 = 이동 키를 누른 채 쓴 스킬은 첫 발동까지 그 입력을 무시
|
||||
public float holdMaxSeconds = 1.5f; // ① 의 상한(발동 이벤트가 없는 스킬 대비)
|
||||
public string note = "";
|
||||
|
|
@ -48,7 +49,7 @@ namespace WL.Combat.Weapon
|
|||
static PCActor s_pc;
|
||||
static string s_effect = "";
|
||||
static float s_castAt;
|
||||
static bool s_active, s_fired, s_heldAtCast, s_lock, s_hold;
|
||||
static bool s_active, s_fired, s_heldAtCast, s_lock, s_hold, s_lockFire; // s_lockFire = #942 발동까지 잠금
|
||||
static int s_pendingBrake = -1; // -1 없음 · 0 = Set_AutoBraking(false) · 1 = Set_AutoBraking(true)
|
||||
static GameObject s_runner;
|
||||
static FieldInfo s_fDicSkill;
|
||||
|
|
@ -102,8 +103,9 @@ namespace WL.Combat.Weapon
|
|||
s_heldAtCast = pc.JoystickStatus == 1;
|
||||
s_lock = Has(c.lockMove, s_effect);
|
||||
s_hold = Has(c.holdMove, s_effect);
|
||||
s_lockFire = Has(c.lockUntilFire, s_effect);
|
||||
Casts++;
|
||||
LastLog = "시작 " + s_effect + (s_lock ? " · 이동 잠금" : "") + (s_heldAtCast ? " · 이동 키 누른 채" : "");
|
||||
LastLog = "시작 " + s_effect + (s_lock ? " · 이동 잠금" : "") + (s_lockFire ? " · 발동까지 잠금" : "") + (s_heldAtCast ? " · 이동 키 누른 채" : "");
|
||||
}
|
||||
|
||||
static void OnFired(in SkillFiredEvent e) { if (s_active && ReferenceEquals(e.actor, s_pc)) s_fired = true; }
|
||||
|
|
@ -141,6 +143,7 @@ namespace WL.Combat.Weapon
|
|||
if (!s_active || !ReferenceEquals(pc, s_pc) || pc.Get_CurAnim() != eAnim.Skill) return false;
|
||||
if (s_lock) return true;
|
||||
var c = Cfg;
|
||||
if (s_lockFire && !s_fired && Time.time - s_castAt < c.holdMaxSeconds) return true; // #942 발동 전엔 새 이동 입력도 무시
|
||||
return c.holdUntilFire != 0 && s_heldAtCast && !s_fired && Time.time - s_castAt < c.holdMaxSeconds;
|
||||
}
|
||||
|
||||
|
|
@ -155,7 +158,8 @@ namespace WL.Combat.Weapon
|
|||
/// <summary>WLDoubleTapDodge 훅 — 이동 잠금 스킬(점프) 중엔 구르기도 무시.</summary>
|
||||
public static bool BlockDodge(PCActor pc)
|
||||
{
|
||||
if (pc == null || !s_active || !s_lock || !ReferenceEquals(pc, s_pc) || pc.Get_CurAnim() != eAnim.Skill) return false;
|
||||
if (pc == null || !s_active || !ReferenceEquals(pc, s_pc) || pc.Get_CurAnim() != eAnim.Skill) return false;
|
||||
if (!s_lock && !(s_lockFire && !s_fired && Time.time - s_castAt < Cfg.holdMaxSeconds)) return false; // #942 발동 전 구르기도 무시
|
||||
DodgeBlocked++; return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ namespace WL.Combat.Weapon
|
|||
var dir = !DSUtil.CheckNull(e.attacker) ? at - e.attacker.Get_Center_position() : e.victim.transform.forward;
|
||||
dir.y = 0f;
|
||||
var rot = dir.sqrMagnitude > 1e-4f ? Quaternion.LookRotation(dir) : Quaternion.identity;
|
||||
if (Spawn(r.hit, at, rot)) Hits++;
|
||||
if (Spawn(r.hit, at + WL.Combat.Impact.WLImpactFx.TowardCamera(e.victim), rot)) Hits++; // #941 몸 앞(카메라 쪽)
|
||||
if ((r.launchHeight > 0f || r.stunSeconds > 0f) && WLLaunch.Apply(e.victim, r.launchHeight, r.launchSeconds, r.stunSeconds)) Launched++; // #902
|
||||
}
|
||||
catch (System.Exception ex) { Errors++; LastLog = "hit 실패 — " + ex.Message; }
|
||||
|
|
|
|||
Loading…
Reference in New Issue