当前位置: 首页 > 知识库问答 >
问题:

协同程序和触发器

范翰海
2023-03-14

我的问题是,我正在制作一个团结的游戏,我想做的是,当我游戏中的敌人击中障碍物时,它每秒都会造成x次伤害。

“桌面”障碍物上有一个对撞机和健康脚本,以及一个用于移动和攻击敌人的碰撞体和脚本。

敌人在与书桌物体碰撞时停止,并造成伤害!但是,损害是持续的...我试过协程和调用,但所有的结果都是一样的;每次触发探测造成10点伤害,而不是每秒。

以下是脚本:

敌人的运动和攻击:

private Animator anim;
public GameObject Desk;
private DeskHealth deskHealth;
//private bool inQueue = false;
private bool collidingWithDesk;
public float timeAfterStart;
[Range(0,10)]
public float attackSpeedEnemy = 1f;

[Range(10,100)]
public float walkSpeed;

[SerializeField] float damageDealtToDesk = 10f;


void Start () {
    anim = GetComponent<Animator>();  
    deskHealth = GetComponent<DeskHealth>();
    collidingWithDesk = false;
}

void Update()
{
    if (collidingWithDesk == false)
    {
        enemyIsWalking();
    }
}

void enemyIsWalking()
{
    transform.Translate(0, 0, (-walkSpeed * Time.deltaTime));
}

IEnumerator enemyIsAttacking()
{
    var deskHealth = Desk.GetComponent<DeskHealth>();
    deskHealth.DealDamageToDesk(damageDealtToDesk);
    yield return new WaitForSeconds(5f);        
}

void OnTriggerStay(Collider otherCollider)
{
    if (otherCollider.tag == "Desk")
    { 
        collidingWithDesk = true;
        transform.Translate(0, 0, 0);
        anim.Play("enemyHit");
        StartCoroutine(enemyIsAttacking());
    }
}

桌面健康:

[SerializeField] float deskHealth;
Animator anim;

public void DealDamageToDesk(float deskDamage)

{
    deskHealth -= deskDamage;
    if (deskHealth <= 0)
    {
        print("am ded");
        //anim.Play("deskDestroyed");
    }
}

共有1个答案

颛孙沈义
2023-03-14

对于doc所说的“对于每个碰撞器,除了接触触发器的碰撞器,每次物理更新都会调用OnTriggerStay一次。”这意味着您的代码:

if (otherCollider.tag == "Desk")
{ 
    collidingWithDesk = true;
    transform.Translate(0, 0, 0);
    anim.Play("enemyHit");
    StartCoroutine(enemyIsAttacking());
}

将在每次更新时被调用,然后暂停5秒,因为产生返回新的WaitFor秒数(5f);您应该使用OnColliderEnter,或者使用OnTriggerEnter可能更好,因为这个将被调用一次。如果您希望每秒一次,请将WaitFor秒数调用中的值更改为1。

同样按照天龙18的规定,你的收益什么都不等。你应该做这样的事情:

IEnumerator enemyIsAttacking()
{
    var deskHealth = Desk.GetComponent<DeskHealth>();
    while(collidingWithDesk)
    {
        deskHealth.DealDamageToDesk(damageDealtToDesk);
        yield return new WaitForSeconds(1f);        
    }
}

void OnTriggerExit(Collider otherCollider)
{
    if (otherCollider.tag == "Desk")
    { 
        collidingWithDesk = false;
        // rest of your code
    }
}
 类似资料:
  • 主要内容:什么是协同(coroutine)?,coroutine_test.lua 文件,实例,生产者-消费者问题,实例什么是协同(coroutine)? Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。 协同是非常强大的功能,但是用起来也很复杂。 线程和协同程序区别 线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行。 在任一指定时刻只有

  • 什么是协同(coroutine)? Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。 协同是非常强大的功能,但是用起来也很复杂。 线程和协同程序区别 线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行。 在任一指定时刻只有一个协同程序在运行,

  • tornado.gen — Simplify asynchronous code Decorators Utility functions Legacy interface tornado.concurrent — Work with threads and futures Consumer methods Producer methods tornado.locks – Synchronizat

  • 协同程序 当调用一个函数时,在它返回之前,会一直运行到完成。这意味着该函数中的任何动作都必须在一帧内完成;函数调用不能包含过程动画或一段时间内的事件序列。例如有这样一个任务,逐渐降低一个对象的 alpha(不透明度)值,直到它完全不可见。 void Fade() { for (float f = 1f; f >= 0; f -= 0.1f) { Color c = rend

  • 在本节中,介绍了在MySQL 5.1中使用触发程序的方法,并介绍了在使用触发程序方面的限制。 触发程序是与表有关的命名数据库对象,当表上出现特定事件时,将激活该对象。在某些触发程序的用法中,可用于检查插入到表中的值,或对更新涉及的值进行计算。 触发程序与表相关,当对表执行INSERT、DELETE或UPDATE语句时,将激活触发程序。可以将触发程序设置为在执行语句之前或之后激活。例如,可以在从表中

  • 目录 21.1. CREATE TRIGGER语法 21.2. DROP TRIGGER语法 21.3. 使用触发程序 MySQL 5.1包含对触发程序的支持。触发程序是与表有关的命名数据库对象,当表上出现特定事件时,将激活该对象。例如,下述语句将创建1个表和1个INSERT触发程序。触发程序将插入表中某一列的值加在一起: mysql> CREATE TABLE account (acct_num