第二章 Unity游戏人工智能系统架构解析与构建

2.1 游戏AI系统的层次化架构模型

2.1.1 运动控制层的设计与实现

运动控制层是游戏人工智能系统的基础,负责处理AI角色的基本移动和物理行为。这一层的主要目标是让AI角色能够在游戏世界中自然、流畅地移动,同时响应环境的变化和约束。

在Unity商业项目中,运动控制层的实现通常需要考虑以下关键因素:

  • 物理系统的集成
  • 动画状态的同步
  • 移动性能的优化
  • 环境障碍的规避
  • 移动行为的多样性

下面是一个基础的运动控制层实现示例,展示了如何在Unity中构建可扩展的运动系统:

using UnityEngine;

public class AIMovementController : MonoBehaviour
{
    [System.Serializable]
    public class MovementSettings
    {
        public float maxSpeed = 5.0f;
        public float acceleration = 10.0f;
        public float deceleration = 15.0f;
        public float rotationSpeed = 540.0f;
        public float stoppingDistance = 0.5f;
        public float gravityMultiplier = 2.0f;
    }

    [Header("运动设置")]
    [SerializeField]
    private MovementSettings movementSettings = new MovementSettings();

    [Header("组件引用")]
    [SerializeField]
    private CharacterController characterController;

    [SerializeField]
    private Animator animator;

    [Header("状态追踪")]
    [SerializeField]
    private Vector3 currentVelocity;

    [SerializeField]
    private Vector3 targetVelocity;

    [SerializeField]
    private Vector3 moveDirection;

    [SerializeField]
    private bool isGrounded;

    [SerializeField]
    private float verticalVelocity;

    private Transform cachedTransform;
    private Vector3 lastPosition;
    private float currentSpeed;

    private const float groundCheckDistance = 0.3f;
    private const float groundCheckRadius = 0.2f;
    private const float gravity = -9.81f;

    public Vector3 CurrentVelocity
    {
        get { return currentVelocity; }
    }

    public float CurrentSpeed
    {
        get { return currentSpeed; }
    }

    public bool IsGrounded
    {
        get { return isGrounded; }
    }

    private void Awake()
    {
        InitializeComponents();
    }

    private void InitializeComponents()
    {
        cachedTransform = transform;

        if (characterController == null)
        {
            characterController = GetComponent<CharacterController>();
        }

        if (animator == null)
        {
            animator = GetComponent<Animator>();
        }

        currentVelocity = Vector3.zero;
        targetVelocity = Vector3.zero;
        moveDirection = Vector3.zero;
        verticalVelocity = 0f;
    }

    private void Update()
    {
        UpdateGroundStatus();
        ApplyGravity();
        UpdateMovement();
        UpdateAnimator();
    }

    private void UpdateGroundStatus()
    {
        bool wasGrounded = isGrounded;

        // 使用射线检测地面
        RaycastHit hit;
        Vector3 rayStart = cachedTransform.position + Vector3.up * 0.1f;
        
        if (Physics.SphereCast(
            rayStart,
            groundCheckRadius,
            Vector3.down,
            out hit,
            groundCheckDistance,
            Physics.AllLayers,
            QueryTriggerInteraction.Ignore
        ))
        {
            isGrounded = true;
            verticalVelocity = 0f;
        }
        else
        {
            isGrounded = false;
        }

        // 地面状态变化事件
        if (wasGrounded != isGrounded)
        {
            if (isGrounded)
            {
                OnLanded();
            }
            else
            {
                OnAirborne();
            }
        }
    }

    private void ApplyGravity()
    {
        if (!isGrounded)
        {
            verticalVelocity += gravity * movementSettings.gravityMultiplier * Time.deltaTime;
        }
        else
        {
            // 保持在地面上
            verticalVelocity = gravity * 0.1f;
        }
    }

    public void MoveToPosition(Vector3 targetPosition, bool usePathfinding = true)
    {
        if (!IsPositionReachable(targetPosition))
        {
            Debug.LogWarning($"目标位置不可达: {targetPosition}");
            return;
        }

        Vector3 directionToTarget;
        
        if (usePathfinding)
        {
            // 使用路径规划
            directionToTarget = CalculatePathDirection(targetPosition);
        }
        else
        {
            // 直线移动
            directionToTarget = (targetPosition - cachedTransform.position).normalized;
        }

        MoveInDirection(directionToTarget);
    }

    public void MoveInDirection(Vector3 direction)
    {
        if (direction.magnitude < 0.01f)
        {
            // 停止移动
            targetVelocity = Vector3.zero;
            return;
        }

        // 标准化方向向量
        direction.Normalize();

        // 计算目标速度
        targetVelocity = direction * movementSettings.maxSpeed;

        // 更新移动方向
        moveDirection = direction;
    }

    public void StopMovement()
    {
        targetVelocity = Vector3.zero;
        moveDirection = Vector3.zero;
    }

    private void UpdateMovement()
    {
        // 计算速度差值
        Vector3 velocityDifference = targetVelocity - currentVelocity;

        // 根据加速度或减速度调整当前速度
        float accelerationRate = velocityDifference.magnitude > 0.01f 
            ? movementSettings.acceleration 
            : movementSettings.deceleration;

        // 插值当前速度到目标速度
        currentVelocity = Vector3.MoveTowards(
            currentVelocity,
            targetVelocity,
            accelerationRate * Time.deltaTime
        );

        // 创建最终移动向量(包括垂直速度)
        Vector3 finalMoveVector = currentVelocity;
        finalMoveVector.y = verticalVelocity;

        // 应用移动
        if (characterController != null && characterController.enabled)
        {
            characterController.Move(finalMoveVector * Time.deltaTime);
        }
        else
        {
            cachedTransform.position += finalMoveVector * Time.deltaTime;
        }

        // 更新实际速度(用于动画和状态判断)
        currentSpeed = currentVelocity.magnitude;

        // 如果正在移动,旋转到移动方向
        if (currentSpeed > 0.1f && moveDirection.magnitude > 0.01f)
        {
            RotateTowardsDirection(moveDirection);
        }
    }

    private void RotateTowardsDirection(Vector3 direction)
    {
        if (direction.magnitude < 0.01f)
        {
            return;
        }

        // 计算目标旋转
        Quaternion targetRotation = Quaternion.LookRotation(direction);
        
        // 平滑旋转
        cachedTransform.rotation = Quaternion.RotateTowards(
            cachedTransform.rotation,
            targetRotation,
            movementSettings.rotationSpeed * Time.deltaTime
        );
    }

    private Vector3 CalculatePathDirection(Vector3 targetPosition)
    {
        // 简化版路径计算
        // 在实际项目中,这里会集成A*或NavMesh系统
        
        Vector3 direction = (targetPosition - cachedTransform.position).normalized;
        
        // 简单的障碍物回避
        RaycastHit hit;
        if (Physics.Raycast(
            cachedTransform.position,
            direction,
            out hit,
            2.0f,
            LayerMask.GetMask("Obstacle"),
            QueryTriggerInteraction.Ignore
        ))
        {
            // 计算回避方向
            Vector3 avoidanceDirection = Vector3.Cross(hit.normal, Vector3.up).normalized;
            
            // 选择与当前方向更接近的回避方向
            float dotProduct = Vector3.Dot(avoidanceDirection, direction);
            if (dotProduct < 0)
            {
                avoidanceDirection = -avoidanceDirection;
            }
            
            // 混合原始方向和回避方向
            direction = Vector3.Lerp(direction, avoidanceDirection, 0.7f).normalized;
        }
        
        return direction;
    }

    private bool IsPositionReachable(Vector3 position)
    {
        // 简化可达性检查
        // 在实际项目中,这里会进行更复杂的检查
        
        float distance = Vector3.Distance(cachedTransform.position, position);
        
        if (distance > 100f) // 最大移动距离限制
        {
            return false;
        }

        // 检查是否有直接路径(无遮挡)
        RaycastHit hit;
        if (Physics.Linecast(
            cachedTransform.position,
            position,
            out hit,
            LayerMask.GetMask("Impassable"),
            QueryTriggerInteraction.Ignore
        ))
        {
            return false;
        }

        return true;
    }

    private void UpdateAnimator()
    {
        if (animator == null)
        {
            return;
        }

        // 更新动画参数
        animator.SetFloat("Speed", currentSpeed);
        animator.SetFloat("MotionSpeed", currentSpeed / movementSettings.maxSpeed);
        animator.SetBool("IsGrounded", isGrounded);
        
        // 设置移动方向参数(用于8向移动混合)
        if (currentSpeed > 0.1f)
        {
            Vector3 localMoveDirection = cachedTransform.InverseTransformDirection(moveDirection);
            animator.SetFloat("MoveX", localMoveDirection.x);
            animator.SetFloat("MoveZ", localMoveDirection.z);
        }
    }

    private void OnLanded()
    {
        // 着陆时的处理
        if (animator != null)
        {
            animator.SetTrigger("Land");
        }

        // 重置移动参数
        currentVelocity.y = 0f;
    }

    private void OnAirborne()
    {
        // 离地时的处理
        if (animator != null)
        {
            animator.SetTrigger("Jump");
        }
    }

    public void Jump(float jumpForce)
    {
        if (!isGrounded)
        {
            return;
        }

        verticalVelocity = jumpForce;
        isGrounded = false;
    }

    public void SetMovementEnabled(bool enabled)
    {
        if (characterController != null)
        {
            characterController.enabled = enabled;
        }

        enabled = enabled;
    }

    private void OnDrawGizmosSelected()
    {
        if (!Application.isPlaying)
        {
            return;
        }

        // 绘制移动方向
        Gizmos.color = Color.green;
        Gizmos.DrawRay(cachedTransform.position, moveDirection * 2f);

        // 绘制当前速度
        Gizmos.color = Color.blue;
        Gizmos.DrawRay(cachedTransform.position, currentVelocity);

        // 绘制地面检测范围
        Gizmos.color = isGrounded ? Color.green : Color.red;
        Vector3 groundCheckStart = cachedTransform.position + Vector3.up * 0.1f;
        Vector3 groundCheckEnd = groundCheckStart + Vector3.down * groundCheckDistance;
        Gizmos.DrawLine(groundCheckStart, groundCheckEnd);
        Gizmos.DrawWireSphere(groundCheckEnd, groundCheckRadius);
    }
}

2.1.2 决策逻辑层的架构设计

决策逻辑层是AI系统的"大脑",负责根据当前游戏状态、环境信息和角色目标来做出智能决策。这一层处理从简单的状态转换到复杂的计划制定等各种认知任务。

在商业游戏项目中,决策逻辑层的设计需要考虑:

  • 决策的响应速度和准确性
  • 决策的可预测性和可调试性
  • 决策的多样性和适应性
  • 决策系统的可扩展性和维护性

下面是决策逻辑层的核心架构实现:

using UnityEngine;
using System;
using System.Collections.Generic;

public class AIDecisionController : MonoBehaviour
{
    [System.Serializable]
    public class DecisionConfig
    {
        public float decisionUpdateInterval = 0.2f;
        public float maxDecisionTime = 1.0f;
        public bool enableDebugLogging = false;
        public bool enableGizmos = true;
    }

    [System.Serializable]
    public class BehaviorWeight
    {
        public string behaviorName;
        public float baseWeight = 1.0f;
        public AnimationCurve weightCurve = AnimationCurve.Linear(0, 1, 1, 1);
        public List<ConditionModifier> conditionModifiers = new List<ConditionModifier>();
    }

    [System.Serializable]
    public class ConditionModifier
    {
        public string conditionName;
        public float modifierValue = 1.0f;
        public ComparisonOperator comparison = ComparisonOperator.GreaterThan;
        public float threshold = 0.5f;
    }

    public enum ComparisonOperator
    {
        GreaterThan,
        LessThan,
        EqualTo,
        NotEqualTo
    }

    [Header("配置")]
    [SerializeField]
    private DecisionConfig config = new DecisionConfig();

    [Header("行为权重")]
    [SerializeField]
    private List<BehaviorWeight> behaviorWeights = new List<BehaviorWeight>();

    [Header("组件引用")]
    [SerializeField]
    private AIMovementController movementController;

    [SerializeField]
    private AIPerceptionController perceptionController;

    [SerializeField]
    private AIStateController stateController;

    [Header("运行时状态")]
    [SerializeField]
    private string currentDecision;

    [SerializeField]
    private float decisionConfidence;

