Enemy1行动路径优化

This commit is contained in:
ZYT
2025-07-23 13:48:49 +08:00
parent 4a65dc27fd
commit 9fe3d1119e
5 changed files with 586 additions and 510 deletions

View File

@@ -8,35 +8,35 @@ using UnityEngine;
using UnityEngine.AI;
public class CheckEnemyState : Conditional
public class CheckEnemyState : Conditional
{
public SharedInt curEnemyState;
public override TaskStatus OnUpdate()
{
public SharedInt curEnemyState;
public override TaskStatus OnUpdate()
{
if (transform.GetComponent<Enemy>().enemyState == (EnemyState)curEnemyState.Value)
{
return TaskStatus.Success;
}
return TaskStatus.Failure;
}
}
public class SetEnemyState : Action
{
public SharedInt curEnemyState;
public override TaskStatus OnUpdate()
{
var enemy= transform.GetComponent<Enemy>();
if (enemy != null)
{
enemy.enemyState = (EnemyState)curEnemyState.Value;
return TaskStatus.Success;
}
return base.OnUpdate();
}
}
public class MoveToPlayerNearby3 : Action
if (transform.GetComponent<Enemy>().enemyState == (EnemyState)curEnemyState.Value)
{
return TaskStatus.Success;
}
return TaskStatus.Failure;
}
}
public class SetEnemyState : Action
{
public SharedInt curEnemyState;
public override TaskStatus OnUpdate()
{
var enemy = transform.GetComponent<Enemy>();
if (enemy != null)
{
enemy.enemyState = (EnemyState)curEnemyState.Value;
return TaskStatus.Success;
}
return base.OnUpdate();
}
}
public class MoveToPlayerNearby3 : Action
{
public SharedGameObject self;
public SharedFloat minRange = new SharedFloat { Value = 3f };
@@ -52,7 +52,7 @@ using UnityEngine.AI;
{
base.OnStart();
agent = GetComponent<NavMeshAgent>();
// 随机优先级,降低 agent 之间争路
agent.avoidancePriority = Random.Range(0, 100);
agent.obstacleAvoidanceType = ObstacleAvoidanceType.HighQualityObstacleAvoidance;
@@ -75,7 +75,7 @@ using UnityEngine.AI;
{
// 从 Manager 或其他地方拿到所有敌人的引用列表
List<Enemy> allEnemies = GameManager.Ins.curEnemyList;
Vector3 bestPos = Vector3.zero;
float bestScore = -1f;
@@ -132,7 +132,7 @@ using UnityEngine.AI;
// 最后随机返回一个点
return player.position + Random.insideUnitSphere * (minRange.Value + 0.5f);
}
// 调试画出可行区域
void OnDrawGizmosSelected()
{
@@ -144,433 +144,524 @@ using UnityEngine.AI;
public class MoveToPlayerFront : Action
{
public SharedFloat minDistance = new SharedFloat { Value = 3f };
public SharedFloat maxDistance = new SharedFloat { Value = 5f };
public SharedFloat minAngle = new SharedFloat { Value = 30f };
public SharedFloat maxAngle = new SharedFloat { Value = 40f };
// 添加静态字典记录每个怪物的移动状态
private static Dictionary<GameObject, bool> hasMoved = new Dictionary<GameObject, bool>();
public SharedFloat minDistance = 3f; // 最小距离
public SharedFloat maxDistance = 8f; // 最大距离
public SharedFloat minAngle = 30f; // 最小角度(度)
public SharedFloat maxAngle = 40f; // 最大角度(度)
public SharedFloat attackRange = 10f; // 攻击范围
public SharedFloat attackInterval = 1f; // 攻击间隔(秒)
//分散参数
public SharedFloat minSeparation = 2.5f;//最小间距
public int maxPlacementAttempts = 15;//最大尝试次数
private NavMeshAgent agent;
private bool hasReachedPosition;
private Vector3 finalPosition; // 存储最终位置
private Transform playerTransform;
private bool hasReachedDestination;
private float lastAttackTime;
private Enemy1 enemyComponent;
private Vector3 targetPosition;
// 添加静态字典记录每个敌人的移动状态
private static Dictionary<int, bool> hasMovedDict = new Dictionary<int, bool>();
private int instanceID;
public override void OnAwake()
{
instanceID = gameObject.GetInstanceID();
}
//静态列表跟踪所有小兵位置
private static List<Vector3> occupiedPositions = new List<Vector3>();
public override void OnStart()
{
// 检查是否已经移动过
if (hasMovedDict.ContainsKey(instanceID) && hasMovedDict[instanceID])
{
hasReachedPosition = true;
return;
}
agent = GetComponent<NavMeshAgent>();
agent.autoBraking = true;
playerTransform = GameManager.Ins.player.transform;
enemyComponent = GetComponent<Enemy1>();
agent.stoppingDistance = 0.1f;
agent.autoBraking = true;
// 计算玩家正前方扇形区域内的随机位置
finalPosition = CalculateFrontPosition();
// 计算分散位置
targetPosition = CalculateFrontPosition();
agent.SetDestination(targetPosition);
hasReachedDestination = false;
if (agent.isActiveAndEnabled)
{
agent.SetDestination(finalPosition);
hasReachedPosition = false;
}
//添加到已占用位置列表
occupiedPositions.Add(targetPosition);
//初始化攻击计时器
lastAttackTime = Time.time;
}
public override void OnEnd()
{
//从占用列表中移除
occupiedPositions.Remove(targetPosition);
}
public override TaskStatus OnUpdate()
{
// 如果已经移动过,直接返回成功
if (hasMovedDict.ContainsKey(instanceID) && hasMovedDict[instanceID])
// 1. 如果还没到达目标位置,继续移动
if (!hasReachedDestination)
{
return TaskStatus.Success;
}
if (hasReachedPosition)
{
//标记为已移动
hasMovedDict[instanceID] = true;
return TaskStatus.Success;
}
// 检查是否到达目标位置
if (!agent.pathPending && agent.remainingDistance <= agent.stoppingDistance)
{
// 完全停止导航系统
agent.isStopped = true;
agent.ResetPath();
agent.enabled = false; // 禁用导航组件
// 固定位置
transform.position = finalPosition;
// 添加物理约束(如果有刚体)
Rigidbody rb = GetComponent<Rigidbody>();
if (rb != null)
if (!agent.pathPending && agent.remainingDistance <= agent.stoppingDistance)
{
rb.isKinematic = true;
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
// 到达后停止移动并保持原位
agent.isStopped = true;
hasReachedDestination = true;
}
else
{
return TaskStatus.Running;
}
// 标记为已移动
hasMoved[gameObject] = true;
hasReachedPosition = true;
return TaskStatus.Success;
}
// 2. 持续面向玩家
FacePlayer();
// 3. 在攻击范围内且冷却结束,执行攻击
if (CanAttackPlayer())
{
AttackPlayer();
}
// 4. 保持在原位执行攻击
return TaskStatus.Running;
}
private Vector3 CalculateFrontPosition()
{
Transform player = GameManager.Ins.player.transform;
Vector3 playerPos = player.position;
Vector3 playerForward = player.forward;
int attempts = 0;
Vector3 candidatePosition;
bool positionValid;
// 随机角度 (30-40度之间随机左右侧)
float randomAngle = Random.Range(minAngle.Value, maxAngle.Value) *
(Random.value > 0.5f ? 1f : -1f);
do
{
// 1. 生成候选位置
candidatePosition = CalculateRandomFrontPosition();
// 随机距离
// 2. 检查位置是否有效
positionValid = IsPositionValid(candidatePosition);
// 3. 增加尝试计数
attempts++;
} while (!positionValid && attempts < maxPlacementAttempts);
return candidatePosition;
}
private Vector3 CalculateRandomFrontPosition()
{
//获取玩家前方向
Vector3 playerForward = playerTransform.forward;
playerForward.y = 0;
playerForward.Normalize();
//随机角度30-40°之间随机左右
float randomAngle = Random.Range(minAngle.Value, maxAngle.Value);
randomAngle *= (Random.value > 0.5f) ? 1 : -1;//随机左右方向
//随机距离
float randomDistance = Random.Range(minDistance.Value, maxDistance.Value);
// 计算方向向量 (玩家前方旋转随机角度)
Quaternion rotation = Quaternion.Euler(0f, randomAngle, 0f);
//计算方向向量
Quaternion rotation = Quaternion.Euler(0, randomAngle, 0);
Vector3 direction = rotation * playerForward;
// 计算目标位置
Vector3 targetPos = playerPos + direction * randomDistance;
//计算目标位置
Vector3 targetPosition = playerTransform.position + direction * randomDistance;
// 确保位置在NavMesh
if (NavMesh.SamplePosition(targetPos, out NavMeshHit hit, 5f, NavMesh.AllAreas)) // 增加采样范围
//NavMesh采样
if(NavMesh.SamplePosition(targetPosition,out NavMeshHit hit, 2f, NavMesh.AllAreas))
{
// 确保不会出现在半空中
if (Mathf.Abs(hit.position.y - playerPos.y) > 2f)
{
// 如果高度差太大,调整到玩家高度
return new Vector3(hit.position.x, playerPos.y, hit.position.z);
}
return hit.position;
}
// 如果采样失败,使用玩家位置(确保不会出现在半空中)
return playerPos + Vector3.up * 0.1f; // 稍微高于地面
return playerTransform.position + playerForward * minDistance.Value;
}
// 当敌人被销毁时清理记录
public override void OnEnd()
private bool IsPositionValid(Vector3 position)
{
if (hasMovedDict.ContainsKey(instanceID))
//检查是否与其他小怪距离太近
foreach(Vector3 occupiedPos in occupiedPositions)
{
hasMovedDict.Remove(instanceID);
if (Vector3.Distance(position, occupiedPos) < minSeparation.Value)
{
return false;
}
}
}
}
public class SetAttackState : Action
{
public SharedBool attackState;
// 添加静态字典记录每个敌人的攻击状态
private static Dictionary<int, bool> attackStateSet = new Dictionary<int, bool>();
private int instanceID;
public override void OnAwake()
{
instanceID = gameObject.GetInstanceID();
//检查与玩家的距离
float distanceToPlayer = Vector3.Distance(position, playerTransform.position);
if (distanceToPlayer < minDistance.Value || distanceToPlayer > maxDistance.Value)
{
return false;
}
//检查NavMesh是否可以行走
if(!NavMesh.SamplePosition(position,out NavMeshHit hit, 0.5f, NavMesh.AllAreas))
{
return false;
}
return true;
}
public override TaskStatus OnUpdate()
private void FacePlayer()
{
// 如果已经设置过攻击状态,直接返回成功
if (attackStateSet.ContainsKey(instanceID) && attackStateSet[instanceID])
//平滑转向玩家
Vector3 direction = (playerTransform.position - transform.position).normalized;
direction.y = 0;
if (direction != Vector3.zero)
{
return TaskStatus.Success;
Quaternion targetRotation = Quaternion.LookRotation(direction);
transform.rotation = Quaternion.Slerp(
transform.rotation,
targetRotation,
Time.deltaTime * 5f
);
}
Enemy1 enemy = GetComponent<Enemy1>();
if (enemy != null)
{
enemy.SetAttackState(attackState.Value);
// 标记为已设置
attackStateSet[instanceID] = true;
return TaskStatus.Success;
}
return TaskStatus.Failure;
}
// 当敌人被销毁时清理记录
public override void OnEnd()
private bool CanAttackPlayer()
{
if (attackStateSet.ContainsKey(instanceID))
// 1. 检查距离
float distance = Vector3.Distance(transform.position, playerTransform.position);
if (distance > attackRange.Value) return false;
// 2. 检查攻击冷却
if (Time.time - lastAttackTime < attackInterval.Value) return false;
//// 3. 检查视线(可选)
//RaycastHit hit;
//if (Physics.Raycast(transform.position, playerTransform.position - transform.position, out hit, attackRange.Value))
//{
// return hit.transform == playerTransform;
//}
return true; ;
}
private void AttackPlayer()
{
if (enemyComponent != null)
{
attackStateSet.Remove(instanceID);
enemyComponent.Attack();
lastAttackTime = Time.time;
}
}
// 调试可视化
private void OnDrawGizmosSelected()
{
if (!Application.isPlaying || playerTransform == null) return;
Gizmos.color = Color.cyan;
Gizmos.DrawSphere(agent.destination, 0.5f);
// 绘制扇形区域
DrawAngleSector(minAngle.Value, maxAngle.Value, minDistance.Value, maxDistance.Value);
}
private void DrawAngleSector(float minDeg, float maxDeg, float minDist, float maxDist)
{
Gizmos.color = new Color(1, 0.5f, 0, 0.3f);
// 绘制左右扇形
DrawSingleSector(minDeg, maxDeg, minDist, maxDist);
DrawSingleSector(-minDeg, -maxDeg, minDist, maxDist);
}
private void DrawSingleSector(float startDeg, float endDeg, float minDist, float maxDist)
{
Vector3 playerPos = playerTransform.position;
Vector3 baseDir = playerTransform.forward;
int segments = 10;
float angleStep = (endDeg - startDeg) / segments;
// 绘制外弧
for (int i = 0; i <= segments; i++)
{
float angle = startDeg + i * angleStep;
Quaternion rot = Quaternion.Euler(0, angle, 0);
Vector3 dir = rot * baseDir;
Vector3 point = playerPos + dir * maxDist;
if (i > 0)
{
float prevAngle = startDeg + (i - 1) * angleStep;
Quaternion prevRot = Quaternion.Euler(0, prevAngle, 0);
Vector3 prevDir = prevRot * baseDir;
Vector3 prevPoint = playerPos + prevDir * maxDist;
Gizmos.DrawLine(prevPoint, point);
}
}
// 绘制内弧
for (int i = 0; i <= segments; i++)
{
float angle = startDeg + i * angleStep;
Quaternion rot = Quaternion.Euler(0, angle, 0);
Vector3 dir = rot * baseDir;
Vector3 point = playerPos + dir * minDist;
if (i > 0)
{
float prevAngle = startDeg + (i - 1) * angleStep;
Quaternion prevRot = Quaternion.Euler(0, prevAngle, 0);
Vector3 prevDir = prevRot * baseDir;
Vector3 prevPoint = playerPos + prevDir * minDist;
Gizmos.DrawLine(prevPoint, point);
}
}
// 绘制连接线
Vector3 startMin = playerPos + Quaternion.Euler(0, startDeg, 0) * baseDir * minDist;
Vector3 startMax = playerPos + Quaternion.Euler(0, startDeg, 0) * baseDir * maxDist;
Vector3 endMin = playerPos + Quaternion.Euler(0, endDeg, 0) * baseDir * minDist;
Vector3 endMax = playerPos + Quaternion.Euler(0, endDeg, 0) * baseDir * maxDist;
Gizmos.DrawLine(startMin, startMax);
Gizmos.DrawLine(endMin, endMax);
}
}
/// <summary>
/// 检测boss是否到阶段血量
/// </summary>
public class CheckEnemyHp : Conditional
{
public SharedFloat hpIndex;
public override TaskStatus OnUpdate()
{
var curHpIndex = transform.GetComponent<Enemy>().health/transform.GetComponent<Enemy>().maxHealth;
if (curHpIndex <= hpIndex.Value)
{
return TaskStatus.Success;
}
return TaskStatus.Failure;
}
}
public class UserSkill : Action
{
public Enemy EnemyObj;
public SharedFloat hpIndex;
public override void OnStart()
{
base.OnStart();
EnemyObj = transform.GetComponent<Enemy>();
}
public override TaskStatus OnUpdate()
{
if (EnemyObj == null)
return TaskStatus.Failure;
var curHpIndex = EnemyObj.health/EnemyObj.maxHealth;
if (curHpIndex <= hpIndex.Value)
{
EnemyObj.userSillIng = false;
}
var isUserIng = EnemyObj.userSillIng;
if (isUserIng) return TaskStatus.Running;
return TaskStatus.Success;
}
}
public class BossIsUserSkill : Conditional
{
public override TaskStatus OnUpdate()
{
Enemy curEnemy = GetComponent<Enemy>();
if(curEnemy.userSillIng)
return TaskStatus.Success;
return TaskStatus.Failure;
}
}
public class BossIsAttackState : Conditional
{
public override TaskStatus OnUpdate()
{
Enemy curEnemy = GetComponent<Enemy>();
if(curEnemy.isAttack)
return TaskStatus.Success;
return TaskStatus.Failure;
}
}
public class BossIsQteAttack : Conditional
{
public SharedBool isQteAttack;
public override TaskStatus OnUpdate()
{
if(isQteAttack.Value)
return TaskStatus.Success;
return TaskStatus.Failure;
}
}
public class WaitAllPetDie : Action
{
public override TaskStatus OnUpdate()
{
if (GameManager.Ins.IsAllBossPetDie())
{
Enemy curEnemy = GetComponent<Enemy>();
if (curEnemy)
{
curEnemy.isShield = false;
curEnemy.shieldObj.SetActive(false);
}
return TaskStatus.Success;
}
return TaskStatus.Running;
}
}
public class IsBossGunDie : Conditional
{
public SharedString GunIdStr;
private List<int> gunIdList;
public override void OnStart()
{
base.OnStart();
gunIdList=new List<int>();
string[] str=GunIdStr.Value.Split(',');
foreach (var item in str)
{
gunIdList.Add(int.Parse(item));
}
}
public override TaskStatus OnUpdate()
{
Enemy curEnemy = GetComponent<Enemy>();
foreach (var id in gunIdList)
{
if (curEnemy.components[id] != null && !curEnemy.components[id].isDead)
{
return TaskStatus.Failure;
}
}
return TaskStatus.Success;
}
}
public class BossQteAttack : Action
{
private Enemy _curEnemy;
public float QteTime;
public SharedBool IsQteAttacked;
public SharedBool IsStopQteAttacked;
private float _currentQteTime;
public override void OnStart()
{
base.OnStart();
//QteTime = 5;
_curEnemy = GetComponent<Enemy>();
if (_curEnemy)
{
IsQteAttacked.Value = false;
_curEnemy.StartQteAttack();
}
}
public override TaskStatus OnUpdate()
{
_currentQteTime += Time.deltaTime;
if (_curEnemy.components[^1] != null && _curEnemy.components[^1].isDead)
{
IsStopQteAttacked.Value =true;
_curEnemy.StopQteAttack();
return TaskStatus.Success;
}
if (_currentQteTime >= QteTime)
{
IsStopQteAttacked.Value =false;
_curEnemy.ThreeAttackMode();
return TaskStatus.Success;
}
return TaskStatus.Running;
}
}
public class CooldownTick : Action
{
public SharedFloat cooldownTimer;
public SharedBool skillReady;
public SharedFloat hp;
public override TaskStatus OnUpdate()
{
Enemy curEnemy = GetComponent<Enemy>();
var curHpIndex = curEnemy.health/curEnemy.maxHealth;
if (curHpIndex <= hp.Value)
{
skillReady.Value = false;
cooldownTimer.Value = 15;
return TaskStatus.Success;
}
if (cooldownTimer.Value > 0f) {
cooldownTimer.Value -= Time.deltaTime;
if (cooldownTimer.Value <= 0f) {
cooldownTimer.Value = 0f;
skillReady.Value = true;
return TaskStatus.Success;
}
}
return TaskStatus.Running;
}
}
public class ReleaseSkill : Action
{
public SharedFloat cooldownTimer;
public SharedBool skillReady;
public float skillCooldown = 15f;
public override void OnStart()
{
base.OnStart();
// 进入冷却
cooldownTimer.Value = skillCooldown;
skillReady.Value = false;
}
}
public class NormalAttack : Action
{
private Enemy1 enemy;
public SharedFloat hpIndex;
public override void OnAwake()
public override TaskStatus OnUpdate()
{
enemy = GetComponent<Enemy1>();
var curHpIndex = transform.GetComponent<Enemy>().health / transform.GetComponent<Enemy>().maxHealth;
if (curHpIndex <= hpIndex.Value)
{
return TaskStatus.Success;
}
return TaskStatus.Failure;
}
}
public class UserSkill : Action
{
public Enemy EnemyObj;
public SharedFloat hpIndex;
public override void OnStart()
{
base.OnStart();
EnemyObj = transform.GetComponent<Enemy>();
}
public override TaskStatus OnUpdate()
{
if (EnemyObj == null)
return TaskStatus.Failure;
var curHpIndex = EnemyObj.health / EnemyObj.maxHealth;
if (curHpIndex <= hpIndex.Value)
{
EnemyObj.userSillIng = false;
}
var isUserIng = EnemyObj.userSillIng;
if (isUserIng) return TaskStatus.Running;
return TaskStatus.Success;
}
}
public class BossIsUserSkill : Conditional
{
public override TaskStatus OnUpdate()
{
Enemy curEnemy = GetComponent<Enemy>();
if (curEnemy.userSillIng)
return TaskStatus.Success;
return TaskStatus.Failure;
}
}
public class BossIsAttackState : Conditional
{
public override TaskStatus OnUpdate()
{
Enemy curEnemy = GetComponent<Enemy>();
if (curEnemy.isAttack)
return TaskStatus.Success;
return TaskStatus.Failure;
}
}
public class BossIsQteAttack : Conditional
{
public SharedBool isQteAttack;
public override TaskStatus OnUpdate()
{
if (isQteAttack.Value)
return TaskStatus.Success;
return TaskStatus.Failure;
}
}
public class WaitAllPetDie : Action
{
public override TaskStatus OnUpdate()
{
if (GameManager.Ins.IsAllBossPetDie())
{
Enemy curEnemy = GetComponent<Enemy>();
if (curEnemy)
{
curEnemy.isShield = false;
curEnemy.shieldObj.SetActive(false);
}
return TaskStatus.Success;
}
return TaskStatus.Running;
}
}
public class IsBossGunDie : Conditional
{
public SharedString GunIdStr;
private List<int> gunIdList;
public override void OnStart()
{
base.OnStart();
gunIdList = new List<int>();
string[] str = GunIdStr.Value.Split(',');
foreach (var item in str)
{
gunIdList.Add(int.Parse(item));
}
}
public override TaskStatus OnUpdate()
{
Enemy curEnemy = GetComponent<Enemy>();
foreach (var id in gunIdList)
{
if (curEnemy.components[id] != null && !curEnemy.components[id].isDead)
{
return TaskStatus.Failure;
}
}
return TaskStatus.Success;
}
}
public class BossQteAttack : Action
{
private Enemy _curEnemy;
public float QteTime;
public SharedBool IsQteAttacked;
public SharedBool IsStopQteAttacked;
private float _currentQteTime;
public override void OnStart()
{
base.OnStart();
//QteTime = 5;
_curEnemy = GetComponent<Enemy>();
if (_curEnemy)
{
IsQteAttacked.Value = false;
_curEnemy.StartQteAttack();
}
}
public override TaskStatus OnUpdate()
{
_currentQteTime += Time.deltaTime;
if (_curEnemy.components[^1] != null && _curEnemy.components[^1].isDead)
{
IsStopQteAttacked.Value = true;
_curEnemy.StopQteAttack();
return TaskStatus.Success;
}
if (_currentQteTime >= QteTime)
{
IsStopQteAttacked.Value = false;
_curEnemy.ThreeAttackMode();
return TaskStatus.Success;
}
return TaskStatus.Running;
}
}
public class CooldownTick : Action
{
public SharedFloat cooldownTimer;
public SharedBool skillReady;
public SharedFloat hp;
public override TaskStatus OnUpdate()
{
Enemy curEnemy = GetComponent<Enemy>();
var curHpIndex = curEnemy.health / curEnemy.maxHealth;
if (curHpIndex <= hp.Value)
{
skillReady.Value = false;
cooldownTimer.Value = 15;
return TaskStatus.Success;
}
if (cooldownTimer.Value > 0f)
{
cooldownTimer.Value -= Time.deltaTime;
if (cooldownTimer.Value <= 0f)
{
cooldownTimer.Value = 0f;
skillReady.Value = true;
return TaskStatus.Success;
}
}
return TaskStatus.Running;
}
}
public class ReleaseSkill : Action
{
public SharedFloat cooldownTimer;
public SharedBool skillReady;
public float skillCooldown = 15f;
public override void OnStart()
{
//// 你的普攻逻辑
//Debug.Log("执行普攻");
//Enemy curEnemy = GetComponent<Enemy>();
//curEnemy.Attack();
if(enemy != null && !enemy.isAttack)
{
enemy.Attack();
}
base.OnStart();
// 进入冷却
cooldownTimer.Value = skillCooldown;
skillReady.Value = false;
}
}
public class IsSkillReady : Conditional
public class NormalAttack : Action
{
public override void OnStart()
{
public SharedBool skillReady;
public override TaskStatus OnUpdate()
{
return skillReady.Value ? TaskStatus.Success : TaskStatus.Failure;
}
// 你的普攻逻辑
Debug.Log("执行普攻");
Enemy curEnemy = GetComponent<Enemy>();
curEnemy.Attack();
}
}
public class ConditionalStopQte : Conditional
public class IsSkillReady : Conditional
{
public SharedBool skillReady;
public override TaskStatus OnUpdate()
{
public SharedBool IsStopQteAttack;
public override TaskStatus OnUpdate()
{
if(!IsStopQteAttack.Value)
return TaskStatus.Success;
return TaskStatus.Failure;
}
return skillReady.Value ? TaskStatus.Success : TaskStatus.Failure;
}
}
public class ConditionalStopQte : Conditional
{
public SharedBool IsStopQteAttack;
public override TaskStatus OnUpdate()
{
if (!IsStopQteAttack.Value)
return TaskStatus.Success;
return TaskStatus.Failure;
}
}