Unity如何实现敌人与玩家碰撞后短暂停止追逐的功能?
Unity敌人碰撞玩家后停顿实现方案(基于Invoke方法)
第一步:新增必要变量
在原有代码的Logic变量区域新增2个变量,方便后续控制停顿逻辑:
// 碰撞玩家后的停顿时长,可直接在Inspector面板调整数值 public float stunDuration = 1f; // 控制敌人是否可以移动的开关 private bool canMove = true;
第二步:添加停顿恢复方法
新增独立的恢复方法,专门给Invoke延时调用:
private void RecoverFromStun() { canMove = true; // 停顿结束后恢复追逐状态 chasing = true; }
第三步:修改碰撞检测逻辑
找到碰撞检测中判定碰到玩家的代码块,新增停顿触发逻辑:
if(hits[i].tag == "Fighter" && hits[i].name == "Player"){ collidingWithPlayer = true; // 只有当前处于可移动状态才触发停顿,避免重复调用Invoke if(canMove) { canMove = false; chasing = false; // 延时stunDuration秒后调用恢复方法 Invoke(nameof(RecoverFromStun), stunDuration); } }
第四步:修改移动逻辑
在所有调用UpdateMotor的位置新增canMove判断,只有处于可移动状态时才执行移动逻辑。
额外修复原有代码的已知错误
- 你标注的空引用报错是因为声明了
hitbox变量但调用时用了未定义的boxCollider,把boxCollider.OverlapCollider(filter, hits);改为hitbox.OverlapCollider(filter, hits);即可 - 删除
if (hits[i] == null)后面多余的反斜杠,避免语法报错
完整修改后代码
// Experience public int xpValue = 1; //Particle system public GameObject effect; // Logic public float triggerLength = 1; public float chaseLength = 5; public bool chasing; public bool collidingWithPlayer; // 新增:碰撞玩家后的停顿时长 public float stunDuration = 1f; private Transform playerTransform; private Vector3 startingPosition; // 新增:控制敌人是否可移动 private bool canMove = true; // Hitbox public ContactFilter2D filter; private BoxCollider2D hitbox; private Collider2D[] hits = new Collider2D[10]; protected override void Start() { base.Start(); playerTransform = GameManager.instance.player.transform; startingPosition = transform.position; hitbox = transform.GetChild(0).GetComponent<BoxCollider2D>(); } // 新增:停顿恢复方法 private void RecoverFromStun() { canMove = true; chasing = true; } protected void FixedUpdate(){ //Is the player in range? if(Vector3.Distance(playerTransform.position, startingPosition) < chaseLength) { if(Vector3.Distance(playerTransform.position, startingPosition) < triggerLength) chasing = true; if (chasing){ if(!collidingWithPlayer && canMove){ UpdateMotor((playerTransform.position - transform.position).normalized); } } else{ if(canMove) { UpdateMotor(startingPosition - transform.position); } } } else{ if(canMove) { UpdateMotor(startingPosition - transform.position); } chasing = false; } //Check for overlap collidingWithPlayer = false; // 修复空引用报错 hitbox.OverlapCollider(filter, hits); for (int i = 0; i < hits.Length; i++) { // 修复语法错误,删除多余反斜杠 if (hits[i] == null) continue; if(hits[i].tag == "Fighter" && hits[i].name == "Player"){ collidingWithPlayer = true; // 新增碰撞停顿逻辑 if(canMove) { canMove = false; chasing = false; Invoke(nameof(RecoverFromStun), stunDuration); } } //this array is not cleaned up, so we do it ourself hits[i] = null; } }
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

