feat: 젬 장착 제약 시스템 추가

- 기반 스킬 분류를 도입하고 젬별 장착 가능 스킬 타입 조건을 추가함
- 동일 젬 중복 장착, 카테고리 상호 배타, 특정 젬 상호 배타를 로드아웃 검증에 반영함
- 테스트용 젬/스킬 자산과 디버그 생성 메뉴를 새 제약 구조에 맞게 갱신함
- Unity 재컴파일과 콘솔 확인으로 신규 컴파일 에러가 없음을 검증함
This commit is contained in:
2026-03-26 14:49:59 +09:00
parent e4710f9a29
commit 1261d4dc3c
27 changed files with 399 additions and 34 deletions

View File

@@ -624,7 +624,8 @@ namespace Colosseum.Editor
1f,
1f,
0,
damageEffect);
damageEffect,
allowedSkillTypes: SkillBaseType.Attack);
CreateOrUpdateGemAsset(
ChallengerGemPath,
@@ -639,7 +640,8 @@ namespace Colosseum.Editor
1f,
1.5f,
0,
tauntEffect);
tauntEffect,
allowedSkillTypes: SkillBaseType.Attack);
CreateOrUpdateGemAsset(
GuardianGemPath,
@@ -654,7 +656,8 @@ namespace Colosseum.Editor
1.5f,
1f,
0,
shieldEffect);
shieldEffect,
allowedSkillTypes: SkillBaseType.Attack);
CreateOrUpdateGemAsset(
RepeatGemPath,
@@ -669,7 +672,8 @@ namespace Colosseum.Editor
1f,
1f,
1,
null);
null,
allowedSkillTypes: SkillBaseType.Attack);
CreateOrUpdateGemAsset(
FortitudeGemPath,
@@ -718,7 +722,8 @@ namespace Colosseum.Editor
1f,
1f,
0,
edgeDamageEffect);
edgeDamageEffect,
allowedSkillTypes: SkillBaseType.Attack);
CreateOrUpdateGemAsset(
ImpactGemPath,
@@ -733,7 +738,8 @@ namespace Colosseum.Editor
1f,
1f,
0,
impactDamageEffect);
impactDamageEffect,
allowedSkillTypes: SkillBaseType.Attack);
CreateOrUpdateGemAsset(
BreachGemPath,
@@ -748,7 +754,8 @@ namespace Colosseum.Editor
1f,
1f,
0,
breachDamageEffect);
breachDamageEffect,
allowedSkillTypes: SkillBaseType.Attack);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
@@ -786,6 +793,20 @@ namespace Colosseum.Editor
SkillGemData impactGem = AssetDatabase.LoadAssetAtPath<SkillGemData>(ImpactGemPath);
SkillGemData breachGem = AssetDatabase.LoadAssetAtPath<SkillGemData>(BreachGemPath);
SetSkillBaseTypes(slashSkill, SkillBaseType.Attack);
SetSkillBaseTypes(tauntSkill, SkillBaseType.Control | SkillBaseType.Utility);
SetSkillBaseTypes(guardSkill, SkillBaseType.Defense);
SetSkillBaseTypes(dashSkill, SkillBaseType.Mobility);
SetSkillBaseTypes(ironWallSkill, SkillBaseType.Defense | SkillBaseType.Support);
SetSkillBaseTypes(pierceSkill, SkillBaseType.Attack);
SetSkillBaseTypes(gemTestSkill, SkillBaseType.Attack);
SetSkillBaseTypes(healSkill, SkillBaseType.Support);
SetSkillBaseTypes(areaHealSkill, SkillBaseType.Support);
SetSkillBaseTypes(shieldSkill, SkillBaseType.Defense | SkillBaseType.Support);
SetSkillBaseTypes(projectileSkill, SkillBaseType.Attack);
SetSkillBaseTypes(spinSkill, SkillBaseType.Attack);
SetSkillBaseTypes(evadeSkill, SkillBaseType.Mobility);
EnsureGemTestSkillSlotCount(gemTestSkill, 3);
CreateOrUpdatePresetAsset(
@@ -1314,7 +1335,10 @@ namespace Colosseum.Editor
SkillEffect triggeredEffect,
AbnormalityData[] selfAbnormalities = null,
int triggeredAbnormalityIndex = -1,
AbnormalityData[] onHitAbnormalities = null)
AbnormalityData[] onHitAbnormalities = null,
SkillBaseType allowedSkillTypes = SkillBaseType.All,
SkillGemCategory[] incompatibleCategories = null,
SkillGemData[] incompatibleGems = null)
{
SkillGemData gem = AssetDatabase.LoadAssetAtPath<SkillGemData>(assetPath);
if (gem == null)
@@ -1340,6 +1364,21 @@ namespace Colosseum.Editor
serializedGem.FindProperty("shieldMultiplier").floatValue = shieldMultiplier;
serializedGem.FindProperty("threatMultiplier").floatValue = threatMultiplier;
serializedGem.FindProperty("additionalRepeatCount").intValue = additionalRepeatCount;
serializedGem.FindProperty("allowedSkillTypes").intValue = (int)allowedSkillTypes;
SerializedProperty incompatibleCategoriesProperty = serializedGem.FindProperty("incompatibleCategories");
incompatibleCategoriesProperty.arraySize = incompatibleCategories != null ? incompatibleCategories.Length : 0;
for (int i = 0; i < incompatibleCategoriesProperty.arraySize; i++)
{
incompatibleCategoriesProperty.GetArrayElementAtIndex(i).enumValueIndex = (int)incompatibleCategories[i];
}
SerializedProperty incompatibleGemsProperty = serializedGem.FindProperty("incompatibleGems");
incompatibleGemsProperty.arraySize = incompatibleGems != null ? incompatibleGems.Length : 0;
for (int i = 0; i < incompatibleGemsProperty.arraySize; i++)
{
incompatibleGemsProperty.GetArrayElementAtIndex(i).objectReferenceValue = incompatibleGems[i];
}
SerializedProperty castStartEffectsProperty = serializedGem.FindProperty("castStartEffects");
castStartEffectsProperty.arraySize = 0;
@@ -1385,6 +1424,21 @@ namespace Colosseum.Editor
EditorUtility.SetDirty(gem);
}
private static void SetSkillBaseTypes(SkillData skill, SkillBaseType baseTypes)
{
if (skill == null)
return;
SerializedObject serializedSkill = new SerializedObject(skill);
SerializedProperty baseTypesProperty = serializedSkill.FindProperty("baseTypes");
if (baseTypesProperty == null || baseTypesProperty.intValue == (int)baseTypes)
return;
baseTypesProperty.intValue = (int)baseTypes;
serializedSkill.ApplyModifiedPropertiesWithoutUndo();
EditorUtility.SetDirty(skill);
}
private static DamageEffect CreateOrUpdateDamageEffectAsset(string assetPath, float baseDamage)
{
DamageEffect effect = AssetDatabase.LoadAssetAtPath<DamageEffect>(assetPath);