C# 在两个碰撞器接触的每一帧上运行代码

C# 在两个碰撞器接触的每一帧上运行代码,c#,loops,unity3d,if-statement,while-loop,C#,Loops,Unity3d,If Statement,While Loop,我试图让它这样,如果我的角色继续用伤害脚本触摸游戏对象,玩家就会继续受到伤害。而不是这个结果,我只会在触摸游戏对象时受到一次伤害。没有错误消息。我试着用一个while循环来代替if,结果它毁了我的游戏。是否有任何方法可以循环if语句,最好是使用计时方法 if (other.tag == "Player") { healthScript.healthPoints -= damage; } 这是我试图循环的if语句。首先,我假设您使用碰撞器作为触发器,并选择了is Trigger属性。我

我试图让它这样,如果我的角色继续用伤害脚本触摸游戏对象,玩家就会继续受到伤害。而不是这个结果,我只会在触摸游戏对象时受到一次伤害。没有错误消息。我试着用一个while循环来代替if,结果它毁了我的游戏。是否有任何方法可以循环if语句,最好是使用计时方法

if (other.tag == "Player")
{
   healthScript.healthPoints -= damage;

}


这是我试图循环的if语句。

首先,我假设您使用碰撞器作为触发器,并选择了
is Trigger
属性。我还假设这是一个2D游戏。如果没有,同样的方法也可以,您只需将方法从2D更改为3D即可

您需要将
OnTriggerEnter2D()
OnTriggerExit2D()
方法添加到您的玩家健康脚本中。这将允许我们检测玩家何时站在损坏的物体上。从这里开始,我们将启动一个协同程序,该程序可用于以定时方式造成损害

using System.Collections;
using UnityEngine;

public class HealthScript : MonoBehaviour
{
    public float healthPoints = 100f;
    public float damage = 5f;
    public bool OnDamagingObject = false;

    IEnumerator DealDamage()
    {
        while (OnDamagingObject)
        {
            healthPoints -= damage;
            yield return new WaitForSeconds(1f);
        }
    }

    void OnTriggerEnter2D(Collider2D hitInfo)
    {
        GameObject collider = hitInfo.gameObject;
        if (collider.tag == "DamagingObject")
        {
            OnDamagingObject = true;
            StartCoroutine(DealDamage());
        }
    }

    void OnTriggerExit2D(Collider2D hitInfo)
    {
        GameObject collider = hitInfo.gameObject;
        if (collider.tag == "DamagingObject")
        {
            OnDamagingObject = false;
        }
    }
}

对于那些希望使用
OnTriggerStay()
的人,我还将提供一个解决方案。这一次,我们将按照提问者使用的结构,将脚本保留在损坏的对象上

using UnityEngine;

public class DamageScript : MonoBehaviour
{
    public HealthScript healthScript;
    public float damage = 5f;

    void OnTriggerStay2D(Collider2D hitInfo)
    {
        GameObject other = hitInfo.gameObject;
        if (other.CompareTag("Player"))
        {
            healthScript.healthPoints -= damage;
        }
    }
}

正如我的评论中提到的,实现
OnTriggerEnter()
OnTriggerExit()
可以更好地控制对玩家造成的伤害。使用
OnTriggerStay()
的一个缺点是我不确定如何定时处理损坏。此外,
OnTriggerStay()
限制您对玩家造成伤害的方式。如果将来你想在玩家第一次接触伤害对象时对其造成5点伤害,但之后在接触该对象时每秒钟造成2点伤害,那么使用
OnTriggerStay()

是不可能的,你不会这样做,但是你将其设置为触发器,并且当触发器仍然为真时,你会这样做,虽然它没有触发您,但如果您提供触发触摸事件的代码,即首先执行此if语句的代码,则它将非常有用。我想象在某个地方有一个类似“while(stilltouching)…If(other.tag==“Player”)…”的代码。如果是这样,为了避免程序崩溃,如果满足某些条件,例如healthScript.healthPoints<0.
OnTriggerStay
引擎控制循环,而不是你@DRACO18SNOLONGERTRUSSSE的响应是正确的。您的例程依赖于帧速率。你需要用
healthPoints-=damage*Time.deltaTime
否则,高端系统的损坏速度会更快,低端系统的损坏速度会更慢。同样,
OnTiggerStay
存在。“OnTiggerStay”会使代码更容易阅读,但速度会慢得多。在单个实例上您不会注意到这一点,但如果您开始检查多个实例,它可能会成为一个问题。此外,在第一个FixedFrame上不调用“OnTiggerStay”,而只在第二个FixedFrame上调用。我认为OnTiggerStay()不会使代码更具可读性,因为与造成损害相关的所有逻辑都必须仅包含在该方法中。同时实现OnTiggerEnter()和OnTiggerExit()是一个更强大的解决方案,它允许开发人员更好地控制玩家与破坏对象交互时的方式和内容。事实上,OP提到他们希望以定时方式造成破坏。我已经更新了我的答案,包括一个从运行状况中减去,然后在再次减去之前使用WaitForSeconds()的协程。对于OnTiggerStay(),这就不那么简单了。