using System.Collections.Generic; using BehaviorDesigner.Runtime; using BehaviorDesigner.Runtime.Tasks; using BehaviorDesigner.Runtime.Tasks.Movement; using UnityEngine; using UnityEngine.AI; using Valheim; public class Actions { private static readonly int UserSkill = Animator.StringToHash("userSkill"); /// /// 差值旋转到规定角度 /// public class RotationToStipulateAngle : Action { public SharedVector3 angle; public SharedGameObject Target; public override TaskStatus OnUpdate() { Quaternion quaternion = new Quaternion(); quaternion.eulerAngles = angle.Value; if (transform.rotation == quaternion) { return TaskStatus.Success; } else if (transform.eulerAngles.y < 5) { return TaskStatus.Success; } transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.identity, Time.deltaTime * 15); return TaskStatus.Failure; } } public class CheckCurrentEnemyAlive : Conditional { public SharedGameObject Target; public override TaskStatus OnUpdate() { if (Target.Value) { bool IsAlive = Target.Value.GetComponent().IsAlive; if (!IsAlive) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } return TaskStatus.Failure; } } /// /// 移动到某个位置 /// public class MoveToPoint : NavMeshMovement { public SharedVector3 point; public override void OnStart() { base.OnStart(); SetDestination(point.Value); } public override TaskStatus OnUpdate() { SetDestination(point.Value); if (navMeshAgent.remainingDistance < arriveDistance.Value) { navMeshAgent.isStopped = true; navMeshAgent.velocity = Vector3.zero; return TaskStatus.Success; } return TaskStatus.Running; } } public class MoveToPoint2 : Action { public SharedVector3 point; private Pet pet; public override void OnStart() { base.OnStart(); pet = transform.GetComponent(); if (pet != null) { Debug.Log("TO: 开始"); SetDestination(); } } public override TaskStatus OnUpdate() { if (pet == null) { return TaskStatus.Failure; } SetDestination(); if (pet.NavAgent.remainingDistance < 0.1F) { pet.NavAgent.isStopped = true; pet.NavAgent.velocity = Vector3.zero; return TaskStatus.Success; } return TaskStatus.Running; } public void SetDestination() { if (pet != null ) { pet.NavAgent.isStopped = false; pet.NavAgent.SetDestination(point.Value); } } } public class MoveToRegeneration : Action { public SharedTransform Point; private Pet pet; public override void OnStart() { base.OnStart(); pet = transform.GetComponent(); if (pet != null) { SetDestination(); } } public override TaskStatus OnUpdate() { if (pet == null) { return TaskStatus.Failure; } SetDestination(); if (pet.NavAgent.remainingDistance < 0.1F) { pet.NavAgent.isStopped = true; pet.NavAgent.velocity = Vector3.zero; return TaskStatus.Success; } return TaskStatus.Running; } public void SetDestination() { if (pet != null && Point.Value != null) { pet.NavAgent.isStopped = false; int index=Random.Range(0, 11); Vector3 point = Point.Value.gameObject.GetComponent().Points[index].position; //因为字典是从1开始 所以要减1 pet.NavAgent.SetDestination(point); } } } public class CheckArriveTargetPoint : Conditional { public SharedBool IsArriveTargetPoint; public override TaskStatus OnUpdate() { if (IsArriveTargetPoint.Value) { return TaskStatus.Success; } else if (!IsArriveTargetPoint.Value) { return TaskStatus.Failure; } return TaskStatus.Running; } } /// /// 检测范围内是否有敌人 /// public class CheckRangeEnemy : Conditional { public SharedFloat checkRange; public SharedString enemyTag; private bool IsEnemy; public override TaskStatus OnUpdate() { if (GameManager.Ins != null) { List transforms = GameManager.Ins.GetRangeEnemy(transform.position, checkRange.Value, enemyTag.Value); Debug.Log("检测敌人数量:" + transforms.Count); IsEnemy = transforms.Count > 0 ; } if (IsEnemy) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } } public class EnemySearchTargetCon : Conditional { public override TaskStatus OnUpdate() { Enemy self = transform.GetComponent(); if (self == null) return TaskStatus.Failure; bool find = false; foreach (Pet pet in GameManager.Ins.PetList.Values) { // 受训练的宠物 if (pet.state == PetState.Trained) { // 残血的宠物 if (pet.Health <= 0) { continue; } Player player = MRNetworkManager.Ins.roomSlots[pet.teamId].transform.GetComponent(); // 所属训练师不在老巢内 if (player == null || player.InAreaId != self.areaId) { continue; } // 宠物不在老巢内 // if (!GameManager.Ins.CheckPointInArea(self.areaId, pet.transform.position)) // { // continue; // } find = true; Owner.SetVariable("Target", (SharedGameObject)pet.gameObject); find = true; break; } } if (find == false) { SharedGameObject targetShared = new SharedGameObject(); targetShared.Value = null; Owner.SetVariable("Target", targetShared); } return find ? TaskStatus.Success : TaskStatus.Failure; } } public class EnemySearchTarget : Action { public override TaskStatus OnUpdate() { Enemy self = transform.GetComponent(); if (self == null) return TaskStatus.Failure; bool find = false; foreach (Pet pet in GameManager.Ins.PetList.Values) { // 受训练的宠物 if (pet.state == PetState.Trained) { // 残血的宠物 if (pet.Health <= 0) { continue; } if (pet.teamId != 0) { Debug.LogError("宠物队伍错误"); continue; } Player player = MRNetworkManager.Ins.roomSlots[pet.teamId].transform.GetComponent(); // 所属训练师不在老巢内 if (player == null || player.InAreaId != self.areaId) { continue; } // // 宠物不在老巢内 // if (!GameManager.Ins.CheckPointInArea(self.areaId, pet.transform.position)) // { // continue; // } find = true; Owner.SetVariable("Target", (SharedGameObject)pet.gameObject); find = true; break; } } if (find == false) { SharedGameObject targetShared = new SharedGameObject(); targetShared.Value = null; Owner.SetVariable("Target", targetShared); } return TaskStatus.Success; } } public class BossSearchTarget : Action { public override TaskStatus OnUpdate() { EnemyBoss self = transform.GetComponent(); if (self == null) return TaskStatus.Failure; bool find = false; float dis = 10000f; GameObject preTarget = null; foreach (Pet pet in GameManager.Ins.PetList.Values) { // 受训练的宠物 // if (pet.state == PetState.Trained) // { // // 残血的宠物 // // if (pet.Health <= 0) // // { // // continue; // // } // if (pet.state == PetState.Trained) // { // continue; // } // float space = Vector3.Distance(pet.transform.position, self.transform.position); // if (space <= dis) // { // find = true; // preTarget = pet.gameObject; // } // } if (pet.state == PetState.Terminal) { continue; } float space = Vector3.Distance(pet.transform.position, self.transform.position); if (space <= dis) { find = true; preTarget = pet.gameObject; } } if (find == false) { SharedGameObject targetShared = new SharedGameObject(); targetShared.Value = null; Owner.SetVariable("Target", targetShared); return TaskStatus.Failure; } if (find && preTarget != null) { Owner.SetVariable("Target", (SharedGameObject)preTarget); } return TaskStatus.Success; } } public class CheckSelfAlive : Conditional { public override TaskStatus OnUpdate() { bool isAlive = transform.GetComponent().IsAlive; if (isAlive) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } } public class CheckTargetEnemyState : Conditional { public SharedGameObject target; public SharedInt state; public override TaskStatus OnUpdate() { if (target.Value) { Enemy enemy = target.Value.GetComponent(); if (enemy == null) return TaskStatus.Failure; if (enemy.state == (EnemyState)state.Value) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } return TaskStatus.Failure; } } public class CheckEnemyState : Conditional { public SharedInt state; public override TaskStatus OnUpdate() { Enemy enemy = transform.GetComponent(); if (enemy == null) return TaskStatus.Failure; if (enemy.state == (EnemyState)state.Value) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } } public class CheckBossState : Conditional { public SharedInt state; public override TaskStatus OnUpdate() { EnemyBoss boss = transform.GetComponent(); if (boss == null) return TaskStatus.Failure; if (boss.bossState == (BossState)state.Value) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } } public class SetEnemyState : Action { public SharedInt state; public override TaskStatus OnUpdate() { Enemy enemy = transform.GetComponent(); if (enemy == null) return TaskStatus.Failure; //if (GameManager.Ins.isGuide) return TaskStatus.Running; //记录下上一次状态 Owner.SetVariable("LastState", (SharedInt)(int)enemy.state); enemy.state = (EnemyState)state.Value; return TaskStatus.Success; } } public class SetBossState : Action { public SharedInt state; public override TaskStatus OnUpdate() { EnemyBoss boss = transform.GetComponent(); if (boss == null) return TaskStatus.Failure; boss.bossState = (BossState)state.Value; return TaskStatus.Success; } } [TaskDescription("检测自身是否已受训练")] public class CheckIsTrained : Conditional { public override TaskStatus OnUpdate() { PetState state = transform.GetComponent().state; if (state == PetState.Trained) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } } [TaskDescription("检测宠物状态")] public class CheckPetState : Conditional { public SharedInt state; public override TaskStatus OnUpdate() { Pet pet = transform.GetComponent(); if (pet == null) return TaskStatus.Failure; if (pet.state == (PetState)state.Value) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } } [TaskDescription("检测宠物命令")] public class CheckPetOrder : Conditional { public SharedInt order; public override TaskStatus OnUpdate() { Pet pet = transform.GetComponent(); if (pet == null) return TaskStatus.Failure; if (pet.order == (OrderType)order.Value) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } } public class SetPetState : Action { public SharedInt state; public override TaskStatus OnUpdate() { Pet pet = transform.GetComponent(); if (pet == null) return TaskStatus.Failure; pet.state = (PetState)state.Value; return TaskStatus.Success; } } public class SetPetOrder : Action { public SharedInt order; public override TaskStatus OnUpdate() { Pet pet = transform.GetComponent(); if (pet == null) return TaskStatus.Failure; pet.order = (OrderType)order.Value; return TaskStatus.Success; } } /// /// 检测是否在攻击范围 /// //public class CheckInAtkArea : Conditional //{ // public SharedInt checkType; // public SharedGameObject target; // public override TaskStatus OnUpdate() // { // if (target.Value == null) return TaskStatus.Failure; // float atkArea = 0.0f; // if (checkType.Value == 0) // { // Pet pet = transform.GetComponent(); // if (pet != null) // { // atkArea = pet.atkArea; // } // } // else if (checkType.Value == 1) // { // Enemy enemy = transform.GetComponent(); // if (enemy != null) // { // atkArea = enemy.atkArea; // } // } // float dis = 0.0f; // if (checkType.Value == 0) // { // Enemy enemy = target.Value.GetComponent(); // dis = Vector3.Distance(transform.position, target.Value.transform.position) - enemy.radius; // } // else if (checkType.Value == 1) // { // Pet pet = target.Value.GetComponent(); // dis = Vector3.Distance(transform.position, target.Value.transform.position) - pet.radius; // } // if (dis <= atkArea) // { // return TaskStatus.Success; // } // else // { // return TaskStatus.Failure; // } // } //} public class CheckInAtkArea : Conditional { public SharedInt checkType; public SharedGameObject target; // [Tooltip("是否使用边缘距离计算")] public SharedBool useEdgeDistance = true; public override TaskStatus OnUpdate() { if (target.Value == null) { Debug.Log("目标为空"); return TaskStatus.Failure; } // 获取攻击范围 float atkArea = GetAttackRange(); if (atkArea <= 0) { Debug.LogWarning("攻击范围为0或未找到对应组件"); return TaskStatus.Failure; } // 计算距离 float dis = CalculateDistance(); // 添加调试信息 Debug.Log($"检查类型: {checkType.Value}, 攻击范围: {atkArea}, 计算距离: {dis}"); if (dis <= atkArea) { Debug.Log("在攻击范围内"); return TaskStatus.Success; } else { Debug.Log("不在攻击范围内"); return TaskStatus.Failure; } } private float GetAttackRange() { if (checkType.Value == 0) // 宠物 { Pet pet = transform.GetComponent(); return pet != null ? pet.atkArea : 0f; } else if (checkType.Value == 1) // 敌人 { Enemy enemy = transform.GetComponent(); return enemy != null ? enemy.atkArea : 0f; } return 0f; } private float CalculateDistance() { float centerDistance = Vector3.Distance(transform.position, target.Value.transform.position); if (!useEdgeDistance.Value) return centerDistance; // 直接返回中心距离 // 边缘距离计算 if (checkType.Value == 0) // 宠物攻击敌人 { Enemy enemy = target.Value.GetComponent(); return enemy != null ? centerDistance - enemy.radius : centerDistance; } else if (checkType.Value == 1) // 敌人攻击宠物 { Pet pet = target.Value.GetComponent(); return pet != null ? centerDistance - pet.radius : centerDistance; } return centerDistance; } } public class BossCheckInAtkArea : Conditional { public SharedGameObject target; public override TaskStatus OnUpdate() { if (target.Value == null) return TaskStatus.Failure; EnemyBoss enemyBoss = transform.GetComponent(); if (enemyBoss == null) return TaskStatus.Failure; Pet pet = target.Value.GetComponent(); if (pet == null) return TaskStatus.Failure; float atkArea = enemyBoss.atkArea; float dis = Vector3.Distance(transform.position, target.Value.transform.position) - pet.radius; if (dis <= atkArea) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } } public class PlayerIdels : Action { private Animator animator; public override TaskStatus OnUpdate() { if (animator == null) { animator = transform.GetComponent(); } else { //// } return TaskStatus.Success; } } public class SearchRevivePoint : Action { public override TaskStatus OnUpdate() { if (GameManager.Ins.RevivePointList.Count <= 0) return TaskStatus.Failure; GameManager.Ins.RevivePointList.Sort((x, y) => { if (Vector3.Distance(transform.position, x.position) > Vector3.Distance(transform.position, y.position)) { return 1; } else { return -1; } }); Owner.SetVariable("TempPoints", (SharedTransform)GameManager.Ins.RevivePointList[0]); return TaskStatus.Success; } } /// /// 检测target所属训练师是不是在老巢内 /// public class CheckPetOwnerInArea : Conditional { public SharedGameObject target; public override TaskStatus OnUpdate() { if (target.Value == null) return TaskStatus.Failure; Pet pet = target.Value.GetComponent(); if (pet == null) return TaskStatus.Failure; Enemy self = transform.GetComponent(); if (self == null) return TaskStatus.Failure; if (GameManager.Ins.CheckPointInArea(self.areaId, MRNetworkManager.Ins.roomSlots[pet.teamId].transform.position)) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } } public class WaitCurrentAnimationEnd : Action { private Animator animator; public override TaskStatus OnUpdate() { animator = transform.GetComponent(); if (animator == null) { Debug.LogError("Animator is null"); return TaskStatus.Failure; } AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0); if (stateInfo.normalizedTime >= 1f) { // 动画已结束 return TaskStatus.Success; } return TaskStatus.Running; } } public class WaitCurrentAnimationEnd1 : Action { private Animator animator; public override void OnStart() { animator = transform.GetComponent(); } public override TaskStatus OnUpdate() { AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0); if (stateInfo.IsTag("Attack") && stateInfo.normalizedTime >= 1F) { return TaskStatus.Success; } return TaskStatus.Running; } } public class WaitAnimation : Action { private Animator animator; private SharedFloat waitTime = 1; private SharedBool randomWait = false; private SharedFloat randomWaitMin = 1; private SharedFloat randomWaitMax = 1; // The time to wait private float waitDuration; // The time that the task started to wait. private float startTime; // Remember the time that the task is paused so the time paused doesn't contribute to the wait time. private float pauseTime; public override void OnStart() { animator = transform.GetComponent(); if (animator == null) { Debug.LogError("Animator is null"); } // The task is done waiting if the time waitDuration has elapsed since the task was started. AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0); // Remember the start time. startTime = Time.time; waitDuration = stateInfo.length; Debug.Log("Animator D" + waitDuration); } public override TaskStatus OnUpdate() { if (startTime + waitDuration < Time.time) { return TaskStatus.Success; } // Otherwise we are still waiting. return TaskStatus.Running; } public override void OnPause(bool paused) { if (paused) { // Remember the time that the behavior was paused. pauseTime = Time.time; } else { // Add the difference between Time.time and pauseTime to figure out a new start time. startTime += (Time.time - pauseTime); } } public override void OnReset() { // Reset the public properties back to their original values waitTime = 1; randomWait = false; randomWaitMin = 1; randomWaitMax = 1; } } public class PetSetOut : Action { public override TaskStatus OnUpdate() { Pet pet = transform.GetComponent(); if (pet == null) return TaskStatus.Failure; if (GameManager.Ins.SetOutTeam(pet.teamId, pet.id)) { pet.isSetOut = true; return TaskStatus.Success; } else { return TaskStatus.Failure; } } } public class PetReturn2Team : Action { public override TaskStatus OnUpdate() { Pet pet = transform.GetComponent(); if (pet == null) return TaskStatus.Failure; if (GameManager.Ins.Return2Team(pet.teamId, pet.id)) { pet.isSetOut = false; return TaskStatus.Success; } else { return TaskStatus.Failure; } } } public class IsPetSetOut : Conditional { public override TaskStatus OnUpdate() { Pet pet = transform.GetComponent(); if (pet == null) return TaskStatus.Failure; if (pet.isSetOut) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } } public class Seek : NavMeshMovement2 { public SharedInt seekType; [BehaviorDesigner.Runtime.Tasks.Tooltip("The GameObject that the agent is seeking")] public SharedGameObject target; [BehaviorDesigner.Runtime.Tasks.Tooltip("If target is null then use the target position")] public SharedVector3 targetPosition; public float arriveDistance; public override void OnStart() { base.OnStart(); if (seekType.Value == 0) { navMeshAgent.speed = transform.GetComponent().seekSpeed; } else if (seekType.Value == 1) { navMeshAgent.speed = transform.GetComponent().speed; } SetDestination(Target()); } public override TaskStatus OnUpdate() { if (target.Value == null) return TaskStatus.Failure; if (seekType.Value == 0) { Enemy enemy = target.Value.GetComponent(); Pet self = transform.GetComponent(); arriveDistance = enemy.radius + self.radius + 0.1F; // Debug.Log("enemyRadius:" + enemy.radius); } else if (seekType.Value == 1) { Pet pet = target.Value.GetComponent(); Enemy self = transform.GetComponent(); arriveDistance = pet.radius + self.radius + 0.1F; } SetDestination(Target()); // Debug.Log("arriveDistance:" + arriveDistance); if (navMeshAgent.remainingDistance < arriveDistance) { navMeshAgent.isStopped = true; navMeshAgent.velocity = Vector3.zero; return TaskStatus.Success; } return TaskStatus.Running; } private Vector3 Target() { if (target.Value != null) { return target.Value.transform.position; } return targetPosition.Value; } public override void OnReset() { base.OnReset(); target = null; targetPosition = Vector3.zero; } protected override bool HasPath() { return navMeshAgent.hasPath && navMeshAgent.remainingDistance > arriveDistance; } protected override bool HasArrived() { float remainingDistance; if (navMeshAgent.pathPending) { remainingDistance = float.PositiveInfinity; } else { remainingDistance = navMeshAgent.remainingDistance; } return remainingDistance <= arriveDistance; } } public class Flee : NavMeshMovement { public SharedFloat fleedDistance = 20; public SharedFloat lookAheadDistance = 5; public SharedGameObject target; private bool hasMoved; public override void OnStart() { base.OnStart(); hasMoved = false; SetDestination(Target()); } public override TaskStatus OnUpdate() { if (Vector3.Magnitude(Tareget2()) > fleedDistance.Value) { return TaskStatus.Success; } if (HasArrived()) { if (!hasMoved) { return TaskStatus.Failure; } if (!SetDestination(Target())) { return TaskStatus.Failure; } hasMoved = false; } else { return TaskStatus.Running; // If the agent is stuck the task shouldn't continue to return a status of running. // var velocityMagnitude = Velocity().sqrMagnitude; // if (hasMoved && velocityMagnitude <= 0f) // { // // return TaskStatus.Failure; // return TaskStatus.Running; // } // hasMoved = velocityMagnitude > 0f; } return TaskStatus.Running; } // Flee in the opposite direction private Vector3 Target() { if (target == null || target.Value == null) { // Debug.LogError("Target is null, cannot flee."); return transform.position.normalized * lookAheadDistance.Value; ; // 或者返回其他默认行为的位置 } return transform.position + (transform.position - target.Value.transform.position).normalized * lookAheadDistance.Value; } private Vector3 Tareget2() { if (target == null || target.Value == null) { // Debug.LogError("Target is null, cannot flee."); return transform.position; // 或者返回其他默认行为的位置 } return transform.position - target.Value.transform.position; } // Return false if the position isn't valid on the NavMesh. protected override bool SetDestination(Vector3 destination) { if (!SamplePosition(destination)) { return false; } return base.SetDestination(destination); } // Reset the public variables public override void OnReset() { base.OnReset(); fleedDistance = 20; lookAheadDistance = 5; target = null; } } public class RigidBodyMove2Pos : Action { public SharedVector3 targetPos; public SharedFloat speed; private Rigidbody rigidbody; private int loopCount; // 在行为开始时调用 public override void OnStart() { rigidbody = transform.GetComponent(); } // 每次行为更新时调用 public override TaskStatus OnUpdate() { if (rigidbody != null) { // 获取目标位置 Vector3 targetPosition = targetPos.Value; // 计算物体到目标位置的距离向量 Vector3 direction = targetPosition - transform.position; // 设置刚体的速度 rigidbody.velocity = direction.normalized * Time.deltaTime * 50f; } return TaskStatus.Running; } } //是否是满血 public class IsPetMaxHealth : Conditional { public override void OnStart() { base.OnStart(); } public override TaskStatus OnUpdate() { Pet pet = transform.GetComponent(); if (pet == null) return TaskStatus.Failure; if (pet.Health == pet.OriginHealth) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } } public class IsTargetPetCantAtk : Conditional { public SharedGameObject target; public override void OnStart() { base.OnStart(); } public override TaskStatus OnUpdate() { if (target.Value == null) return TaskStatus.Failure; Pet pet = target.Value.GetComponent(); if (pet == null) return TaskStatus.Failure; Enemy self = transform.GetComponent(); if (self == null) return TaskStatus.Failure; Player player = MRNetworkManager.Ins.roomSlots[pet.teamId].transform.GetComponent(); if (player == null) return TaskStatus.Failure; if ( pet.Health <= 0 || // !GameManager.Ins.CheckPointInArea(self.areaId, pet.transform.position) || player.InAreaId != self.areaId ) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } } public class IsTargetBossCantAtk : Conditional { public SharedGameObject target; public override void OnStart() { base.OnStart(); } public override TaskStatus OnUpdate() { if (target.Value == null) return TaskStatus.Failure; Pet pet = target.Value.GetComponent(); if (pet == null) return TaskStatus.Failure; EnemyBoss self = transform.GetComponent(); if (self == null) return TaskStatus.Failure; if (pet.state == PetState.Terminal) { return TaskStatus.Success; } else { return TaskStatus.Failure; } } } /// /// 是否使用时间技能 /// public class IsUserTimeSkill : Conditional { public override TaskStatus OnUpdate() { var enemy = GetComponent(); if(enemy==null) return TaskStatus.Failure; if(!enemy.isUserSkill) return TaskStatus.Failure; int skillId=Random.Range(0, 2); if (GetComponent() != null && GetComponent().id == 2) { skillId = 1; } if(!GameManager.Ins.SkillDataList.ContainsKey(enemy.skillList[skillId])) return TaskStatus.Failure; if (GameManager.Ins.SkillDataList[enemy.skillList[skillId]].SkillInterval > 1) { enemy.GetComponent().SetVariable("skillId", (SharedInt)enemy.skillList[skillId]); enemy.curWaitSkillTime = enemy.waitSkillTime; enemy.isUserSkill = false; return TaskStatus.Success; } return TaskStatus.Failure; } } /// /// 是否使用血量阈值技能 /// public class IsUserHpSkill : Conditional { public override TaskStatus OnUpdate() { var enemy = GetComponent(); if(enemy==null) return TaskStatus.Failure; if(!enemy.isUserHpSkill) return TaskStatus.Failure; foreach (var id in enemy.skillList) { if(!GameManager.Ins.SkillDataList.ContainsKey(id)) return TaskStatus.Failure; if (GameManager.Ins.SkillDataList[id].SkillInterval <= 1) { enemy.GetComponent().SetVariable("skillId", (SharedInt)id); enemy.isUserHpSkill = false; enemy.userHpSkillIndex++; return TaskStatus.Success; } } return TaskStatus.Failure; } } public class RotateTowards : NavMeshMovement { public SharedFloat rotationEpsilon = 0.5f; public SharedFloat maxLookAtRotationDelta = 1; public SharedBool onlyY; public SharedGameObject target; public SharedVector3 targetRotation; public override TaskStatus OnUpdate() { // 1. 计算只绕 Y 轴的目标四元数 Quaternion targetQ = ComputeYawOnlyTarget(); // 2. 检查是否到位 if (Quaternion.Angle(transform.rotation, targetQ) < rotationEpsilon.Value) return TaskStatus.Success; // 3. 旋转时考虑 deltaTime float step = maxLookAtRotationDelta.Value * Time.deltaTime; transform.rotation = Quaternion.RotateTowards(transform.rotation, targetQ, step); return TaskStatus.Running; } private Quaternion ComputeYawOnlyTarget() { // 动态目标 if (target != null && target.Value != null /* && targetId.Value != 0 如果需要再加 */) { Vector3 dir = target.Value.transform.position - transform.position; if (onlyY.Value) dir.y = 0; float yaw = Mathf.Atan2(dir.x, dir.z) * Mathf.Rad2Deg; return Quaternion.Euler(0, yaw, 0); } // 静态角度 return Quaternion.Euler(targetRotation.Value); } // Reset the public variables public override void OnReset() { rotationEpsilon = 0.5f; maxLookAtRotationDelta = 1f; onlyY = false; target = null; targetRotation = Vector3.zero; } } /// /// 敌人追击宠物超过开始点距离判断 如超过需返回巢穴 /// public class ExceedSeekDis : Conditional { public SharedFloat seekDistance; // 最大允许追击距离 public SharedTransform enemyTransform; // 敌人自身的位置 public SharedTransform startPoint; // 敌人开始追击的起点 public override void OnStart() { // 你可以在这里缓存位置,如果需要 enemyTransform.Value = transform; startPoint = transform.GetComponent().startPos; seekDistance = 5f; } public override TaskStatus OnUpdate() { if (enemyTransform.Value == null || startPoint.Value == null) { Debug.LogWarning("Transform 未赋值!"); return TaskStatus.Failure; } float distance = Vector3.Distance(enemyTransform.Value.position, startPoint.Value.position); if (distance > seekDistance.Value) { Debug.LogError("满足触发条件 开始返回老巢!"); // 超出范围,返回 True 表示满足条件 return TaskStatus.Success; } else { // 未超出范围,返回 False return TaskStatus.Failure; } } /// /// 返回老巢(起始点) /// - 进入后不停距离检查 /// - 如果被击中则中断返回 /// - 如果到达起始点则切到警戒状态 /// public class ReturnToNest : Action { public SharedGameObject agentGameObject; public SharedTransform nestPoint; public SharedFloat reachThreshold; public SharedBool isHit; public SharedBool isAlert; // 内部缓存 private NavMeshAgent _agent; public override void OnStart() { // 缓存 NavMeshAgent 组件 if (agentGameObject.Value != null) { _agent = agentGameObject.Value.GetComponent(); } } public override TaskStatus OnUpdate() { // 如果没挂 NavMeshAgent 或者没指定巢穴点,直接失败 if (_agent == null || nestPoint.Value == null) { Debug.LogWarning("ReturnToNest: 缺少 NavMeshAgent 或 nestPoint"); return TaskStatus.Failure; } // 如果在返回过程中被击中,则中断,返回 Failure if (isHit.Value) { _agent.ResetPath(); return TaskStatus.Failure; } // 设置目的地为巢穴 _agent.SetDestination(nestPoint.Value.position); // 如果已经到达巢穴附近 if (!_agent.pathPending && _agent.remainingDistance <= reachThreshold.Value) { // 到巢穴了,触发警戒 isAlert.Value = true; isHit.Value = false; _agent.ResetPath(); return TaskStatus.Success; } // 还在路上,继续返回 return TaskStatus.Running; } public override void OnEnd() { // 清理路径(可选) if (_agent != null && _agent.hasPath) { _agent.ResetPath(); } } } } }