using System;
using UnityEngine;
using BaseGames.Core;
using BaseGames.Core.Save;
using BaseGames.Core.Events;
using BaseGames.Input;
namespace BaseGames.Player
{
///
/// 形态控制器。
/// 管理天魂/地魂/命魂三形态切换,依次触发:
/// 1. _onFormChanged SO 事件(UI/Save 用)
/// 2. OnFormChanged C# 事件(WeaponManager 订阅)
/// 3. _onSkillSetChanged SO 事件(SkillHUD 刷新)
/// 架构 05_PlayerModule §6。
///
public class FormController : MonoBehaviour, ISaveable
{
[Header("配置")]
[SerializeField] private FormConfigSO _config;
[SerializeField] private InputReaderSO _input;
[Header("事件频道")]
[SerializeField] private IntEventChannelSO _onFormChanged; // 广播当前形态索引(UI/Save)
[SerializeField] private VoidEventChannelSO _onSkillSetChanged; // 通知 SkillHUD 刷新
// ── 运行时 ─────────────────────────────────────────────────────────────
public FormSO CurrentForm { get; private set; }
public FormSO[] AllForms => _config.forms;
/// C# 事件,WeaponManager 在 OnEnable 自订阅(架构 05 §6)。
public event Action OnFormChanged;
private void Awake()
{
Debug.Assert(_config != null, "[FormController] _config 未赋值,请在 Inspector 中指定 FormConfigSO。", this);
}
private void OnEnable()
{
ServiceLocator.GetOrDefault()?.Register(this);
if (_input == null) return;
_input.SwitchSkyFormEvent += OnSwitchSky;
_input.SwitchEarthFormEvent += OnSwitchEarth;
_input.SwitchDeathFormEvent += OnSwitchDeath;
}
private void OnDisable()
{
ServiceLocator.GetOrDefault()?.Unregister(this);
if (_input == null) return;
_input.SwitchSkyFormEvent -= OnSwitchSky;
_input.SwitchEarthFormEvent -= OnSwitchEarth;
_input.SwitchDeathFormEvent -= OnSwitchDeath;
}
private void Start()
{
if (_config.forms != null && _config.forms.Length > 0)
CurrentForm = _config.forms[0];
}
// ── 公共 API ────────────────────────────────────────────────────────────
/// 切换到指定形态类型。若已在目标形态则不操作。
public void SwitchForm(FormType newFormType)
{
FormSO newForm = _config.GetFormByType(newFormType);
if (newForm == null || newForm == CurrentForm) return;
CurrentForm = newForm;
// 1. SO 事件广播索引(UI/Save)
_onFormChanged?.Raise(_config.GetFormIndex(newForm));
// 2. C# 事件(WeaponManager 等订阅者)
OnFormChanged?.Invoke();
// 3. SkillHUD 刷新事件
_onSkillSetChanged?.Raise();
}
/// 通过数组索引切换形态。
public void SwitchToFormByIndex(int index)
{
if (_config?.forms == null || index < 0 || index >= _config.forms.Length) return;
var form = _config.forms[index];
if (form != null)
SwitchForm(form.formType);
}
// ── ISaveable ────────────────────────────────────────────────────────────
public void OnSave(SaveData data)
{
data.Player.ActiveFormId = CurrentForm?.formId;
}
public void OnLoad(SaveData data)
{
if (string.IsNullOrEmpty(data.Player.ActiveFormId) || _config?.forms == null)
{
if (_config?.forms != null && _config.forms.Length > 0)
CurrentForm = _config.forms[0];
return;
}
for (int i = 0; i < _config.forms.Length; i++)
{
if (_config.forms[i]?.formId == data.Player.ActiveFormId)
{
// 直接赋值,不触发事件——加载时场景尚未完全就绪,订阅者(WeaponManager 等)
// 会在各自 OnEnable + Register → OnLoad 回调中自行恢复状态。
CurrentForm = _config.forms[i];
return;
}
}
}
// ── 内部输入处理 ────────────────────────────────────────────────────────
private void OnSwitchSky() => SwitchForm(FormType.TianHun);
private void OnSwitchEarth() => SwitchForm(FormType.DiHun);
private void OnSwitchDeath() => SwitchForm(FormType.MingHun);
}
}