feat: 빈사/부활 시스템 및 ReviveEffect 추가

- PlayerNetworkController에 Revive(healthPercent) 메서드와 OnRevived 이벤트 추가

- ReviveEffect 스킬 이펙트 구현 (Area/Ally 타겟팅, healthPercent로 체력 복구)

- GameManager가 OnRevived 구독하여 alivePlayers 동적 복구

- GameManager.Update에서 나중에 스폰된 플레이어 자동 구독 (MPP 대응)

- SkillCancelReason에 Revive 추가

- 부활 스킬/이펙트 ScriptableObject 에셋 생성 (치유 클립 임시 사용)

- PlayerSkillDebugMenu에 즉사/부활/리스폰/스폰/Client1 스킬 디버그 메뉴 추가

- PlayerAbnormalityDebugHUD에 부활 버튼 추가

- DebugExecuteSkillAsServer에 실패 원인 로그 추가

- AGENTS.md에 코드 변경 후 force reload 규칙 추가
This commit is contained in:
2026-03-28 21:03:28 +09:00
parent 057b17e6cc
commit 282e4b29c4
12 changed files with 385 additions and 9 deletions

View File

@@ -130,6 +130,12 @@ namespace Colosseum.Editor
CastOwnedPlayerSkillAsServer(1, 5);
}
[MenuItem("Tools/Colosseum/Debug/Cast Client1 Skill 5")]
private static void CastClient1Skill5()
{
CastOwnedPlayerSkillAsServer(1, 6);
}
[MenuItem("Tools/Colosseum/Debug/Cast Local Heal")]
private static void CastLocalHeal()
{
@@ -167,6 +173,129 @@ namespace Colosseum.Editor
localNetworkController.TakeDamageRpc(30f);
}
[MenuItem("Tools/Colosseum/Debug/Kill Local Player")]
private static void KillLocalPlayer()
{
if (!EditorApplication.isPlaying)
{
Debug.LogWarning("[Debug] 플레이 모드에서만 사용할 수 있습니다.");
return;
}
PlayerNetworkController localNetworkController = FindLocalNetworkController();
if (localNetworkController == null)
{
Debug.LogWarning("[Debug] 로컬 PlayerNetworkController를 찾지 못했습니다.");
return;
}
localNetworkController.TakeDamageRpc(localNetworkController.Health + 999f);
Debug.Log($"[Debug] 로컬 플레이어 즉사 | HP={localNetworkController.Health:F1}");
}
[MenuItem("Tools/Colosseum/Debug/Revive Local Player")]
private static void ReviveLocalPlayer()
{
if (!EditorApplication.isPlaying)
{
Debug.LogWarning("[Debug] 플레이 모드에서만 사용할 수 있습니다.");
return;
}
PlayerNetworkController localNetworkController = FindLocalNetworkController();
if (localNetworkController == null)
{
Debug.LogWarning("[Debug] 로컬 PlayerNetworkController를 찾지 못했습니다.");
return;
}
if (!localNetworkController.IsDead)
{
Debug.LogWarning("[Debug] 로컬 플레이어가 사망 상태가 아닙니다.");
return;
}
localNetworkController.Revive(0.3f);
Debug.Log($"[Debug] 로컬 플레이어 부활 | HP={localNetworkController.Health:F1}");
}
[MenuItem("Tools/Colosseum/Debug/Respawn Local Player")]
private static void RespawnLocalPlayer()
{
if (!EditorApplication.isPlaying)
{
Debug.LogWarning("[Debug] 플레이 모드에서만 사용할 수 있습니다.");
return;
}
PlayerNetworkController localNetworkController = FindLocalNetworkController();
if (localNetworkController == null)
{
Debug.LogWarning("[Debug] 로컬 PlayerNetworkController를 찾지 못했습니다.");
return;
}
localNetworkController.Respawn();
Debug.Log($"[Debug] 로컬 플레이어 리스폰 | HP={localNetworkController.Health:F1}");
}
[MenuItem("Tools/Colosseum/Debug/Spawn Players")]
private static void SpawnPlayers()
{
if (!EditorApplication.isPlaying)
{
Debug.LogWarning("[Debug] 플레이 모드에서만 사용할 수 있습니다.");
return;
}
var networkManager = Unity.Netcode.NetworkManager.Singleton;
if (networkManager == null || !networkManager.IsServer)
{
Debug.LogWarning("[Debug] NetworkManager가 없거나 서버가 아닙니다.");
return;
}
const string playerPrefabPath = "Assets/_Game/Prefabs/Player/Prefab_Player_Default.prefab";
GameObject playerPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(playerPrefabPath);
if (playerPrefab == null)
{
Debug.LogWarning($"[Debug] 플레이어 프리팹을 찾지 못했습니다: {playerPrefabPath}");
return;
}
int spawnedCount = 0;
foreach (ulong clientId in networkManager.ConnectedClientsIds)
{
bool alreadyExists = false;
var allPlayers = Object.FindObjectsByType<PlayerNetworkController>(FindObjectsInactive.Exclude, FindObjectsSortMode.None);
for (int i = 0; i < allPlayers.Length; i++)
{
if (allPlayers[i] != null && allPlayers[i].OwnerClientId == clientId)
{
alreadyExists = true;
break;
}
}
if (alreadyExists)
continue;
var go = Object.Instantiate(playerPrefab);
var no = go.GetComponent<Unity.Netcode.NetworkObject>();
if (no != null)
{
no.SpawnAsPlayerObject(clientId, true);
spawnedCount++;
}
else
{
Object.Destroy(go);
}
}
Debug.Log($"[Debug] 플레이어 스폰 완료 | {spawnedCount}명 스폰 (총 연결: {networkManager.ConnectedClientsIds.Count})");
}
[MenuItem("Tools/Colosseum/Debug/Log Local Player Status")]
private static void LogLocalPlayerStatus()
{