    [SerializeField]
    private float timeSinceLastDecision;

    [SerializeField]
    private List<DecisionHistory> decisionHistory = new List<DecisionHistory>();

    private Dictionary<string, float> conditionValues = new Dictionary<string, float>();
    private Dictionary<string, Func<float>> conditionEvaluators = new Dictionary<string, Func<float>>();
    private Dictionary<string, Action> behaviorExecutors = new Dictionary<string, Action>();
    
    private float decisionTimer;
    private bool isDecisionMaking;

    [System.Serializable]
    public class DecisionHistory
    {
        public string decision;
        public float confidence;
        public float timestamp;
        public Dictionary<string, float> conditions;

        public DecisionHistory(string decision, float confidence, Dictionary<string, float> conditions)
        {
            this.decision = decision;
            this.confidence = confidence;
            this.timestamp = Time.time;
            this.conditions = new Dictionary<string, float>(conditions);
        }
    }

    private void Awake()
    {
        InitializeComponents();
        InitializeConditions();
        InitializeBehaviors();
    }

    private void InitializeComponents()
    {
        if (movementController == null)
        {
            movementController = GetComponent<AIMovementController>();
        }

        if (perceptionController == null)
        {
            perceptionController = GetComponent<AIPerceptionController>();
        }

        if (stateController == null)
        {
            stateController = GetComponent<AIStateController>();
        }
    }

    private void InitializeConditions()
    {
        // 注册条件评估器
        RegisterCondition("HealthRatio", EvaluateHealthRatio);
        RegisterCondition("ThreatLevel", EvaluateThreatLevel);
        RegisterCondition("DistanceToTarget", EvaluateDistanceToTarget);
        RegisterCondition("AmmoRatio", EvaluateAmmoRatio);
        RegisterCondition("HasLineOfSight", EvaluateHasLineOfSight);
        RegisterCondition("IsUnderAttack", EvaluateIsUnderAttack);
        RegisterCondition("TargetVisible", EvaluateTargetVisible);
        RegisterCondition("GroupSize", EvaluateGroupSize);
        RegisterCondition("CoverAvailable", EvaluateCoverAvailable);
        RegisterCondition("ObjectivePriority", EvaluateObjectivePriority);
    }

    private void InitializeBehaviors()
    {
        // 注册行为执行器
        RegisterBehavior("Attack", ExecuteAttackBehavior);
        RegisterBehavior("TakeCover", ExecuteTakeCoverBehavior);
        RegisterBehavior("Retreat", ExecuteRetreatBehavior);
        RegisterBehavior("Patrol", ExecutePatrolBehavior);
        RegisterBehavior("Investigate", ExecuteInvestigateBehavior);
        RegisterBehavior("Search", ExecuteSearchBehavior);
        RegisterBehavior("Heal", ExecuteHealBehavior);
        RegisterBehavior("Reload", ExecuteReloadBehavior);
        RegisterBehavior("CallForHelp", ExecuteCallForHelpBehavior);
        RegisterBehavior("Flank", ExecuteFlankBehavior);
    }

    private void Update()
    {
        UpdateDecisionMaking();
    }

    private void UpdateDecisionMaking()
    {
        timeSinceLastDecision += Time.deltaTime;
        decisionTimer += Time.deltaTime;

        // 定期更新决策
        if (decisionTimer >= config.decisionUpdateInterval)
        {
            UpdateConditionValues();
            MakeDecision();
            decisionTimer = 0f;
        }

        // 执行当前决策
        ExecuteCurrentDecision();
    }

    private void UpdateConditionValues()
    {
        // 更新所有条件值
        foreach (var evaluator in conditionEvaluators)
        {
            try
            {
                conditionValues[evaluator.Key] = evaluator.Value();
            }
            catch (Exception e)
            {
                Debug.LogError($"条件评估失败: {evaluator.Key}, 错误: {e.Message}");
                conditionValues[evaluator.Key] = 0f;
            }
        }
    }

    private void MakeDecision()
    {
        if (isDecisionMaking)
        {
            // 防止重复决策
            return;
        }

        isDecisionMaking = true;
        
        // 记录决策开始时间
        float startTime = Time.time;

        // 计算每个行为的权重
        Dictionary<string, float> behaviorScores = new Dictionary<string, float>();
        float totalScore = 0f;

        foreach (BehaviorWeight behaviorWeight in behaviorWeights)
        {
            float score = CalculateBehaviorScore(behaviorWeight);
            behaviorScores[behaviorWeight.behaviorName] = score;
            totalScore += score;
        }

        // 选择得分最高的行为
        string bestBehavior = null;
        float bestScore = -1f;

        foreach (var score in behaviorScores)
        {
            if (score.Value > bestScore)
            {
                bestScore = score.Value;
                bestBehavior = score.Key;
            }
        }

        // 计算决策置信度
        float confidence = totalScore > 0 ? bestScore / totalScore : 0f;

        // 应用决策
        if (bestBehavior != null && bestScore > 0)
        {
            ApplyDecision(bestBehavior, confidence);
        }

        // 检查决策时间
        float decisionTime = Time.time - startTime;
        if (decisionTime > config.maxDecisionTime)
        {
            Debug.LogWarning($"决策时间过长: {decisionTime:F2}秒");
        }

        isDecisionMaking = false;
    }

    private float CalculateBehaviorScore(BehaviorWeight behaviorWeight)
    {
        float score = behaviorWeight.baseWeight;

        // 应用曲线调整
        float timeFactor = Mathf.Clamp01(timeSinceLastDecision / 10f);
        score *= behaviorWeight.weightCurve.Evaluate(timeFactor);

        // 应用条件修饰符
        foreach (ConditionModifier modifier in behaviorWeight.conditionModifiers)
        {
            if (conditionValues.ContainsKey(modifier.conditionName))
            {
                float conditionValue = conditionValues[modifier.conditionName];
                bool conditionMet = EvaluateCondition(conditionValue, modifier);

                if (conditionMet)
                {
                    score *= modifier.modifierValue;
                }
            }
        }

        return Mathf.Max(0, score);
    }

    private bool EvaluateCondition(float value, ConditionModifier modifier)
    {
        switch (modifier.comparison)
        {
            case ComparisonOperator.GreaterThan:
                return value > modifier.threshold;
            case ComparisonOperator.LessThan:
                return value < modifier.threshold;
            case ComparisonOperator.EqualTo:
                return Mathf.Approximately(value, modifier.threshold);
            case ComparisonOperator.NotEqualTo:
                return !Mathf.Approximately(value, modifier.threshold);
            default:
                return false;
        }
    }

    private void ApplyDecision(string behavior, float confidence)
    {
        // 避免频繁切换相同决策
        if (currentDecision == behavior && confidence < decisionConfidence * 1.1f)
        {
            return;
        }

        // 记录决策历史
        decisionHistory.Add(new DecisionHistory(
            behavior, 
            confidence, 
            new Dictionary<string, float>(conditionValues)
        ));

        // 限制历史记录数量
        if (decisionHistory.Count > 50)
        {
            decisionHistory.RemoveAt(0);
        }

        // 更新当前决策
        string previousDecision = currentDecision;
        currentDecision = behavior;
        decisionConfidence = confidence;
        timeSinceLastDecision = 0f;

        // 触发决策变化事件
        OnDecisionChanged(previousDecision, behavior, confidence);

        if (config.enableDebugLogging)
        {
            Debug.Log($"决策改变: {previousDecision} -> {behavior} (置信度: {confidence:F2})");
        }
    }

    private void ExecuteCurrentDecision()
    {
        if (string.IsNullOrEmpty(currentDecision))
        {
            return;
        }

        if (behaviorExecutors.ContainsKey(currentDecision))
        {
            try
            {
                behaviorExecutors[currentDecision]();
            }
            catch (Exception e)
            {
                Debug.LogError($"行为执行失败: {currentDecision}, 错误: {e.Message}");
            }
        }
    }

    #region 条件评估方法

    private float EvaluateHealthRatio()
    {
        // 获取健康值比例 (0-1)
        // 这里需要根据实际游戏系统实现
        HealthComponent health = GetComponent<HealthComponent>();
        if (health != null)
        {
            return health.CurrentHealth / health.MaxHealth;
        }
        return 1.0f;
    }

    private float EvaluateThreatLevel()
    {
        // 评估威胁等级 (0-1)
        if (perceptionController == null)
        {
            return 0f;
        }

        GameObject primaryThreat = perceptionController.GetPrimaryThreat();
        if (primaryThreat == null)
        {
            return 0f;
        }

        // 基于距离和威胁类型的简单评估
        float distance = Vector3.Distance(transform.position, primaryThreat.transform.position);
        float distanceFactor = Mathf.Clamp01(1 - (distance / 50f));

        // 这里可以添加更复杂的威胁评估逻辑
        return distanceFactor;
    }

    private float EvaluateDistanceToTarget()
    {
        // 评估到目标的距离 (0-1, 1表示非常近)
        if (stateController == null || stateController.CurrentTarget == null)
        {
            return 0f;
        }

        float distance = Vector3.Distance(transform.position, stateController.CurrentTarget.transform.position);
        float maxDistance = 100f;
        
        return Mathf.Clamp01(1 - (distance / maxDistance));
    }

    private float EvaluateAmmoRatio()
    {
        // 评估弹药比例 (0-1)
        // 这里需要根据实际武器系统实现
        WeaponController weapon = GetComponent<WeaponController>();
        if (weapon != null)
        {
            return weapon.GetAmmoRatio();
        }
        return 1.0f;
    }

    private float EvaluateHasLineOfSight()
    {
        // 是否有视线 (0或1)
        if (stateController == null || stateController.CurrentTarget == null)
        {
            return 0f;
        }

        Vector3 direction = stateController.CurrentTarget.transform.position - transform.position;
        RaycastHit hit;
        
        if (Physics.Raycast(
            transform.position,
            direction.normalized,
            out hit,
            direction.magnitude,
            LayerMask.GetMask("Obstacle", "Default"),
            QueryTriggerInteraction.Ignore
        ))
        {
            return hit.collider.gameObject == stateController.CurrentTarget ? 1f : 0f;
        }

        return 1f;
    }

    private float EvaluateIsUnderAttack()
    {
        // 是否正在被攻击 (0或1)
        DamageReceiver damageReceiver = GetComponent<DamageReceiver>();
        if (damageReceiver != null)
        {
            return damageReceiver.IsUnderAttack() ? 1f : 0f;
        }
        return 0f;
    }

    private float EvaluateTargetVisible()
    {
        // 目标是否可见 (0或1)
        if (perceptionController == null)
        {
            return 0f;
        }

        return perceptionController.IsTargetVisible() ? 1f : 0f;
    }

    private float EvaluateGroupSize()
    {
        // 评估群体大小 (0-1)
        // 这里需要根据实际群体系统实现
        AIGroupManager groupManager = AIGroupManager.Instance;
        if (groupManager != null)
        {
            AIGroup group = groupManager.GetGroupForMember(gameObject);
            if (group != null)
            {
                int memberCount = group.GetMemberCount();
                return Mathf.Clamp01(memberCount / 10f); // 假设最大10人小组
            }
        }
        return 0f;
    }

    private float EvaluateCoverAvailable()
    {
        // 评估是否有掩护可用 (0或1)
        CoverSystem coverSystem = GetComponent<CoverSystem>();
        if (coverSystem != null)
        {
            return coverSystem.HasAvailableCover() ? 1f : 0f;
        }
        return 0f;
    }

    private float EvaluateObjectivePriority()
    {
        // 评估目标优先级 (0-1)
        if (stateController == null)
        {
            return 0f;
        }

        return stateController.GetCurrentObjectivePriority();
    }

    #endregion

    #region 行为执行方法

    private void ExecuteAttackBehavior()
    {
        if (stateController == null || stateController.CurrentTarget == null)
        {
            return;
        }

        // 移动到攻击位置
        Vector3 attackPosition = CalculateAttackPosition();
        movementController.MoveToPosition(attackPosition);

        // 面向目标
        Vector3 directionToTarget = stateController.CurrentTarget.transform.position - transform.position;
        movementController.RotateTowardsDirection(directionToTarget);

        // 尝试攻击
        WeaponController weapon = GetComponent<WeaponController>();
        if (weapon != null && weapon.CanFire())
        {
            weapon.FireAtTarget(stateController.CurrentTarget);
        }
    }

