Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7dd125bc0 | ||
|
|
f7eb2d4368 | ||
|
|
09bdda970a | ||
|
|
5ccab35948 | ||
|
|
bedb0f8ff4 | ||
|
|
01787e9c34 | ||
|
|
613f93c13e | ||
|
|
64822595b3 | ||
|
|
862a1e5899 | ||
|
|
5922ef373d | ||
|
|
1866f323e4 | ||
|
|
ef7ff63b67 | ||
|
|
8515dfa7ab | ||
|
|
3bafc4cbaa |
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"enabledPlugins": {
|
||||
"superpowers@claude-plugins-official": true,
|
||||
"ralph-loop@claude-plugins-official": true
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,16 @@
|
||||
{
|
||||
"permissions": {
|
||||
"dangerouslySkipPermissions": true,
|
||||
"allow": [
|
||||
"Read(*)",
|
||||
"Write(*)",
|
||||
"Bash(*)",
|
||||
"mcp__unity-mcp__*"
|
||||
]
|
||||
"mcp__unity-mcp__*",
|
||||
"PowerShell(Select-String -Path \"E:\\\\Works\\\\Unity\\\\Projects\\\\zeling_v2\\\\Assets\\\\_Game\\\\Prefabs\\\\Player\\\\Player.prefab\" -Pattern \"7ca41f67644b6b843ba7ef65e78b13e5\" -Context 2,8 | ForEach-Object { $_.Context.PreContext + $_.Line + $_.Context.PostContext })",
|
||||
"PowerShell(foreach \\($f in @\\(\"Combat\\\\EVT_CheckpointRespawn\",\"Core\\\\EVT_FadeOutRequest\",\"Core\\\\EVT_FadeInRequest\"\\)\\) { $g = \\(Get-Content \"E:\\\\Works\\\\Unity\\\\Projects\\\\zeling_v2\\\\Assets\\\\_Game\\\\Data\\\\Events\\\\$f.asset.meta\" | Select-String 'guid: \\(\\\\w+\\)'\\).Matches[0].Groups[1].Value; \"$f -> $g\" })",
|
||||
"PowerShell(Select-String *)",
|
||||
"PowerShell(rtk git *)",
|
||||
"PowerShell(Select-String -Path \"E:\\\\Works\\\\Unity\\\\Projects\\\\zeling_v2\\\\Assets\\\\_Game\\\\Prefabs\\\\Weapons\\\\WPN_WPN_DiHun_HitBox.prefab\" -Pattern \"adb4af2f574f356449634bc130f94592\" -Context 0,7 | ForEach-Object { $_.Line; $_.Context.PostContext })"
|
||||
],
|
||||
"dangerouslySkipPermissions": true
|
||||
}
|
||||
}
|
||||
|
||||
Submodule
+1
Submodule .claude/skills/planning-with-files added at 5f37e662b0
@@ -0,0 +1,28 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 96b10c11e6173394a8fa8d9c614b0035, type: 3}
|
||||
m_Name: CMB_Player_ATK_Air1
|
||||
m_EditorClassIdentifier:
|
||||
sourceId:
|
||||
skillId:
|
||||
BaseDamage: 10
|
||||
DamageMultiplier: 1
|
||||
Type: 0
|
||||
Category: 0
|
||||
Flags: 2
|
||||
Tags: 1
|
||||
KnockbackForce: 5
|
||||
HitStunDuration: 0.1
|
||||
BreakLevel: 1
|
||||
FxType: 1
|
||||
ComboWindowDuration: 0.4
|
||||
CancelWindowEnd: 0.5
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88812fa8d3e028a41b8a20f2ca90c9fa
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 96b10c11e6173394a8fa8d9c614b0035, type: 3}
|
||||
m_Name: CMB_Player_ATK_Air2
|
||||
m_EditorClassIdentifier:
|
||||
sourceId:
|
||||
skillId:
|
||||
BaseDamage: 10
|
||||
DamageMultiplier: 1
|
||||
Type: 0
|
||||
Category: 0
|
||||
Flags: 2
|
||||
Tags: 1
|
||||
KnockbackForce: 5
|
||||
HitStunDuration: 0.1
|
||||
BreakLevel: 1
|
||||
FxType: 1
|
||||
ComboWindowDuration: 0.4
|
||||
CancelWindowEnd: 0.5
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 967b72666e8bb2f498e4f7a03719e7c9
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 96b10c11e6173394a8fa8d9c614b0035, type: 3}
|
||||
m_Name: CMB_Player_ATK_Down
|
||||
m_EditorClassIdentifier:
|
||||
sourceId:
|
||||
skillId:
|
||||
BaseDamage: 10
|
||||
DamageMultiplier: 1
|
||||
Type: 0
|
||||
Category: 0
|
||||
Flags: 2
|
||||
Tags: 1
|
||||
KnockbackForce: 5
|
||||
HitStunDuration: 0.1
|
||||
BreakLevel: 1
|
||||
FxType: 1
|
||||
ComboWindowDuration: 0.4
|
||||
CancelWindowEnd: 0.5
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c81ccb5ed489a444b02709ec4506c5e
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 96b10c11e6173394a8fa8d9c614b0035, type: 3}
|
||||
m_Name: CMB_Player_ATK_Up
|
||||
m_EditorClassIdentifier:
|
||||
sourceId:
|
||||
skillId:
|
||||
BaseDamage: 10
|
||||
DamageMultiplier: 1
|
||||
Type: 0
|
||||
Category: 0
|
||||
Flags: 2
|
||||
Tags: 1
|
||||
KnockbackForce: 5
|
||||
HitStunDuration: 0.1
|
||||
BreakLevel: 1
|
||||
FxType: 1
|
||||
ComboWindowDuration: 0.4
|
||||
CancelWindowEnd: 0.5
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef2a60dea66f7e44c8659264b94a9c38
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -13,6 +13,7 @@ MonoBehaviour:
|
||||
m_Name: PROJ_Boomerang_Config
|
||||
m_EditorClassIdentifier:
|
||||
DamageSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2}
|
||||
MaxHits: 1
|
||||
Speed: 10
|
||||
Lifetime: 6
|
||||
LaunchAngleDeg: 0
|
||||
@@ -21,3 +22,6 @@ MonoBehaviour:
|
||||
PoolKey: PROJ_Boomerang
|
||||
ParrySpeedMultiplier: 1.2
|
||||
ParryDamageMultiplier: 2
|
||||
ReflectedTargetLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 134217728
|
||||
|
||||
@@ -13,6 +13,7 @@ MonoBehaviour:
|
||||
m_Name: PROJ_FeiZhi_Acid_Config
|
||||
m_EditorClassIdentifier:
|
||||
DamageSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2}
|
||||
MaxHits: 1
|
||||
Speed: 9
|
||||
Lifetime: 4
|
||||
LaunchAngleDeg: 45
|
||||
@@ -21,3 +22,6 @@ MonoBehaviour:
|
||||
PoolKey: PROJ_FeiZhi_Acid
|
||||
ParrySpeedMultiplier: 1.2
|
||||
ParryDamageMultiplier: 2
|
||||
ReflectedTargetLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 134217728
|
||||
|
||||
@@ -13,6 +13,7 @@ MonoBehaviour:
|
||||
m_Name: PROJ_TornadoLarge_Config
|
||||
m_EditorClassIdentifier:
|
||||
DamageSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2}
|
||||
MaxHits: 1
|
||||
Speed: 0
|
||||
Lifetime: 5
|
||||
LaunchAngleDeg: 0
|
||||
@@ -21,3 +22,6 @@ MonoBehaviour:
|
||||
PoolKey: PROJ_TornadoLarge
|
||||
ParrySpeedMultiplier: 1.2
|
||||
ParryDamageMultiplier: 2
|
||||
ReflectedTargetLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 134217728
|
||||
|
||||
@@ -13,6 +13,7 @@ MonoBehaviour:
|
||||
m_Name: PROJ_TornadoSmall_Config
|
||||
m_EditorClassIdentifier:
|
||||
DamageSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2}
|
||||
MaxHits: 1
|
||||
Speed: 7
|
||||
Lifetime: 4
|
||||
LaunchAngleDeg: 0
|
||||
@@ -21,3 +22,6 @@ MonoBehaviour:
|
||||
PoolKey: PROJ_TornadoSmall
|
||||
ParrySpeedMultiplier: 1.2
|
||||
ParryDamageMultiplier: 2
|
||||
ReflectedTargetLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 134217728
|
||||
|
||||
@@ -13,6 +13,7 @@ MonoBehaviour:
|
||||
m_Name: PROJ_WindStone_Config
|
||||
m_EditorClassIdentifier:
|
||||
DamageSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2}
|
||||
MaxHits: 1
|
||||
Speed: 6
|
||||
Lifetime: 4
|
||||
LaunchAngleDeg: -90
|
||||
@@ -21,3 +22,6 @@ MonoBehaviour:
|
||||
PoolKey: PROJ_WindStone
|
||||
ParrySpeedMultiplier: 1.2
|
||||
ParryDamageMultiplier: 2
|
||||
ReflectedTargetLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 134217728
|
||||
|
||||
@@ -13,6 +13,7 @@ MonoBehaviour:
|
||||
m_Name: PROJ_ZhiMu_Acid_Config
|
||||
m_EditorClassIdentifier:
|
||||
DamageSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2}
|
||||
MaxHits: 1
|
||||
Speed: 9
|
||||
Lifetime: 4
|
||||
LaunchAngleDeg: 45
|
||||
@@ -21,3 +22,6 @@ MonoBehaviour:
|
||||
PoolKey: PROJ_ZhiMu_Acid
|
||||
ParrySpeedMultiplier: 1.2
|
||||
ParryDamageMultiplier: 2
|
||||
ReflectedTargetLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 134217728
|
||||
|
||||
@@ -63,7 +63,7 @@ MonoBehaviour:
|
||||
_Names: []
|
||||
_Clip: {fileID: 7400000, guid: bde6a54ec8fc04f45a424f9bcd7845df, type: 2}
|
||||
_NormalizedStartTime: NaN
|
||||
damageSource: {fileID: 0}
|
||||
damageSource: {fileID: 11400000, guid: 88812fa8d3e028a41b8a20f2ca90c9fa, type: 2}
|
||||
hitBoxEnter: 0.1
|
||||
hitBoxExit: 0.8
|
||||
comboInputOpen: 0
|
||||
@@ -81,7 +81,7 @@ MonoBehaviour:
|
||||
_Names: []
|
||||
_Clip: {fileID: 7400000, guid: c0ef319f521c2a2448022cebcf9c9266, type: 2}
|
||||
_NormalizedStartTime: NaN
|
||||
damageSource: {fileID: 0}
|
||||
damageSource: {fileID: 11400000, guid: 967b72666e8bb2f498e4f7a03719e7c9, type: 2}
|
||||
hitBoxEnter: 0.1
|
||||
hitBoxExit: 0.8
|
||||
comboInputOpen: 0.026
|
||||
@@ -100,7 +100,7 @@ MonoBehaviour:
|
||||
_Names: []
|
||||
_Clip: {fileID: 7400000, guid: baae11fb27958444d911f8d637448184, type: 2}
|
||||
_NormalizedStartTime: NaN
|
||||
damageSource: {fileID: 0}
|
||||
damageSource: {fileID: 11400000, guid: ef2a60dea66f7e44c8659264b94a9c38, type: 2}
|
||||
hitBoxEnter: 0.2
|
||||
hitBoxExit: 0.7
|
||||
comboInputOpen: 0
|
||||
@@ -119,7 +119,7 @@ MonoBehaviour:
|
||||
_Names: []
|
||||
_Clip: {fileID: 7400000, guid: d199f06821d6b92478f9fd7c3f0cd11d, type: 2}
|
||||
_NormalizedStartTime: NaN
|
||||
damageSource: {fileID: 0}
|
||||
damageSource: {fileID: 11400000, guid: 6c81ccb5ed489a444b02709ec4506c5e, type: 2}
|
||||
hitBoxEnter: 0.1
|
||||
hitBoxExit: 0.9
|
||||
comboInputOpen: 0
|
||||
|
||||
@@ -29,6 +29,7 @@ MonoBehaviour:
|
||||
DashCooldown: 0.4
|
||||
DashInvincibilityDuration: 0.2
|
||||
DashInvincibilityCooldown: 0.9
|
||||
PogoBounceForce: 15
|
||||
DownDashSpeed: 22
|
||||
DownDashDuration: 0.25
|
||||
WallSlideSpeed: 3
|
||||
|
||||
@@ -21,4 +21,4 @@ MonoBehaviour:
|
||||
SpringKillThreshold: 4
|
||||
InvincibilityDuration: 0.6
|
||||
InitialLingZhu: 0
|
||||
InitialAbilities: 4194295
|
||||
InitialAbilities: 4194167
|
||||
|
||||
@@ -657,6 +657,11 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
_defaultSource: {fileID: 11400000, guid: caae9c7600281fe4e8d8637fa3fd2ca1, type: 2}
|
||||
_hitCooldown: 0.1
|
||||
_hitMode: 0
|
||||
_hitInterval: 0.5
|
||||
_targetLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 32768
|
||||
_id:
|
||||
_rivalHitBoxMask:
|
||||
serializedVersion: 2
|
||||
|
||||
@@ -248,6 +248,7 @@ GameObject:
|
||||
- component: {fileID: 8116248334753210478}
|
||||
- component: {fileID: 2674139131311821727}
|
||||
- component: {fileID: 1348220184733719450}
|
||||
- component: {fileID: 6289226623396459915}
|
||||
m_Layer: 9
|
||||
m_Name: Player
|
||||
m_TagString: Player
|
||||
@@ -777,8 +778,22 @@ MonoBehaviour:
|
||||
serializedVersion: 2
|
||||
m_Bits: 16777216
|
||||
_inputReader: {fileID: 11400000, guid: 88fadef8bc554e04483edd7418d20aa2, type: 2}
|
||||
_onShowInteractPrompt: {fileID: 11400000, guid: 18bb3dbe7d352dc4a9b62b13e068eb9d, type: 2}
|
||||
_onHideInteractPrompt: {fileID: 11400000, guid: b8cfbee27c2493e4ea75b4158a74a7c4, type: 2}
|
||||
--- !u!114 &6289226623396459915
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6834103521996502824}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 7ca41f67644b6b843ba7ef65e78b13e5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_onCheckpointRespawn: {fileID: 11400000, guid: eef5aef659932dd448be6d91119082e6, type: 2}
|
||||
_onFadeOutRequest: {fileID: 11400000, guid: a17901d6793dcf2409e2672ffb383208, type: 2}
|
||||
_onFadeInRequest: {fileID: 11400000, guid: f8d520fe699782b4184ff72ce5200c25, type: 2}
|
||||
_fadeHalfDuration: 0.2
|
||||
--- !u!1001 &5247753868797769228
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -27,7 +27,7 @@ Transform:
|
||||
m_GameObject: {fileID: 1932889250901504761}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalPosition: {x: 0, y: -1.099, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
@@ -65,7 +65,7 @@ BoxCollider2D:
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_UsedByComposite: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Offset: {x: 0.15452856, y: -0.38786495}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0, y: 0}
|
||||
@@ -76,7 +76,7 @@ BoxCollider2D:
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
serializedVersion: 2
|
||||
m_Size: {x: 1, y: 0.5}
|
||||
m_Size: {x: 1.6900157, y: 1.2757299}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!114 &6478051166999031478
|
||||
MonoBehaviour:
|
||||
@@ -92,6 +92,11 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
_defaultSource: {fileID: 0}
|
||||
_hitCooldown: 0.1
|
||||
_hitMode: 0
|
||||
_hitInterval: 0.5
|
||||
_targetLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 134217728
|
||||
_id:
|
||||
_rivalHitBoxMask:
|
||||
serializedVersion: 2
|
||||
@@ -161,7 +166,7 @@ BoxCollider2D:
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_UsedByComposite: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Offset: {x: 0.84977627, y: -0.11744261}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0, y: 0}
|
||||
@@ -172,7 +177,7 @@ BoxCollider2D:
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
serializedVersion: 2
|
||||
m_Size: {x: 1, y: 0.5}
|
||||
m_Size: {x: 1.1095867, y: 1.4387312}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!114 &4757677899241504248
|
||||
MonoBehaviour:
|
||||
@@ -188,6 +193,11 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
_defaultSource: {fileID: 0}
|
||||
_hitCooldown: 0.1
|
||||
_hitMode: 0
|
||||
_hitInterval: 0.5
|
||||
_targetLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 134217728
|
||||
_id:
|
||||
_rivalHitBoxMask:
|
||||
serializedVersion: 2
|
||||
@@ -219,7 +229,7 @@ Transform:
|
||||
m_GameObject: {fileID: 4335406389674002762}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalPosition: {x: 0, y: 1.349, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
@@ -257,7 +267,7 @@ BoxCollider2D:
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_UsedByComposite: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Offset: {x: 0.1258812, y: -0.178514}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0, y: 0}
|
||||
@@ -268,7 +278,7 @@ BoxCollider2D:
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
serializedVersion: 2
|
||||
m_Size: {x: 0.5, y: 1}
|
||||
m_Size: {x: 1.5816574, y: 0.7235365}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!114 &1392799324577637263
|
||||
MonoBehaviour:
|
||||
@@ -284,6 +294,11 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
_defaultSource: {fileID: 0}
|
||||
_hitCooldown: 0.1
|
||||
_hitMode: 0
|
||||
_hitInterval: 0.5
|
||||
_targetLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 134217728
|
||||
_id:
|
||||
_rivalHitBoxMask:
|
||||
serializedVersion: 2
|
||||
@@ -298,6 +313,7 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 8975424752584779179}
|
||||
- component: {fileID: 3691925044832415471}
|
||||
- component: {fileID: 7280738434496013396}
|
||||
m_Layer: 0
|
||||
m_Name: WPN_WPN_DiHun_HitBox
|
||||
m_TagString: Untagged
|
||||
@@ -340,6 +356,24 @@ MonoBehaviour:
|
||||
_hitBoxUp: {fileID: 1392799324577637263}
|
||||
_hitBoxDown: {fileID: 6478051166999031478}
|
||||
_hitBoxAir: {fileID: 1382006829078153708}
|
||||
--- !u!114 &7280738434496013396
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4821376343125962025}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: adb4af2f574f356449634bc130f94592, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_onHitLight: {fileID: 0}
|
||||
_onHitMedium: {fileID: 0}
|
||||
_onHitHeavy: {fileID: 0}
|
||||
_hitPositionMode: 1
|
||||
_onAttackWhoosh: {fileID: 0}
|
||||
_namedPresets: []
|
||||
--- !u!1 &6434981771063321190
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -405,7 +439,7 @@ BoxCollider2D:
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_UsedByComposite: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Offset: {x: 0.84977627, y: -0.11744261}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0, y: 0}
|
||||
@@ -416,7 +450,7 @@ BoxCollider2D:
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
serializedVersion: 2
|
||||
m_Size: {x: 0.5, y: 1}
|
||||
m_Size: {x: 1.1095867, y: 1.4387312}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!114 &1382006829078153708
|
||||
MonoBehaviour:
|
||||
@@ -432,6 +466,11 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
_defaultSource: {fileID: 0}
|
||||
_hitCooldown: 0.1
|
||||
_hitMode: 0
|
||||
_hitInterval: 0.5
|
||||
_targetLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 134217728
|
||||
_id:
|
||||
_rivalHitBoxMask:
|
||||
serializedVersion: 2
|
||||
|
||||
@@ -9203,6 +9203,37 @@ BoxCollider2D:
|
||||
serializedVersion: 2
|
||||
m_Size: {x: 0.1, y: 4}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!1 &505494683
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 505494684}
|
||||
m_Layer: 0
|
||||
m_Name: RespawnPoint
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &505494684
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 505494683}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 1.7, y: -0.48, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 2146472069}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &510769166
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -15949,6 +15980,102 @@ Transform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1328380148}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &960547552
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 960547555}
|
||||
- component: {fileID: 960547554}
|
||||
- component: {fileID: 960547553}
|
||||
m_Layer: 24
|
||||
m_Name: CheckpointMarker_2
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &960547553
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 960547552}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 81b8a6464ad9a90459fa28f2a0e1ce02, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_playerLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 512
|
||||
_respawnPoint: {fileID: 1476535863}
|
||||
_onCheckpointReached: {fileID: 11400000, guid: 172e9bc777b1b4b4b99f47e43cbaedb1, type: 2}
|
||||
--- !u!61 &960547554
|
||||
BoxCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 960547552}
|
||||
m_Enabled: 1
|
||||
m_Density: 1
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_ForceSendLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ForceReceiveLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ContactCaptureLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_CallbackLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_UsedByComposite: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0, y: 0}
|
||||
oldSize: {x: 0, y: 0}
|
||||
newSize: {x: 0, y: 0}
|
||||
adaptiveTilingThreshold: 0
|
||||
drawMode: 0
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
serializedVersion: 2
|
||||
m_Size: {x: 1, y: 2}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!4 &960547555
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 960547552}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: -34.06, y: 2.2, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 1476535863}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &985676459
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -22824,6 +22951,157 @@ PolygonCollider2D:
|
||||
- {x: -13, y: 14}
|
||||
- {x: -13, y: -17}
|
||||
m_UseDelaunayMesh: 0
|
||||
--- !u!1 &1288627275
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1288627279}
|
||||
- component: {fileID: 1288627278}
|
||||
- component: {fileID: 1288627277}
|
||||
- component: {fileID: 1288627276}
|
||||
m_Layer: 25
|
||||
m_Name: LethalTrap
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &1288627276
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1288627275}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 03c34fc042c310942a02cfa075dcd981, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_damage: 1
|
||||
_playerLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 32768
|
||||
_onPlayerDied: {fileID: 11400000, guid: 7e1624bde83886d40b32f43e84a65a75, type: 2}
|
||||
_onCheckpointRespawn: {fileID: 11400000, guid: eef5aef659932dd448be6d91119082e6, type: 2}
|
||||
_canPogo: 1
|
||||
--- !u!212 &1288627277
|
||||
SpriteRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1288627275}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 0
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: 6c1a7b756ba1d4646a405f7f6e0833ad, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 0
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_Sprite: {fileID: 7482667652216324306, guid: 311925a002f4447b3a28927169b83ea6, type: 3}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_FlipX: 0
|
||||
m_FlipY: 0
|
||||
m_DrawMode: 0
|
||||
m_Size: {x: 1, y: 1}
|
||||
m_AdaptiveModeThreshold: 0.5
|
||||
m_SpriteTileMode: 0
|
||||
m_WasSpriteAssigned: 1
|
||||
m_MaskInteraction: 0
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!61 &1288627278
|
||||
BoxCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1288627275}
|
||||
m_Enabled: 1
|
||||
m_Density: 1
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_ForceSendLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ForceReceiveLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ContactCaptureLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_CallbackLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_UsedByComposite: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
oldSize: {x: 1, y: 1}
|
||||
newSize: {x: 1, y: 1}
|
||||
adaptiveTilingThreshold: 0.5
|
||||
drawMode: 0
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
serializedVersion: 2
|
||||
m_Size: {x: 2, y: 0.5}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!4 &1288627279
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1288627275}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: -30.57, y: 1.49, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 2040911888}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1295644709
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -25323,10 +25601,13 @@ MonoBehaviour:
|
||||
_hitCooldown: 0.1
|
||||
_hitMode: 1
|
||||
_hitInterval: 0.5
|
||||
_targetLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 32768
|
||||
_id:
|
||||
_rivalHitBoxMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 512
|
||||
m_Bits: 0
|
||||
--- !u!58 &1380656263
|
||||
CircleCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -26015,7 +26296,7 @@ MonoBehaviour:
|
||||
_edgeCheckDownLen: 0.6
|
||||
_groundMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_Bits: 256
|
||||
--- !u!114 &1409939195
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -28100,6 +28381,37 @@ Transform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 368251301}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1476535862
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1476535863}
|
||||
m_Layer: 0
|
||||
m_Name: RespawnPoint
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1476535863
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1476535862}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: -2.04, y: -0.69, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 960547555}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1476942765
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -208662,6 +208974,37 @@ Transform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1223440397}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1608402817
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1608402818}
|
||||
m_Layer: 0
|
||||
m_Name: RespawnPoint
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1608402818
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1608402817}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 6.3, y: -0.31, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 2124924423}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1611181745
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -215691,6 +216034,98 @@ PolygonCollider2D:
|
||||
- {x: -19.5, y: 7.5}
|
||||
- {x: -19.5, y: -2.5}
|
||||
m_UseDelaunayMesh: 0
|
||||
--- !u!1 &2040911887
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2040911888}
|
||||
- component: {fileID: 2040911890}
|
||||
- component: {fileID: 2040911889}
|
||||
m_Layer: 27
|
||||
m_Name: HurtBox
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &2040911888
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2040911887}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1288627279}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &2040911889
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2040911887}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d7b7a233d7f70aa4f86b473412b826de, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_onDamageDealt: {fileID: 0}
|
||||
_onHitConfirmed: {fileID: 0}
|
||||
--- !u!61 &2040911890
|
||||
BoxCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2040911887}
|
||||
m_Enabled: 1
|
||||
m_Density: 1
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_ForceSendLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ForceReceiveLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ContactCaptureLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_CallbackLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_UsedByComposite: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0, y: 0}
|
||||
oldSize: {x: 0, y: 0}
|
||||
newSize: {x: 0, y: 0}
|
||||
adaptiveTilingThreshold: 0
|
||||
drawMode: 0
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
serializedVersion: 2
|
||||
m_Size: {x: 2, y: 0.3}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!1 &2043137490
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -216962,6 +217397,102 @@ Transform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 432776958}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &2124924420
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2124924423}
|
||||
- component: {fileID: 2124924422}
|
||||
- component: {fileID: 2124924421}
|
||||
m_Layer: 24
|
||||
m_Name: CheckpointMarker_1
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &2124924421
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2124924420}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 81b8a6464ad9a90459fa28f2a0e1ce02, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_playerLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 512
|
||||
_respawnPoint: {fileID: 1608402818}
|
||||
_onCheckpointReached: {fileID: 11400000, guid: 172e9bc777b1b4b4b99f47e43cbaedb1, type: 2}
|
||||
--- !u!61 &2124924422
|
||||
BoxCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2124924420}
|
||||
m_Enabled: 1
|
||||
m_Density: 1
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_ForceSendLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ForceReceiveLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ContactCaptureLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_CallbackLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_UsedByComposite: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0, y: 0}
|
||||
oldSize: {x: 0, y: 0}
|
||||
newSize: {x: 0, y: 0}
|
||||
adaptiveTilingThreshold: 0
|
||||
drawMode: 0
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
serializedVersion: 2
|
||||
m_Size: {x: 1, y: 2}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!4 &2124924423
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2124924420}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: -20.24, y: 3.03, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 1608402818}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &2127047899
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -217340,6 +217871,102 @@ Transform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 81962682}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &2146472066
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2146472069}
|
||||
- component: {fileID: 2146472068}
|
||||
- component: {fileID: 2146472067}
|
||||
m_Layer: 24
|
||||
m_Name: CheckpointMarker
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &2146472067
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2146472066}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 81b8a6464ad9a90459fa28f2a0e1ce02, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_playerLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 512
|
||||
_respawnPoint: {fileID: 505494684}
|
||||
_onCheckpointReached: {fileID: 11400000, guid: 172e9bc777b1b4b4b99f47e43cbaedb1, type: 2}
|
||||
--- !u!61 &2146472068
|
||||
BoxCollider2D:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2146472066}
|
||||
m_Enabled: 1
|
||||
m_Density: 1
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_ForceSendLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ForceReceiveLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_ContactCaptureLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_CallbackLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_IsTrigger: 1
|
||||
m_UsedByEffector: 0
|
||||
m_UsedByComposite: 0
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_SpriteTilingProperty:
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
pivot: {x: 0, y: 0}
|
||||
oldSize: {x: 0, y: 0}
|
||||
newSize: {x: 0, y: 0}
|
||||
adaptiveTilingThreshold: 0
|
||||
drawMode: 0
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
serializedVersion: 2
|
||||
m_Size: {x: 1, y: 2}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!4 &2146472069
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2146472066}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: -24.6, y: 2.05, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 505494684}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1660057539 &9223372036854775807
|
||||
SceneRoots:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -217348,3 +217975,7 @@ SceneRoots:
|
||||
- {fileID: 1354690328}
|
||||
- {fileID: 783576435}
|
||||
- {fileID: 1409939202}
|
||||
- {fileID: 1288627279}
|
||||
- {fileID: 2146472069}
|
||||
- {fileID: 2124924423}
|
||||
- {fileID: 960547555}
|
||||
|
||||
@@ -34,8 +34,15 @@ namespace BaseGames.Combat
|
||||
/// </summary>
|
||||
[System.NonSerialized] public uint HitActivationId;
|
||||
/// <summary>
|
||||
/// 命中点世界坐标。HitBox 结算时写入精确接触点(ClosestPoint);
|
||||
/// 直接调用 HurtBox.ReceiveDamage 的路径由 HurtBox 以解析后的命中点兜底写入。
|
||||
/// 供"击中位置"模式的反馈在该点生成(FeedbackPositionMode.HitPoint)。
|
||||
/// [NonSerialized]:运行时逐次命中生成,不需要序列化。
|
||||
/// </summary>
|
||||
[System.NonSerialized] public Vector3 HitPoint;
|
||||
/// <summary>
|
||||
/// 攻击来源投射物(仅当攻击方是 Projectile 时非 null)。
|
||||
/// 用于弹反成功时调用 ReflectAsPlayerProjectile() 翻转阵营。
|
||||
/// 用于弹反成功时调用 ReflectBy(parrier) 按弹反者阵营反射(玩家弹反才翻转阵营)。
|
||||
/// [NonSerialized]:MonoBehaviour 引用不参与 Unity 资产序列化。
|
||||
/// </summary>
|
||||
[System.NonSerialized] public Projectile SourceProjectile;
|
||||
|
||||
@@ -34,6 +34,12 @@ namespace BaseGames.Combat
|
||||
[Tooltip("Interval 模式下,对同一目标重复造成伤害的间隔(秒)。")]
|
||||
[SerializeField] private float _hitInterval = 0.5f;
|
||||
|
||||
[Header("伤害目标")]
|
||||
[Tooltip("本判定盒可造成伤害的 Layer(实例级过滤,叠加在 Physics2D 碰撞矩阵之上)。" +
|
||||
"矩阵决定哪些层之间会产生 Trigger 事件(全局),此掩码决定事件发生后是否实际结算伤害(单盒)。" +
|
||||
"默认 Everything = 行为与仅靠矩阵时一致。典型配置:EnemyHitBox 盒勾 PlayerHurtBox(不误伤友军则不勾 EnemyHurtBox)。")]
|
||||
[SerializeField] private LayerMask _targetLayers = ~0;
|
||||
|
||||
/// <summary>
|
||||
/// HitBox 标识符,供 PlayerAnimationEvents / EnemyAnimationEvents 按名称精确激活特定判定盒。
|
||||
/// 留空表示"无 Id";事件 payload 为空时将操作所有 HitBox。
|
||||
@@ -77,6 +83,13 @@ namespace BaseGames.Combat
|
||||
/// <summary>命中确认委托(PlayerCombat / EnemyCombat 订阅)。</summary>
|
||||
public event System.Action<DamageInfo> OnHitConfirmed;
|
||||
|
||||
/// <summary>
|
||||
/// 命中可破坏物(IBreakable)确认事件。
|
||||
/// 与 OnHitConfirmed 区分:不走 HurtBox 伤害流水线,不参与灵力获取;
|
||||
/// 供下劈弹跳等"打到实体即生效"的逻辑订阅。
|
||||
/// </summary>
|
||||
public event System.Action<DamageInfo> OnBreakableHitConfirmed;
|
||||
|
||||
// 宿主投射物缓存(Activate 时填入,DamageInfo.SourceProjectile 写入用)
|
||||
private Projectile _ownerProjectile;
|
||||
|
||||
@@ -196,6 +209,13 @@ namespace BaseGames.Combat
|
||||
Debug.LogWarning($"[HitBox] {name}: 无 DamageSourceSO,跳过命中。", this);
|
||||
return;
|
||||
}
|
||||
// 目标层过滤:既非伤害目标层、也非拼刀对象层时直接忽略,
|
||||
// 不进入命中/占用跟踪(矩阵管"事件是否发生",此掩码管"本盒是否结算")
|
||||
int enterLayer = other.gameObject.layer;
|
||||
bool isDamageTarget = (_targetLayers.value & (1 << enterLayer)) != 0;
|
||||
bool isClashRival = (_rivalHitBoxMask.value & (1 << enterLayer)) != 0 && CanClash;
|
||||
if (!isDamageTarget && !isClashRival) return;
|
||||
|
||||
if (_hitMode == HitMode.Interval)
|
||||
{
|
||||
// 周期接触模式:记录占用并立即结算一次;后续由 Update 按间隔对仍停留的目标重判。
|
||||
@@ -219,18 +239,6 @@ namespace BaseGames.Combat
|
||||
// 排除自身:攻击方与受击方属于同一根 GameObject 时跳过(防止近战 EnemyHitBox 命中同一敌人的 EnemyHurtBox)
|
||||
if (other.transform.root == _attackerTransform.root) return;
|
||||
|
||||
Vector2 knockDir = ((Vector2)other.bounds.center
|
||||
- (Vector2)_attackerTransform.position).normalized;
|
||||
|
||||
// ⚡ 零 GC:struct 工厂,运行时字段内联传入
|
||||
var info = DamageInfo.From(
|
||||
_currentSource,
|
||||
knockDir,
|
||||
_attackerTransform.position,
|
||||
_attackerTransform.gameObject.layer,
|
||||
_ownerProjectile);
|
||||
info.HitActivationId = _currentActivationId;
|
||||
|
||||
// ① 拼刀检测:当前 HitBox 携带 CanClash 标记,且碰到对立阵营的 HitBox 层
|
||||
int otherLayer = other.gameObject.layer;
|
||||
bool isRivalHitBoxLayer = (_rivalHitBoxMask.value & (1 << otherLayer)) != 0;
|
||||
@@ -244,15 +252,34 @@ namespace BaseGames.Combat
|
||||
}
|
||||
}
|
||||
|
||||
// 目标层过滤:拼刀之外,仅对 _targetLayers 内的层结算伤害。
|
||||
// Enter 入口已过滤,这里再守一次:覆盖 Interval 占用期间目标 Layer 被运行时改变的情况(如投射物弹反换层)。
|
||||
if ((_targetLayers.value & (1 << otherLayer)) == 0) return;
|
||||
|
||||
Vector2 knockDir = ((Vector2)other.bounds.center
|
||||
- (Vector2)_attackerTransform.position).normalized;
|
||||
|
||||
// ⚡ 零 GC:struct 工厂,运行时字段内联传入
|
||||
var info = DamageInfo.From(
|
||||
_currentSource,
|
||||
knockDir,
|
||||
_attackerTransform.position,
|
||||
_attackerTransform.gameObject.layer,
|
||||
_ownerProjectile);
|
||||
info.HitActivationId = _currentActivationId;
|
||||
|
||||
// hitPoint:优先使用触发命中的碰撞体中心在目标表面的最近点;
|
||||
// 无 sourceCollider(直属碰撞体)时回退到 HitBox 节点坐标。
|
||||
// 写入 info.HitPoint 供下游"击中位置"模式的反馈在该点生成。
|
||||
Vector2 hitOrigin = sourceCollider != null
|
||||
? (Vector2)sourceCollider.bounds.center
|
||||
: (Vector2)transform.position;
|
||||
Vector3 hitPoint = other.ClosestPoint(hitOrigin);
|
||||
info.HitPoint = hitPoint;
|
||||
|
||||
// ② 命中 HurtBox
|
||||
if (other.TryGetComponent<HurtBox>(out var hurtBox))
|
||||
{
|
||||
// hitPoint:优先使用触发命中的碰撞体中心在 HurtBox 表面的最近点;
|
||||
// 无 sourceCollider(直属碰撞体)时回退到 HitBox 节点坐标。
|
||||
Vector2 hitOrigin = sourceCollider != null
|
||||
? (Vector2)sourceCollider.bounds.center
|
||||
: (Vector2)transform.position;
|
||||
Vector3 hitPoint = other.ClosestPoint(hitOrigin);
|
||||
hurtBox.ReceiveDamage(info, hitPoint);
|
||||
OnHitConfirmed?.Invoke(info);
|
||||
return;
|
||||
@@ -260,7 +287,10 @@ namespace BaseGames.Combat
|
||||
|
||||
// ③ 命中 IBreakable(机关/障碍物)
|
||||
if (other.TryGetComponent<IBreakable>(out var breakable))
|
||||
{
|
||||
breakable.TryInteract(info);
|
||||
OnBreakableHitConfirmed?.Invoke(info);
|
||||
}
|
||||
}
|
||||
|
||||
// ── 当前激活期已命中目标集合(防止复合子 Collider 导致同帧多次命中)────────────
|
||||
@@ -272,6 +302,16 @@ namespace BaseGames.Combat
|
||||
// Update 轮询时的临时缓冲(避免遍历字典时修改 + 降低 GC)
|
||||
private readonly List<Collider2D> _intervalTickBuffer = new(8);
|
||||
|
||||
/// <summary>
|
||||
/// 伤害目标层掩码(实例级过滤,叠加在 Physics2D 碰撞矩阵之上)。
|
||||
/// 运行时可写:投射物弹反换阵营时由 Projectile 翻转目标侧。
|
||||
/// </summary>
|
||||
public LayerMask TargetLayers
|
||||
{
|
||||
get => _targetLayers;
|
||||
set => _targetLayers = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置为周期接触伤害模式(BodyContactDamage 等持续接触源在 OnEnable 时调用)。
|
||||
/// 使持续接触的判定盒按 <paramref name="interval"/> 对停留目标重复造成伤害,
|
||||
|
||||
@@ -61,6 +61,9 @@ namespace BaseGames.Combat
|
||||
public void ReceiveDamage(DamageInfo info, Vector3? hitPoint = null)
|
||||
{
|
||||
Vector3 resolvedHitPoint = hitPoint ?? transform.position;
|
||||
// 兜底盖戳:直接调用本方法的路径(陷阱/环境伤害)没有 HitBox 写入的精确接触点,
|
||||
// 统一以解析后的命中点填充,保证下游"击中位置"模式反馈始终有效
|
||||
info.HitPoint = resolvedHitPoint;
|
||||
if (!_isActive || _owner == null) return;
|
||||
// 所有者级去重:同一 HitBox 激活期内多个 HurtBox 子节点只处理首次命中(共享 HP)
|
||||
if (_ownerGuard != null && !_ownerGuard.TryRegisterHit(info.HitActivationId)) return;
|
||||
@@ -75,8 +78,9 @@ namespace BaseGames.Combat
|
||||
{
|
||||
if (_parrySystem.ConsumeParry())
|
||||
{
|
||||
// 若攻击来源是投射物,翻转其阵营 Layer 与飞行方向
|
||||
info.SourceProjectile?.ReflectAsPlayerProjectile();
|
||||
// 若攻击来源是投射物,按弹反者阵营反射:
|
||||
// 玩家弹反翻转阵营 Layer 与伤害目标层;敌人弹反仅反转方向
|
||||
info.SourceProjectile?.ReflectBy(transform);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,11 @@ namespace BaseGames.Combat
|
||||
[Tooltip("true = 顶部有 HurtBox 子节点可下劈弹跳(需手动添加 Pogo Surface 子节点)")]
|
||||
[SerializeField] private bool _canPogo = true;
|
||||
|
||||
/// <summary>
|
||||
/// 单次接触闩锁:防止同一次触碰内重复结算(如淡出等待期间的物理回调)。
|
||||
/// 玩家 HurtBox 离开触发区(OnTriggerExit2D,含检查点传送移位)后重置,
|
||||
/// 使陷阱对下一次触碰再次生效;死亡路径则经场景重载由 OnEnable 重置。
|
||||
/// </summary>
|
||||
private bool _triggered;
|
||||
|
||||
private void Awake()
|
||||
@@ -84,9 +89,12 @@ namespace BaseGames.Combat
|
||||
hurtBox.ReceiveDamage(info);
|
||||
|
||||
// 检测伤害后玩家存活状态:
|
||||
// 若已死亡,PlayerController.TakeDamage 已在同帧内 Raise EVT_PlayerDied;
|
||||
// 若已死亡,PlayerController.TakeDamage 已在同帧内 Raise EVT_PlayerDied,
|
||||
// 走完整死亡流程,本组件不得再 Raise 检查点回溯;
|
||||
// 若存活,需由本组件 Raise 使其回到检查点。
|
||||
var damageable = other.transform.root.GetComponentInParent<IDamageable>();
|
||||
// 从 HurtBox 自身向上查找(而非 transform.root):玩家被临时挂到
|
||||
// 其他父物体(如移动平台)下时 root 不是玩家根节点,会漏判死亡。
|
||||
var damageable = other.GetComponentInParent<IDamageable>();
|
||||
playerDiedFromDamage = damageable != null && !damageable.IsAlive;
|
||||
}
|
||||
}
|
||||
@@ -102,6 +110,12 @@ namespace BaseGames.Combat
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTriggerExit2D(Collider2D other)
|
||||
{
|
||||
if ((_playerLayers.value & (1 << other.gameObject.layer)) == 0) return;
|
||||
_triggered = false;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[UnityEngine.ContextMenu("打印 Pogo 提示")]
|
||||
private void PrintPogoInfo()
|
||||
|
||||
@@ -34,6 +34,17 @@ namespace BaseGames.Combat
|
||||
Direction = -Direction;
|
||||
_rb.velocity = Direction * _config.Speed * _config.ParrySpeedMultiplier;
|
||||
|
||||
// 仅当弹反者是玩家时翻转阵营:切到 PlayerProjectile 层(否则碰撞矩阵
|
||||
// EnemyProjectile↔EnemyHurtBox 不碰撞,反射后永远打不中敌人),
|
||||
// 伤害目标层同步切换(优先取配置的 ReflectedTargetLayers)。
|
||||
// 敌人弹反敌人投射物:阵营与目标层保持不变,仅上面已反转方向。
|
||||
if (parrySystem.transform.root.CompareTag("Player"))
|
||||
{
|
||||
int playerProjLayer = LayerMask.NameToLayer("PlayerProjectile");
|
||||
if (playerProjLayer >= 0) gameObject.layer = playerProjLayer;
|
||||
ApplyReflectedTargetLayers();
|
||||
}
|
||||
|
||||
if (_reflectSource != null)
|
||||
DamageInfo = DamageInfo.From(_reflectSource);
|
||||
return;
|
||||
@@ -41,6 +52,8 @@ namespace BaseGames.Combat
|
||||
}
|
||||
|
||||
// ── 正常命中 ─────────────────────────────────────────────────
|
||||
// 本类绕过 HitBox 自行判定,需自行套用其伤害目标层过滤
|
||||
if ((_hitBox.TargetLayers.value & (1 << other.gameObject.layer)) == 0) return;
|
||||
var hurtBox = other.GetComponent<HurtBox>();
|
||||
if (hurtBox != null)
|
||||
{
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace BaseGames.Combat
|
||||
private int _hitsRemaining;
|
||||
// 弹反帧标记:弹反命中不计入命中预算(避免反射后立即被回收)
|
||||
private bool _justReflected;
|
||||
// 预制体上配置的初始伤害目标层:对象池复用时还原,避免上一发弹反翻转后的掩码污染下一发
|
||||
private LayerMask _initialTargetLayers;
|
||||
|
||||
private PooledObject _pooledObject;
|
||||
|
||||
@@ -34,6 +36,7 @@ namespace BaseGames.Combat
|
||||
_rb = GetComponent<Rigidbody2D>();
|
||||
_hitBox = GetComponent<HitBox>();
|
||||
_pooledObject = GetComponent<PooledObject>();
|
||||
_initialTargetLayers = _hitBox.TargetLayers;
|
||||
// 订阅命中确认:按命中预算决定何时回收(穿透 / 命中即消失)
|
||||
_hitBox.OnHitConfirmed += HandleHitConfirmed;
|
||||
}
|
||||
@@ -49,6 +52,8 @@ namespace BaseGames.Combat
|
||||
_maxHits = config.MaxHits;
|
||||
_hitsRemaining = config.MaxHits;
|
||||
_justReflected = false;
|
||||
// 还原预制体配置的伤害目标层(清除上一次弹反翻转的影响)
|
||||
_hitBox.TargetLayers = _initialTargetLayers;
|
||||
|
||||
SetFactionLayer(ownerLayer);
|
||||
_hitBox.Activate(config.DamageSource);
|
||||
@@ -66,9 +71,31 @@ namespace BaseGames.Combat
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 弹反:将投射物阵营从 EnemyProjectile 切换为 PlayerProjectile。
|
||||
/// 阵营感知弹反入口:根据弹反者阵营决定反射行为。
|
||||
/// 玩家弹反 → 切 PlayerProjectile 层并切换伤害目标层(走 <see cref="ReflectAsPlayerProjectile"/>);
|
||||
/// 敌人弹反 → 阵营层与伤害目标层均保持不变(仍是敌方投射物、仍打玩家侧),仅反转方向并重置命中记录。
|
||||
/// 由 HurtBox.ReceiveDamage() 在弹反成功后调用,传入弹反者 Transform。
|
||||
/// </summary>
|
||||
public virtual void ReflectBy(Transform parrier)
|
||||
{
|
||||
if (parrier != null && parrier.root.CompareTag("Player"))
|
||||
{
|
||||
ReflectAsPlayerProjectile();
|
||||
return;
|
||||
}
|
||||
|
||||
// ── 敌人弹反:不换阵营、不换目标层,仅反转飞行并重置判定 ──
|
||||
Direction = -Direction;
|
||||
_rb.velocity = -_rb.velocity;
|
||||
_hitBox.Deactivate();
|
||||
_hitBox.Activate(_config?.DamageSource);
|
||||
_hitsRemaining = _maxHits;
|
||||
_justReflected = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 玩家弹反:将投射物阵营从 EnemyProjectile 切换为 PlayerProjectile。
|
||||
/// 反转飞行方向,并重置 HitBox 命中记录使其能够命中新目标(敌人)。
|
||||
/// 由 HurtBox.ReceiveDamage() 在弹反成功后调用。
|
||||
/// </summary>
|
||||
public virtual void ReflectAsPlayerProjectile()
|
||||
{
|
||||
@@ -82,12 +109,36 @@ namespace BaseGames.Combat
|
||||
// 重置 HitBox 命中记录,确保反射后可命中新目标
|
||||
_hitBox.Deactivate();
|
||||
_hitBox.Activate(_config?.DamageSource);
|
||||
// 伤害目标随阵营切换(优先取配置的显式目标层)
|
||||
ApplyReflectedTargetLayers();
|
||||
|
||||
// 反射后重置命中预算,并跳过本次(弹反)命中的扣减,避免反射后立即被回收
|
||||
_hitsRemaining = _maxHits;
|
||||
_justReflected = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 弹反换阵营后应用伤害目标层:
|
||||
/// 优先使用 <see cref="ProjectileConfigSO.ReflectedTargetLayers"/> 的显式配置;
|
||||
/// 未配置(Nothing)时自动翻转——仅交换 PlayerHurtBox→EnemyHurtBox 位,
|
||||
/// 保留可破坏物等其他目标层。
|
||||
/// </summary>
|
||||
protected void ApplyReflectedTargetLayers()
|
||||
{
|
||||
if (_config != null && _config.ReflectedTargetLayers.value != 0)
|
||||
{
|
||||
_hitBox.TargetLayers = _config.ReflectedTargetLayers;
|
||||
return;
|
||||
}
|
||||
int playerHurt = LayerMask.NameToLayer("PlayerHurtBox");
|
||||
int enemyHurt = LayerMask.NameToLayer("EnemyHurtBox");
|
||||
if (playerHurt < 0 || enemyHurt < 0) return; // Layer 尚未创建,保留现有掩码
|
||||
int mask = _hitBox.TargetLayers.value;
|
||||
mask &= ~(1 << playerHurt);
|
||||
mask |= 1 << enemyHurt;
|
||||
_hitBox.TargetLayers = mask;
|
||||
}
|
||||
|
||||
/// <summary>HitBox 命中确认回调:按命中预算决定是否回收(穿透 / 命中即消失)。</summary>
|
||||
private void HandleHitConfirmed(DamageInfo _)
|
||||
{
|
||||
|
||||
@@ -26,5 +26,8 @@ namespace BaseGames.Combat
|
||||
[Header("弹反")]
|
||||
public float ParrySpeedMultiplier = 1.2f;
|
||||
public float ParryDamageMultiplier = 2.0f;
|
||||
[Tooltip("弹反后本投射物可造成伤害判定的 Layer(显式配置,写入 HitBox.TargetLayers)。" +
|
||||
"留空(Nothing) = 自动翻转:在原目标层基础上 PlayerHurtBox 位换为 EnemyHurtBox 位、其余位保留。")]
|
||||
public LayerMask ReflectedTargetLayers;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using BaseGames.Combat;
|
||||
using BaseGames.Feedback;
|
||||
using BaseGames.Player;
|
||||
|
||||
namespace BaseGames.Editor.Combat
|
||||
@@ -12,11 +13,14 @@ namespace BaseGames.Editor.Combat
|
||||
///
|
||||
/// 生成路径规范:Assets/_Game/Prefabs/Weapons/WPN_{weaponId}_HitBox.prefab
|
||||
/// Prefab 结构:
|
||||
/// [WPN_{weaponId}_HitBox] ← WeaponHitBoxInstance
|
||||
/// [WPN_{weaponId}_HitBox] ← WeaponHitBoxInstance + WeaponFeedback(武器本地反馈:命中粒子/音效/破风)
|
||||
/// ├── [HitBox_Ground] ← Collider2D(IsTrigger, 形状可选) + HitBox, Layer=PlayerHitBox
|
||||
/// ├── [HitBox_Up]
|
||||
/// ├── [HitBox_Down]
|
||||
/// └── [HitBox_Air]
|
||||
///
|
||||
/// WeaponFeedback 的 MMF_Player 反馈链留待 Inspector 编排;
|
||||
/// 缺失该组件时 WeaponHitBoxInstance 会静默落到 NullFeedbackPlayer(无武器级表现)。
|
||||
/// </summary>
|
||||
public class WeaponHitBoxWizard : ScriptableWizard
|
||||
{
|
||||
@@ -101,6 +105,9 @@ namespace BaseGames.Editor.Combat
|
||||
// ── 构建 Prefab ────────────────────────────────────────────────
|
||||
var root = new GameObject(prefabName);
|
||||
var instance = root.AddComponent<WeaponHitBoxInstance>();
|
||||
// 武器本地反馈(WeaponHitBoxInstance.Awake 经 GetComponentInChildren<IFeedbackPlayer>() 获取);
|
||||
// MMF_Player 反馈链留待 Inspector 编排
|
||||
root.AddComponent<WeaponFeedback>();
|
||||
var so = new SerializedObject(instance);
|
||||
|
||||
void AddDirection(bool enabled, string nodeName, string fieldName, ColliderShape shape)
|
||||
|
||||
@@ -232,6 +232,13 @@ namespace BaseGames.Editor
|
||||
if (inputReader != null)
|
||||
AssignReference(interactDetector, "_inputReader", inputReader, report);
|
||||
|
||||
// ── 检查点回溯(LethalTrap 存活路径:淡出 → 传送至最近检查点 → 淡入)──
|
||||
// 须与 Rigidbody2D 同节点(传送时直接写 rb.position)。
|
||||
CheckpointRespawnHandler checkpointRespawn = GetOrAddComponent<CheckpointRespawnHandler>(root);
|
||||
AssignAsset(checkpointRespawn, "_onCheckpointRespawn", report, false, "EVT_CheckpointRespawn");
|
||||
AssignAsset(checkpointRespawn, "_onFadeOutRequest", report, false, "EVT_FadeOutRequest");
|
||||
AssignAsset(checkpointRespawn, "_onFadeInRequest", report, false, "EVT_FadeInRequest");
|
||||
|
||||
if (animConfig == null) report.Add("★ 需创建并绑定:PlayerController._animConfig(PLY_PlayerAnimationConfig)");
|
||||
if (statsConfig == null) report.Add("★ 需创建并绑定:PlayerStats._config(PlayerStatsSO)");
|
||||
if (inputReader == null) report.Add("★ 需手动绑定:PlayerController._inputReader / FormController._input / SkillManager._input(InputReaderSO)");
|
||||
@@ -1629,8 +1636,14 @@ namespace BaseGames.Editor
|
||||
AssignLayerMask(marker, "_playerLayers", "Player", report);
|
||||
AssignAsset(marker, "_onCheckpointReached", report, false, "EVT_CheckpointReached");
|
||||
|
||||
// RespawnPoint 子节点:玩家回溯时的出生位置(触发区与出生点解耦)
|
||||
Transform respawnT = GetOrCreateChild(go.transform, "RespawnPoint");
|
||||
respawnT.localPosition = Vector3.zero;
|
||||
AssignReference(marker, "_respawnPoint", respawnT, report);
|
||||
|
||||
report.Add("放置于跳跳乐段落的关键节点处;玩家经过后成为该房间最近检查点。");
|
||||
report.Add("同一房间可放置多个,以最近经过的为准。");
|
||||
report.Add("调整 RespawnPoint 子节点位置 = 玩家回溯出生位置(须落在安全平台上)。");
|
||||
|
||||
Selection.activeGameObject = go;
|
||||
MarkDirtyAndLog("Checkpoint Marker", go, report);
|
||||
|
||||
@@ -15,13 +15,17 @@ namespace BaseGames.Enemies
|
||||
[SerializeField] private MMF_Player _onHitLight;
|
||||
[SerializeField] private MMF_Player _onHitMedium;
|
||||
[SerializeField] private MMF_Player _onHitHeavy;
|
||||
[Tooltip("命中反馈生成位置:Fixed = 反馈链编排的固定位置;HitPoint = 在命中点生成")]
|
||||
[SerializeField] private FeedbackPositionMode _hitPositionMode = FeedbackPositionMode.Fixed;
|
||||
|
||||
[Header("受伤 / 死亡反馈")]
|
||||
[SerializeField] private MMF_Player _onTakeHit;
|
||||
[Tooltip("受击反馈生成位置:Fixed = 反馈链编排的固定位置;HitPoint = 在受击点生成(血粒子等贴点表现)")]
|
||||
[SerializeField] private FeedbackPositionMode _takeHitPositionMode = FeedbackPositionMode.Fixed;
|
||||
[SerializeField] private MMF_Player _onDeath;
|
||||
|
||||
// ── IFeedbackPlayer ──────────────────────────────────────────────────────
|
||||
public void PlayHit(HitWeight weight)
|
||||
public void PlayHit(HitWeight weight, Vector3 hitPoint)
|
||||
{
|
||||
var player = weight switch
|
||||
{
|
||||
@@ -30,10 +34,11 @@ namespace BaseGames.Enemies
|
||||
HitWeight.Heavy => _onHitHeavy,
|
||||
_ => _onHitLight,
|
||||
};
|
||||
player?.PlayFeedbacks();
|
||||
FeedbackPlayback.Play(player, _hitPositionMode, hitPoint);
|
||||
}
|
||||
|
||||
public void PlayTakeHit() => _onTakeHit?.PlayFeedbacks();
|
||||
public void PlayTakeHit(Vector3 hitPoint)
|
||||
=> FeedbackPlayback.Play(_onTakeHit, _takeHitPositionMode, hitPoint);
|
||||
public void PlayDeath() => _onDeath?.PlayFeedbacks();
|
||||
|
||||
// 以下方法对敌人无意义,提供空实现保持接口完整
|
||||
@@ -51,7 +56,7 @@ namespace BaseGames.Enemies
|
||||
/// <summary>受到伤害时调用(由 EnemyBase 触发)。</summary>
|
||||
public void OnHit(DamageInfo info)
|
||||
{
|
||||
PlayTakeHit();
|
||||
PlayTakeHit(info.HitPoint);
|
||||
}
|
||||
|
||||
/// <summary>死亡时调用(由 EnemyBase 触发)。</summary>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
using UnityEngine;
|
||||
using MoreMountains.Feedbacks;
|
||||
|
||||
namespace BaseGames.Feedback
|
||||
{
|
||||
/// <summary>
|
||||
@@ -8,15 +11,22 @@ namespace BaseGames.Feedback
|
||||
public interface IFeedbackPlayer
|
||||
{
|
||||
// ── 命中 ──────────────────────────────────────────────────────────────────
|
||||
/// <summary>对目标造成命中时播放对应力度的反馈(摄像机震屏 + 控制器振动等)。</summary>
|
||||
void PlayHit(HitWeight weight);
|
||||
/// <summary>
|
||||
/// 对目标造成命中时播放对应力度的反馈(摄像机震屏 + 控制器振动等)。
|
||||
/// hitPoint = 命中点世界坐标(DamageInfo.HitPoint);
|
||||
/// 实际生成位置取决于实现方各槽位的 FeedbackPositionMode 配置。
|
||||
/// </summary>
|
||||
void PlayHit(HitWeight weight, Vector3 hitPoint);
|
||||
|
||||
/// <summary>成功弹反(Parry)时播放反馈。</summary>
|
||||
void PlayParrySuccess();
|
||||
|
||||
// ── 受伤 / 死亡 ──────────────────────────────────────────────────────────
|
||||
/// <summary>角色受到伤害时播放反馈(闪白 + 轻微震屏等)。</summary>
|
||||
void PlayTakeHit();
|
||||
/// <summary>
|
||||
/// 角色受到伤害时播放反馈(闪白 + 轻微震屏等)。
|
||||
/// hitPoint = 受击点世界坐标(DamageInfo.HitPoint)。
|
||||
/// </summary>
|
||||
void PlayTakeHit(Vector3 hitPoint);
|
||||
|
||||
/// <summary>角色死亡时播放反馈(慢动作 + 震屏 + 音效)。</summary>
|
||||
void PlayDeath();
|
||||
@@ -53,6 +63,34 @@ namespace BaseGames.Feedback
|
||||
/// <summary>命中力度。</summary>
|
||||
public enum HitWeight { Light, Medium, Heavy }
|
||||
|
||||
/// <summary>
|
||||
/// 反馈生成位置模式。反馈链本身由开发者在 Inspector 编排,
|
||||
/// 此模式只决定播放时是否把命中点传入反馈链。
|
||||
/// </summary>
|
||||
public enum FeedbackPositionMode
|
||||
{
|
||||
/// <summary>固定位置:按反馈链各模块编排时设定的位置播放(不传入命中点)。</summary>
|
||||
Fixed,
|
||||
/// <summary>击中位置:把命中点传入反馈链,启用了播放位置选项的模块在命中点生成。</summary>
|
||||
HitPoint,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反馈播放辅助:统一"按位置模式播放 MMF_Player"的实现,供各 IFeedbackPlayer 实现复用。
|
||||
/// </summary>
|
||||
public static class FeedbackPlayback
|
||||
{
|
||||
/// <summary>按位置模式播放。HitPoint 模式将命中点传给反馈链(仅启用位置选项的模块生效)。</summary>
|
||||
public static void Play(MMF_Player player, FeedbackPositionMode mode, Vector3 hitPoint)
|
||||
{
|
||||
if (player == null) return;
|
||||
if (mode == FeedbackPositionMode.HitPoint)
|
||||
player.PlayFeedbacks(hitPoint);
|
||||
else
|
||||
player.PlayFeedbacks();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 空对象模式实现:所有方法均为空操作,用于测试和不需要反馈的实体。
|
||||
/// </summary>
|
||||
@@ -60,9 +98,9 @@ namespace BaseGames.Feedback
|
||||
{
|
||||
public static readonly NullFeedbackPlayer Instance = new NullFeedbackPlayer();
|
||||
|
||||
public void PlayHit(HitWeight weight) { }
|
||||
public void PlayHit(HitWeight weight, Vector3 hitPoint) { }
|
||||
public void PlayParrySuccess() { }
|
||||
public void PlayTakeHit() { }
|
||||
public void PlayTakeHit(Vector3 hitPoint) { }
|
||||
public void PlayDeath() { }
|
||||
public void PlayHeal() { }
|
||||
public void PlayLandImpact() { }
|
||||
@@ -74,4 +112,3 @@ namespace BaseGames.Feedback
|
||||
public void PlayFormSwitch(int formIndex) { }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,14 @@ namespace BaseGames.Feedback
|
||||
[SerializeField] private MMF_Player _onHitLight;
|
||||
[SerializeField] private MMF_Player _onHitMedium;
|
||||
[SerializeField] private MMF_Player _onHitHeavy;
|
||||
[Tooltip("命中反馈生成位置:Fixed = 反馈链编排的固定位置;HitPoint = 在命中点生成")]
|
||||
[SerializeField] private FeedbackPositionMode _hitPositionMode = FeedbackPositionMode.Fixed;
|
||||
[SerializeField] private MMF_Player _onParrySuccess;
|
||||
|
||||
[Header("受伤 / 死亡反馈")]
|
||||
[SerializeField] private MMF_Player _onTakeHit;
|
||||
[Tooltip("受击反馈生成位置:Fixed = 反馈链编排的固定位置;HitPoint = 在受击点生成")]
|
||||
[SerializeField] private FeedbackPositionMode _takeHitPositionMode = FeedbackPositionMode.Fixed;
|
||||
[SerializeField] private MMF_Player _onDeath;
|
||||
|
||||
[Header("恢复反馈")]
|
||||
@@ -53,7 +57,7 @@ namespace BaseGames.Feedback
|
||||
}
|
||||
|
||||
// ── IFeedbackPlayer ──────────────────────────────────────────────────────
|
||||
public void PlayHit(HitWeight weight)
|
||||
public void PlayHit(HitWeight weight, Vector3 hitPoint)
|
||||
{
|
||||
var player = weight switch
|
||||
{
|
||||
@@ -62,11 +66,12 @@ namespace BaseGames.Feedback
|
||||
HitWeight.Heavy => _onHitHeavy,
|
||||
_ => _onHitLight,
|
||||
};
|
||||
player?.PlayFeedbacks();
|
||||
FeedbackPlayback.Play(player, _hitPositionMode, hitPoint);
|
||||
}
|
||||
|
||||
public void PlayParrySuccess() => _onParrySuccess?.PlayFeedbacks();
|
||||
public void PlayTakeHit() => _onTakeHit?.PlayFeedbacks();
|
||||
public void PlayTakeHit(Vector3 hitPoint)
|
||||
=> FeedbackPlayback.Play(_onTakeHit, _takeHitPositionMode, hitPoint);
|
||||
public void PlayDeath() => _onDeath?.PlayFeedbacks();
|
||||
public void PlayHeal() => _onHeal?.PlayFeedbacks();
|
||||
public void PlayLandImpact() => _onLandImpact?.PlayFeedbacks();
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace BaseGames.Feedback
|
||||
[SerializeField] private MMF_Player _onHitLight;
|
||||
[SerializeField] private MMF_Player _onHitMedium;
|
||||
[SerializeField] private MMF_Player _onHitHeavy;
|
||||
[Tooltip("命中反馈生成位置:Fixed = 反馈链编排的固定位置;HitPoint = 在命中点生成(命中火花等贴点表现)")]
|
||||
[SerializeField] private FeedbackPositionMode _hitPositionMode = FeedbackPositionMode.HitPoint;
|
||||
|
||||
[Header("攻击破风")]
|
||||
[SerializeField] private MMF_Player _onAttackWhoosh;
|
||||
@@ -30,7 +32,7 @@ namespace BaseGames.Feedback
|
||||
|
||||
// ── IFeedbackPlayer 实现 ──────────────────────────────────────────────
|
||||
|
||||
public void PlayHit(HitWeight weight)
|
||||
public void PlayHit(HitWeight weight, Vector3 hitPoint)
|
||||
{
|
||||
var player = weight switch
|
||||
{
|
||||
@@ -38,7 +40,7 @@ namespace BaseGames.Feedback
|
||||
HitWeight.Heavy => _onHitHeavy,
|
||||
_ => _onHitMedium,
|
||||
};
|
||||
player?.PlayFeedbacks();
|
||||
FeedbackPlayback.Play(player, _hitPositionMode, hitPoint);
|
||||
}
|
||||
|
||||
public void PlayAttackWhoosh() => _onAttackWhoosh?.PlayFeedbacks();
|
||||
@@ -52,7 +54,7 @@ namespace BaseGames.Feedback
|
||||
|
||||
// ── 武器上不适用的反馈,空实现 ────────────────────────────────────────
|
||||
public void PlayParrySuccess() { }
|
||||
public void PlayTakeHit() { }
|
||||
public void PlayTakeHit(Vector3 hitPoint){ }
|
||||
public void PlayDeath() { }
|
||||
public void PlayHeal() { }
|
||||
public void PlayLandImpact() { }
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace BaseGames.Player
|
||||
var weight = info.FinalDamage <= 5 ? HitWeight.Light
|
||||
: info.FinalDamage <= 15 ? HitWeight.Medium
|
||||
: HitWeight.Heavy;
|
||||
_feedback.PlayHit(weight);
|
||||
_feedback.PlayHit(weight, info.HitPoint);
|
||||
|
||||
// 攻击命中反嵈:向攻击反方向施加微小后退冲量,增强打击感
|
||||
if (_movement?.Rb != null && info.KnockbackDirection.x != 0f)
|
||||
|
||||
@@ -214,6 +214,17 @@ namespace BaseGames.Player
|
||||
_rb.velocity = new Vector2(_rb.velocity.x, _rb.velocity.y * _config.JumpCutMultiplier);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下劈命中弹跳(DownAttackState 调用)。覆盖当前垂直速度为 PogoBounceForce;
|
||||
/// 固定高度(JumpCancelledEvent 仅 JumpState 处理,弹跳不受变高跳截断影响)。
|
||||
/// </summary>
|
||||
public void PogoBounce()
|
||||
{
|
||||
_rb.velocity = new Vector2(_rb.velocity.x, _config.PogoBounceForce);
|
||||
_coyoteTimer = 0f;
|
||||
_slopeSnapDisabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 二段跳。覆盖当前垂直速度为 DoubleJumpForce。
|
||||
/// FallState / JumpState 在检测到 HasAbility(DoubleJump) && AirJumpsLeft > 0 时调用。
|
||||
|
||||
@@ -60,6 +60,10 @@ namespace BaseGames.Player
|
||||
[Tooltip("无敌的独立冷却(秒)。CD 内再次冲刺不会获得无敌帧,防止连冲变相持续无敌(推荐 0.9s)。")]
|
||||
public float DashInvincibilityCooldown = 0.9f;
|
||||
|
||||
[Header("下劈弹跳(Pogo)")]
|
||||
[Tooltip("下劈命中后的向上弹跳初速度。推荐略低于 JumpForce(如 JumpForce=18 时取 15),\n弹跳略矮于满跳;固定高度,不受变高跳截断影响。")]
|
||||
public float PogoBounceForce = 15f;
|
||||
|
||||
[Header("下冲刺")]
|
||||
[Tooltip("向下冲刺速度(单位/秒)。推荐 22,快速向下穿透空间。")]
|
||||
public float DownDashSpeed = 22f;
|
||||
|
||||
@@ -42,9 +42,8 @@ namespace BaseGames.Player.States
|
||||
OnClipEnd();
|
||||
}
|
||||
|
||||
// 施加向下的速度(下劈冲击)
|
||||
if (Move?.Rb != null)
|
||||
Move.Rb.velocity = new Vector2(Move.Rb.velocity.x, -18f);
|
||||
// 下劈为纯向下攻击:保持角色原有的自然下落,不额外施加向下俯冲位移
|
||||
// (俯冲位移会让下劈手感变成下冲,命中弹跳逻辑见 OnDownHitConfirmed)
|
||||
}
|
||||
|
||||
public override void OnStateExit()
|
||||
@@ -59,10 +58,10 @@ namespace BaseGames.Player.States
|
||||
{
|
||||
if (_hasHitEnemy) return;
|
||||
_hasHitEnemy = true;
|
||||
// Pogo 弹跳:命中敌人后向上弹起,同时重置空中能力(等同落地效果)
|
||||
// Pogo 弹跳:命中后向上弹起(独立弹跳力,略矮于满跳),同时重置空中能力(等同落地效果)
|
||||
Owner.ResetAirJumps();
|
||||
Owner.GetState<DashState>()?.ResetDashCharge();
|
||||
Move.Jump();
|
||||
Move.PogoBounce();
|
||||
}
|
||||
|
||||
public override void OnStateUpdate()
|
||||
@@ -74,6 +73,25 @@ namespace BaseGames.Player.States
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnStateFixedUpdate()
|
||||
{
|
||||
// 下劈期间保留完整空中水平操控(与 FallState 同款贴墙保护,防止压墙摩擦/卡角)
|
||||
if (Mathf.Abs(Input.MoveInput.x) > 0.01f)
|
||||
{
|
||||
int inputDir = Input.MoveInput.x > 0 ? 1 : -1;
|
||||
var wd = Owner.WallDetector;
|
||||
bool currentFrameWall = inputDir > 0 ? Move.IsWallRight : Move.IsWallLeft;
|
||||
if (currentFrameWall
|
||||
|| (wd != null && (wd.IsTouchingWall && wd.WallDirection == inputDir
|
||||
|| wd.HasPartialContact(inputDir))))
|
||||
Move.ZeroHorizontalVelocity();
|
||||
else
|
||||
Move.Move(Input.MoveInput.x * Cfg.RunSpeed);
|
||||
}
|
||||
else
|
||||
Move.ZeroHorizontalVelocity();
|
||||
}
|
||||
|
||||
private void OnClipEnd()
|
||||
{
|
||||
if (_exited) return;
|
||||
|
||||
@@ -10,14 +10,16 @@ namespace BaseGames.Player.States
|
||||
/// </summary>
|
||||
public class HurtState : PlayerStateBase
|
||||
{
|
||||
private float _timer;
|
||||
private bool _ended;
|
||||
private float _timer;
|
||||
private bool _ended;
|
||||
private Vector3 _hitPoint;
|
||||
|
||||
public HurtState(PlayerController owner) : base(owner) { }
|
||||
|
||||
public void Initialize(BaseGames.Combat.DamageInfo info)
|
||||
{
|
||||
// 由 PlayerController.TakeDamage 传入伤害信息
|
||||
_hitPoint = info.HitPoint;
|
||||
if (info.KnockbackForce > 0.01f)
|
||||
Move?.ApplyKnockback(info.KnockbackDirection, info.KnockbackForce);
|
||||
}
|
||||
@@ -28,7 +30,7 @@ namespace BaseGames.Player.States
|
||||
_timer = Owner.AnimConfig?.HurtDuration ?? 0.4f;
|
||||
_ended = false;
|
||||
Stats?.BeginInvincibility();
|
||||
Feedback.PlayTakeHit();
|
||||
Feedback.PlayTakeHit(_hitPoint);
|
||||
|
||||
if (AnimCfg?.Hurt != null)
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace BaseGames.Player
|
||||
private AttackDirection _activeDir;
|
||||
private IFeedbackPlayer _feedback;
|
||||
|
||||
/// <summary>下劈命中确认事件(供 DownAttackState Pogo 逻辑)。</summary>
|
||||
/// <summary>下劈命中确认事件(供 DownAttackState Pogo 逻辑)。命中 HurtBox 或可破坏物均触发。</summary>
|
||||
public event System.Action<DamageInfo> OnDownHitConfirmed;
|
||||
|
||||
/// <summary>任意 HitBox 命中确认事件(供 PlayerCombat 订阅通用命中反馈)。</summary>
|
||||
@@ -41,7 +41,10 @@ namespace BaseGames.Player
|
||||
{
|
||||
_allHitBoxes = GetComponentsInChildren<HitBox>(true);
|
||||
foreach (var hb in _allHitBoxes)
|
||||
hb.OnHitConfirmed += OnAnyHitConfirmed;
|
||||
{
|
||||
hb.OnHitConfirmed += OnAnyHitConfirmed;
|
||||
hb.OnBreakableHitConfirmed += OnAnyBreakableHitConfirmed;
|
||||
}
|
||||
_feedback = GetComponentInChildren<IFeedbackPlayer>() ?? NullFeedbackPlayer.Instance;
|
||||
}
|
||||
|
||||
@@ -50,13 +53,24 @@ namespace BaseGames.Player
|
||||
var weight = info.FinalDamage <= 5 ? HitWeight.Light
|
||||
: info.FinalDamage <= 15 ? HitWeight.Medium
|
||||
: HitWeight.Heavy;
|
||||
_feedback.PlayHit(weight);
|
||||
_feedback.PlayHit(weight, info.HitPoint);
|
||||
|
||||
OnHitConfirmed?.Invoke(info);
|
||||
if (_activeDir == AttackDirection.Down)
|
||||
OnDownHitConfirmed?.Invoke(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 命中可破坏物:播放轻量打击反馈;下劈方向时同样触发弹跳。
|
||||
/// 不转发 OnHitConfirmed(可破坏物不参与灵力获取)。
|
||||
/// </summary>
|
||||
private void OnAnyBreakableHitConfirmed(DamageInfo info)
|
||||
{
|
||||
_feedback.PlayHit(HitWeight.Light, info.HitPoint);
|
||||
if (_activeDir == AttackDirection.Down)
|
||||
OnDownHitConfirmed?.Invoke(info);
|
||||
}
|
||||
|
||||
// ── 公共 API ──────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -9,9 +9,12 @@ namespace BaseGames.World
|
||||
/// 玩家经过时自动激活,成为 LethalTrap 回溯的目标位置。
|
||||
///
|
||||
/// 设计要点:
|
||||
/// - 同一房间可放置多个,取最近经过的一个
|
||||
/// - 同一房间可放置多个,取最近经过的一个(折返重新经过早先的标记同样覆盖注册)
|
||||
/// - 激活状态仅存于运行时,不持久化,换房间后重置
|
||||
/// - 每个 CheckpointMarker 仅激活一次(重复进入同一触发区无效)
|
||||
/// - 闩锁按接触周期:进入时注册并广播一次,离开触发区后重置,
|
||||
/// 同一次接触内不重复结算
|
||||
/// - 触发区与出生位置解耦:注册的是 _respawnPoint 子节点的位置,
|
||||
/// 触发区可横跨通道,出生点精确落在安全平台上
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Collider2D))]
|
||||
public class CheckpointMarker : MonoBehaviour
|
||||
@@ -20,13 +23,17 @@ namespace BaseGames.World
|
||||
[Tooltip("勾选 Player 层")]
|
||||
[SerializeField] private LayerMask _playerLayers;
|
||||
|
||||
[Header("复活点")]
|
||||
[Tooltip("玩家回溯时出现的位置(必配,脚手架自动创建 RespawnPoint 子节点)")]
|
||||
[SerializeField] private Transform _respawnPoint;
|
||||
|
||||
[Header("事件")]
|
||||
[Tooltip("EVT_CheckpointReached — 激活时广播,供 VFX/SFX 使用")]
|
||||
[SerializeField] private VoidEventChannelSO _onCheckpointReached;
|
||||
|
||||
private bool _isActivated;
|
||||
|
||||
/// <summary>当前运行时是否已被激活。</summary>
|
||||
/// <summary>本次接触是否已注册过(玩家离开触发区后重置)。</summary>
|
||||
public bool IsActivated => _isActivated;
|
||||
|
||||
private void Awake()
|
||||
@@ -37,18 +44,29 @@ namespace BaseGames.World
|
||||
col.isTrigger = true;
|
||||
Debug.LogWarning($"[CheckpointMarker] {name}: Collider2D.isTrigger 已自动设为 true。", this);
|
||||
}
|
||||
|
||||
if (_respawnPoint == null)
|
||||
Debug.LogError($"[CheckpointMarker] {name}: _respawnPoint 未绑定,检查点无法注册。" +
|
||||
"请用脚手架(BaseGames/Scene/Place/Checkpoint Marker)创建,或手动补 RespawnPoint 子节点并绑定。", this);
|
||||
}
|
||||
|
||||
private void OnTriggerEnter2D(Collider2D other)
|
||||
{
|
||||
if (_isActivated) return;
|
||||
if ((_playerLayers.value & (1 << other.gameObject.layer)) == 0) return;
|
||||
if (_respawnPoint == null) return; // 漏配已在 Awake 报错,此处不以标记自身位置兜底
|
||||
|
||||
_isActivated = true;
|
||||
ServiceLocator.GetOrDefault<ICheckpointService>()?.RegisterCheckpoint(transform.position);
|
||||
ServiceLocator.GetOrDefault<ICheckpointService>()?.RegisterCheckpoint(_respawnPoint.position);
|
||||
_onCheckpointReached?.Raise();
|
||||
}
|
||||
|
||||
private void OnTriggerExit2D(Collider2D other)
|
||||
{
|
||||
if ((_playerLayers.value & (1 << other.gameObject.layer)) == 0) return;
|
||||
_isActivated = false;
|
||||
}
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
Gizmos.color = _isActivated
|
||||
@@ -57,6 +75,23 @@ namespace BaseGames.World
|
||||
Gizmos.DrawWireSphere(transform.position, 0.4f);
|
||||
Gizmos.DrawLine(transform.position + Vector3.down * 0.4f,
|
||||
transform.position + Vector3.up * 0.8f);
|
||||
|
||||
// 复活点:青色小球 + 落点竖线 + 与触发区的连线;漏配画红叉警示
|
||||
if (_respawnPoint != null)
|
||||
{
|
||||
Gizmos.color = new Color(0f, 0.8f, 1f, 0.9f);
|
||||
Gizmos.DrawWireSphere(_respawnPoint.position, 0.25f);
|
||||
Gizmos.DrawLine(_respawnPoint.position + Vector3.down * 0.5f,
|
||||
_respawnPoint.position + Vector3.up * 0.5f);
|
||||
Gizmos.color = new Color(0f, 0.8f, 1f, 0.4f);
|
||||
Gizmos.DrawLine(transform.position, _respawnPoint.position);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawLine(transform.position + new Vector3(-0.3f, -0.3f), transform.position + new Vector3(0.3f, 0.3f));
|
||||
Gizmos.DrawLine(transform.position + new Vector3(-0.3f, 0.3f), transform.position + new Vector3(0.3f, -0.3f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user