微信网站开发制作公司免费的api接口网站

张小明 2026/1/9 22:23:15
微信网站开发制作公司,免费的api接口网站,企业做网站系统,手机版制作app软件状态模式是一种行为设计模式#xff0c;允许对象在内部状态改变时改变其行为#xff0c;使对象看起来像是修改了其类。1. 状态模式基本概念1.1 状态模式的核心思想将状态封装成独立的类将状态相关的行为委托给当前状态对象允许状态对象在运行时切换1.2 状态模式的三个主要组件…状态模式是一种行为设计模式允许对象在内部状态改变时改变其行为使对象看起来像是修改了其类。1. 状态模式基本概念1.1 状态模式的核心思想将状态封装成独立的类将状态相关的行为委托给当前状态对象允许状态对象在运行时切换1.2 状态模式的三个主要组件Context上下文维护当前状态并将与状态相关的操作委托给当前状态对象State状态接口定义所有具体状态的通用接口ConcreteState具体状态实现特定状态的行为2. 基础状态模式实现2.1 基本接口和类结构csharp// 状态接口 public interface IState { void Enter(); void Update(); void Exit(); } // 上下文基类 public abstract class StateContext : MonoBehaviour { protected IState currentState; public void ChangeState(IState newState) { if (currentState ! null) currentState.Exit(); currentState newState; currentState.Enter(); } protected virtual void Update() { if (currentState ! null) currentState.Update(); } }3. Unity中的具体实现示例玩家状态机3.1 玩家状态接口和具体状态csharp// 玩家状态接口 public interface IPlayerState : IState { void HandleInput(PlayerInput input); } // 玩家输入结构 public struct PlayerInput { public float Horizontal; public float Vertical; public bool JumpPressed; public bool AttackPressed; } // 空闲状态 public class IdleState : IPlayerState { private PlayerController player; private Animator animator; public IdleState(PlayerController player) { this.player player; this.animator player.GetComponentAnimator(); } public void Enter() { Debug.Log(进入空闲状态); animator.SetBool(IsWalking, false); animator.SetBool(IsRunning, false); } public void Update() { // 空闲状态下的更新逻辑 } public void HandleInput(PlayerInput input) { if (Mathf.Abs(input.Horizontal) 0.1f || Mathf.Abs(input.Vertical) 0.1f) { if (input.Horizontal 0.5f || input.Vertical 0.5f) player.ChangeState(new RunState(player)); else player.ChangeState(new WalkState(player)); } if (input.JumpPressed) { player.ChangeState(new JumpState(player)); } } public void Exit() { Debug.Log(退出空闲状态); } } // 行走状态 public class WalkState : IPlayerState { private PlayerController player; private Animator animator; private float walkSpeed 3f; public WalkState(PlayerController player) { this.player player; this.animator player.GetComponentAnimator(); } public void Enter() { Debug.Log(进入行走状态); animator.SetBool(IsWalking, true); animator.SetBool(IsRunning, false); } public void Update() { player.Move(walkSpeed); } public void HandleInput(PlayerInput input) { if (Mathf.Abs(input.Horizontal) 0.1f Mathf.Abs(input.Vertical) 0.1f) { player.ChangeState(new IdleState(player)); } else if (input.Horizontal 0.5f || input.Vertical 0.5f) { player.ChangeState(new RunState(player)); } if (input.JumpPressed) { player.ChangeState(new JumpState(player)); } } public void Exit() { Debug.Log(退出行走状态); } } // 奔跑状态 public class RunState : IPlayerState { private PlayerController player; private Animator animator; private float runSpeed 6f; public RunState(PlayerController player) { this.player player; this.animator player.GetComponentAnimator(); } public void Enter() { Debug.Log(进入奔跑状态); animator.SetBool(IsWalking, false); animator.SetBool(IsRunning, true); } public void Update() { player.Move(runSpeed); } public void HandleInput(PlayerInput input) { if (Mathf.Abs(input.Horizontal) 0.1f Mathf.Abs(input.Vertical) 0.1f) { player.ChangeState(new IdleState(player)); } else if (input.Horizontal 0.5f input.Vertical 0.5f) { player.ChangeState(new WalkState(player)); } if (input.JumpPressed) { player.ChangeState(new JumpState(player)); } } public void Exit() { Debug.Log(退出奔跑状态); } } // 跳跃状态 public class JumpState : IPlayerState { private PlayerController player; private Animator animator; private float jumpForce 8f; private bool isGrounded; public JumpState(PlayerController player) { this.player player; this.animator player.GetComponentAnimator(); } public void Enter() { Debug.Log(进入跳跃状态); animator.SetTrigger(Jump); player.Jump(jumpForce); isGrounded false; } public void Update() { isGrounded player.IsGrounded(); if (isGrounded) { player.ChangeState(new IdleState(player)); } player.Move(4f); // 跳跃中的移动速度 } public void HandleInput(PlayerInput input) { // 跳跃中可能处理一些输入如攻击 if (input.AttackPressed) { // 跳跃攻击 } } public void Exit() { Debug.Log(退出跳跃状态); } }3.2 玩家控制器上下文csharppublic class PlayerController : StateContext { [SerializeField] private float moveSpeed 5f; [SerializeField] private float gravity -9.81f; [SerializeField] private LayerMask groundLayer; private CharacterController characterController; private Vector3 velocity; private PlayerInput currentInput; private void Start() { characterController GetComponentCharacterController(); // 初始状态 ChangeState(new IdleState(this)); } protected override void Update() { // 收集输入 currentInput new PlayerInput { Horizontal Input.GetAxis(Horizontal), Vertical Input.GetAxis(Vertical), JumpPressed Input.GetButtonDown(Jump), AttackPressed Input.GetButtonDown(Fire1) }; // 处理重力 if (characterController.isGrounded velocity.y 0) { velocity.y -2f; } velocity.y gravity * Time.deltaTime; characterController.Move(velocity * Time.deltaTime); // 更新当前状态 if (currentState is IPlayerState playerState) { playerState.HandleInput(currentInput); base.Update(); } } public void Move(float speed) { Vector3 moveDirection new Vector3(currentInput.Horizontal, 0, currentInput.Vertical); if (moveDirection.magnitude 0.1f) { // 旋转朝向移动方向 float targetAngle Mathf.Atan2(moveDirection.x, moveDirection.z) * Mathf.Rad2Deg; transform.rotation Quaternion.Euler(0, targetAngle, 0); // 移动 characterController.Move(moveDirection.normalized * speed * Time.deltaTime); } } public void Jump(float force) { velocity.y Mathf.Sqrt(force * -2f * gravity); } public bool IsGrounded() { return characterController.isGrounded; } }4. 高级状态模式实现4.1 带参数的状态机csharp// 带参数的状态接口 public interface IParamStateT : IState { void SetContext(StateContext context); void SetParameter(T parameter); } // 泛型状态机 public class StateMachineT : MonoBehaviour where T : System.Enum { private DictionaryT, IState states new DictionaryT, IState(); private IState currentState; private T currentStateType; public void RegisterState(T stateType, IState state) { states[stateType] state; } public void ChangeState(T newStateType) { if (states.TryGetValue(newStateType, out IState newState)) { if (currentState ! null) currentState.Exit(); currentState newState; currentStateType newStateType; currentState.Enter(); } } public T GetCurrentStateType() { return currentStateType; } protected virtual void Update() { if (currentState ! null) currentState.Update(); } }4.2 动画集成状态机csharp// 动画状态机 public class AnimatorStateMachine : MonoBehaviour { [System.Serializable] public class StateAnimationPair { public string StateName; public AnimationClip Animation; public float TransitionDuration 0.1f; } [SerializeField] private Animator animator; [SerializeField] private ListStateAnimationPair stateAnimations; private Dictionarystring, int animationHashes new Dictionarystring, int(); private string currentState; private void Start() { // 预计算动画哈希 foreach (var pair in stateAnimations) { animationHashes[pair.StateName] Animator.StringToHash(pair.Animation.name); } } public void ChangeState(string stateName) { if (currentState stateName) return; if (animationHashes.ContainsKey(stateName)) { animator.CrossFade(animationHashes[stateName], GetTransitionDuration(stateName)); currentState stateName; } } private float GetTransitionDuration(string stateName) { var pair stateAnimations.Find(p p.StateName stateName); return pair ! null ? pair.TransitionDuration : 0.1f; } }5. 状态模式的最佳实践5.1 状态工厂模式csharp// 状态工厂 public class StateFactory { private DictionaryType, IState stateCache new DictionaryType, IState(); public T GetStateT(object context) where T : IState, new() { Type stateType typeof(T); if (!stateCache.ContainsKey(stateType)) { T state new T(); // 如果状态需要上下文设置上下文 if (state is IContextState contextState) { contextState.SetContext(context); } stateCache[stateType] state; } return (T)stateCache[stateType]; } } // 需要上下文的接口 public interface IContextState : IState { void SetContext(object context); }5.2 状态模式在AI中的应用csharp// AI敌人状态机 public class AIEnemy : MonoBehaviour { public enum AIState { Patrol, Chase, Attack, Flee } private StateMachineAIState stateMachine; private Transform player; private void Start() { player GameObject.FindGameObjectWithTag(Player).transform; stateMachine gameObject.AddComponentStateMachineAIState(); // 注册状态 stateMachine.RegisterState(AIState.Patrol, new PatrolState(this)); stateMachine.RegisterState(AIState.Chase, new ChaseState(this, player)); stateMachine.RegisterState(AIState.Attack, new AttackState(this, player)); stateMachine.RegisterState(AIState.Flee, new FleeState(this, player)); // 初始状态 stateMachine.ChangeState(AIState.Patrol); } } // 巡逻状态 public class PatrolState : IState { private AIEnemy enemy; private Vector3[] patrolPoints; private int currentPointIndex 0; public PatrolState(AIEnemy enemy) { this.enemy enemy; // 初始化巡逻点 } public void Enter() { Debug.Log(开始巡逻); } public void Update() { // 巡逻逻辑 if (Vector3.Distance(enemy.transform.position, patrolPoints[currentPointIndex]) 0.5f) { currentPointIndex (currentPointIndex 1) % patrolPoints.Length; } // 检测玩家 // 如果检测到玩家切换到追逐状态 } public void Exit() { Debug.Log(结束巡逻); } }6. 状态模式的优缺点优点单一职责原则每个状态都有自己的类代码更清晰开闭原则易于添加新状态而不修改现有代码消除条件语句减少了大量的if-else或switch语句状态转换逻辑明确状态转换集中管理缺点类数量增加每个状态都需要一个类过度设计对于简单状态机可能过度复杂状态间依赖状态之间可能有复杂的依赖关系7. 实际应用建议何时使用状态模式对象有多个状态且状态间频繁转换状态相关行为复杂且有大量条件语句需要清晰的状态管理结构Unity特定优化结合Unity的Animator Controller使用ScriptableObject创建可配置的状态利用Unity的协程处理状态中的时序逻辑性能考虑避免频繁创建状态对象使用对象池或缓存对于简单状态机考虑使用枚举switch使用状态模式时注意内存占用状态模式在Unity中特别适合用于角色控制、AI行为、游戏流程管理等场景能够使代码更加模块化和可维护。补充与优化1. 状态机的性能优化策略1.1 状态缓存与对象池csharp// 状态工厂与缓存 public class StateFactory { private static readonly DictionaryType, IState stateCache new DictionaryType, IState(); private static readonly DictionaryType, object stateContexts new DictionaryType, object(); public static T GetStateT() where T : IState, new() { Type type typeof(T); if (!stateCache.ContainsKey(type)) { stateCache[type] new T(); } return (T)stateCache[type]; } public static T GetStateT(object context) where T : IState, new() { Type type typeof(T); if (!stateCache.ContainsKey(type)) { T state new T(); // 如果状态需要初始化上下文 if (state is IContextableState contextable) { contextable.SetContext(context); } stateCache[type] state; stateContexts[type] context; } else if (stateCache[type] is IContextableState cachedContextable) { // 更新上下文 cachedContextable.SetContext(context); } return (T)stateCache[type]; } } // 支持上下文的状态接口 public interface IContextableState : IState { void SetContext(object context); }1.2 批处理状态切换csharp// 延迟状态切换管理器 public class StateQueueManager : MonoBehaviour { private class StateRequest { public IState State; public object Param; public float Delay; public System.Action OnComplete; } private QueueStateRequest stateQueue new QueueStateRequest(); private Coroutine currentTransition; public void QueueState(IState state, object param null, float delay 0f, System.Action onComplete null) { stateQueue.Enqueue(new StateRequest { State state, Param param, Delay delay, OnComplete onComplete }); if (currentTransition null) { currentTransition StartCoroutine(ProcessQueue()); } } private IEnumerator ProcessQueue() { while (stateQueue.Count 0) { var request stateQueue.Dequeue(); if (request.Delay 0) yield return new WaitForSeconds(request.Delay); // 执行状态切换 request.State.Enter(request.Param); request.OnComplete?.Invoke(); yield return null; } currentTransition null; } public void ClearQueue() { stateQueue.Clear(); if (currentTransition ! null) { StopCoroutine(currentTransition); currentTransition null; } } }2. 复合状态模式状态嵌套2.1 子状态机系统csharp// 子状态机支持 public class SubStateMachine : IState { private StateMachine innerStateMachine; private IState parentState; public SubStateMachine(IState parent) { parentState parent; innerStateMachine new StateMachine(); } public void Enter(object param null) { innerStateMachine.Start(); } public void Update() { innerStateMachine.Update(); // 检查是否应该退出子状态机 if (ShouldExitSubStateMachine()) { parentState.Exit(); } } public void Exit() { innerStateMachine.Stop(); } public void RegisterSubState(IState state, System.Funcbool exitCondition null) { innerStateMachine.RegisterState(state, exitCondition); } private bool ShouldExitSubStateMachine() { // 根据游戏逻辑判断是否退出 return false; } } // 支持子状态的状态机 public class AdvancedStateMachine : MonoBehaviour { private StackIState stateStack new StackIState(); private DictionaryType, SubStateMachine subStateMachines new DictionaryType, SubStateMachine(); public void PushState(IState state) { if (stateStack.Count 0) stateStack.Peek().Exit(); stateStack.Push(state); state.Enter(); } public IState PopState() { if (stateStack.Count 0) { IState state stateStack.Pop(); state.Exit(); if (stateStack.Count 0) stateStack.Peek().Enter(); return state; } return null; } public void RegisterSubStateMachine(Type parentStateType, SubStateMachine subStateMachine) { subStateMachines[parentStateType] subStateMachine; } public SubStateMachine GetSubStateMachine(Type parentStateType) { subStateMachines.TryGetValue(parentStateType, out SubStateMachine result); return result; } }3. 可序列化的状态配置3.1 ScriptableObject状态配置csharp// 可序列化的状态配置 [CreateAssetMenu(fileName NewStateConfig, menuName State Machine/State Config)] public class StateConfig : ScriptableObject { [System.Serializable] public class StateTransition { public string FromState; public string ToState; public string Condition; public float Delay; } [System.Serializable] public class StateData { public string StateName; public AnimationClip Animation; public float AnimationSpeed 1f; public AudioClip EnterSound; public AudioClip ExitSound; public float MinDuration 0f; public float MaxDuration float.MaxValue; public ListStateTransition Transitions new ListStateTransition(); } public ListStateData States new ListStateData(); public StateData GetStateData(string stateName) { return States.Find(s s.StateName stateName); } } // 基于配置的状态工厂 public class ConfigurableStateFactory : MonoBehaviour { [SerializeField] private StateConfig stateConfig; private Dictionarystring, IState createdStates new Dictionarystring, IState(); private StateMachine stateMachine; private void Start() { stateMachine GetComponentStateMachine(); InitializeStates(); } private void InitializeStates() { foreach (var stateData in stateConfig.States) { var state CreateStateFromConfig(stateData); createdStates[stateData.StateName] state; stateMachine.RegisterState(state); } } private IState CreateStateFromConfig(StateConfig.StateData data) { return new ConfigurableState(data); } private class ConfigurableState : IState { private readonly StateConfig.StateData data; private float timeInState; public ConfigurableState(StateConfig.StateData data) { this.data data; } public void Enter() { timeInState 0f; if (data.EnterSound ! null) { // 播放音效 } Debug.Log($Entering state: {data.StateName}); } public void Update() { timeInState Time.deltaTime; // 检查转换条件 foreach (var transition in data.Transitions) { if (CheckTransitionCondition(transition)) { // 执行状态转换 break; } } // 检查最大持续时间 if (timeInState data.MaxDuration) { // 强制转换状态 } } public void Exit() { if (data.ExitSound ! null) { // 播放音效 } Debug.Log($Exiting state: {data.StateName}); } private bool CheckTransitionCondition(StateConfig.StateTransition transition) { // 实现条件检查逻辑 return false; } } }4. 可视化状态机编辑器扩展4.1 自定义编辑器窗口csharp#if UNITY_EDITOR using UnityEditor; using UnityEngine; public class StateMachineEditor : EditorWindow { private StateMachine targetMachine; private Vector2 scrollPosition; private GUIStyle stateStyle; private GUIStyle transitionStyle; [MenuItem(Tools/State Machine Editor)] public static void ShowWindow() { GetWindowStateMachineEditor(State Machine Editor); } private void OnEnable() { stateStyle new GUIStyle(GUI.skin.box) { alignment TextAnchor.MiddleCenter, fontStyle FontStyle.Bold }; transitionStyle new GUIStyle(GUI.skin.label) { alignment TextAnchor.MiddleCenter }; } private void OnGUI() { EditorGUILayout.BeginHorizontal(); // 选择目标状态机 targetMachine EditorGUILayout.ObjectField(Target State Machine, targetMachine, typeof(StateMachine), true) as StateMachine; EditorGUILayout.EndHorizontal(); if (targetMachine null) { EditorGUILayout.HelpBox(Please assign a State Machine component, MessageType.Info); return; } scrollPosition EditorGUILayout.BeginScrollView(scrollPosition); DrawStateMachineGraph(); EditorGUILayout.EndScrollView(); if (GUILayout.Button(Refresh)) { Repaint(); } } private void DrawStateMachineGraph() { // 绘制状态节点 foreach (var state in GetStates()) { DrawStateNode(state); } // 绘制状态转换 foreach (var transition in GetTransitions()) { DrawTransitionArrow(transition); } } private void DrawStateNode(IState state) { Rect rect new Rect(50, 50, 150, 50); GUI.Box(rect, state.GetType().Name, stateStyle); // 如果是当前状态高亮显示 if (IsCurrentState(state)) { EditorGUI.DrawRect(rect, new Color(0, 1, 0, 0.2f)); } } private void DrawTransitionArrow(StateTransition transition) { // 绘制箭头和标签 Handles.color Color.white; Handles.DrawLine(transition.FromPosition, transition.ToPosition); Vector2 labelPosition (transition.FromPosition transition.ToPosition) / 2; GUI.Label(new Rect(labelPosition.x, labelPosition.y, 100, 20), transition.Condition, transitionStyle); } private bool IsCurrentState(IState state) { return targetMachine.CurrentState state; } private ListIState GetStates() { // 通过反射获取所有状态 return new ListIState(); } private ListStateTransition GetTransitions() { // 获取状态转换信息 return new ListStateTransition(); } private class StateTransition { public Vector2 FromPosition; public Vector2 ToPosition; public string Condition; } } #endif5. 异步状态支持5.1 协程状态csharp// 支持协程的状态接口 public interface ICoroutineState : IState { IEnumerator EnterCoroutine(); IEnumerator ExitCoroutine(); bool IsTransitioning { get; } } // 协程状态机 public class CoroutineStateMachine : MonoBehaviour { private ICoroutineState currentState; private Coroutine enterCoroutine; private Coroutine exitCoroutine; public async void ChangeState(ICoroutineState newState) { if (currentState ! null currentState.IsTransitioning) { Debug.LogWarning(State is transitioning, cannot change now); return; } // 退出当前状态 if (currentState ! null) { currentState.Exit(); if (exitCoroutine ! null) StopCoroutine(exitCoroutine); exitCoroutine StartCoroutine(currentState.ExitCoroutine()); await WaitForCoroutine(exitCoroutine); } // 进入新状态 currentState newState; currentState.Enter(); if (enterCoroutine ! null) StopCoroutine(enterCoroutine); enterCoroutine StartCoroutine(currentState.EnterCoroutine()); await WaitForCoroutine(enterCoroutine); } private async System.Threading.Tasks.Task WaitForCoroutine(Coroutine coroutine) { while (coroutine ! null) { await System.Threading.Tasks.Task.Yield(); } } private void Update() { if (currentState ! null !currentState.IsTransitioning) { currentState.Update(); } } } // 示例加载场景状态 public class LoadSceneState : ICoroutineState { private string sceneName; private AsyncOperation loadOperation; public bool IsTransitioning loadOperation ! null !loadOperation.isDone; public LoadSceneState(string sceneName) { this.sceneName sceneName; } public void Enter() { Debug.Log($Starting to load scene: {sceneName}); } public IEnumerator EnterCoroutine() { loadOperation UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(sceneName); loadOperation.allowSceneActivation false; while (!loadOperation.isDone) { float progress Mathf.Clamp01(loadOperation.progress / 0.9f); Debug.Log($Loading progress: {progress * 100}%); if (progress 0.9f) { // 等待输入或延迟后激活场景 yield return new WaitForSeconds(1f); loadOperation.allowSceneActivation true; } yield return null; } } public void Update() { // 更新加载界面等 } public void Exit() { Debug.Log(Exiting load scene state); } public IEnumerator ExitCoroutine() { yield return null; } }6. 状态模式与UniRx结合6.1 响应式状态机csharpusing UniRx; using UniRx.Triggers; public class ReactiveStateMachine : MonoBehaviour { private ReactivePropertyIState currentState new ReactivePropertyIState(); private CompositeDisposable disposables new CompositeDisposable(); public IReadOnlyReactivePropertyIState CurrentState currentState; public void Initialize(IState initialState) { ChangeState(initialState); // 每帧更新当前状态 this.UpdateAsObservable() .Where(_ currentState.Value ! null) .Subscribe(_ currentState.Value.Update()) .AddTo(disposables); // 状态变化时的回调 currentState .Skip(1) // 跳过初始值 .Pairwise() .Subscribe(pair { Debug.Log($State changed from {pair.Previous?.GetType().Name} to {pair.Current?.GetType().Name}); }) .AddTo(disposables); } public void ChangeState(IState newState) { if (currentState.Value ! null) currentState.Value.Exit(); currentState.Value newState; newState.Enter(); } private void OnDestroy() { disposables.Dispose(); currentState.Value?.Exit(); } } // 响应式状态示例 public class ReactiveIdleState : IState { private SubjectUnit onEnter new SubjectUnit(); private SubjectUnit onExit new SubjectUnit(); private Subjectfloat onUpdate new Subjectfloat(); public IObservableUnit OnEnter onEnter; public IObservableUnit OnExit onExit; public IObservablefloat OnUpdate onUpdate; public void Enter() { onEnter.OnNext(Unit.Default); } public void Update() { onUpdate.OnNext(Time.deltaTime); } public void Exit() { onExit.OnNext(Unit.Default); } }7. 状态模式的单元测试7.1 可测试的状态机csharp// 可测试的状态接口 public interface ITestableState : IState { int EnterCount { get; } int UpdateCount { get; } int ExitCount { get; } object LastEnterParam { get; } } // 单元测试辅助类 public class StateMachineTester : MonoBehaviour { private StateMachine stateMachine; private DictionaryType, ITestableState testStates new DictionaryType, ITestableState(); public void SetupTest() { stateMachine GetComponentStateMachine(); // 替换为测试状态 ReplaceStatesWithTestVersions(); } private void ReplaceStatesWithTestVersions() { // 通过反射获取所有状态并替换为测试版本 var fieldInfo typeof(StateMachine).GetField(states, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (fieldInfo ! null) { var states fieldInfo.GetValue(stateMachine) as DictionarySystem.Type, IState; foreach (var kvp in states) { if (kvp.Value is ITestableState testableState) { testStates[kvp.Key] testableState; } } } } public void AssertStateEnteredTState(int expectedCount 1) where TState : ITestableState { Type type typeof(TState); if (testStates.TryGetValue(type, out ITestableState state)) { Assert.AreEqual(expectedCount, state.EnterCount, $State {type.Name} should have been entered {expectedCount} times); } } public void AssertStateExitedTState(int expectedCount 1) where TState : ITestableState { Type type typeof(TState); if (testStates.TryGetValue(type, out ITestableState state)) { Assert.AreEqual(expectedCount, state.ExitCount, $State {type.Name} should have been exited {expectedCount} times); } } public void SimulateStateTransitionTFrom, TTo() where TFrom : ITestableState where TTo : ITestableState { // 模拟状态转换条件 // ... } } // 测试用状态 public class TestIdleState : IdleState, ITestableState { public int EnterCount { get; private set; } public int UpdateCount { get; private set; } public int ExitCount { get; private set; } public object LastEnterParam { get; private set; } public TestIdleState(PlayerController player) : base(player) { } public override void Enter(object param null) { EnterCount; LastEnterParam param; base.Enter(param); } public override void Update() { UpdateCount; base.Update(); } public override void Exit() { ExitCount; base.Exit(); } }8. 性能监控与调试8.1 状态机性能监控csharppublic class StateMachineProfiler : MonoBehaviour { [System.Serializable] public class StateProfile { public string StateName; public float TotalTime; public int TransitionCount; public float AverageDuration; } private Dictionarystring, StateProfile profiles new Dictionarystring, StateProfile(); private string currentStateName; private float stateStartTime; public void OnStateChanged(string previousState, string newState) { // 记录上一个状态的时间 if (!string.IsNullOrEmpty(previousState)) { if (profiles.TryGetValue(previousState, out StateProfile profile)) { profile.TotalTime Time.time - stateStartTime; profile.TransitionCount; profile.AverageDuration profile.TotalTime / profile.TransitionCount; } } // 开始记录新状态 currentStateName newState; stateStartTime Time.time; if (!profiles.ContainsKey(newState)) { profiles[newState] new StateProfile { StateName newState }; } } public void LogProfiles() { Debug.Log( State Machine Profile ); foreach (var profile in profiles.Values) { Debug.Log(${profile.StateName}: $Total{profile.TotalTime:F2}s, $Transitions{profile.TransitionCount}, $Avg{profile.AverageDuration:F2}s); } } // 在编辑器窗口中显示 #if UNITY_EDITOR private void OnDrawGizmos() { GUIStyle style new GUIStyle(); style.normal.textColor Color.yellow; Vector3 position transform.position Vector3.up * 2f; UnityEditor.Handles.Label(position, $Current: {currentStateName}, style); } #endif }9. 总结与最佳实践9.1 选择合适的状态模式变体使用场景推荐实现优点简单状态5个枚举 switch简单直接性能好中等复杂度经典状态模式结构清晰易维护复杂AI/角色分层状态机支持状态嵌套减少重复需要配置ScriptableObject状态非程序员可配置数据驱动异步操作协程状态机支持长时间运行操作9.2 性能优化建议状态缓存复用状态对象避免频繁GC条件检查优化使用事件驱动代替每帧检查状态预加载提前初始化可能用到的状态避免深度嵌套过深的子状态机影响性能使用值类型状态参数尽量使用值类型9.3 调试技巧状态历史记录状态变化历史便于调试可视化工具开发编辑器扩展监控状态断点条件在特定状态转换时触发断点日志分级不同详细程度的调试日志性能统计监控每个状态的执行时间和频率通过以上补充和优化状态模式可以更好地适应Unity项目中的各种复杂需求提供高性能、易维护且功能强大的状态管理解决方案。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

