diff --git a/Assets/_Game/Scripts/Editor/Scene/SceneObjectPlacerTool.cs b/Assets/_Game/Scripts/Editor/Scene/SceneObjectPlacerTool.cs
index ec2a8b6e..5ee3e35b 100644
--- a/Assets/_Game/Scripts/Editor/Scene/SceneObjectPlacerTool.cs
+++ b/Assets/_Game/Scripts/Editor/Scene/SceneObjectPlacerTool.cs
@@ -2304,6 +2304,44 @@ namespace BaseGames.Editor
c.isTrigger = true;
}
+ /// Sprite 有则用其世界包围盒尺寸(sprite.bounds.size),否则回退。
+ private static Vector2 SpriteSizeOr(Sprite s, Vector2 fallback)
+ => s != null ? (Vector2)s.bounds.size : fallback;
+
+ ///
+ /// 建/更新 HurtBox 与 ContactDamageZone 两个子节点:均为 BoxCollider2D、同尺寸 size、
+ /// 底部对齐 y=0、isTrigger=true。ContactDamageZone 带 HitBox + BodyContactDamage。
+ /// contactEnabled:BodyContactDamage 初始启用状态(不需要接触伤害的敌人可传 false 或后续置节点非激活)。
+ /// 返回 (hurtBox, bodyContact, contactHitBox) 供上层按需接线(如伤害源/能力引用)。
+ ///
+ private static (HurtBox hurt, BodyContactDamage contact, HitBox contactHitBox)
+ SetupHurtAndContactBoxes(GameObject root, Vector2 size, bool contactEnabled, List report)
+ {
+ // HurtBox 子节点
+ var hurtT = GetOrCreateChild(root.transform, "HurtBox");
+ SetLayer(hurtT.gameObject, "EnemyHurtBox", report);
+ var hurtCol = GetOrAddComponent(hurtT.gameObject);
+ hurtCol.size = size;
+ hurtCol.isTrigger = true;
+ AlignColliderBottomToPivot(hurtCol);
+ var hurtBox = GetOrAddComponent(hurtT.gameObject);
+ EnsureCollidersAreTriggers(hurtT.gameObject);
+
+ // ContactDamageZone 子节点
+ var contactT = GetOrCreateChild(root.transform, "ContactDamageZone");
+ SetLayer(contactT.gameObject, "EnemyHitBox", report);
+ var contactCol = GetOrAddComponent(contactT.gameObject);
+ contactCol.size = size;
+ contactCol.isTrigger = true;
+ AlignColliderBottomToPivot(contactCol);
+ var contactHitBox = GetOrAddComponent(contactT.gameObject);
+ var bodyContact = GetOrAddComponent(contactT.gameObject);
+ bodyContact.enabled = contactEnabled;
+ EnsureCollidersAreTriggers(contactT.gameObject);
+
+ return (hurtBox, bodyContact, contactHitBox);
+ }
+
private static void AssignReference(Object target, string propName, Object value, List report = null)
{
var so = new SerializedObject(target);