    private void ExecuteTakeCoverBehavior()
    {
        CoverSystem coverSystem = GetComponent<CoverSystem>();
        if (coverSystem == null)
        {
            return;
        }

        GameObject bestCover = coverSystem.FindBestCover();
        if (bestCover != null)
        {
            movementController.MoveToPosition(bestCover.transform.position);
            coverSystem.TakeCover(bestCover);
        }
    }

    private void ExecuteRetreatBehavior()
    {
        if (stateController == null || stateController.CurrentTarget == null)
        {
            return;
        }

        // 计算撤退方向(远离目标)
        Vector3 retreatDirection = transform.position - stateController.CurrentTarget.transform.position;
        retreatDirection.y = 0;
        retreatDirection.Normalize();

        // 计算撤退位置
        Vector3 retreatPosition = transform.position + retreatDirection * 20f;
        movementController.MoveToPosition(retreatPosition);
    }

    private void ExecutePatrolBehavior()
    {
        PatrolSystem patrolSystem = GetComponent<PatrolSystem>();
        if (patrolSystem != null)
        {
            patrolSystem.Patrol();
        }
        else
        {
            // 简单的巡逻行为
            ExecuteDefaultPatrol();
        }
    }

    private void ExecuteDefaultPatrol()
    {
        // 实现简单的巡逻逻辑
        if (movementController.CurrentSpeed < 0.1f)
        {
            // 随机选择新的巡逻点
            Vector3 randomDirection = new Vector3(
                Random.Range(-1f, 1f),
                0,
                Random.Range(-1f, 1f)
            ).normalized;

            Vector3 patrolPoint = transform.position + randomDirection * 10f;
            movementController.MoveToPosition(patrolPoint, false);
        }
    }

    private void ExecuteInvestigateBehavior()
    {
        if (stateController == null)
        {
            return;
        }

        Vector3 investigationPoint = stateController.GetInvestigationPoint();
        if (investigationPoint != Vector3.zero)
        {
            movementController.MoveToPosition(investigationPoint);
        }
    }

    private void ExecuteSearchBehavior()
    {
        SearchSystem searchSystem = GetComponent<SearchSystem>();
        if (searchSystem != null)
        {
            searchSystem.SearchArea();
        }
    }

    private void ExecuteHealBehavior()
    {
        // 寻找治疗物品或安全区域
        GameObject healingItem = FindClosestHealingItem();
        if (healingItem != null)
        {
            movementController.MoveToPosition(healingItem.transform.position);
        }
        else
        {
            // 撤退到安全区域
            ExecuteRetreatBehavior();
        }
    }

    private void ExecuteReloadBehavior()
    {
        WeaponController weapon = GetComponent<WeaponController>();
        if (weapon != null && weapon.NeedsReload())
        {
            weapon.Reload();
            
            // 寻找掩护
            ExecuteTakeCoverBehavior();
        }
    }

    private void ExecuteCallForHelpBehavior()
    {
        AIGroupManager groupManager = AIGroupManager.Instance;
        if (groupManager != null)
        {
            groupManager.RequestBackup(gameObject, transform.position);
        }
    }

    private void ExecuteFlankBehavior()
    {
        if (stateController == null || stateController.CurrentTarget == null)
        {
            return;
        }

        // 计算侧翼位置
        Vector3 flankPosition = CalculateFlankPosition();
        movementController.MoveToPosition(flankPosition);
    }

    #endregion

    #region 辅助方法

    private Vector3 CalculateAttackPosition()
    {
        if (stateController == null || stateController.CurrentTarget == null)
        {
            return transform.position;
        }

        Vector3 targetPosition = stateController.CurrentTarget.transform.position;
        Vector3 directionToTarget = targetPosition - transform.position;
        float idealDistance = 15f; // 理想攻击距离

        // 计算理想攻击位置
        if (directionToTarget.magnitude > idealDistance * 1.5f)
        {
            // 太远,靠近目标
            return targetPosition - directionToTarget.normalized * idealDistance;
        }
        else if (directionToTarget.magnitude < idealDistance * 0.5f)
        {
            // 太近,后退
            return transform.position - directionToTarget.normalized * idealDistance;
        }
        else
        {
            // 寻找更好的攻击角度
            Vector3 rightFlank = Vector3.Cross(directionToTarget, Vector3.up).normalized;
            return targetPosition + rightFlank * 5f;
        }
    }

    private Vector3 CalculateFlankPosition()
    {
        if (stateController == null || stateController.CurrentTarget == null)
        {
            return transform.position;
        }

        Vector3 targetPosition = stateController.CurrentTarget.transform.position;
        Vector3 directionToTarget = (targetPosition - transform.position).normalized;
        
        // 计算侧翼方向(垂直于视线方向)
        Vector3 flankDirection = Vector3.Cross(directionToTarget, Vector3.up).normalized;
        
        // 随机选择左侧或右侧
        if (Random.value > 0.5f)
        {
            flankDirection = -flankDirection;
        }

        // 计算侧翼位置
        return targetPosition + flankDirection * 20f;
    }

    private GameObject FindClosestHealingItem()
    {
        // 在实际项目中,这里会查询游戏世界的物品系统
        GameObject[] healthPacks = GameObject.FindGameObjectsWithTag("HealthPack");
        GameObject closest = null;
        float closestDistance = float.MaxValue;

        foreach (GameObject healthPack in healthPacks)
        {
            float distance = Vector3.Distance(transform.position, healthPack.transform.position);
            if (distance < closestDistance && distance < 50f) // 最大搜索距离
            {
                closestDistance = distance;
                closest = healthPack;
            }
        }

        return closest;
    }

    #endregion

    #region 公共接口

    public void RegisterCondition(string conditionName, Func<float> evaluator)
    {
        conditionEvaluators[conditionName] = evaluator;
        conditionValues[conditionName] = 0f;
    }

    public void RegisterBehavior(string behaviorName, Action executor)
    {
        behaviorExecutors[behaviorName] = executor;
    }

    public void ForceDecision(string behavior, float confidence = 1.0f)
    {
        ApplyDecision(behavior, confidence);
    }

    public string GetCurrentDecision()
    {
        return currentDecision;
    }

    public float GetDecisionConfidence()
    {
        return decisionConfidence;
    }

    public Dictionary<string, float> GetConditionValues()
    {
        return new Dictionary<string, float>(conditionValues);
    }

    public List<DecisionHistory> GetDecisionHistory(int count = 10)
    {
        if (decisionHistory.Count <= count)
        {
            return new List<DecisionHistory>(decisionHistory);
        }

        return decisionHistory.GetRange(decisionHistory.Count - count, count);
    }

    public void ClearDecisionHistory()
    {
        decisionHistory.Clear();
    }

    #endregion

    #region 事件

    public event Action<string, string, float> OnDecisionChanged = delegate { };

    #endregion

    private void OnDrawGizmos()
    {
        if (!config.enableGizmos || !Application.isPlaying)
        {
            return;
        }

        // 绘制当前决策
        #if UNITY_EDITOR
        UnityEditor.Handles.Label(
            transform.position + Vector3.up * 3f,
            $"决策: {currentDecision}\n置信度: {decisionConfidence:F2}"
        );
        #endif

        // 绘制攻击位置(如果当前决策是攻击)
        if (currentDecision == "Attack" && stateController != null && stateController.CurrentTarget != null)
        {
            Vector3 attackPosition = CalculateAttackPosition();
            Gizmos.color = Color.red;
            Gizmos.DrawWireSphere(attackPosition, 1f);
            Gizmos.DrawLine(transform.position, attackPosition);
        }
    }
}

2.1.3 战略规划层的实现机制

战略规划层处理更高层次的AI行为,包括长期目标设定、资源管理、团队协调和战术制定。这一层使AI能够表现出更复杂、更智能的行为,特别适用于策略游戏、团队射击游戏和大型多人在线游戏。

在商业项目中,战略规划层的实现需要考虑:

  • 长期目标的优先级管理
  • 资源分配和经济效益分析
  • 团队角色分配和协作
  • 动态战术调整
  • 风险评估和管理

下面是战略规划层的基础实现:

using UnityEngine;
using System;
using System.Collections.Generic;
using System.Linq;

public class AIStrategicController : MonoBehaviour
{
    [System.Serializable]
    public class StrategicObjective
    {
        public string objectiveId;
        public string objectiveName;
        public ObjectiveType objectiveType;
        public float priority;
        public float basePriority;
        public Vector3 targetPosition;
        public GameObject targetObject;
        public bool isActive;
        public float timeAssigned;
        public float timeCompleted;
        public List<string> requiredResources;
        public Dictionary<string, float> successFactors = new Dictionary<string, float>();

        public StrategicObjective(
            string id, 
            string name, 
            ObjectiveType type, 
            float basePriority
        )
        {
            objectiveId = id;
            objectiveName = name;
            objectiveType = type;
            this.basePriority = basePriority;
            priority = basePriority;
            isActive = false;
            timeAssigned = 0f;
            timeCompleted = 0f;
            requiredResources = new List<string>();
        }

        public float GetAge()
        {
            if (!isActive)
            {
                return 0f;
            }
            return Time.time - timeAssigned;
        }

        public void UpdatePriority(float modifier)
        {
            priority = basePriority * modifier;
            priority = Mathf.Max(0, priority);
        }
    }

    [System.Serializable]
    public class ResourceAllocation
    {
        public string resourceType;
        public float currentAmount;
        public float maxAmount;
        public float regenerationRate;
        public float lastUpdateTime;

        public ResourceAllocation(string type, float max, float regeneration)
        {
            resourceType = type;
            maxAmount = max;
            currentAmount = max;
            regenerationRate = regeneration;
            lastUpdateTime = Time.time;
        }

        public void UpdateResource()
        {
            float timePassed = Time.time - lastUpdateTime;
            currentAmount = Mathf.Min(
                maxAmount, 
                currentAmount + regenerationRate * timePassed
            );
            lastUpdateTime = Time.time;
        }

        public bool Consume(float amount)
        {
            if (currentAmount >= amount)
            {
                currentAmount -= amount;
                return true;
            }
            return false;
        }
    }

    public enum ObjectiveType
    {
        Offensive,
        Defensive,
        Support,
        Resource,
        Reconnaissance,
        Survival,
        Strategic
    }

    [Header("战略配置")]
    [SerializeField]
    private float strategyUpdateInterval = 1.0f;

    [SerializeField]
    private int maxActiveObjectives = 3;

    [SerializeField]
    private float objectiveReevaluationTime = 5.0f;

    [Header("资源管理")]
    [SerializeField]
    private List<ResourceAllocation> resources = new List<ResourceAllocation>();

    [Header("目标管理")]
    [SerializeField]
    private List<StrategicObjective> allObjectives = new List<StrategicObjective>();

    [SerializeField]
    private List<StrategicObjective> activeObjectives = new List<StrategicObjective>();

    [SerializeField]
    private List<StrategicObjective> completedObjectives = new List<StrategicObjective>();

    [Header("团队协调")]
    [SerializeField]
    private AIGroup assignedGroup;

    [SerializeField]
    private TeamRole assignedRole = TeamRole.Soldier;

    private Dictionary<ObjectiveType, float> typeWeights = new Dictionary<ObjectiveType, float>();
    private float strategyTimer;
    private float reevaluationTimer;

    public enum TeamRole
    {
        Leader,
        Soldier,
        Sniper,
        Support,
        Medic,
        Engineer,
        Scout
    }

    private void Awake()
    {
        InitializeTypeWeights();
        InitializeResources();
        InitializeDefaultObjectives();
    }

    private void InitializeTypeWeights()
    {
        // 设置目标类型权重
        typeWeights[ObjectiveType.Offensive] = 1.2f;
        typeWeights[ObjectiveType.Defensive] = 1.0f;
        typeWeights[ObjectiveType.Support] = 0.8f;
        typeWeights[ObjectiveType.Resource] = 0.7f;
        typeWeights[ObjectiveType.Reconnaissance] = 0.6f;
        typeWeights[ObjectiveType.Survival] = 1.5f;
        typeWeights[ObjectiveType.Strategic] = 1.3f;
    }

    private void InitializeResources()
    {
        // 初始化资源
        resources.Add(new ResourceAllocation("Health", 100f, 0.1f));
        resources.Add(new ResourceAllocation("Ammo", 100f, 0f));
        resources.Add(new ResourceAllocation("Energy", 100f, 1.0f));
        resources.Add(new ResourceAllocation("Morale", 100f, 0.2f));
    }

