231 lines
8.4 KiB
C#

/*
* @Author: 白哉
* @Description: AI 逻辑总模块
* @Date: 2025年04月01日 星期二 14:04:01
* @Modify:
*/
using System.Collections.Generic;
using System.Diagnostics;
using Logic.Action;
using NodeCanvas.BehaviourTrees;
using NodeCanvas.Framework;
using UnityEngine;
using RuntimeData;
using Debug = UnityEngine.Debug;
namespace Logic.AI
{
public enum AILogicState
{
Prepare,
Playing,
PrePlay,
Pausing,
Finished,
}
public enum AIActionType
{
Grid,
City,
Unit,
Tech,
Max,
}
public class AILogic
{
public AILogicState AILogicState;
private float _targetTime;
private float _excuteTime;
private AIActionScoreCalculator _scoreCalculator;
private AIActionGenerator _generator;
private List<AIActionBase> RecordActions;
private AIActionBase MaxScoreAction;
private MapData _mapData;
private PlayerData _playerData;
private AIConfigAsset _cfg;
private GameObject _logicObject;
private BehaviourTreeOwner _btOwner;
private AICalculatorData _data;
public AILogic()
{
AILogicState = AILogicState.Prepare;
RecordActions = new List<AIActionBase>();
_scoreCalculator = new AIActionScoreCalculator();
_cfg = Resources.Load<AIConfigAsset>("DataAssets/AIConfig");
_generator = new AIActionGenerator();
_logicObject = GameObject.Find("AIBT");
_btOwner = _logicObject.GetComponent<BehaviourTreeOwner>();
var data = _btOwner.blackboard.GetVariable<AICalculatorData>("Data");
if (data.value == null)
{
_data = new AICalculatorData();
data.value = _data;
}
else _data = data.value;
}
// 开始 AI 逻辑
public void StartAILogic(MapData mapData, PlayerData playerData)
{
AILogicState = AILogicState.Playing;
_mapData = mapData;
_playerData = playerData;
_generator.Init(_mapData, _playerData);
_data.Refresh(mapData, playerData);
_btOwner.StopBehaviour();
_btOwner.StartBehaviour();
MainEditor.Instance.Data = _data;
}
// 结束 AI 逻辑
public void FinishAILogic()
{
RecordActions.Clear();
}
// 更新 AI 逻辑
public void Update()
{
if (AILogicState == AILogicState.Finished || AILogicState == AILogicState.Prepare) return;
if (AILogicState == AILogicState.PrePlay)
{
if (Time.time < _excuteTime) return;
if (_data.MaxAiAction == null)
{
AILogicState = AILogicState.Playing;
return;
}
_data.MaxAiAction.ActionLogic.Execute(_data.MaxAiAction.Param);
var animTime = _data.MaxAiAction.ActionLogic.GetAnimTime(_data.MaxAiAction.Param);
if (!_data.MaxAiAction.IsInSight) _targetTime = Time.time + 0.04f;
else _targetTime = Time.time + animTime;
MainEditor.Instance.OnActionExcuted();
_data.MaxAiAction = null;
AILogicState = AILogicState.Pausing;
}
if (AILogicState == AILogicState.Pausing)
{
if (Time.time > _targetTime) AILogicState = AILogicState.Playing;
}
if (AILogicState == AILogicState.Playing)
{
Stopwatch sw = new Stopwatch();
var index = 0;
while (true)
{
if (MainEditor.Instance.IsEditor && !MainEditor.Instance.IsGo) return;
index++;
_data.ClearCache();
sw.Start();
_btOwner.UpdateBehaviour();
if (sw.Elapsed.TotalMilliseconds > 20)
Debug.Log($"{_generator.ActionType} 耗时:{sw.Elapsed.TotalMilliseconds} ms");
MainEditor.Instance.IsGo = false;
if (_data.MaxAiAction != null || _data.IsFinish) break;
if (index > 100)
{
Debug.LogWarning($"死循环了");
break;
}
}
if (_data.MaxAiAction == null || index > 100) AILogicState = AILogicState.Finished;
else
{
if (_data.MaxAiAction.IsInSight)
_excuteTime = Time.time + Table.Instance.AnimDataAssets.AIBeforeAnimWaitTime;
else _excuteTime = Time.time;
AILogicState = AILogicState.PrePlay;
}
}
// if (AILogicState == AILogicState.Playing)
// {
// Stopwatch sw = new Stopwatch();
// sw.Start();
// RecordActions.Clear();
// _generator.GeneratorOneStepActions(_mapData, _playerData, RecordActions);
// CalculateMaxScoreAction();
// if (sw.Elapsed.TotalMilliseconds > 20) Debug.Log($"{_generator.ActionType} 耗时:{sw.Elapsed.TotalMilliseconds} ms");
//
// // AI 执行已结束
// if (!GetAILogicPermission())
// {
// AILogicState = AILogicState.Finished;
// }
// // 无行动可执行
// else if(MaxScoreAction == null)
// {
// AILogicState = AILogicState.Finished;
// FinishAILogic();
// }
// // 执行行动
// else
// {
// MaxScoreAction.Param.MapData = _mapData;
// MaxScoreAction.Param.RefreshParams();
//
// if (MaxScoreAction.ActionLogic is UnitAttackAction)
// {
// _mapData.GetGridDataByUnitId(MaxScoreAction.Param.UnitData.Id, out var grid);
// _mapData.GetGridDataByUnitId(MaxScoreAction.Param.TargetUnitData.Id, out var target);
// Debug.Log($"小兵攻击 {MaxScoreAction.Param.UnitData.Id}, " +
// $"位置{grid.Pos.X}, {grid.Pos.Y}, " +
// $"目标 {MaxScoreAction.Param.TargetUnitData.Id}, " +
// $"目标位置{target.Pos.X}, {target.Pos.Y}");
// }
//
// if (MaxScoreAction.ActionLogic is UnitMoveAction)
// {
// _mapData.GetGridDataByUnitId(MaxScoreAction.Param.UnitData.Id, out var grid);
// Debug.Log($"小兵移动 {MaxScoreAction.Param.UnitData.Id}, " +
// $"位置{grid.Pos.X}, {grid.Pos.Y}, " +
// $"目标 {MaxScoreAction.Param.GridData.Pos.X}, {MaxScoreAction.Param.GridData.Pos.Y}");
// }
//
// MaxScoreAction.CheckIsActionInPlayerSight();
// MaxScoreAction.ActionLogic.Execute(MaxScoreAction.Param);
// AILogicState = AILogicState.Pausing;
// _recordTime = Time.time;
// if (!MaxScoreAction.IsInSight) _recordTime -= DebugCenter.Instance.DebugAIActionTime - 0.04f;
// MaxScoreAction = null;
// }
// }
}
// 获取 AI 执行权限
private bool GetAILogicPermission()
{
return true;
}
// 选取最高得分行动
private void CalculateMaxScoreAction()
{
if (RecordActions.Count == 0) return;
MaxScoreAction = _scoreCalculator.CalculateMaxScoreAIAction(_mapData, _playerData, RecordActions, _cfg);
if (MaxScoreAction != null && MaxScoreAction.ActionLogic.ActionId != null &&
MaxScoreAction.ActionLogic.ActionId.ActionType == CommonActionType.LearnTech)
{
Debug.LogWarning($"学习科技了!!!!! {MaxScoreAction.ActionLogic.ActionId.TechType}");
}
}
}
}