154 lines
6.6 KiB
C#
154 lines
6.6 KiB
C#
using UnityEngine;
|
|
|
|
namespace BrewMonster
|
|
{
|
|
/// <summary>
|
|
/// Animation test scene helpers for editor/bootstrap weapon iteration.
|
|
/// 动画测试场景:编辑器 / Bootstrap 武器调试辅助。
|
|
/// </summary>
|
|
public abstract partial class CECPlayer
|
|
{
|
|
/// <summary>
|
|
/// Attach weapon prefabs like <see cref="CECPlayer_Inventory.ShowEquipments"/> (hand hooks), and set <see cref="m_uAttackType"/> for <see cref="GetShowingWeaponType"/>.
|
|
/// Omit both prefabs (or pass <see cref="DEFAULT_ACTION_TYPE"/>) to clear meshes and reset attack type.
|
|
/// 与 ShowEquipments 相同挂点挂接武器,并设置 m_uAttackType 以驱动动作后缀。两预制体均为空则清除并还原默认攻击类型。
|
|
/// </summary>
|
|
public void AnimSceneAttachWeaponPrefabs(GameObject rightPrefab, GameObject leftPrefab, uint weaponActionType)
|
|
{
|
|
if (_currentRightHandWeapon != null)
|
|
{
|
|
Destroy(_currentRightHandWeapon);
|
|
_currentRightHandWeapon = null;
|
|
}
|
|
|
|
if (_currentLeftHandWeapon != null)
|
|
{
|
|
Destroy(_currentLeftHandWeapon);
|
|
_currentLeftHandWeapon = null;
|
|
}
|
|
|
|
bool anyAttached = false;
|
|
|
|
if (rightPrefab != null)
|
|
{
|
|
GameObject hookGo = FindChildObjectRecursive(transform, _hh_right_hand_weapon);
|
|
if (hookGo != null)
|
|
{
|
|
GameObject weaponObject = Instantiate(rightPrefab);
|
|
weaponObject.transform.SetParent(hookGo.transform);
|
|
weaponObject.transform.localPosition = rightPrefab.transform.localPosition;
|
|
weaponObject.transform.localRotation = rightPrefab.transform.localRotation;
|
|
weaponObject.transform.localScale = Vector3.one;
|
|
weaponObject.SetActive(true);
|
|
_currentRightHandWeapon = weaponObject;
|
|
anyAttached = true;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning(
|
|
"[AnimSceneBootstrap] AnimSceneAttachWeaponPrefabs: hook not found: " + _hh_right_hand_weapon);
|
|
}
|
|
}
|
|
|
|
if (leftPrefab != null)
|
|
{
|
|
GameObject hookGo = FindChildObjectRecursive(transform, _hh_left_hand_weapon);
|
|
if (hookGo != null)
|
|
{
|
|
GameObject weaponObject = Instantiate(leftPrefab);
|
|
weaponObject.transform.SetParent(hookGo.transform);
|
|
weaponObject.transform.localPosition = leftPrefab.transform.localPosition;
|
|
weaponObject.transform.localRotation = leftPrefab.transform.localRotation;
|
|
weaponObject.transform.localScale = Vector3.one;
|
|
weaponObject.SetActive(true);
|
|
_currentLeftHandWeapon = weaponObject;
|
|
anyAttached = true;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning(
|
|
"[AnimSceneBootstrap] AnimSceneAttachWeaponPrefabs: hook not found: " + _hh_left_hand_weapon);
|
|
}
|
|
}
|
|
|
|
if (anyAttached)
|
|
{
|
|
m_uAttackType = weaponActionType;
|
|
m_bWeaponAttached = true;
|
|
}
|
|
else
|
|
{
|
|
m_uAttackType = DEFAULT_ACTION_TYPE;
|
|
AttachWeapon();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// <see cref="Awake"/> assigns <see cref="m_PlayerActions"/> = <see cref="_default_actions"/> before <see cref="InitStaticRes"/> fills the static table — rebind after bootstrap calls <c>InitStaticRes</c>.
|
|
/// Mirrors <see cref="SetNewExtendStates"/> (state 111 → turning table).
|
|
/// Awake 时静态动作表可能尚未构建;Bootstrap 在 InitStaticRes 之后调用本方法。逻辑与 SetNewExtendStates 一致(扩展状态 111 用旋转表)。
|
|
/// </summary>
|
|
public void AnimSceneRebindPlayerActions()
|
|
{
|
|
if (GetExtState(111) && _turning_actions != null)
|
|
{
|
|
m_PlayerActions = _turning_actions;
|
|
}
|
|
else
|
|
{
|
|
m_PlayerActions = _default_actions;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Animation test scene: <c>elementdataman</c> may not register <c>DT_FASHION_WEAPON_CONFIG</c>, so <see cref="IsFashionWeaponTypeFit"/>
|
|
/// can NRE on a null <c>action_mask</c> when <see cref="m_iFashionWeaponType"/> is in <c>[0, NUM_WEAPON_TYPE)</c>.
|
|
/// Setting <c>-1</c> makes <see cref="GetShowingWeaponType"/> skip the fashion branch (early out in IsFashionWeaponTypeFit).
|
|
/// 动画测试:元素表可能未注册时装武器配置;将时尚武器类型置为 -1 避免 IsFashionWeaponTypeFit 空引用。
|
|
/// </summary>
|
|
public void AnimSceneSanitizeFashionWeaponStateForElementDataCompat()
|
|
{
|
|
m_iFashionWeaponType = -1;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Inspector/debug: non-null string means <see cref="PlayAction"/> will no-op or return false before Animancer runs.
|
|
/// 非空表示 PlayAction 会在播放前失败或直接被拒。
|
|
/// </summary>
|
|
public string AnimSceneTryExplainPlayActionFailure(int iAction)
|
|
{
|
|
if (iAction < 0 || iAction >= (int)PLAYER_ACTION_TYPE.ACT_MAX)
|
|
{
|
|
return $"Action index must be 0..{(int)PLAYER_ACTION_TYPE.ACT_MAX - 1}.";
|
|
}
|
|
|
|
if (m_pPlayerCECModel == null)
|
|
{
|
|
return "CECModel is null — wait for SetPlayerModel / Switch model to finish.";
|
|
}
|
|
|
|
if (m_PlayerActions == null)
|
|
{
|
|
return "m_PlayerActions is null — click Play again after bootstrap runs, or call AnimSceneRebindPlayerActions().";
|
|
}
|
|
|
|
if (m_PlayerActions[iAction].data.id == 0)
|
|
{
|
|
return $"No PLAYER_ACTION_INFO_CONFIG for index {iAction} (data.id==0). Check actions_player / element data for this action.";
|
|
}
|
|
|
|
if (m_pActionController == null)
|
|
{
|
|
return "m_pActionController is null — model setup did not call RecreateActionController (SetPlayerModel incomplete?).";
|
|
}
|
|
|
|
if (iAction >= (int)PLAYER_ACTION_TYPE.ACT_ATTACK_1 && iAction <= (int)PLAYER_ACTION_TYPE.ACT_ATTACK_4)
|
|
{
|
|
return "ACT_ATTACK_1..4 are blocked in PlayActionWithConfig — use skill/combat paths.";
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|