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

1 line
6.4 KiB
C#

using System;
using BehaviorDesigner.Runtime.Tasks;
using Gameplay;
using Gameplay.AI;
using Gameplay.BT.Variables;
using Gameplay.Character;
using Gameplay.Level;
using Gameplay.Unit;
using UnityEngine;
using Action = BehaviorDesigner.Runtime.Tasks.Action;
// 包抄移动
public class BTMoveAroundTo : Action
{
public SharedBattleInfo SharedBattleInfo;
public EMoveDirection MoveDirection = EMoveDirection.Clockwise;
private Character _owner;
private Character _target;
private Map _map;
public enum EMoveDirection
{
Clockwise,
AntiClockwise,
}
// target owner
// |
// | 1
// | 3 |
// | 2 |
// --------------------
//
private enum EStage
{
None,
Stage1,
Stage2,
MoveToTarget // 3
}
private EStage _stage = EStage.None;
private int _stageTargetCellIndex = -1;
private int _targetCellIndex = -1;
private Vector3 _baseDirection = Vector3.zero;
public override void OnStart()
{
var level = LevelManager.Instance.CurrentLevel;
_owner = GameUnitManager.instance.infightUnits.Search(SharedBattleInfo.Value.ownerId) as Character;
_target = GameUnitManager.instance.infightUnits.Search(SharedBattleInfo.Value.theChosenOneId) as Character;
_map = level?.Map;
_stage = EStage.None;
_stageTargetCellIndex = -1;
_targetCellIndex = -1;
if (_owner != null)
{
DebugUtil.Log("BT move to start, owner: {0}",_owner?.GetID());
}
if (_map != null && _target != null && _owner != null)
{
var targetPosition = _map.TGSCellIndex2WorldPosition(_target.transData.cellIndex);
var selfPosition = _map.TGSCellIndex2WorldPosition(_owner.transData.cellIndex);
_baseDirection = targetPosition - selfPosition;
}
}
public override TaskStatus OnUpdate()
{
if (_target == null)
{
return TaskStatus.Failure;
}
var attackDistance = _owner.fightData.attackDistance;
var selfAsideDistance = attackDistance / 2;
var targetAsideDistance = attackDistance;
if (HasTargetMoved())
{
RememberTarget();
switch (_stage)
{
case EStage.None:
_stageTargetCellIndex = GetStage1TargetCell(selfAsideDistance);
_stage = EStage.Stage1;
_owner?.MoveTo(_stageTargetCellIndex, true);
break;
case EStage.Stage1:
_stageTargetCellIndex = GetStage1TargetCell(selfAsideDistance);
_owner?.MoveTo(_stageTargetCellIndex, true);
break;
case EStage.Stage2:
_stageTargetCellIndex = GetStage2TargetCell(targetAsideDistance);
_owner?.MoveTo(_stageTargetCellIndex, true);
break;
case EStage.MoveToTarget:
break;
default:
throw new ArgumentOutOfRangeException();
}
return TaskStatus.Running;
}
else if (HasStageArrived() && !AIUtils.IsNeedStop(_owner))
{
switch (_stage)
{
case EStage.None:
DebugUtil.LogError(" BTMoveAroundTo OnUpdate error, stage is none, owner: {0}",_owner?.GetID());
break;
case EStage.Stage1:
_stageTargetCellIndex = GetStage2TargetCell(targetAsideDistance);
_stage = EStage.Stage2;
_owner?.MoveTo(_stageTargetCellIndex, true);
return TaskStatus.Running;
case EStage.Stage2:
_stage = EStage.MoveToTarget;
_owner?.MoveTo(_target);
return TaskStatus.Success;
}
}
return TaskStatus.Running;
}
private int GetStage1TargetCell(int distance)
{
var targetPosition = _map.TGSCellIndex2WorldPosition(_target.transData.cellIndex);
var supposedStartPosition = targetPosition - _baseDirection;
Vector3 move;
if (MoveDirection == EMoveDirection.Clockwise)
{
move = new Vector3(_baseDirection.z, 0, -_baseDirection.x);
}
else
{
move = new Vector3(-_baseDirection.z, 0, _baseDirection.x);
}
while (distance-- > 0)
{
var supposedMoveTo = supposedStartPosition + move.normalized * distance;
if (_map.WorldPosition2TGSCellIndex(supposedMoveTo, out var cellIndex) &&
_map.GetRuntimeBlockProperty(cellIndex, out var data) &&
MapUtils.CanPass(_owner.commonData.crossLevel, data))
{
return cellIndex;
}
}
return _owner.transData.cellIndex;
}
private int GetStage2TargetCell(int distance)
{
var targetPosition = _map.TGSCellIndex2WorldPosition(_target.transData.cellIndex);
Vector3 move;
if (MoveDirection == EMoveDirection.Clockwise)
{
move = new Vector3(_baseDirection.z, 0, -_baseDirection.x);
}
else
{
move = new Vector3(-_baseDirection.z, 0, _baseDirection.x);
}
while (distance-- > 0)
{
var supposedMoveTo = targetPosition + move.normalized * distance;
if (_map.WorldPosition2TGSCellIndex(supposedMoveTo, out var cellIndex) &&
_map.GetRuntimeBlockProperty(cellIndex, out var data) &&
MapUtils.CanPass(_owner.commonData.crossLevel, data))
{
return cellIndex;
}
}
return _target.transData.cellIndex;
}
private bool HasTargetMoved()
{
return _targetCellIndex != _target.transData.cellIndex;
}
private void RememberTarget()
{
_targetCellIndex = _target.transData.cellIndex;
}
private bool HasStageArrived()
{
return _stageTargetCellIndex == _owner?.transData.cellIndex;
}
}