如何在与玩家碰撞后让敌人停下来一秒钟?团结[重复]

Posted

技术标签:

【中文标题】如何在与玩家碰撞后让敌人停下来一秒钟?团结[重复]【英文标题】:How can I make an enemy stop for a second after colliding with the player? Unity [duplicate] 【发布时间】:2021-11-28 20:27:21 【问题描述】:

敌人撞到玩家后我想让他停下一段时间,所以它不会一直追着他。看起来很奇怪。比如,添加一个调用函数或其他东西(不是专业人士)。请立即实施(我只是一个初学者)这是代码(我正在学习一些 7 小时的教程):

// 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;
private Transform playerTransform;
private Vector3 startingPosition;

// 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>();


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)
                UpdateMotor((playerTransform.position - transform.position).normalized);
            
        
        else
            UpdateMotor(startingPosition - transform.position);
        
    
    else
        UpdateMotor(startingPosition - transform.position);
        chasing = false;
    

    //Check for overlap
    collidingWithPlayer = false;
    boxCollider.OverlapCollider(filter, hits); // null reference expection
    for (int i = 0; i < hits.Length; i++)
    
        if (hits[i] == null)\

            continue;

            if(hits[i].tag == "Fighter" && hits[i].name == "Player")
                collidingWithPlayer = true;
            

        //this array is not cleaned up, so we do it ourself
        hits[i] = null;
    

【问题讨论】:

为什么所有受保护的语句?您不需要覆盖开始。你有什么尝试添加任何形式的延迟? @BugFinder 如果有一个不是MonoBehaviour 的通用基类,那么将Unity 消息方法实现为protected virtual 是很常见的,以便能够安全地override 它们而不隐藏基本实现并导致 Unity 框架不调用基本方法等问题 【参考方案1】:

您可能希望使用协程或计时器来实现此目的。 这是未经测试的,可能可以对此进行一些优化。

计时器

private bool hasAttacked = false;

private float attackTimer = 0;
private float waitTime = 0.5f;

private void Update()

   if (!hasAttacked)
   
      hasAttacked = true;
      attack();
      attackTimer = Time.time + waitTime;
   
   else
   
      if ( Time.time > attackTimer)
      
         hasAttacked = false;
      
   

这个sn-p会运行一个攻击函数,然后等待0.5秒,再次运行代码。

【讨论】:

【参考方案2】:

最简单的解决方案是研究协程。它们在主线程上运行,但可以暂停并等待延迟或事件。

bool CanAttack()

    return true; //Check if can attack here


void Attack()

    //Put your attacking code here


void Start()

    StartCoroutine(AttackLoop());


IEnumerator AttackLoop()

    while (true)
    
        //Check if enemy can attack
        if (CanAttack())
        
            Attack();
            //Waits 2 seconds before continuing
            yield return new WaitForSeconds(2f);
        

        //Wait one frame
        //Prevents an infinite loop
        yield return null;
    

【讨论】:

这些都不起作用。你能在我的代码中实现你所写的吗?我只是一个初学者,将不胜感激!!!

以上是关于如何在与玩家碰撞后让敌人停下来一秒钟?团结[重复]的主要内容,如果未能解决你的问题,请参考以下文章

玩家在与标记对象碰撞时消失

当敌人与 Player-Unity 碰撞时加载场景

如何在与另一个物理体碰撞时阻止物体失去位置

如何使 Physics2D.OverlapBoxAll() 活动 x 时间,并且只与它碰撞的新对象交互?

通过复制玩家位置跟随玩家的幽灵敌人 AI

如何检查我的播放器是否与对象发生碰撞?