    private void InitializeDefaultObjectives()
    {
        // 创建默认战略目标
        AddObjective(new StrategicObjective(
            "survive_01",
            "生存",
            ObjectiveType.Survival,
            0.8f
        ));

        AddObjective(new StrategicObjective(
            "defend_base_01",
            "保卫基地",
            ObjectiveType.Defensive,
            0.7f
        ));

        AddObjective(new StrategicObjective(
            "attack_enemy_01",
            "攻击敌人",
            ObjectiveType.Offensive,
            0.6f
        ));

        AddObjective(new StrategicObjective(
            "gather_intel_01",
            "收集情报",
            ObjectiveType.Reconnaissance,
            0.5f
        ));
    }

    private void Update()
    {
        UpdateResources();
        UpdateStrategy();
        UpdateActiveObjectives();
    }

    private void UpdateResources()
    {
        // 更新所有资源
        foreach (ResourceAllocation resource in resources)
        {
            resource.UpdateResource();
        }
    }

    private void UpdateStrategy()
    {
        strategyTimer += Time.deltaTime;
        reevaluationTimer += Time.deltaTime;

        // 定期更新战略
        if (strategyTimer >= strategyUpdateInterval)
        {
            ReevaluateObjectives();
            strategyTimer = 0f;
        }

        // 定期重新评估目标优先级
        if (reevaluationTimer >= objectiveReevaluationTime)
        {
            UpdateObjectivePriorities();
            reevaluationTimer = 0f;
        }
    }

    private void ReevaluateObjectives()
    {
        // 更新当前环境评估
        UpdateEnvironmentalAssessment();

        // 计算每个目标的当前优先级
        foreach (StrategicObjective objective in allObjectives)
        {
            CalculateObjectivePriority(objective);
        }

        // 选择要激活的目标
        SelectActiveObjectives();
    }

    private void UpdateEnvironmentalAssessment()
    {
        // 评估当前环境状况
        // 在实际项目中,这里会集成感知系统和游戏状态信息
        
        float threatLevel = AssessThreatLevel();
        float resourceStatus = AssessResourceStatus();
        float teamStatus = AssessTeamStatus();
        float gameProgress = AssessGameProgress();

        // 更新类型权重(根据环境动态调整)
        UpdateDynamicTypeWeights(threatLevel, resourceStatus, teamStatus, gameProgress);
    }

    private float AssessThreatLevel()
    {
        // 评估威胁等级 (0-1)
        AIPerceptionController perception = GetComponent<AIPerceptionController>();
        if (perception != null)
        {
            return perception.GetThreatLevel();
        }
        return 0.5f;
    }

    private float AssessResourceStatus()
    {
        // 评估资源状态 (0-1, 1表示资源充足)
        float totalResourceRatio = 0f;
        foreach (ResourceAllocation resource in resources)
        {
            totalResourceRatio += resource.currentAmount / resource.maxAmount;
        }
        return totalResourceRatio / resources.Count;
    }

    private float AssessTeamStatus()
    {
        // 评估团队状态 (0-1)
        if (assignedGroup == null)
        {
            return 1.0f; // 没有团队,自主行动
        }

        return assignedGroup.GetGroupEffectiveness();
    }

    private float AssessGameProgress()
    {
        // 评估游戏进度 (0-1)
        // 这里需要根据实际游戏系统实现
        return 0.5f;
    }

    private void UpdateDynamicTypeWeights(float threatLevel, float resourceStatus, float teamStatus, float gameProgress)
    {
        // 根据环境动态调整目标类型权重
        
        // 威胁高时增加防御和生存权重
        if (threatLevel > 0.7f)
        {
            typeWeights[ObjectiveType.Defensive] = 1.5f;
            typeWeights[ObjectiveType.Survival] = 2.0f;
        }
        else
        {
            typeWeights[ObjectiveType.Defensive] = 1.0f;
            typeWeights[ObjectiveType.Survival] = 1.5f;
        }

        // 资源不足时增加资源收集权重
        if (resourceStatus < 0.3f)
        {
            typeWeights[ObjectiveType.Resource] = 1.2f;
        }
        else
        {
            typeWeights[ObjectiveType.Resource] = 0.7f;
        }

        // 游戏后期增加战略目标权重
        if (gameProgress > 0.7f)
        {
            typeWeights[ObjectiveType.Strategic] = 1.8f;
        }
    }

    private void CalculateObjectivePriority(StrategicObjective objective)
    {
        float basePriority = objective.basePriority;
        float typeWeight = typeWeights.ContainsKey(objective.objectiveType) 
            ? typeWeights[objective.objectiveType] 
            : 1.0f;

        // 计算时间衰减
        float ageFactor = CalculateAgeFactor(objective);

        // 计算资源可用性
        float resourceFactor = CalculateResourceFactor(objective);

        // 计算角色适配度
        float roleFactor = CalculateRoleFactor(objective);

        // 计算团队需求
        float teamFactor = CalculateTeamFactor(objective);

        // 组合所有因素
        float finalPriority = basePriority * typeWeight * ageFactor * resourceFactor * roleFactor * teamFactor;

        objective.UpdatePriority(finalPriority / basePriority);
    }

    private float CalculateAgeFactor(StrategicObjective objective)
    {
        // 目标年龄影响因子(新鲜目标优先级更高)
        float age = objective.GetAge();
        float maxAge = 300f; // 5分钟

        return Mathf.Clamp01(1.0f - (age / maxAge));
    }

    private float CalculateResourceFactor(StrategicObjective objective)
    {
        // 检查是否有足够资源执行目标
        if (objective.requiredResources.Count == 0)
        {
            return 1.0f;
        }

        int satisfiedRequirements = 0;
        foreach (string resourceType in objective.requiredResources)
        {
            ResourceAllocation resource = resources.Find(r => r.resourceType == resourceType);
            if (resource != null && resource.currentAmount > resource.maxAmount * 0.3f)
            {
                satisfiedRequirements++;
            }
        }

        return (float)satisfiedRequirements / objective.requiredResources.Count;
    }

    private float CalculateRoleFactor(StrategicObjective objective)
    {
        // 计算目标与角色适配度
        Dictionary<TeamRole, float> roleWeights = new Dictionary<TeamRole, float>();

        // 设置不同角色对不同类型目标的适配权重
        switch (assignedRole)
        {
            case TeamRole.Leader:
                roleWeights[ObjectiveType.Strategic] = 1.5f;
                roleWeights[ObjectiveType.Offensive] = 1.2f;
                roleWeights[ObjectiveType.Defensive] = 1.0f;
                break;

            case TeamRole.Soldier:
                roleWeights[ObjectiveType.Offensive] = 1.3f;
                roleWeights[ObjectiveType.Defensive] = 1.1f;
                break;

            case TeamRole.Sniper:
                roleWeights[ObjectiveType.Reconnaissance] = 1.4f;
                roleWeights[ObjectiveType.Offensive] = 1.2f;
                break;

            case TeamRole.Support:
                roleWeights[ObjectiveType.Support] = 1.5f;
                roleWeights[ObjectiveType.Resource] = 1.2f;
                break;

            case TeamRole.Medic:
                roleWeights[ObjectiveType.Support] = 1.6f;
                roleWeights[ObjectiveType.Survival] = 1.3f;
                break;

            case TeamRole.Engineer:
                roleWeights[ObjectiveType.Resource] = 1.4f;
                roleWeights[ObjectiveType.Defensive] = 1.2f;
                break;

            case TeamRole.Scout:
                roleWeights[ObjectiveType.Reconnaissance] = 1.6f;
                break;

            default:
                return 1.0f;
        }

        if (roleWeights.ContainsKey(objective.objectiveType))
        {
            return roleWeights[objective.objectiveType];
        }

        return 0.8f; // 默认权重
    }

    private float CalculateTeamFactor(StrategicObjective objective)
    {
        if (assignedGroup == null)
        {
            return 1.0f;
        }

        // 检查团队是否需要执行此目标
        float teamNeed = assignedGroup.GetObjectiveNeed(objective.objectiveId);
        
        // 检查是否有其他成员正在执行此目标
        bool isBeingExecuted = assignedGroup.IsObjectiveBeingExecuted(objective.objectiveId);
        
        if (isBeingExecuted)
        {
            return teamNeed * 0.5f; // 减少重复执行
        }

        return teamNeed;
    }

    private void SelectActiveObjectives()
    {
        // 按优先级排序所有目标
        List<StrategicObjective> sortedObjectives = allObjectives
            .Where(obj => !obj.isActive && !completedObjectives.Contains(obj))
            .OrderByDescending(obj => obj.priority)
            .ToList();

        // 停用低优先级目标
        for (int i = activeObjectives.Count - 1; i >= 0; i--)
        {
            StrategicObjective activeObj = activeObjectives[i];
            bool shouldDeactivate = false;

            // 检查目标是否已完成
            if (IsObjectiveCompleted(activeObj))
            {
                CompleteObjective(activeObj.objectiveId);
                shouldDeactivate = true;
            }
            // 检查目标是否已过时
            else if (activeObj.GetAge() > 600f) // 10分钟
            {
                shouldDeactivate = true;
            }
            // 检查是否有更高优先级目标需要激活
            else if (sortedObjectives.Count > 0 && 
                     sortedObjectives[0].priority > activeObj.priority * 1.2f)
            {
                shouldDeactivate = true;
            }

            if (shouldDeactivate)
            {
                DeactivateObjective(activeObj.objectiveId);
            }
        }

        // 激活新目标
        while (activeObjectives.Count < maxActiveObjectives && sortedObjectives.Count > 0)
        {
            StrategicObjective nextObjective = sortedObjectives[0];
            ActivateObjective(nextObjective.objectiveId);
            sortedObjectives.RemoveAt(0);
        }
    }

    private void UpdateActiveObjectives()
    {
        // 更新激活目标的执行状态
        foreach (StrategicObjective objective in activeObjectives)
        {
            UpdateObjectiveExecution(objective);
        }
    }

    private void UpdateObjectiveExecution(StrategicObjective objective)
    {
        // 根据目标类型执行相应的战略行为
        switch (objective.objectiveType)
        {
            case ObjectiveType.Offensive:
                ExecuteOffensiveObjective(objective);
                break;

            case ObjectiveType.Defensive:
                ExecuteDefensiveObjective(objective);
                break;

            case ObjectiveType.Support:
                ExecuteSupportObjective(objective);
                break;

            case ObjectiveType.Resource:
                ExecuteResourceObjective(objective);
                break;

            case ObjectiveType.Reconnaissance:
                ExecuteReconnaissanceObjective(objective);
                break;

            case ObjectiveType.Survival:
                ExecuteSurvivalObjective(objective);
                break;

            case ObjectiveType.Strategic:
                ExecuteStrategicObjective(objective);
                break;
        }

        // 更新目标成功因素
        UpdateSuccessFactors(objective);
    }

    #region 目标执行方法

    private void ExecuteOffensiveObjective(StrategicObjective objective)
    {
        // 执行进攻目标
        AIDecisionController decisionController = GetComponent<AIDecisionController>();
        if (decisionController != null)
        {
            // 设置攻击行为
            decisionController.ForceDecision("Attack", 0.8f);
        }

        // 更新目标位置(如果需要)
        if (objective.targetObject != null)
        {
            objective.targetPosition = objective.targetObject.transform.position;
        }

        // 记录进攻进度
        RecordObjectiveProgress(objective, "进攻执行中");
    }

    private void ExecuteDefensiveObjective(StrategicObjective objective)
    {
        // 执行防御目标
        AIDecisionController decisionController = GetComponent<AIDecisionController>();
        if (decisionController != null)
        {
            // 寻找并占据防御位置
            decisionController.ForceDecision("TakeCover", 0.7f);
        }

        // 检查防御区域
        if (objective.targetPosition != Vector3.zero)
        {
            float distanceToDefensePoint = Vector3.Distance(
                transform.position, 
                objective.targetPosition
            );

            if (distanceToDefensePoint > 10f)
            {
                // 移动到防御点
                AIMovementController movementController = GetComponent<AIMovementController>();
                if (movementController != null)
                {
                    movementController.MoveToPosition(objective.targetPosition);
                }
            }
        }

        RecordObjectiveProgress(objective, "防御执行中");
    }

