diff --git a/Assets/_Game/Scripts/Editor/Scene/SceneObjectPlacerTool.cs b/Assets/_Game/Scripts/Editor/Scene/SceneObjectPlacerTool.cs index 300b57d6..a53a60c6 100644 --- a/Assets/_Game/Scripts/Editor/Scene/SceneObjectPlacerTool.cs +++ b/Assets/_Game/Scripts/Editor/Scene/SceneObjectPlacerTool.cs @@ -271,9 +271,9 @@ namespace BaseGames.Editor } [MenuItem("BaseGames/Scene/Place/Enemy (Basic)", priority = 110)] - public static void PlaceEnemy() => PlaceEnemy(EnemyBodyColliderType.Box); + public static void PlaceEnemy() => PlaceEnemy(EnemyBodyColliderType.Box, null); - public static void PlaceEnemy(EnemyBodyColliderType bodyCollider) + public static void PlaceEnemy(EnemyBodyColliderType bodyCollider, Sprite defaultSprite = null) { var report = new List(); int undoGroup = Undo.GetCurrentGroup(); @@ -291,12 +291,14 @@ namespace BaseGames.Editor rb.constraints = RigidbodyConstraints2D.FreezeRotation; rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous; - Collider2D body = CreateBodyCollider(go, bodyCollider, new Vector2(0.7f, 0.9f)); + Vector2 size = SpriteSizeOr(defaultSprite, new Vector2(0.7f, 0.9f)); + Collider2D body = CreateBodyCollider(go, bodyCollider, size); Transform visual = GetOrCreateChild(go.transform, "Visual"); visual.localPosition = (Vector3)(Vector2)body.offset; GetOrAddComponent(visual.gameObject); AnimancerComponent animancer = GetOrAddComponent(visual.gameObject); SpriteRenderer sr = SetupSpriteRenderer(visual.gameObject); + if (defaultSprite != null) sr.sprite = defaultSprite; EnemyBase enemyBase = GetOrAddComponent(go); EnemyStats enemyStats = GetOrAddComponent(go); @@ -307,21 +309,8 @@ namespace BaseGames.Editor GetOrAddComponent(go); // required by EnemyNavAgent [RequireComponent] PhysicsPerceptionSystem sensorHub = GetOrAddComponent(go); - // HurtBox child - Transform hurtBoxT = GetOrCreateChild(go.transform, "HurtBox"); - SetLayer(hurtBoxT.gameObject, "EnemyHurtBox", report); - CapsuleCollider2D hurtCollider = GetOrAddComponent(hurtBoxT.gameObject); - hurtCollider.isTrigger = true; - HurtBox hurtBox = GetOrAddComponent(hurtBoxT.gameObject); - - // Contact-damage HitBox child - Transform hitBodyT = GetOrCreateChild(go.transform, "HitBox_Body"); - SetLayer(hitBodyT.gameObject, "EnemyHitBox", report); - CircleCollider2D hitCollider = GetOrAddComponent(hitBodyT.gameObject); - hitCollider.isTrigger = true; - hitCollider.radius = 0.55f; - HitBox hitBox = GetOrAddComponent(hitBodyT.gameObject); - GetOrAddComponent(hitBodyT.gameObject); + var (hurtBox, bodyContact, contactHitBox) = + SetupHurtAndContactBoxes(go, size, contactEnabled: true, report); // Wire EnemyBase AssignReference(enemyBase, "_stats", enemyStats, report); @@ -346,9 +335,9 @@ namespace BaseGames.Editor // DamageSourceSO for body contact Object dmgSrc = FindFirstAsset("CMB_DS_EnemyBody", "DS_EnemyBody"); if (dmgSrc != null) - AssignReference(hitBox, "_defaultSource", dmgSrc, report); + AssignReference(contactHitBox, "_defaultSource", dmgSrc, report); else - report.Add("未找到 DamageSourceSO,HitBox_Body._defaultSource 未绑定。请创建 CMB_DS_EnemyBody.asset。"); + report.Add("未找到 DamageSourceSO,ContactDamageZone._defaultSource 未绑定。请创建 CMB_DS_EnemyBody.asset。"); SetupPerceptionSystemSlots(sensorHub, new[] { "aggro", "los" }, report); report.Add("★ 指定 EnemyBase._statsSO、_animConfig 资产(按所创建的敌人类型命名)。"); @@ -361,9 +350,9 @@ namespace BaseGames.Editor } [MenuItem("BaseGames/Scene/Place/Boss Enemy", priority = 115)] - public static void PlaceBossEnemy() => PlaceBossEnemy(EnemyBodyColliderType.Box); + public static void PlaceBossEnemy() => PlaceBossEnemy(EnemyBodyColliderType.Box, null); - public static void PlaceBossEnemy(EnemyBodyColliderType bodyCollider) + public static void PlaceBossEnemy(EnemyBodyColliderType bodyCollider, Sprite defaultSprite = null) { var report = new List(); @@ -379,30 +368,18 @@ namespace BaseGames.Editor rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous; rb.interpolation = RigidbodyInterpolation2D.Interpolate; - CreateBodyCollider(go, bodyCollider, new Vector2(1.5f, 2.5f)); + Vector2 size = SpriteSizeOr(defaultSprite, new Vector2(1.5f, 2.5f)); + CreateBodyCollider(go, bodyCollider, size); GetOrAddComponent(go); - SetupSpriteRenderer(go); + SpriteRenderer sr = SetupSpriteRenderer(go); + if (defaultSprite != null) sr.sprite = defaultSprite; BossBase bossBase = GetOrAddComponent(go); EnemyStats bossStats = GetOrAddComponent(go); PhysicsPerceptionSystem sensorHub = GetOrAddComponent(go); - // HurtBox child - Transform hurtBoxT = GetOrCreateChild(go.transform, "HurtBox"); - SetLayer(hurtBoxT.gameObject, "EnemyHurtBox", report); - CapsuleCollider2D hurtCollider = GetOrAddComponent(hurtBoxT.gameObject); - hurtCollider.isTrigger = true; - hurtCollider.size = new Vector2(1.5f, 2.5f); - HurtBox hurtBox = GetOrAddComponent(hurtBoxT.gameObject); - - // Contact-damage HitBox child - Transform hitBodyT = GetOrCreateChild(go.transform, "HitBox_Body"); - SetLayer(hitBodyT.gameObject, "EnemyHitBox", report); - CircleCollider2D hitCollider = GetOrAddComponent(hitBodyT.gameObject); - hitCollider.isTrigger = true; - hitCollider.radius = 0.9f; - HitBox hitBox = GetOrAddComponent(hitBodyT.gameObject); - GetOrAddComponent(hitBodyT.gameObject); + var (hurtBox, bodyContact, contactHitBox) = + SetupHurtAndContactBoxes(go, size, contactEnabled: true, report); // References AssignReference(bossBase, "_stats", bossStats, report); @@ -410,9 +387,9 @@ namespace BaseGames.Editor // DamageSourceSO Object dmgSrc = FindFirstAsset("CMB_DS_BossBody", "CMB_DS_EnemyBody", "DS_BossBody"); if (dmgSrc != null) - AssignReference(hitBox, "_defaultSource", dmgSrc, report); + AssignReference(contactHitBox, "_defaultSource", dmgSrc, report); else - report.Add("未找到 DamageSourceSO,HitBox_Body._defaultSource 未绑定。请按规范创建 CMB_DS_BossBody.asset。"); + report.Add("未找到 DamageSourceSO,ContactDamageZone._defaultSource 未绑定。请按规范创建 CMB_DS_BossBody.asset。"); // Event channels AssignAsset(bossBase, "_onEnemyDied", report, false, "EVT_EnemyDied"); @@ -1063,9 +1040,9 @@ namespace BaseGames.Editor } [MenuItem("BaseGames/Scene/Place/Boss 嘲风 (ChaoFeng)", priority = 117)] - public static void PlaceChaoFeng() => PlaceChaoFeng(EnemyBodyColliderType.Box); + public static void PlaceChaoFeng() => PlaceChaoFeng(EnemyBodyColliderType.Box, null); - public static void PlaceChaoFeng(EnemyBodyColliderType bodyCollider) + public static void PlaceChaoFeng(EnemyBodyColliderType bodyCollider, Sprite defaultSprite = null) { var report = new List(); int undoGroup = Undo.GetCurrentGroup(); @@ -1083,12 +1060,14 @@ namespace BaseGames.Editor rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous; rb.interpolation = RigidbodyInterpolation2D.Interpolate; - Collider2D body = CreateBodyCollider(go, bodyCollider, new Vector2(1.2f, 2.0f)); + Vector2 size = SpriteSizeOr(defaultSprite, new Vector2(1.2f, 2.0f)); + Collider2D body = CreateBodyCollider(go, bodyCollider, size); Transform visual = GetOrCreateChild(go.transform, "Visual"); visual.localPosition = (Vector3)(Vector2)body.offset; GetOrAddComponent(visual.gameObject); AnimancerComponent animancer = GetOrAddComponent(visual.gameObject); SpriteRenderer srBoss = SetupSpriteRenderer(visual.gameObject); + if (defaultSprite != null) srBoss.sprite = defaultSprite; ChaoFengBoss bossBase = GetOrAddComponent(go); EnemyStats bossStats = GetOrAddComponent(go); @@ -1102,13 +1081,9 @@ namespace BaseGames.Editor ChaoFengKnockdownCounter knockdown = GetOrAddComponent(go); PhysicsPerceptionSystem sensorHub = GetOrAddComponent(go); - // HurtBox - Transform hurtBoxT = GetOrCreateChild(go.transform, "HurtBox"); - SetLayer(hurtBoxT.gameObject, "EnemyHurtBox", report); - CapsuleCollider2D hurtCap = GetOrAddComponent(hurtBoxT.gameObject); - hurtCap.isTrigger = true; - hurtCap.size = new Vector2(1.1f, 1.9f); - HurtBox hurtBox = GetOrAddComponent(hurtBoxT.gameObject); + // HurtBox + ContactDamageZone(Boss 身体接触伤害区,默认启用;策划可在 Inspector 关闭该子节点) + var (hurtBox, bodyContact, contactHitBox) = + SetupHurtAndContactBoxes(go, size, contactEnabled: true, report); // Phase1 攻击 HitBox(默认禁用;技能执行时由 BossSkillExecutor 开关)。 // 计划:挥扇三连 FanCombo ×3 + 龙卷接触 Tornado。 @@ -1191,7 +1166,7 @@ namespace BaseGames.Editor Object dmgSrc = FindFirstAsset("CMB_DS_BossBody", "CMB_DS_EnemyBody"); if (dmgSrc != null) { - foreach (var hb in new[] { fan1, fan2, fan3, tornadoHB }) + foreach (var hb in new[] { fan1, fan2, fan3, tornadoHB, contactHitBox }) if (hb != null) AssignReference(hb, "_defaultSource", dmgSrc, report); }