C# 试图让敌人每设定秒造成伤害(团结)

C# 试图让敌人每设定秒造成伤害(团结),c#,unity3d,raycasting,C#,Unity3d,Raycasting,我正在创造一个3D射手,我试图让一个敌人每一秒都对玩家造成伤害。我让敌人用射线投射造成伤害,但是它造成伤害的速度太快了 我认为使用收益率返回新的WaitForSeconds2会每2秒对玩家造成1点伤害,但对玩家造成伤害的速度要快得多 using System.Collections; using System.Collections.Generic; using UnityEngine; public class EnemyMove : MonoBehaviour { public T

我正在创造一个3D射手,我试图让一个敌人每一秒都对玩家造成伤害。我让敌人用射线投射造成伤害,但是它造成伤害的速度太快了

我认为使用收益率返回新的WaitForSeconds2会每2秒对玩家造成1点伤害,但对玩家造成伤害的速度要快得多

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyMove : MonoBehaviour
{
    public Transform target;
    public Transform player;
    public float enemySpeed;
    public int moveTrigger = 1;
    public int isAttacking;

    public float distanceFromPlayer;

    void Update()
    {
        distanceFromPlayer = Vector3.Distance(target.transform.position, player.transform.position);

        if (distanceFromPlayer <= 10 && moveTrigger == 1)
        {
            transform.LookAt(target);
            StartCoroutine(EnemyDamage());
        }
        if (distanceFromPlayer <10 && moveTrigger == 1 && distanceFromPlayer >3)
        {
            transform.Translate(Vector3.forward * enemySpeed * Time.deltaTime);
        }
    }

    IEnumerator EnemyDamage()
    {
        RaycastHit PlayerHit;
        if (Physics.Raycast(target.transform.position, target.transform.forward, out PlayerHit))
        {
            Debug.Log(PlayerHit.transform.name);
            Target target = PlayerHit.transform.GetComponent<Target>();
            if (target != null)
            {
                yield return new WaitForSeconds(2);
                GlobalHealth.playerHealth -= 1;
                yield return null;
            }
        }
    }
}
您可以使用FixeUpdate→ 设置局部变量bool alreadyShoot=false

在你的敌人伤害中添加一个if!在损坏应用程序之前进行alreadyShoot,并在损坏应用程序之后将alreadyShoot设置为true

在FixeUpdate中,可以将alreadyShoot设置为false


您可以选择其他解决方案将alreadyShoot设置为false,而不是FixedUpdate,例如每秒触发一次的协同程序,

您正在每个更新循环中启动一次协同程序,因此您的伤害协同程序的每一帧都会被调用,并在2秒后应用您的1点伤害。
如果你想在一段时间内造成伤害,使用游戏计时的建议是正确的,但是如果你想让你的敌人只能每x秒攻击一次,你需要对你的伤害功能进行某种冷却。例如,添加Time.deltaTime直到你想要的时间过去,只有这样敌人才能再次造成伤害。你可以用一个布尔值

在更新循环中,检查玩家在射程内的两秒钟时间

float timeInRange = 0.0f;
bool inRange = false;

if (distanceFromPlayer <= 10 && moveTrigger == 1)
{
    inRange = true;
} 
else 
{
    inRange = false;
    timeInRange = 0;
}

if (inRange) 
{
    timeInRange += Time.DeltaTime;
}

if (timeInRange > 2.0f) 
{
    GlobalHealth.playerHealth -= 1;
    timeInRange = 0.0f;
}

正如在其他答案中提到的,您将在每一帧开始一个新的协同路由。当执行从yeild状态退出并重新进入您的协程时,您应该在您的协程中执行所有等待和循环。这就是你写这篇文章的方式

// in update
if (distanceFromPlayer <= 10 && moveTrigger == 1){
        transform.LookAt(target);
        if(!isAttacking)
            StartCoroutine(EnemyDamage());
}

游戏玩家/游戏设计师的发言是:我想对玩家应用“随时间而造成的伤害”点效应请注意,您通常不会以秒为单位进行测量,而是以游戏时间为单位。你正在寻找一个计时器,它实际上是依靠游戏的节拍,而不是实时。
IEnumerator EnemyDamage()
{
    isAttacking = true;
    while(distanceFromPlayer <= 10){ // in range
        RaycastHit PlayerHit;
        if (Physics.Raycast(target.transform.position, target.transform.forward, out PlayerHit)){
            Target target = PlayerHit.transform.GetComponent<Target>();
            if (target != null){
                GlobalHealth.playerHealth -= 1;
                yield return new WaitForSeconds(2);      
            }
        }
    }
    isAttacking = false; // out of range
    yield return null;
}