    private void ExecuteSupportObjective(StrategicObjective objective)
    {
        // 执行支援目标
        if (assignedGroup != null)
        {
            // 寻找需要支援的队友
            GameObject allyInNeed = assignedGroup.FindAllyInNeed();
            if (allyInNeed != null)
            {
                // 移动到队友位置
                AIMovementController movementController = GetComponent<AIMovementController>();
                if (movementController != null)
                {
                    movementController.MoveToPosition(allyInNeed.transform.position);
                }

                // 提供支援
                ProvideSupportToAlly(allyInNeed);
            }
        }

        RecordObjectiveProgress(objective, "支援执行中");
    }

    private void ExecuteResourceObjective(StrategicObjective objective)
    {
        // 执行资源收集目标
        if (objective.targetObject != null)
        {
            // 移动到资源位置
            AIMovementController movementController = GetComponent<AIMovementController>();
            if (movementController != null)
            {
                movementController.MoveToPosition(objective.targetObject.transform.position);
            }

            // 收集资源
            float distance = Vector3.Distance(
                transform.position, 
                objective.targetObject.transform.position
            );

            if (distance < 2f)
            {
                CollectResource(objective.targetObject);
            }
        }

        RecordObjectiveProgress(objective, "资源收集中");
    }

    private void ExecuteReconnaissanceObjective(StrategicObjective objective)
    {
        // 执行侦察目标
        AIDecisionController decisionController = GetComponent<AIDecisionController>();
        if (decisionController != null)
        {
            decisionController.ForceDecision("Investigate", 0.6f);
        }

        // 探索未知区域
        if (objective.targetPosition != Vector3.zero)
        {
            AIMovementController movementController = GetComponent<AIMovementController>();
            if (movementController != null)
            {
                movementController.MoveToPosition(objective.targetPosition);
            }
        }

        RecordObjectiveProgress(objective, "侦察执行中");
    }

    private void ExecuteSurvivalObjective(StrategicObjective objective)
    {
        // 执行生存目标
        AIDecisionController decisionController = GetComponent<AIDecisionController>();
        if (decisionController != null)
        {
            // 生存行为:治疗、躲避、撤退
            float healthRatio = GetResourceAmount("Health") / 100f;
            
            if (healthRatio < 0.3f)
            {
                decisionController.ForceDecision("Heal", 0.9f);
            }
            else
            {
                decisionController.ForceDecision("TakeCover", 0.8f);
            }
        }

        RecordObjectiveProgress(objective, "生存模式");
    }

    private void ExecuteStrategicObjective(StrategicObjective objective)
    {
        // 执行战略目标
        // 这通常是高层次的目标,需要多个步骤
        RecordObjectiveProgress(objective, "战略执行中");
    }

    #endregion

    #region 辅助方法

    private void ProvideSupportToAlly(GameObject ally)
    {
        // 提供支援给队友
        // 在实际项目中,这里会有具体的支援逻辑
        
        Debug.Log($"正在支援队友: {ally.name}");

        // 检查队友状态
        HealthComponent allyHealth = ally.GetComponent<HealthComponent>();
        if (allyHealth != null && allyHealth.CurrentHealth < allyHealth.MaxHealth * 0.5f)
        {
            // 队友生命值低,尝试治疗
            Debug.Log("队友生命值低,提供医疗支援");
        }

        // 提供火力支援
        WeaponController weapon = GetComponent<WeaponController>();
        if (weapon != null)
        {
            // 瞄准队友附近的敌人
            AIPerceptionController perception = ally.GetComponent<AIPerceptionController>();
            if (perception != null)
            {
                GameObject primaryThreat = perception.GetPrimaryThreat();
                if (primaryThreat != null)
                {
                    weapon.FireAtTarget(primaryThreat);
                }
            }
        }
    }

    private void CollectResource(GameObject resourceObject)
    {
        // 收集资源
        ResourcePickup resourcePickup = resourceObject.GetComponent<ResourcePickup>();
        if (resourcePickup != null)
        {
            resourcePickup.Collect(gameObject);
            Debug.Log($"收集资源: {resourceObject.name}");
        }
    }

    private void UpdateSuccessFactors(StrategicObjective objective)
    {
        // 更新目标成功因素
        // 这些因素用于评估目标执行的成功程度

        if (!objective.successFactors.ContainsKey("time_spent"))
        {
            objective.successFactors["time_spent"] = 0f;
        }

        objective.successFactors["time_spent"] += Time.deltaTime;

        // 根据目标类型添加特定的成功因素
        switch (objective.objectiveType)
        {
            case ObjectiveType.Offensive:
                UpdateOffensiveSuccessFactors(objective);
                break;

            case ObjectiveType.Defensive:
                UpdateDefensiveSuccessFactors(objective);
                break;
        }
    }

    private void UpdateOffensiveSuccessFactors(StrategicObjective objective)
    {
        // 更新进攻目标成功因素
        if (objective.targetObject != null)
        {
            float distance = Vector3.Distance(
                transform.position, 
                objective.targetObject.transform.position
            );

            if (!objective.successFactors.ContainsKey("distance_to_target"))
            {
                objective.successFactors["distance_to_target"] = distance;
            }
            else
            {
                objective.successFactors["distance_to_target"] = Mathf.Min(
                    objective.successFactors["distance_to_target"], 
                    distance
                );
            }
        }
    }

    private void UpdateDefensiveSuccessFactors(StrategicObjective objective)
    {
        // 更新防御目标成功因素
        if (objective.targetPosition != Vector3.zero)
        {
            float distance = Vector3.Distance(transform.position, objective.targetPosition);
            
            if (!objective.successFactors.ContainsKey("distance_to_defense_point"))
            {
                objective.successFactors["distance_to_defense_point"] = distance;
            }
            else
            {
                objective.successFactors["distance_to_defense_point"] = Mathf.Min(
                    objective.successFactors["distance_to_defense_point"], 
                    distance
                );
            }
        }
    }

    private void RecordObjectiveProgress(StrategicObjective objective, string status)
    {
        // 记录目标进度
        // 在实际项目中,这里可能会更新UI或发送事件
        objective.successFactors["last_status"] = Time.time;
    }

    private bool IsObjectiveCompleted(StrategicObjective objective)
    {
        // 检查目标是否已完成
        // 根据目标类型有不同的完成条件

        switch (objective.objectiveType)
        {
            case ObjectiveType.Offensive:
                return IsOffensiveObjectiveCompleted(objective);

            case ObjectiveType.Defensive:
                return IsDefensiveObjectiveCompleted(objective);

            case ObjectiveType.Resource:
                return IsResourceObjectiveCompleted(objective);

            case ObjectiveType.Reconnaissance:
                return IsReconnaissanceObjectiveCompleted(objective);

            default:
                return false;
        }
    }

    private bool IsOffensiveObjectiveCompleted(StrategicObjective objective)
    {
        // 进攻目标完成条件:目标被消灭或超出时间限制
        if (objective.targetObject == null)
        {
            return true; // 目标已不存在
        }

        // 检查是否超出时间限制
        float timeSpent = objective.successFactors.ContainsKey("time_spent") 
            ? objective.successFactors["time_spent"] 
            : 0f;

        if (timeSpent > 300f) // 5分钟
        {
            return true; // 超时
        }

        return false;
    }

    private bool IsDefensiveObjectiveCompleted(StrategicObjective objective)
    {
        // 防御目标完成条件:成功防御一定时间或威胁解除
        float timeSpent = objective.successFactors.ContainsKey("time_spent") 
            ? objective.successFactors["time_spent"] 
            : 0f;

        if (timeSpent > 180f) // 3分钟
        {
            return true; // 成功防御足够时间
        }

        // 检查威胁等级
        float threatLevel = AssessThreatLevel();
        if (threatLevel < 0.2f)
        {
            return true; // 威胁解除
        }

        return false;
    }

    private bool IsResourceObjectiveCompleted(StrategicObjective objective)
    {
        // 资源目标完成条件:资源收集完成或资源不存在
        if (objective.targetObject == null)
        {
            return true;
        }

        ResourcePickup resourcePickup = objective.targetObject.GetComponent<ResourcePickup>();
        if (resourcePickup != null && resourcePickup.IsCollected())
        {
            return true;
        }

        return false;
    }

    private bool IsReconnaissanceObjectiveCompleted(StrategicObjective objective)
    {
        // 侦察目标完成条件:到达侦察点并停留足够时间
        if (objective.targetPosition == Vector3.zero)
        {
            return true;
        }

        float distance = Vector3.Distance(transform.position, objective.targetPosition);
        float timeSpent = objective.successFactors.ContainsKey("time_spent") 
            ? objective.successFactors["time_spent"] 
            : 0f;

        if (distance < 5f && timeSpent > 30f)
        {
            return true; // 到达侦察点并停留30秒
        }

        return false;
    }

    private void UpdateObjectivePriorities()
    {
        // 更新所有目标的优先级
        foreach (StrategicObjective objective in allObjectives)
        {
            CalculateObjectivePriority(objective);
        }
    }

    #endregion

    #region 公共接口

    public void AddObjective(StrategicObjective objective)
    {
        allObjectives.Add(objective);
    }

    public bool ActivateObjective(string objectiveId)
    {
        StrategicObjective objective = allObjectives.Find(obj => obj.objectiveId == objectiveId);
        if (objective != null && !objective.isActive)
        {
            objective.isActive = true;
            objective.timeAssigned = Time.time;
            activeObjectives.Add(objective);

            Debug.Log($"激活目标: {objective.objectiveName}");

            // 触发目标激活事件
            OnObjectiveActivated?.Invoke(objective);

            return true;
        }

        return false;
    }

    public bool DeactivateObjective(string objectiveId)
    {
        StrategicObjective objective = activeObjectives.Find(obj => obj.objectiveId == objectiveId);
        if (objective != null)
        {
            objective.isActive = false;
            activeObjectives.Remove(objective);

            Debug.Log($"停用目标: {objective.objectiveName}");

            // 触发目标停用事件
            OnObjectiveDeactivated?.Invoke(objective);

            return true;
        }

        return false;
    }

    public bool CompleteObjective(string objectiveId)
    {
        StrategicObjective objective = activeObjectives.Find(obj => obj.objectiveId == objectiveId);
        if (objective != null)
        {
            objective.isActive = false;
            objective.timeCompleted = Time.time;
            activeObjectives.Remove(objective);
            completedObjectives.Add(objective);

            Debug.Log($"完成目标: {objective.objectiveName}");

            // 触发目标完成事件
            OnObjectiveCompleted?.Invoke(objective);

            return true;
        }

        return false;
    }

    public List<StrategicObjective> GetActiveObjectives()
    {
        return new List<StrategicObjective>(activeObjectives);
    }

    public StrategicObjective GetHighestPriorityObjective()
    {
        if (activeObjectives.Count == 0)
        {
            return null;
        }

        return activeObjectives.OrderByDescending(obj => obj.priority).First();
    }

    public float GetResourceAmount(string resourceType)
    {
        ResourceAllocation resource = resources.Find(r => r.resourceType == resourceType);
        return resource != null ? resource.currentAmount : 0f;
    }

    public bool ConsumeResource(string resourceType, float amount)
    {
        ResourceAllocation resource = resources.Find(r => r.resourceType == resourceType);
        return resource != null && resource.Consume(amount);
    }

    public void AssignToGroup(AIGroup group, TeamRole role)
    {
        assignedGroup = group;
        assignedRole = role;

        if (group != null)
        {
            group.RegisterMember(gameObject, role);
        }
    }

    public void SetTeamRole(TeamRole role)
    {
        assignedRole = role;
    }

    #endregion

    #region 事件

    public event Action<StrategicObjective> OnObjectiveActivated = delegate { };
    public event Action<StrategicObjective> OnObjectiveDeactivated = delegate { };
    public event Action<StrategicObjective> OnObjectiveCompleted = delegate { };

    #endregion

    private void OnDrawGizmosSelected()
    {
        if (!Application.isPlaying)
        {
            return;
        }

        // 绘制激活目标
        Gizmos.color = Color.yellow;
        foreach (StrategicObjective objective in activeObjectives)
        {
            if (objective.targetPosition != Vector3.zero)
            {
                Gizmos.DrawWireSphere(objective.targetPosition, 1f);
                Gizmos.DrawLine(transform.position, objective.targetPosition);
            }
        }

        // 绘制最高优先级目标
        StrategicObjective highestPriority = GetHighestPriorityObjective();
        if (highestPriority != null && highestPriority.targetPosition != Vector3.zero)
        {
            Gizmos.color = Color.red;
            Gizmos.DrawWireSphere(highestPriority.targetPosition, 1.5f);
            Gizmos.DrawLine(transform.position, highestPriority.targetPosition);
        }

        // 显示当前角色和目标信息
        #if UNITY_EDITOR
        string info = $"角色: {assignedRole}\n";
        info += $"激活目标: {activeObjectives.Count}\n";
        
        if (highestPriority != null)
        {
            info += $"最高优先级: {highestPriority.objectiveName}\n";
            info += $"优先级: {highestPriority.priority:F2}";
        }

        UnityEditor.Handles.Label(
            transform.position + Vector3.up * 2.5f,
            info
        );
        #endif
    }
}

