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