67 lines
2.5 KiB
C#
67 lines
2.5 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace WL.Player
|
|
{
|
|
/// <summary>
|
|
/// 플레이어 레벨·경험치 런타임 상태 (PD #727). 씬에 1개("PlayerProgress")를 둔다.
|
|
/// 값은 PlayerProgressSettings 에서 읽고(C45), 바뀔 때 Changed 를 발화한다 — HUD 가 구독한다.
|
|
/// 경험치는 Enemy.AnyDied(처치 1회)마다 설정의 xpPerKill 만큼 더한다 — 표기가 실제로 움직이도록 최소 연결(임시값).
|
|
/// </summary>
|
|
public class PlayerProgress : MonoBehaviour
|
|
{
|
|
[Header("설정 (ScriptableObject)")]
|
|
[SerializeField] private PlayerProgressSettings settings;
|
|
|
|
public int Level { get; private set; }
|
|
public long Xp { get; private set; }
|
|
public long XpToNext { get; private set; }
|
|
public PlayerProgressSettings Settings { get { return settings; } }
|
|
|
|
/// <summary>레벨·경험치가 바뀔 때.</summary>
|
|
public event Action Changed;
|
|
|
|
private void Awake() { ResetFromSettings(); }
|
|
|
|
private void OnEnable() { Enemy.AnyDied += OnAnyEnemyDied; }
|
|
private void OnDisable() { Enemy.AnyDied -= OnAnyEnemyDied; }
|
|
|
|
private void OnAnyEnemyDied(Enemy e)
|
|
{
|
|
if (e != null && e.IsInvincible) return; // 무적 더미 봇은 죽지 않지만 방어적으로 제외
|
|
OnEnemyKilled();
|
|
}
|
|
|
|
/// <summary>설정값으로 되돌린다(시작 시·검증용).</summary>
|
|
public void ResetFromSettings()
|
|
{
|
|
Level = settings != null ? Mathf.Max(settings.startLevel, 1) : 1;
|
|
Xp = settings != null ? Math.Max(settings.startXp, 0L) : 0L;
|
|
XpToNext = settings != null ? settings.XpToNext(Level) : 100L;
|
|
if (Changed != null) Changed();
|
|
}
|
|
|
|
/// <summary>경험치를 더하고 필요 경험치를 넘으면 레벨업한다(여러 단계 연속 가능).</summary>
|
|
public void AddXp(long amount)
|
|
{
|
|
if (amount <= 0) return;
|
|
Xp += amount;
|
|
int guard = 0;
|
|
while (Xp >= XpToNext && guard++ < 1000)
|
|
{
|
|
Xp -= XpToNext;
|
|
Level++;
|
|
XpToNext = settings != null ? settings.XpToNext(Level) : XpToNext;
|
|
}
|
|
if (Changed != null) Changed();
|
|
}
|
|
|
|
/// <summary>몬스터 처치 보상(설정 xpPerKill). 처치 이벤트 연결 시 호출한다.</summary>
|
|
public void OnEnemyKilled()
|
|
{
|
|
if (settings == null) return;
|
|
AddXp(settings.xpPerKill);
|
|
}
|
|
}
|
|
}
|