2.1.4 AI架构支撑系统的完善

一个完整的AI架构除了核心的三层结构外,还需要支撑系统来确保AI的稳定运行和高效表现。这些支撑系统包括性能管理、调试工具、配置系统和集成接口。

下面是支撑系统的实现示例:

using UnityEngine;
using System;
using System.Collections.Generic;
using System.Text;

public class AISupportSystem : MonoBehaviour
{
    [System.Serializable]
    public class PerformanceSettings
    {
        public bool enablePerformanceMonitoring = true;
        public float performanceUpdateInterval = 1.0f;
        public int maxFrameTimeMs = 16; // 60 FPS
        public bool enableAdaptiveUpdate = true;
        public float minUpdateInterval = 0.05f;
        public float maxUpdateInterval = 0.5f;
    }

    [System.Serializable]
    public class DebugSettings
    {
        public bool enableDebugOverlay = false;
        public bool logAIEvents = false;
        public bool logPerformanceWarnings = true;
        public bool enableVisualDebugging = true;
        public Color debugTextColor = Color.white;
        public int maxLogEntries = 100;
    }

    [System.Serializable]
    public class AIConfig
    {
        public string aiName = "DefaultAI";
        public int aiVersion = 1;
        public string behaviorProfile = "Aggressive";
        public Dictionary<string, string> customParameters = new Dictionary<string, string>();
    }

    [Header("性能设置")]
    [SerializeField]
    private PerformanceSettings performanceSettings = new PerformanceSettings();

    [Header("调试设置")]
    [SerializeField]
    private DebugSettings debugSettings = new DebugSettings();

    [Header("AI配置")]
    [SerializeField]
    private AIConfig aiConfig = new AIConfig();

    [Header("组件引用")]
    [SerializeField]
    private AIMovementController movementController;

    [SerializeField]
    private AIDecisionController decisionController;

    [SerializeField]
    private AIStrategicController strategicController;

    [Header("性能统计")]
    [SerializeField]
    private float averageFrameTime;

    [SerializeField]
    private float maxFrameTime;

    [SerializeField]
    private float minFrameTime;

    [SerializeField]
    private int frameCount;

    [SerializeField]
    private float performanceTimer;

    [Header("调试信息")]
    [SerializeField]
    private List<DebugLogEntry> debugLog = new List<DebugLogEntry>();

    [SerializeField]
    private StringBuilder debugOverlayText = new StringBuilder();

    private Dictionary<string, float> componentUpdateTimes = new Dictionary<string, float>();
    private Dictionary<string, int> componentCallCounts = new Dictionary<string, int>();

    private float adaptiveUpdateInterval;
    private bool isInitialized;

    [System.Serializable]
    public class DebugLogEntry
    {
        public string message;
        public LogType logType;
        public float timestamp;
        public string source;

        public DebugLogEntry(string message, LogType logType, string source)
        {
            this.message = message;
            this.logType = logType;
            this.timestamp = Time.time;
            this.source = source;
        }
    }

    public enum LogType
    {
        Info,
        Warning,
        Error,
        Performance
    }

    private void Awake()
    {
        InitializeSupportSystem();
    }

    private void InitializeSupportSystem()
    {
        // 获取组件引用
        if (movementController == null)
        {
            movementController = GetComponent<AIMovementController>();
        }

        if (decisionController == null)
        {
            decisionController = GetComponent<AIDecisionController>();
        }

        if (strategicController == null)
        {
            strategicController = GetComponent<AIStrategicController>();
        }

        // 初始化自适应更新间隔
        adaptiveUpdateInterval = performanceSettings.minUpdateInterval;

        // 初始化性能监控
        InitializePerformanceMonitoring();

        // 初始化调试系统
        InitializeDebugSystem();

        isInitialized = true;

        LogInfo("AI支撑系统初始化完成", "AISupportSystem");
    }

    private void InitializePerformanceMonitoring()
    {
        averageFrameTime = 0f;
        maxFrameTime = 0f;
        minFrameTime = float.MaxValue;
        frameCount = 0;
        performanceTimer = 0f;

        // 初始化组件性能追踪
        componentUpdateTimes["Movement"] = 0f;
        componentUpdateTimes["Decision"] = 0f;
        componentUpdateTimes["Strategic"] = 0f;

        componentCallCounts["Movement"] = 0;
        componentCallCounts["Decision"] = 0;
        componentCallCounts["Strategic"] = 0;
    }

    private void InitializeDebugSystem()
    {
        debugLog.Clear();
        debugOverlayText.Clear();

        // 注册调试命令
        RegisterDebugCommands();
    }

    private void Update()
    {
        if (!isInitialized)
        {
            return;
        }

        UpdatePerformanceMonitoring();
        UpdateAdaptiveSystem();
        UpdateDebugOverlay();
    }

    private void UpdatePerformanceMonitoring()
    {
        if (!performanceSettings.enablePerformanceMonitoring)
        {
            return;
        }

        // 测量帧时间
        float frameTime = Time.deltaTime * 1000f; // 转换为毫秒
        UpdateFrameTimeStatistics(frameTime);

        // 更新性能计时器
        performanceTimer += Time.deltaTime;
        if (performanceTimer >= performanceSettings.performanceUpdateInterval)
        {
            AnalyzePerformance();
            performanceTimer = 0f;
        }
    }

    private void UpdateFrameTimeStatistics(float frameTime)
    {
        // 更新帧时间统计
        frameCount++;

        // 移动平均
        averageFrameTime = (averageFrameTime * (frameCount - 1) + frameTime) / frameCount;

        // 更新最大/最小帧时间
        if (frameTime > maxFrameTime)
        {
            maxFrameTime = frameTime;
        }

        if (frameTime < minFrameTime)
        {
            minFrameTime = frameTime;
        }

        // 检查性能警告
        if (frameTime > performanceSettings.maxFrameTimeMs && debugSettings.logPerformanceWarnings)
        {
            LogWarning($"帧时间超标: {frameTime:F1}ms (限制: {performanceSettings.maxFrameTimeMs}ms)", 
                      "Performance");
        }
    }

    private void AnalyzePerformance()
    {
        // 分析性能数据并调整系统
        if (performanceSettings.enableAdaptiveUpdate)
        {
            AdjustUpdateIntervals();
        }

        // 记录性能日志
        if (debugSettings.logPerformanceWarnings && averageFrameTime > performanceSettings.maxFrameTimeMs * 0.8f)
        {
            LogPerformance($"性能警告: 平均帧时间 {averageFrameTime:F1}ms");
        }

        // 重置统计
        frameCount = 0;
        averageFrameTime = 0f;
        maxFrameTime = 0f;
        minFrameTime = float.MaxValue;
    }

    private void AdjustUpdateIntervals()
    {
        // 根据性能调整更新间隔
        if (averageFrameTime > performanceSettings.maxFrameTimeMs * 0.9f)
        {
            // 性能紧张,增加更新间隔
            adaptiveUpdateInterval = Mathf.Min(
                adaptiveUpdateInterval * 1.2f,
                performanceSettings.maxUpdateInterval
            );

            ApplyAdaptiveUpdates();
        }
        else if (averageFrameTime < performanceSettings.maxFrameTimeMs * 0.5f)
        {
            // 性能充足,减少更新间隔
            adaptiveUpdateInterval = Mathf.Max(
                adaptiveUpdateInterval * 0.9f,
                performanceSettings.minUpdateInterval
            );

            ApplyAdaptiveUpdates();
        }
    }

    private void ApplyAdaptiveUpdates()
    {
        // 应用自适应更新间隔到各个组件
        if (decisionController != null)
        {
            // 这里需要决策控制器支持更新间隔调整
            // decisionController.SetUpdateInterval(adaptiveUpdateInterval);
        }

        if (strategicController != null)
        {
            // strategicController.SetUpdateInterval(adaptiveUpdateInterval * 2f);
        }
    }

    private void UpdateAdaptiveSystem()
    {
        // 更新自适应系统(LOD、剔除等)
        UpdateLevelOfDetail();
        UpdateCullingSystem();
    }

    private void UpdateLevelOfDetail()
    {
        // 根据距离调整AI细节层次
        GameObject player = GameObject.FindGameObjectWithTag("Player");
        if (player == null)
        {
            return;
        }

        float distanceToPlayer = Vector3.Distance(transform.position, player.transform.position);
        float lodLevel = CalculateLODLevel(distanceToPlayer);

        ApplyLODSettings(lodLevel);
    }

    private float CalculateLODLevel(float distance)
    {
        // 计算LOD级别 (0-1, 0表示最低细节)
        if (distance < 10f)
        {
            return 1.0f; // 高细节
        }
        else if (distance < 30f)
        {
            return 0.7f; // 中等细节
        }
        else if (distance < 50f)
        {
            return 0.4f; // 低细节
        }
        else
        {
            return 0.1f; // 最低细节
        }
    }

    private void ApplyLODSettings(float lodLevel)
    {
        // 应用LOD设置到各个组件
        if (decisionController != null)
        {
            // 调整决策精度
            // decisionController.SetDecisionPrecision(lodLevel);
        }

        if (movementController != null)
        {
            // 调整移动精度
            // movementController.SetMovementPrecision(lodLevel);
        }
    }

    private void UpdateCullingSystem()
    {
        // 更新剔除系统(远离玩家或不可见时禁用AI)
        GameObject player = GameObject.FindGameObjectWithTag("Player");
        if (player == null)
        {
            return;
        }

        Camera mainCamera = Camera.main;
        if (mainCamera == null)
        {
            return;
        }

        // 计算视锥剔除
        Vector3 viewportPoint = mainCamera.WorldToViewportPoint(transform.position);
        bool isInView = viewportPoint.x >= 0 && viewportPoint.x <= 1 && 
                       viewportPoint.y >= 0 && viewportPoint.y <= 1 && 
                       viewportPoint.z > 0;

        // 计算距离剔除
        float distanceToPlayer = Vector3.Distance(transform.position, player.transform.position);
        bool isInRange = distanceToPlayer < 100f; // 最大AI激活距离

        // 应用剔除
        bool shouldBeActive = isInView && isInRange;
        SetAIActive(shouldBeActive);
    }

    private void UpdateDebugOverlay()
    {
        if (!debugSettings.enableDebugOverlay)
        {
            return;
        }

        // 更新调试叠加文本
        debugOverlayText.Clear();

        // 添加性能信息
        debugOverlayText.AppendLine($"=== AI 调试信息 ===");
        debugOverlayText.AppendLine($"名称: {aiConfig.aiName}");
        debugOverlayText.AppendLine($"配置: {aiConfig.behaviorProfile}");
        debugOverlayText.AppendLine($"帧时间: {averageFrameTime:F1}ms");
        debugOverlayText.AppendLine($"更新间隔: {adaptiveUpdateInterval:F2}s");

        // 添加组件状态
        if (movementController != null)
        {
            debugOverlayText.AppendLine($"移动速度: {movementController.CurrentSpeed:F1}");
            debugOverlayText.AppendLine($"是否接地: {movementController.IsGrounded}");
        }

        if (decisionController != null)
        {
            debugOverlayText.AppendLine($"当前决策: {decisionController.GetCurrentDecision()}");
            debugOverlayText.AppendLine($"决策置信度: {decisionController.GetDecisionConfidence():F2}");
        }

        if (strategicController != null)
        {
            var activeObjectives = strategicController.GetActiveObjectives();
            debugOverlayText.AppendLine($"激活目标: {activeObjectives.Count}");
            
            foreach (var objective in activeObjectives)
            {
                debugOverlayText.AppendLine($"  - {objective.objectiveName}: {objective.priority:F2}");
            }
        }

        // 添加最近的日志
        debugOverlayText.AppendLine($"=== 最近日志 ===");
        int logCount = Mathf.Min(debugLog.Count, 5);
        for (int i = debugLog.Count - logCount; i < debugLog.Count; i++)
        {
            if (i >= 0)
            {
                var logEntry = debugLog[i];
                debugOverlayText.AppendLine($"[{logEntry.timestamp:F1}] {logEntry.message}");
            }
        }
    }

