摄像机区域的架构改动
This commit is contained in:
127
Assets/_Game/Scripts/Editor/Skills/SkillHitBoxWizard.cs
Normal file
127
Assets/_Game/Scripts/Editor/Skills/SkillHitBoxWizard.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using BaseGames.Combat;
|
||||
|
||||
namespace BaseGames.Editor.Skills
|
||||
{
|
||||
/// <summary>
|
||||
/// 向导:一键生成技能 HitBox Prefab(W-11)。
|
||||
/// 菜单:BaseGames / Create / Skill HitBox Prefab
|
||||
///
|
||||
/// 生成路径规范:Assets/_Game/Prefabs/Skills/SKL_{skillId}_HitBox.prefab
|
||||
/// Prefab 结构(以 hitBoxCount=1 为例):
|
||||
/// [SKL_{skillId}_HitBox] ← SkillHitBoxInstance (_hitBoxes 自动赋值)
|
||||
/// └── [HitBox_0] ← PolygonCollider2D(IsTrigger) + HitBox, Layer=PlayerHitBox
|
||||
/// </summary>
|
||||
public class SkillHitBoxWizard : ScriptableWizard
|
||||
{
|
||||
private const string OutputFolder = "Assets/_Game/Prefabs/Skills";
|
||||
|
||||
[MenuItem("BaseGames/Create/Skill HitBox Prefab", priority = 201)]
|
||||
public static void Open() =>
|
||||
DisplayWizard<SkillHitBoxWizard>("Skill HitBox Prefab 向导", "创建");
|
||||
|
||||
[Tooltip("技能唯一 ID,如 SkySlash。Prefab 将命名为 SKL_{skillId}_HitBox")]
|
||||
public string skillId = "";
|
||||
|
||||
[Tooltip("多段伤害时可设置 >1(每段一个 HitBox 子节点)")]
|
||||
[Range(1, 4)]
|
||||
public int hitBoxCount = 1;
|
||||
|
||||
// ── 向导回调 ──────────────────────────────────────────────────────────
|
||||
|
||||
private void OnWizardUpdate()
|
||||
{
|
||||
isValid = !string.IsNullOrWhiteSpace(skillId);
|
||||
helpString = isValid
|
||||
? $"将创建:{OutputFolder}/SKL_{skillId}_HitBox.prefab({hitBoxCount} 个 HitBox)"
|
||||
: "请输入 skillId(技能唯一 ID,如 SkySlash)。";
|
||||
}
|
||||
|
||||
private void OnWizardCreate()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(skillId))
|
||||
{
|
||||
EditorUtility.DisplayDialog("错误", "skillId 不能为空。", "确认");
|
||||
return;
|
||||
}
|
||||
|
||||
string prefabName = $"SKL_{skillId}_HitBox";
|
||||
string assetPath = $"{OutputFolder}/{prefabName}.prefab";
|
||||
|
||||
string fullPath = Path.Combine(
|
||||
Path.GetDirectoryName(Application.dataPath)!,
|
||||
assetPath.Replace('/', Path.DirectorySeparatorChar));
|
||||
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
if (!EditorUtility.DisplayDialog("已存在",
|
||||
$"{assetPath}\n\n该 Prefab 已存在,是否覆盖?",
|
||||
"覆盖", "取消"))
|
||||
return;
|
||||
}
|
||||
|
||||
EditorScaffoldUtils.EnsureFolder(OutputFolder);
|
||||
|
||||
int hitBoxLayer = LayerMask.NameToLayer("PlayerHitBox");
|
||||
if (hitBoxLayer < 0)
|
||||
{
|
||||
Debug.LogWarning("[SkillHitBoxWizard] 未找到 Physics Layer 'PlayerHitBox',子节点 Layer 将设为 Default。");
|
||||
hitBoxLayer = 0;
|
||||
}
|
||||
|
||||
// ── 构建 Prefab ────────────────────────────────────────────────
|
||||
var root = new GameObject(prefabName);
|
||||
var instance = root.AddComponent<SkillHitBoxInstance>();
|
||||
var so = new SerializedObject(instance);
|
||||
|
||||
var hbRefs = new HitBox[hitBoxCount];
|
||||
for (int i = 0; i < hitBoxCount; i++)
|
||||
{
|
||||
var child = new GameObject($"HitBox_{i}");
|
||||
child.transform.SetParent(root.transform, false);
|
||||
child.layer = hitBoxLayer;
|
||||
|
||||
// PolygonCollider2D 默认菱形(1×0.5),策划在 Scene 中调整具体形状
|
||||
var poly = child.AddComponent<PolygonCollider2D>();
|
||||
poly.isTrigger = true;
|
||||
poly.SetPath(0, new Vector2[]
|
||||
{
|
||||
new(-0.5f, -0.25f), new(0.5f, -0.25f),
|
||||
new(0.5f, 0.25f), new(-0.5f, 0.25f),
|
||||
});
|
||||
|
||||
hbRefs[i] = child.AddComponent<HitBox>();
|
||||
}
|
||||
|
||||
// 将 HitBox[] 赋值给 _hitBoxes
|
||||
var arrayProp = so.FindProperty("_hitBoxes");
|
||||
if (arrayProp != null && arrayProp.isArray)
|
||||
{
|
||||
arrayProp.arraySize = hitBoxCount;
|
||||
for (int i = 0; i < hitBoxCount; i++)
|
||||
arrayProp.GetArrayElementAtIndex(i).objectReferenceValue = hbRefs[i];
|
||||
so.ApplyModifiedPropertiesWithoutUndo();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[SkillHitBoxWizard] 未找到 SkillHitBoxInstance._hitBoxes 字段,请手动赋值。");
|
||||
}
|
||||
|
||||
var prefab = PrefabUtility.SaveAsPrefabAsset(root, assetPath);
|
||||
Object.DestroyImmediate(root);
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
if (prefab != null)
|
||||
{
|
||||
EditorScaffoldUtils.PingAndSelect(prefab);
|
||||
Debug.Log($"[SkillHitBoxWizard] 已创建:{assetPath}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"[SkillHitBoxWizard] Prefab 保存失败:{assetPath}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user