国外哪些网站可以注册域名宝安三网合一网站建设

Driver.js 1.x终极迁移指南:从旧版本平滑升级的完整教程 【免费下载链接】driver.js driver.js - 一个轻量级、无依赖的纯 JavaScript 库,用于控制用户在网页上的焦点移动,适用于需要实现网页交互和用户指引的前端开发者。 项目地址: https…

张小明 2026/1/9 22:21:14 网站建设

用dw做的网站生成链接吗flash网站有哪些

Excalidraw浏览器兼容性测试:主流平台表现汇总 在远程办公成为常态的今天,一个能“随手画、随时改、多人看”的协作白板,几乎成了技术团队开会时的刚需。无论是敏捷站会中快速勾勒系统架构,还是故障复盘时还原事件时间线&#xff…

张小明 2026/1/9 22:19:11 网站建设

张家界seo网站优化北京建筑大学研究生招生网电气

第一章:MCP SC-400 的风险评估在部署和配置 MCP SC-400 安全控制策略时,全面的风险评估是确保系统安全性的关键环节。该过程不仅涉及对现有基础设施的审查,还包括识别潜在威胁、分析漏洞影响以及制定缓解措施。威胁建模与攻击面分析 通过采用…

张小明 2026/1/9 22:17:09 网站建设

