207 lines
7.4 KiB
C#
207 lines
7.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,
|
|
Pausing,
|
|
Finished,
|
|
}
|
|
|
|
public enum AIActionType
|
|
{
|
|
Grid,
|
|
City,
|
|
Unit,
|
|
Tech,
|
|
Max,
|
|
}
|
|
|
|
|
|
public class AILogic
|
|
{
|
|
public AILogicState AILogicState;
|
|
|
|
private float _targetTime;
|
|
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>();
|
|
_data = new AICalculatorData();
|
|
var data = _btOwner.blackboard.GetVariable<AICalculatorData>("Data");
|
|
data.value = _data;
|
|
}
|
|
|
|
// 开始 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.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.IsExcute || _data.IsFinish) break;
|
|
if (index > 100)
|
|
{
|
|
Debug.LogWarning($"死循环了");
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (_data.IsExcute)
|
|
{
|
|
AILogicState = AILogicState.Pausing;
|
|
if (!_data.IsInSight) _targetTime = Time.time + 0.04f;
|
|
else _targetTime = Time.time + _data.Time;
|
|
MainEditor.Instance.OnActionExcuted();
|
|
}
|
|
else AILogicState = AILogicState.Finished;
|
|
}
|
|
|
|
// 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}");
|
|
}
|
|
}
|
|
}
|
|
} |