    private void RegisterDebugCommands()
    {
        // 注册调试命令
        // 在实际项目中,这里会集成到游戏的控制台系统
        DebugCommandSystem commandSystem = DebugCommandSystem.Instance;
        if (commandSystem != null)
        {
            commandSystem.RegisterCommand("ai_status", "显示AI状态", ShowAIStatus);
            commandSystem.RegisterCommand("ai_log", "显示AI日志", ShowAILog);
            commandSystem.RegisterCommand("ai_performance", "显示AI性能", ShowAIPerformance);
            commandSystem.RegisterCommand("ai_setprofile", "设置AI配置", SetAIProfile);
        }
    }

    #region 调试命令处理

    private string ShowAIStatus(string[] args)
    {
        StringBuilder status = new StringBuilder();
        status.AppendLine($"AI状态报告 - {aiConfig.aiName}");
        status.AppendLine($"位置: {transform.position}");
        status.AppendLine($"旋转: {transform.rotation.eulerAngles}");
        status.AppendLine($"激活: {gameObject.activeSelf}");

        if (movementController != null)
        {
            status.AppendLine($"移动状态: {movementController.CurrentSpeed:F1} 单位/秒");
        }

        if (decisionController != null)
        {
            status.AppendLine($"决策: {decisionController.GetCurrentDecision()}");
        }

        return status.ToString();
    }

    private string ShowAILog(string[] args)
    {
        StringBuilder logOutput = new StringBuilder();
        logOutput.AppendLine($"AI日志 - 最近 {debugLog.Count} 条");

        foreach (var logEntry in debugLog)
        {
            string logTypeStr = logEntry.logType.ToString().PadRight(10);
            logOutput.AppendLine($"[{logEntry.timestamp:F2}] [{logTypeStr}] {logEntry.message}");
        }

        return logOutput.ToString();
    }

    private string ShowAIPerformance(string[] args)
    {
        StringBuilder performance = new StringBuilder();
        performance.AppendLine($"AI性能统计");
        performance.AppendLine($"平均帧时间: {averageFrameTime:F1}ms");
        performance.AppendLine($"最大帧时间: {maxFrameTime:F1}ms");
        performance.AppendLine($"最小帧时间: {minFrameTime:F1}ms");
        performance.AppendLine($"自适应更新间隔: {adaptiveUpdateInterval:F2}s");

        performance.AppendLine($"组件调用次数:");
        foreach (var pair in componentCallCounts)
        {
            performance.AppendLine($"  {pair.Key}: {pair.Value}");
        }

        performance.AppendLine($"组件更新时间:");
        foreach (var pair in componentUpdateTimes)
        {
            performance.AppendLine($"  {pair.Key}: {pair.Value:F2}ms");
        }

        return performance.ToString();
    }

    private string SetAIProfile(string[] args)
    {
        if (args.Length < 2)
        {
            return "用法: ai_setprofile <配置名称>";
        }

        string profileName = args[1];
        aiConfig.behaviorProfile = profileName;

        // 应用新的配置
        ApplyBehaviorProfile(profileName);

        return $"AI配置已更改为: {profileName}";
    }

    #endregion

    #region 公共接口

    public void LogInfo(string message, string source = "AI")
    {
        AddDebugLog(message, LogType.Info, source);
        
        if (debugSettings.logAIEvents)
        {
            Debug.Log($"[AI-Info] {source}: {message}");
        }
    }

    public void LogWarning(string message, string source = "AI")
    {
        AddDebugLog(message, LogType.Warning, source);
        
        if (debugSettings.logAIEvents)
        {
            Debug.LogWarning($"[AI-Warning] {source}: {message}");
        }
    }

    public void LogError(string message, string source = "AI")
    {
        AddDebugLog(message, LogType.Error, source);
        
        if (debugSettings.logAIEvents)
        {
            Debug.LogError($"[AI-Error] {source}: {message}");
        }
    }

    public void LogPerformance(string message, string source = "AI")
    {
        AddDebugLog(message, LogType.Performance, source);
    }

    private void AddDebugLog(string message, LogType logType, string source)
    {
        DebugLogEntry logEntry = new DebugLogEntry(message, logType, source);
        debugLog.Add(logEntry);

        // 限制日志数量
        if (debugLog.Count > debugSettings.maxLogEntries)
        {
            debugLog.RemoveAt(0);
        }
    }

    public void RecordComponentTime(string componentName, float timeMs)
    {
        if (!componentUpdateTimes.ContainsKey(componentName))
        {
            componentUpdateTimes[componentName] = 0f;
            componentCallCounts[componentName] = 0;
        }

        componentUpdateTimes[componentName] = (componentUpdateTimes[componentName] + timeMs) / 2; // 移动平均
        componentCallCounts[componentName]++;
    }

    public void SetAIActive(bool active)
    {
        if (movementController != null)
        {
            movementController.SetMovementEnabled(active);
        }

        if (decisionController != null)
        {
            decisionController.enabled = active;
        }

        if (strategicController != null)
        {
            strategicController.enabled = active;
        }

        enabled = active;

        LogInfo($"AI激活状态: {active}", "AISupportSystem");
    }

    public void SetBehaviorProfile(string profileName)
    {
        aiConfig.behaviorProfile = profileName;
        ApplyBehaviorProfile(profileName);
    }

    private void ApplyBehaviorProfile(string profileName)
    {
        // 根据配置名称应用不同的行为设置
        switch (profileName.ToLower())
        {
            case "aggressive":
                ApplyAggressiveProfile();
                break;

            case "defensive":
                ApplyDefensiveProfile();
                break;

            case "stealth":
                ApplyStealthProfile();
                break;

            case "support":
                ApplySupportProfile();
                break;

            default:
                ApplyDefaultProfile();
                break;
        }

        LogInfo($"应用行为配置: {profileName}", "AISupportSystem");
    }

    private void ApplyAggressiveProfile()
    {
        // 应用侵略性配置
        if (decisionController != null)
        {
            // 设置更高的攻击权重
            // decisionController.SetBehaviorWeight("Attack", 2.0f);
        }

        if (strategicController != null)
        {
            // 设置进攻性目标
            strategicController.SetTeamRole(AIStrategicController.TeamRole.Soldier);
        }
    }

    private void ApplyDefensiveProfile()
    {
        // 应用防御性配置
        if (decisionController != null)
        {
            // 设置更高的防御权重
            // decisionController.SetBehaviorWeight("TakeCover", 1.5f);
        }
    }

    private void ApplyStealthProfile()
    {
        // 应用潜行配置
        if (movementController != null)
        {
            // 降低移动速度
            // movementController.SetMaxSpeed(3.0f);
        }
    }

    private void ApplySupportProfile()
    {
        // 应用支援配置
        if (strategicController != null)
        {
            strategicController.SetTeamRole(AIStrategicController.TeamRole.Support);
        }
    }

    private void ApplyDefaultProfile()
    {
        // 应用默认配置
        // 重置所有设置
    }

    public string GetDebugOverlayText()
    {
        return debugOverlayText.ToString();
    }

    public Dictionary<string, string> GetAIConfiguration()
    {
        Dictionary<string, string> config = new Dictionary<string, string>
        {
            ["Name"] = aiConfig.aiName,
            ["Version"] = aiConfig.aiVersion.ToString(),
            ["Profile"] = aiConfig.behaviorProfile,
            ["Performance"] = $"{averageFrameTime:F1}ms"
        };

        foreach (var param in aiConfig.customParameters)
        {
            config[param.Key] = param.Value;
        }

        return config;
    }

    public void SetCustomParameter(string key, string value)
    {
        aiConfig.customParameters[key] = value;
    }

    public string GetCustomParameter(string key)
    {
        return aiConfig.customParameters.ContainsKey(key) 
            ? aiConfig.customParameters[key] 
            : string.Empty;
    }

    #endregion

    #region 调试绘制

    private void OnDrawGizmos()
    {
        if (!debugSettings.enableVisualDebugging || !Application.isPlaying)
        {
            return;
        }

        // 绘制调试信息
        DrawDebugGizmos();
    }

    private void DrawDebugGizmos()
    {
        // 绘制AI活动范围
        Gizmos.color = new Color(0, 1, 0, 0.1f);
        Gizmos.DrawWireSphere(transform.position, 100f);

        // 绘制到目标的线(如果有)
        if (decisionController != null)
        {
            var conditionValues = decisionController.GetConditionValues();
            if (conditionValues.ContainsKey("DistanceToTarget") && conditionValues["DistanceToTarget"] > 0)
            {
                Gizmos.color = Color.red;
                // 这里需要获取实际目标位置
                // Gizmos.DrawLine(transform.position, targetPosition);
            }
        }

        // 绘制LOD范围
        Gizmos.color = new Color(1, 1, 0, 0.2f);
        Gizmos.DrawWireSphere(transform.position, 10f);  // 高细节
        Gizmos.DrawWireSphere(transform.position, 30f);  // 中细节
        Gizmos.DrawWireSphere(transform.position, 50f);  // 低细节

        // 绘制调试文本
        #if UNITY_EDITOR
        if (debugSettings.enableDebugOverlay)
        {
            UnityEditor.Handles.color = debugSettings.debugTextColor;
            UnityEditor.Handles.Label(
                transform.position + Vector3.up * 3f,
                GetDebugOverlayText()
            );
        }
        #endif
    }

    #endregion

    private void OnDestroy()
    {
        // 清理资源
        CleanupSupportSystem();
    }

    private void CleanupSupportSystem()
    {
        // 注销调试命令
        DebugCommandSystem commandSystem = DebugCommandSystem.Instance;
        if (commandSystem != null)
        {
            commandSystem.UnregisterCommand("ai_status");
            commandSystem.UnregisterCommand("ai_log");
            commandSystem.UnregisterCommand("ai_performance");
            commandSystem.UnregisterCommand("ai_setprofile");
        }

        LogInfo("AI支撑系统清理完成", "AISupportSystem");
    }
}

2.2 FPS/TPS游戏AI架构的实践解析

2.2.1 FPS/TPS游戏中运动层的特殊需求

第一人称射击游戏(FPS)和第三人称射击游戏(TPS)对AI的运动控制有着特殊的要求。这些游戏中的AI不仅需要基本的移动能力,还需要表现出符合射击游戏特点的行为模式,如寻找掩护、战术移动、精确瞄准等。

在商业FPS/TPS项目中,运动层的实现需要特别关注以下方面:

  1. 掩护系统集成:AI需要能够识别并使用环境中的掩护物
  2. 战术移动:包括侧翼移动、跃进、撤退等战术动作
  3. 瞄准与射击:精确的瞄准系统和射击行为
  4. 团队协调移动:小队成员的协同移动和阵型保持

下面是针对FPS/TPS游戏的增强运动控制器实现:

using UnityEngine;

public class FPSAIMovementController : AIMovementController
{
    [System.Serializable]
    public class FPSMovementSettings : MovementSettings
    {
        public float crouchSpeedMultiplier = 0.6f;
        public float sprintSpeedMultiplier = 1.5f;
        public float proneSpeedMultiplier = 0.3f;
        public float strafeSpeedMultiplier = 0.8f;
        public float backwardsSpeedMultiplier = 0.6f;
        public float coverMoveSpeed = 2.0f;
        public float peekSpeed = 1.0f;
    }

    [Header("FPS特殊设置")]
    [SerializeField]
    private FPSMovementSettings fpsSettings = new FPSMovementSettings();

    [Header("掩护系统")]
    [SerializeField]
    private CoverSystem coverSystem;

    [SerializeField]
    private bool isInCover;

    [SerializeField]
    private CoverPoint currentCover;

    [Header("姿态系统")]
    [SerializeField]
    private PostureState currentPosture = PostureState.Standing;

    [SerializeField]
    private float postureTransitionSpeed = 5.0f;

    [SerializeField]
    private float standingHeight = 2.0f;

    [SerializeField]
    private float crouchingHeight = 1.2f;

    [SerializeField]
    private float proneHeight = 0.5f;

    private float targetHeight;
    private Vector3 coverPeekDirection;
    private bool isPeeking;

    public enum PostureState
    {
        Standing,
        Crouching,
        Prone,
        InCover
    }

