NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/AI/Task/BTMoveAroundTo.cs

1 line
7.2 KiB
C#

using System;
using Gameplay;
using Framework;
using Gameplay.AI;
using UnityEngine;
using Gameplay.Unit;
using Gameplay.Level;
using Gameplay.BT.Variables;
using BehaviorDesigner.Runtime.Tasks;
using Action = BehaviorDesigner.Runtime.Tasks.Action;
public class BTMoveAroundTo : Action
{
public SharedBattleInfo SharedBattleInfo;
private GameUnit _owner;
private GameUnit _target;
private Map _map;
private EStage _stage = EStage.None;
private int _stageTargetCellIndex = -1;
private int _targetCellIndex = -1;
private int _targetAttackDistance;
private PosDirection posDirection;
private Vector2Int targetV2;
private Vector2Int ownerV2;
private uint _lastTarget;
private enum PosDirection
{
Left,
Right,
}
private enum EStage
{
None,
Stage1,
Stage2,
MoveToTarget
}
public override void OnStart()
{
var level = LevelManager.Instance.CurrentLevel;
_map = level?.Map;
UpdateEnemyData();
posDirection = targetV2.y > ownerV2.y ? PosDirection.Left : PosDirection.Right;
}
private void UpdateEnemyData()
{
_owner = GameUnitManager.instance.infightUnits.Search(SharedBattleInfo.Value.ownerId);
_target = GameUnitManager.instance.infightUnits.Search(SharedBattleInfo.Value.theChosenOneId);
_targetAttackDistance = _target.fightData.attackDistance;
_stage = EStage.None;
_stageTargetCellIndex = -1;
_targetCellIndex = -1;
if (_map != null && _target != null && _owner != null)
{
targetV2 = _map.TGSCellIndex2BlockPosition(_target.transData.cellIndex);
ownerV2 = _map.TGSCellIndex2BlockPosition(_owner.transData.cellIndex);
}
}
public override TaskStatus OnUpdate()
{
if (SharedBattleInfo.Value.theChosenOneId != Constants.INVALID_UINT_ID)
{
if (_owner?.controlData.targetEnemy == null && _stage == EStage.MoveToTarget)
{
var enemy = GameUnitManager.instance.infightUnits.Search(SharedBattleInfo.Value.theChosenOneId);
if (enemy != null && !enemy.statusData.isDead)
{
_target = enemy;
_targetCellIndex = enemy.transData.cellIndex;
_stage = EStage.None;
}
else
{
SharedBattleInfo.Value.theChosenOneId = Constants.INVALID_UINT_ID;
}
}
if (HasTargetMoved())
{
RememberTarget();
switch (_stage)
{
case EStage.None:
_stageTargetCellIndex = GetStage1TargetCell();
_stage = EStage.Stage1;
AIUtils.CheckAndMove(_owner, _stageTargetCellIndex);
break;
case EStage.Stage1:
_stageTargetCellIndex = GetStage1TargetCell();
AIUtils.CheckAndMove(_owner, _stageTargetCellIndex);
break;
case EStage.Stage2:
_stageTargetCellIndex = GetStage2TargetCell();
AIUtils.CheckAndMove(_owner, _stageTargetCellIndex);
break;
case EStage.MoveToTarget:
break;
default:
throw new ArgumentOutOfRangeException();
}
return TaskStatus.Running;
}
if (HasStageArrived() && !AIUtils.IsNeedStop(_owner))
{
switch (_stage)
{
case EStage.Stage1:
_stageTargetCellIndex = GetStage2TargetCell();
_stage = EStage.Stage2;
AIUtils.CheckAndMove(_owner, _stageTargetCellIndex);
break;
case EStage.Stage2:
_stageTargetCellIndex = _target.transData.cellIndex;
_stage = EStage.MoveToTarget;
AIUtils.CheckAndMove(_owner, _stageTargetCellIndex, false);
break;
}
}
return TaskStatus.Running;
}
return TaskStatus.Failure;
}
private int GetStage1TargetCell()
{
// 竖轴移动 默认逆时针
var curDistance = MapUtils.Distance(_map, targetV2, ownerV2);
var targetCellIndex = _owner.transData.cellIndex;
// 在攻击范围内 先移出攻击范围
if (curDistance <= _targetAttackDistance)
{
// 方位在右边
// 顺时针 +x 逆时针-x
if (posDirection == PosDirection.Right) //(ownerV2.y >= targetV2.y)
{
var targetX = targetV2.x + _targetAttackDistance + 1;
while (targetX >= _map.MapData.Height)
{
targetX--;
}
var newPos = new Vector2Int(targetX, ownerV2.y);
var newIndex = _map.BlockPosition2TGSCellIndex(newPos);
targetCellIndex = AIUtils.CheckAndGetCanPassOneCycleCellIndex(_map, _owner, newIndex);
}
// 方位在左边
else
{
var targetX = targetV2.x - _targetAttackDistance - 1;
while (targetX < 0)
{
targetX++;
}
var newPos = new Vector2Int(targetX, ownerV2.y);
var newIndex = _map.BlockPosition2TGSCellIndex(newPos);
targetCellIndex = AIUtils.CheckAndGetCanPassOneCycleCellIndex(_map, _owner, newIndex);
}
}
// DebugUtil.LogError("阶段一找到的位置是:{0}", targetCellIndex);
return targetCellIndex;
}
// TODO 多余走了好几步 能攻击就停下
private int GetStage2TargetCell()
{
// 横轴移动 改变y值
targetV2 = _map.TGSCellIndex2BlockPosition(_target.transData.cellIndex);
ownerV2 = _map.TGSCellIndex2BlockPosition(_owner.transData.cellIndex);
var targetY = ownerV2.y;
if (posDirection == PosDirection.Right)
{
while (targetV2.y - 1 <= targetY)
{
targetY--;
}
}
else
{
while (targetV2.y + 1 >= targetY)
{
targetY++;
}
}
var newPos = new Vector2Int(ownerV2.x, targetY);
var newIndex = _map.BlockPosition2TGSCellIndex(newPos);
var targetCellIndex = AIUtils.CheckAndGetCanPassOneCycleCellIndex(_map, _owner, newIndex);
// DebugUtil.LogError("阶段二找到的位置是:{0}", targetCellIndex);
return targetCellIndex;
}
private bool HasTargetMoved()
{
return _targetCellIndex != _target.transData.cellIndex;
}
private void RememberTarget()
{
_targetCellIndex = _target.transData.cellIndex;
}
private bool HasStageArrived()
{
return _stageTargetCellIndex == _owner?.transData.cellIndex;
}
}