【问题标题】: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 框架不调用基本方法等问题

标签: c# unity3d game-engine


【解决方案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;
        }
    }
    

    【讨论】:

    • 这些都不起作用。你能在我的代码中实现你所写的吗?我只是一个初学者,将不胜感激!!!
    猜你喜欢
    • 2023-03-21
    • 2022-01-26
    • 2021-05-10
    • 1970-01-01
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多