using BehaviorDesigner.Runtime.Tasks; using Cysharp.Threading.Tasks; using Gameplay.BT.Variables; using Gameplay.Unit; using Gameplay.AI; using Framework; namespace Code.Scripts.Gameplay.BT.Task { public class BTMoveTo : Action { public SharedBattleInfo SharedBattleInfo; private GameUnit _owner; private GameUnit _target; private uint _lastTarget; private bool _needAvoidCheck; private float _avoidCheckTimer; private float _currentAvoidDelay; private const float MIN_AVOID_DELAY = 0f; private const float MAX_AVOID_DELAY = 1f; public override void OnStart() { _owner = GameUnitManager.instance.infightUnits.Search(SharedBattleInfo.Value.ownerID); } public override TaskStatus OnUpdate() { if (_owner == null) return TaskStatus.Failure; // 避开其他AI AvoidOtherUnit(); if (SharedBattleInfo.Value.targetID != Constants.INVALID_UINT_ID) { if (_lastTarget != SharedBattleInfo.Value.targetID && !AIUtils.IsNeedStop(_owner)) { _lastTarget = SharedBattleInfo.Value.targetID; if (GameUnitManager.instance.infightUnits.Contains(SharedBattleInfo.Value.targetID)) { var target = GameUnitManager.instance.infightUnits.Search(SharedBattleInfo.Value.targetID); if (target != null) { AIUtils.CheckAndMove(_owner, target.transData.cellIndex); } } } if (_owner?.controlData.targetEnemy == null) { _lastTarget = Constants.INVALID_UINT_ID; } return TaskStatus.Running; } return TaskStatus.Failure; } private void AvoidOtherUnit() { if (AIUtils.IsNeedStop(_owner)) return; if (_owner.statusData.isMoveing && !_needAvoidCheck) { _needAvoidCheck = true; _currentAvoidDelay = UnityEngine.Random.Range(MIN_AVOID_DELAY, MAX_AVOID_DELAY); _avoidCheckTimer = 0f; } if (_needAvoidCheck && !_owner.statusData.isMoveing && _owner.controlData.targetCellIndex == -1) { _avoidCheckTimer += UnityEngine.Time.deltaTime; if(_avoidCheckTimer >= _currentAvoidDelay) { _needAvoidCheck = false; AIUtils.CheckAreaIsOtherEnemyUnit(_owner, SharedBattleInfo.Value.targetID); } } } } }