0基础学网站开发2018年期刊网站建设调查

ms.js终极指南:快速掌握JavaScript毫秒转换技巧 【免费下载链接】ms 项目地址: https://gitcode.com/gh_mirrors/msj/ms.js ms.js是一个轻量级的JavaScript时间转换工具库,专门用于在时间格式与毫秒之间进行便捷转换。无论你是前端开发者还是Nod…

张小明 2026/1/9 22:15:06 网站建设

做网站中山wordpress 文章获取接口

积分系统小程序搭建大概会分为5个步骤:1. 需求分析、2. 系统设计、3. 开发、4. 测试、5. 部署。就这几个步骤起码需要三个人:产品经理、技术人员、测试人员。 如果是只是要搭建自己企业的积分商城,根本没必要自己搭建,因为最后拆…

张小明 2026/1/9 22:13:04 网站建设

做网站空间哪家好自己做的网站403

PKHeX插件完全指南:解锁宝可梦数据管理终极解决方案 【免费下载链接】PKHeX-Plugins Plugins for PKHeX 项目地址: https://gitcode.com/gh_mirrors/pk/PKHeX-Plugins 还在为繁琐的宝可梦数据调整而困扰?PKHeX插件集合为你带来革命性的宝可梦数据…

张小明 2026/1/9 22:11:02 网站建设