    public enum CoverPeekDirection
    {
        None,
        Left,
        Right,
        Up
    }

    protected override void Awake()
    {
        base.Awake();
        InitializeFPSSystems();
    }

    private void InitializeFPSSystems()
    {
        if (coverSystem == null)
        {
            coverSystem = GetComponent<CoverSystem>();
        }

        targetHeight = standingHeight;
        currentPosture = PostureState.Standing;
        isInCover = false;
        isPeeking = false;
    }

    protected override void Update()
    {
        base.Update();
        UpdatePosture();
        UpdateCoverBehavior();
    }

    private void UpdatePosture()
    {
        // 平滑过渡到目标高度
        if (characterController != null)
        {
            float currentHeight = characterController.height;
            
            if (Mathf.Abs(currentHeight - targetHeight) > 0.01f)
            {
                characterController.height = Mathf.Lerp(
                    currentHeight,
                    targetHeight,
                    postureTransitionSpeed * Time.deltaTime
                );

                // 调整中心点以保持脚部在地面
                Vector3 newCenter = characterController.center;
                newCenter.y = characterController.height / 2f;
                characterController.center = newCenter;
            }
        }

        // 更新动画参数
        if (animator != null)
        {
            animator.SetBool("IsCrouching", currentPosture == PostureState.Crouching);
            animator.SetBool("IsProne", currentPosture == PostureState.Prone);
            animator.SetBool("IsInCover", isInCover);
        }
    }

    private void UpdateCoverBehavior()
    {
        if (!isInCover || currentCover == null)
        {
            return;
        }

        // 在掩护中的特殊行为
        UpdateCoverMovement();
        UpdatePeeking();
    }

    public void EnterCover(CoverPoint cover)
    {
        if (cover == null)
        {
            return;
        }

        currentCover = cover;
        isInCover = true;
        currentPosture = PostureState.InCover;

        // 调整到掩护高度
        targetHeight = crouchingHeight;

        // 面向掩护方向
        Vector3 coverDirection = cover.GetCoverDirection();
        RotateTowardsDirection(-coverDirection);

        // 移动到掩护位置
        Vector3 coverPosition = cover.GetCoverPosition();
        cachedTransform.position = coverPosition;

        // 更新动画
        if (animator != null)
        {
            animator.SetTrigger("EnterCover");
        }

        Debug.Log($"进入掩护: {cover.gameObject.name}");
    }

    public void ExitCover()
    {
        if (!isInCover)
        {
            return;
        }

        isInCover = false;
        currentCover = null;
        currentPosture = PostureState.Crouching;

        // 恢复到站立高度
        SetPosture(PostureState.Standing);

        // 更新动画
        if (animator != null)
        {
            animator.SetTrigger("ExitCover");
        }

        Debug.Log("离开掩护");
    }

    public void SetPosture(PostureState newPosture)
    {
        if (currentPosture == newPosture)
        {
            return;
        }

        // 检查姿势转换是否允许
        if (!CanChangePosture(newPosture))
        {
            return;
        }

        PostureState previousPosture = currentPosture;
        currentPosture = newPosture;

        // 设置目标高度
        switch (newPosture)
        {
            case PostureState.Standing:
                targetHeight = standingHeight;
                movementSettings.maxSpeed = fpsSettings.maxSpeed;
                break;

            case PostureState.Crouching:
                targetHeight = crouchingHeight;
                movementSettings.maxSpeed = fpsSettings.maxSpeed * fpsSettings.crouchSpeedMultiplier;
                break;

            case PostureState.Prone:
                targetHeight = proneHeight;
                movementSettings.maxSpeed = fpsSettings.maxSpeed * fpsSettings.proneSpeedMultiplier;
                break;

            case PostureState.InCover:
                targetHeight = crouchingHeight;
                movementSettings.maxSpeed = fpsSettings.coverMoveSpeed;
                break;
        }

        // 触发姿势变化事件
        OnPostureChanged(previousPosture, newPosture);
    }

    private bool CanChangePosture(PostureState newPosture)
    {
        // 检查是否有足够的空间改变姿势
        if (newPosture == PostureState.Standing && currentPosture == PostureState.Prone)
        {
            // 检查上方空间
            RaycastHit hit;
            if (Physics.Raycast(
                cachedTransform.position,
                Vector3.up,
                out hit,
                standingHeight - proneHeight,
                Physics.AllLayers,
                QueryTriggerInteraction.Ignore
            ))
            {
                return false; // 没有足够的空间站起来
            }
        }

        return true;
    }

    public void StartPeeking(CoverPeekDirection direction)
    {
        if (!isInCover || currentCover == null)
        {
            return;
        }

        isPeeking = true;
        
        switch (direction)
        {
            case CoverPeekDirection.Left:
                coverPeekDirection = -currentCover.transform.right;
                break;

            case CoverPeekDirection.Right:
                coverPeekDirection = currentCover.transform.right;
                break;

            case CoverPeekDirection.Up:
                coverPeekDirection = Vector3.up;
                break;

            default:
                isPeeking = false;
                return;
        }

        // 更新动画
        if (animator != null)
        {
            animator.SetBool("IsPeeking", true);
            animator.SetFloat("PeekDirection", (float)direction);
        }
    }

    public void StopPeeking()
    {
        if (!isPeeking)
        {
            return;
        }

        isPeeking = false;
        coverPeekDirection = Vector3.zero;

        // 更新动画
        if (animator != null)
        {
            animator.SetBool("IsPeeking", false);
        }
    }

    private void UpdateCoverMovement()
    {
        if (!isInCover || currentCover == null)
        {
            return;
        }

        // 沿着掩护移动
        Vector3 coverDirection = currentCover.GetCoverDirection();
        Vector3 moveAlongCover = Vector3.Cross(coverDirection, Vector3.up).normalized;

        // 限制移动范围在掩护长度内
        float maxMovement = currentCover.GetCoverLength() / 2f;
        float currentOffset = GetCoverOffset();

        if (Mathf.Abs(currentOffset) >= maxMovement)
        {
            // 到达掩护边缘
            moveDirection = Vector3.zero;
        }
        else
        {
            // 允许沿着掩护移动
            moveDirection = moveAlongCover;
        }
    }

    private void UpdatePeeking()
    {
        if (!isPeeking || currentCover == null)
        {
            return;
        }

        // 执行窥视移动
        Vector3 peekMovement = coverPeekDirection * fpsSettings.peekSpeed * Time.deltaTime;
        
        // 检查窥视是否安全
        if (IsPeekSafe(coverPeekDirection))
        {
            characterController.Move(peekMovement);
        }
        else
        {
            StopPeeking();
        }
    }

    private bool IsPeekSafe(Vector3 peekDirection)
    {
        if (currentCover == null)
        {
            return false;
        }

        // 检查窥视方向是否安全(无敌人视线)
        Vector3 peekPosition = cachedTransform.position + peekDirection * 0.5f;
        
        // 在实际项目中,这里会检查是否有敌人在这个方向
        // 简化实现:总是返回安全
        return true;
    }

    private float GetCoverOffset()
    {
        if (currentCover == null)
        {
            return 0f;
        }

        Vector3 coverToAI = cachedTransform.position - currentCover.transform.position;
        Vector3 coverDirection = currentCover.GetCoverDirection();
        Vector3 coverRight = Vector3.Cross(coverDirection, Vector3.up).normalized;

        return Vector3.Dot(coverToAI, coverRight);
    }

    public void Sprint(bool startSprinting)
    {
        if (startSprinting)
        {
            if (currentPosture == PostureState.Standing)
            {
                movementSettings.maxSpeed = fpsSettings.maxSpeed * fpsSettings.sprintSpeedMultiplier;
                
                if (animator != null)
                {
                    animator.SetBool("IsSprinting", true);
                }
            }
        }
        else
        {
            movementSettings.maxSpeed = fpsSettings.maxSpeed;
            
            if (animator != null)
            {
                animator.SetBool("IsSprinting", false);
            }
        }
    }

    public void Strafe(Vector3 direction)
    {
        // 侧向移动
        if (direction.magnitude > 0.1f)
        {
            moveDirection = direction.normalized;
            movementSettings.maxSpeed = fpsSettings.maxSpeed * fpsSettings.strafeSpeedMultiplier;
        }
    }

    public void MoveBackwards(Vector3 direction)
    {
        // 后退移动
        if (direction.magnitude > 0.1f)
        {
            moveDirection = direction.normalized;
            movementSettings.maxSpeed = fpsSettings.maxSpeed * fpsSettings.backwardsSpeedMultiplier;
        }
    }

    public bool IsInCover()
    {
        return isInCover;
    }

    public CoverPoint GetCurrentCover()
    {
        return currentCover;
    }

    public PostureState GetCurrentPosture()
    {
        return currentPosture;
    }

    public event Action<PostureState, PostureState> OnPostureChanged = delegate { };

    protected override void OnDrawGizmosSelected()
    {
        base.OnDrawGizmosSelected();

        if (!Application.isPlaying)
        {
            return;
        }

        // 绘制掩护信息
        if (isInCover && currentCover != null)
        {
            Gizmos.color = Color.blue;
            Gizmos.DrawWireSphere(currentCover.transform.position, 0.5f);
            Gizmos.DrawLine(cachedTransform.position, currentCover.transform.position);

            // 绘制掩护方向
            Vector3 coverDirection = currentCover.GetCoverDirection();
            Gizmos.DrawRay(currentCover.transform.position, coverDirection * 2f);

            // 绘制掩护范围
            float coverLength = currentCover.GetCoverLength();
            Vector3 coverRight = Vector3.Cross(coverDirection, Vector3.up).normalized;
            Vector3 coverStart = currentCover.transform.position - coverRight * coverLength / 2f;
            Vector3 coverEnd = currentCover.transform.position + coverRight * coverLength / 2f;
            
            Gizmos.DrawLine(coverStart, coverEnd);
        }

        // 绘制姿势信息
        Gizmos.color = Color.green;
        string postureText = $"姿势: {currentPosture}";
        
        #if UNITY_EDITOR
        UnityEditor.Handles.Label(
            cachedTransform.position + Vector3.up * 2.2f,
            postureText
        );
        #endif
    }
}

[System.Serializable]
public class CoverPoint : MonoBehaviour
{
    [SerializeField]
    private float coverLength = 5.0f;

    [SerializeField]
    private float coverHeight = 1.5f;

    [SerializeField]
    private CoverType coverType = CoverType.Full;

    [SerializeField]
    private Vector3 coverDirection = Vector3.forward;

    public enum CoverType
    {
        Full,
        Half,
        Low,
        Destructible
    }

    public Vector3 GetCoverPosition()
    {
        return transform.position;
    }

    public Vector3 GetCoverDirection()
    {
        return transform.TransformDirection(coverDirection).normalized;
    }

    public float GetCoverLength()
    {
        return coverLength;
    }

    public float GetCoverHeight()
    {
        return coverHeight;
    }

    public CoverType GetCoverType()
    {
        return coverType;
    }

    public bool IsOccupied()
    {
        // 检查是否已被占用
        Collider[] colliders = Physics.OverlapBox(
            transform.position,
            new Vector3(coverLength / 2f, 1f, 1f),
            transform.rotation
        );

        foreach (Collider collider in colliders)
        {
            if (collider.CompareTag("AI") && collider.gameObject != gameObject)
            {
                return true;
            }
        }

        return false;
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.blue;
        Gizmos.DrawWireCube(
            transform.position,
            new Vector3(coverLength, coverHeight, 0.5f)
        );

        // 绘制掩护方向
        Gizmos.color = Color.red;
        Vector3 direction = transform.TransformDirection(coverDirection).normalized;
        Gizmos.DrawRay(transform.position, direction * 2f);
    }
}

这个增强的运动控制器为FPS/TPS游戏提供了专门的移动能力,包括掩护系统、多种姿态(站立、蹲下、匍匐)、战术移动(冲刺、侧移、后退)以及精确的瞄准支持。在实际商业项目中,这些功能可以根据具体游戏需求进一步扩展和优化。

通过本章介绍的完整AI架构系统,开发者可以在Unity中构建出强大、灵活且高性能的游戏人工智能。这些系统不仅提供了基础的AI功能,还考虑了商业项目中的实际需求,如性能优化、调试支持、配置管理和团队协作等。无论是独立游戏还是大型商业项目,这套架构都能为AI开发提供坚实的基础。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