feat: 플레이어 역할별 스킬 프리셋 적용 경로 추가
- 탱커, 지원, 딜러 기본 슬롯 프리셋을 로컬 플레이어에 즉시 적용하는 디버그 메뉴를 추가 - PlayerSkillInput에 7칸 슬롯 자동 보정과 일괄 갱신 API를 넣어 기존 프리팹 직렬화와 호환되도록 정리 - SkillQuickSlotUI가 스킬 슬롯 변경 이벤트를 구독해 프리셋 적용 시 액션바가 즉시 갱신되도록 보강 - 플레이 검증에서 탱커, 지원, 딜러 프리셋이 모두 기대한 슬롯 순서와 Ctrl 회피 슬롯까지 정상 적용되는 것을 확인
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using Unity.Netcode;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Colosseum.Skills;
|
||||
using Colosseum.Weapons;
|
||||
@@ -14,9 +16,11 @@ namespace Colosseum.Player
|
||||
[RequireComponent(typeof(PlayerActionState))]
|
||||
public class PlayerSkillInput : NetworkBehaviour
|
||||
{
|
||||
private const int ExpectedSkillSlotCount = 7;
|
||||
|
||||
[Header("Skill Slots")]
|
||||
[Tooltip("각 슬롯에 등록할 스킬 데이터 (6개 + 추가 슬롯)")]
|
||||
[SerializeField] private SkillData[] skillSlots = new SkillData[7];
|
||||
[SerializeField] private SkillData[] skillSlots = new SkillData[ExpectedSkillSlotCount];
|
||||
|
||||
[Header("References")]
|
||||
[Tooltip("SkillController (없으면 자동 검색)")]
|
||||
@@ -32,8 +36,15 @@ namespace Colosseum.Player
|
||||
|
||||
public SkillData[] SkillSlots => skillSlots;
|
||||
|
||||
/// <summary>
|
||||
/// 스킬 슬롯 구성이 변경되었을 때 호출됩니다.
|
||||
/// </summary>
|
||||
public event Action OnSkillSlotsChanged;
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
EnsureSkillSlotCapacity();
|
||||
|
||||
if (!IsOwner)
|
||||
{
|
||||
enabled = false;
|
||||
@@ -99,6 +110,16 @@ namespace Colosseum.Player
|
||||
CleanupInputActions();
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
EnsureSkillSlotCapacity();
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
EnsureSkillSlotCapacity();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (IsOwner && inputActions != null)
|
||||
@@ -107,6 +128,28 @@ namespace Colosseum.Player
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 기존 프리팹이나 씬 직렬화 데이터가 6칸으로 남아 있어도
|
||||
/// 긴급 회피 슬롯까지 포함한 7칸 구성을 항상 보장합니다.
|
||||
/// </summary>
|
||||
private void EnsureSkillSlotCapacity()
|
||||
{
|
||||
if (skillSlots != null && skillSlots.Length == ExpectedSkillSlotCount)
|
||||
return;
|
||||
|
||||
SkillData[] resizedSlots = new SkillData[ExpectedSkillSlotCount];
|
||||
if (skillSlots != null)
|
||||
{
|
||||
int copyCount = Mathf.Min(skillSlots.Length, resizedSlots.Length);
|
||||
for (int i = 0; i < copyCount; i++)
|
||||
{
|
||||
resizedSlots[i] = skillSlots[i];
|
||||
}
|
||||
}
|
||||
|
||||
skillSlots = resizedSlots;
|
||||
}
|
||||
|
||||
private void CleanupInputActions()
|
||||
{
|
||||
if (inputActions != null)
|
||||
@@ -227,6 +270,8 @@ namespace Colosseum.Player
|
||||
/// </summary>
|
||||
public SkillData GetSkill(int slotIndex)
|
||||
{
|
||||
EnsureSkillSlotCapacity();
|
||||
|
||||
if (slotIndex < 0 || slotIndex >= skillSlots.Length)
|
||||
return null;
|
||||
return skillSlots[slotIndex];
|
||||
@@ -237,10 +282,37 @@ namespace Colosseum.Player
|
||||
/// </summary>
|
||||
public void SetSkill(int slotIndex, SkillData skill)
|
||||
{
|
||||
EnsureSkillSlotCapacity();
|
||||
|
||||
if (slotIndex < 0 || slotIndex >= skillSlots.Length)
|
||||
return;
|
||||
|
||||
skillSlots[slotIndex] = skill;
|
||||
OnSkillSlotsChanged?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 전체 스킬 슬롯을 한 번에 갱신합니다.
|
||||
/// </summary>
|
||||
public void SetSkills(IReadOnlyList<SkillData> skills)
|
||||
{
|
||||
EnsureSkillSlotCapacity();
|
||||
|
||||
if (skills == null)
|
||||
return;
|
||||
|
||||
int count = Mathf.Min(skillSlots.Length, skills.Count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
skillSlots[i] = skills[i];
|
||||
}
|
||||
|
||||
for (int i = count; i < skillSlots.Length; i++)
|
||||
{
|
||||
skillSlots[i] = null;
|
||||
}
|
||||
|
||||
OnSkillSlotsChanged?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user