Files
test/Assets/PerfectWorld/Scripts/Editor/AnimScenePlayerBootstrapEditor.cs
2026-05-29 10:16:30 +07:00

236 lines
9.4 KiB
C#

#if UNITY_EDITOR
using BrewMonster;
using BrewMonster.Scripts;
using UnityEditor;
using UnityEngine;
namespace PerfectWorld.Scripts
{
[CustomEditor(typeof(AnimScenePlayerBootstrap))]
internal sealed class AnimScenePlayerBootstrapEditor : UnityEditor.Editor
{
private Profession _editorSwitchProfession = Profession.PROF_MAGE;
private Gender _editorSwitchGender = Gender.GENDER_FEMALE;
private int _playActionIndex;
private bool _playActionRestart = true;
static AnimScenePlayerBootstrapEditor()
{
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
}
private static void OnPlayModeStateChanged(PlayModeStateChange state)
{
if (state != PlayModeStateChange.ExitingEditMode)
{
return;
}
var boots = Object.FindObjectsByType<AnimScenePlayerBootstrap>(
FindObjectsInactive.Include,
FindObjectsSortMode.None);
foreach (AnimScenePlayerBootstrap boot in boots)
{
boot.ApplyPersistedEditorSwitchRole();
EditorUtility.SetDirty(boot);
}
}
private void OnEnable()
{
_editorSwitchProfession = (Profession)EditorPrefs.GetInt(
AnimScenePlayerBootstrap.EditorPrefsSwitchProfessionKey,
(int)Profession.PROF_MAGE);
_editorSwitchGender = (Gender)EditorPrefs.GetInt(
AnimScenePlayerBootstrap.EditorPrefsSwitchGenderKey,
(int)Gender.GENDER_FEMALE);
}
private void OnDisable()
{
SaveSwitchModelEditorPrefs();
}
private static void SaveSwitchModelEditorPrefs(Profession profession, Gender gender)
{
EditorPrefs.SetInt(AnimScenePlayerBootstrap.EditorPrefsSwitchProfessionKey, (int)profession);
EditorPrefs.SetInt(AnimScenePlayerBootstrap.EditorPrefsSwitchGenderKey, (int)gender);
}
private void SaveSwitchModelEditorPrefs()
{
SaveSwitchModelEditorPrefs(_editorSwitchProfession, _editorSwitchGender);
}
public override void OnInspectorGUI()
{
DrawDefaultInspector();
EditorGUILayout.Space(8f);
EditorGUILayout.LabelField("Play Mode — switch model", EditorStyles.boldLabel);
EditorGUILayout.HelpBox(
"On Play Mode enter, the model loads from the profession / gender below (saved in EditorPrefs). " +
"Use Switch model to change role while playing.",
MessageType.Info);
using (new EditorGUI.DisabledScope(!Application.isPlaying))
{
Profession profession = (Profession)EditorGUILayout.EnumPopup(
"Switch to profession",
_editorSwitchProfession);
if (profession != _editorSwitchProfession)
{
_editorSwitchProfession = profession;
SaveSwitchModelEditorPrefs();
}
Gender gender = (Gender)EditorGUILayout.EnumPopup("Switch to gender", _editorSwitchGender);
if (gender != _editorSwitchGender)
{
_editorSwitchGender = gender;
SaveSwitchModelEditorPrefs();
}
}
using (new EditorGUI.DisabledScope(!Application.isPlaying))
{
if (GUILayout.Button("Switch model", GUILayout.Height(28f)))
{
var boot = (AnimScenePlayerBootstrap)target;
boot.SwitchRole(_editorSwitchProfession, _editorSwitchGender);
}
}
EditorGUILayout.Space(8f);
EditorGUILayout.LabelField("Play Mode — play action", EditorStyles.boldLabel);
EditorGUILayout.HelpBox(
"Calls CECHostPlayer.PlayAction(index, restart). ACT_ATTACK_1..4 may still be blocked by design — " +
"use combat/skill paths for those.",
MessageType.Info);
serializedObject.Update();
SerializedProperty playerProp = serializedObject.FindProperty("player");
var host = playerProp != null ? playerProp.objectReferenceValue as CECHostPlayer : null;
using (new EditorGUI.DisabledScope(!Application.isPlaying))
{
_playActionIndex = EditorGUILayout.IntField("Action index (PLAYER_ACTION_TYPE)", _playActionIndex);
_playActionRestart = EditorGUILayout.Toggle("Restart", _playActionRestart);
if (host != null && Application.isPlaying)
{
string preflight = host.AnimSceneTryExplainPlayActionFailure(_playActionIndex);
if (!string.IsNullOrEmpty(preflight))
{
EditorGUILayout.HelpBox(preflight, MessageType.Warning);
}
}
EditorGUILayout.BeginHorizontal();
using (new EditorGUI.DisabledScope(!Application.isPlaying || host == null))
{
if (GUILayout.Button("Stand (0)", GUILayout.Height(22f)))
{
_playActionIndex = (int)PLAYER_ACTION_TYPE.ACT_STAND;
TryPlayActionOnHost((AnimScenePlayerBootstrap)target, host, _playActionIndex, _playActionRestart);
}
if (GUILayout.Button("Fight stand (1)", GUILayout.Height(22f)))
{
_playActionIndex = (int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND;
TryPlayActionOnHost((AnimScenePlayerBootstrap)target, host, _playActionIndex, _playActionRestart);
}
if (GUILayout.Button("Run (3)", GUILayout.Height(22f)))
{
_playActionIndex = (int)PLAYER_ACTION_TYPE.ACT_RUN;
TryPlayActionOnHost((AnimScenePlayerBootstrap)target, host, _playActionIndex, _playActionRestart);
}
}
EditorGUILayout.EndHorizontal();
using (new EditorGUI.DisabledScope(host == null))
{
if (GUILayout.Button("Play action", GUILayout.Height(28f)))
{
TryPlayActionOnHost((AnimScenePlayerBootstrap)target, host, _playActionIndex, _playActionRestart);
}
}
}
EditorGUILayout.Space(8f);
EditorGUILayout.LabelField("Play Mode — weapon", EditorStyles.boldLabel);
using (new EditorGUI.DisabledScope(!Application.isPlaying))
{
if (GUILayout.Button("Re-apply active weapon slot", GUILayout.Height(28f)))
{
var boot = (AnimScenePlayerBootstrap)target;
boot.ApplyWeaponForActiveSlot();
}
}
// EditorGUILayout.Space(8f);
// EditorGUILayout.LabelField("Play Mode — skill grid", EditorStyles.boldLabel);
// EditorGUILayout.HelpBox(
// "Reset Skills (With Restrictions) re-applies the active weapon slot, rebuilds the skill catalog, " +
// "and shows only skills that pass weapon / form / move-env checks.",
// MessageType.Info);
// using (new EditorGUI.DisabledScope(!Application.isPlaying))
// {
// EditorGUILayout.BeginHorizontal();
// if (GUILayout.Button("Reset Skills", GUILayout.Height(28f)))
// {
// ((AnimScenePlayerBootstrap)target).ResetSkillsWithoutRestrictions();
// }
// if (GUILayout.Button("Reset Skills (With Restrictions)", GUILayout.Height(28f)))
// {
// ((AnimScenePlayerBootstrap)target).ResetSkillsWithRestrictions();
// }
// EditorGUILayout.EndHorizontal();
// }
}
private static void TryPlayActionOnHost(
AnimScenePlayerBootstrap boot,
CECHostPlayer host,
int index,
bool restart)
{
if (boot == null || host == null)
{
return;
}
boot.AnimSceneEnsureFashionPathSafeBeforePlayAction(host);
string reason = host.AnimSceneTryExplainPlayActionFailure(index);
if (reason != null && reason.IndexOf("m_PlayerActions is null", System.StringComparison.Ordinal) >= 0)
{
host.AnimSceneRebindPlayerActions();
reason = host.AnimSceneTryExplainPlayActionFailure(index);
}
if (!string.IsNullOrEmpty(reason))
{
Debug.LogWarning("[AnimSceneBootstrap] Play action skipped: " + reason);
return;
}
bool ok = host.PlayAction(index, restart);
if (!ok)
{
Debug.LogWarning("[AnimSceneBootstrap] PlayAction(" + index + ") returned false.");
}
else
{
Debug.Log(
"[AnimSceneBootstrap] PlayAction(" + index + ") called. If you see no motion, " +
"CECModel.PlayActionByName may not have matched a clip on the loaded CombinedActionSO / Animancer.");
}
}
}
}
#endif