实例化的敌人对每一个在他之后生成的敌人输出双倍的伤害

本文关键字:敌人 输出 伤害 后生 每一个 实例化 之后 | 更新日期: 2023-09-27 18:16:16

我正在制作一款FPS生存类游戏。我制作了一个GameManager脚本来处理游戏中的敌人刷出部分。我的EnemyAttack脚本处理敌人的攻击。问题是,当第一个敌人出现时,我只受到1点伤害(设置在攻击伤害中),但当第二个敌人出现时,即使我只进入1个敌人的攻击范围,我也会受到2点伤害(攻击伤害* 2)。以下是我所有的敌人脚本:

EnemyAttack.cs :

   using UnityEngine;
   using UnityEngine.UI;
   using System.Collections;
  public class EnemyAttack : MonoBehaviour
  {
public float AttackDamage = 1.0f;
public float AttackSpeed = 1.0f;
void Start() {
    StartCoroutine(Attack());
}
IEnumerator Attack() {
    while (true)
    {
        while (PlayerMovement.isEnemyAttacking == true) {
            EnemyAttacking();
            yield return new WaitForSeconds(AttackSpeed);
        }
        yield return 0;
    }
}
public void EnemyAttacking() {
    Debug.Log("Enemy Attacking!");
    PlayerHealth.Health -= AttackDamage;
    GameObject.FindGameObjectWithTag("HealthPoints").GetComponent<Text>().text = "HEALTH: " + PlayerHealth.Health;
}
 }

EnemyAI.cs :

   using UnityEngine;
      using System.Collections;
        public class EnemyAI : MonoBehaviour {
public Transform TriggerBox;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update()
{
    if (EnemySight.inSight == true)
    {
        NavMeshAgent agent = GetComponent<NavMeshAgent>();
        agent.destination = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>().position;
    }
     }
    }

EnemySight.cs :

     using UnityEngine;
         using System.Collections;
      public class EnemySight : MonoBehaviour {
public static bool inSight = false;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
void OnTriggerEnter(Collider other)
{
    if (other.gameObject.tag == "Player")
    {
        inSight = true;
    }
}
void OnTriggerExit(Collider other) {
    if (other.gameObject.tag == "Player")
    {
        inSight = false;
    }
   }
   }

PlayerHealth.cs :

  using UnityEngine;
  using UnityEngine.UI;
       using System.Collections;
    public class PlayerHealth : MonoBehaviour {
public Transform Player;
public static float Health = 100;
public static float maxHealth = 100;
// Use this for initialization
void Start () {
    GameObject.FindGameObjectWithTag("HealthPoints").GetComponent<Text>().text = "HEALTH: " + Health;
}
// Update is called once per frame
void Update () {
    if (Health <= 0) {
        Dead();
    }
}
public static void Dead() {

}
 }

实例化的敌人对每一个在他之后生成的敌人输出双倍的伤害

你的脚本有几个问题…

我想你不明白静态变量是什么。

静态变量在类

的所有实例中共享其值

来源
public static bool inSight;

不应该是静态的

PlayerMovement.isEnemyAttacking

也不应该是静态的

现在,只要你有一个敌人满足"攻击"条件,你就会设置和读取一个静态变量,导致所有敌人攻击。你应该让你的变量属于每一个敌方实例,不要让你的变量是静态的。

基本上,您只需要了解什么是静态变量。一旦你知道了,你就会明白为什么你的逻辑不起作用。

编辑:解决方案

PlayerHealth脚本。将此脚本附加到场景中的玩家GameObject上。

using UnityEngine;
using UnityEngine.UI;
public class PlayerHealth : MonoBehaviour
{
    public static float Health;
    public static float maxHealth = 100;
    private Text healthText;

    void Start()
    {
        healthText = GameObject.FindGameObjectWithTag("HealthPoints").GetComponent<Text>();
        //Make it full 100% health on start
        Health = maxHealth;
        RefreshHealthBar();
    }

    public void TakeDamage(float damage)
    {
        Health -= damage;
        RefreshHealthBar();
        if (Health <= 0)
            Die();
    }
    public void Die()
    {
        Health = 0;
        RefreshHealthBar();
        //TODO: Your code
    }
    void RefreshHealthBar()
    {
        healthText.text = "HEALTH: " + Health;
    }
}

EnnemyAI脚本。把这个附在你的敌人的预制件上。

 using System.Collections;
using UnityEngine;
public class EnnemyAI : MonoBehaviour
{
    public float AttackDamage = 1.0f;
    public float AttackSpeed = 1.0f;
    public float AttackRange = 1.0f;
    private bool isPlayerInSight;
    private GameObject target;
    private NavMeshAgent agent;

    // Use this for initialization
    void Start ()
    {
        target = GameObject.FindGameObjectWithTag("Player");
        agent = GetComponent<NavMeshAgent>();
        StartCoroutine(AttackLoop());
    }
    // Update is called once per frame
    void Update ()
    {
        if (isPlayerInSight)
        {
            agent.destination = target.transform.position;
        }
    }
    IEnumerator AttackLoop()
    {
        while (true)
        {
            //I don't know your attacking logic, so lets say they can attack in a 1 unit range
            while (Vector3.Distance(target.transform.position, this.transform.position) <= AttackRange)
            {
                Attack();
                yield return new WaitForSeconds(AttackSpeed);
            }
            yield return 0;
        }
    }
    void Attack()
    {
        target.GetComponent<PlayerHealth>().TakeDamage(AttackDamage);
    }
    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "Player")
        {
            isPlayerInSight = true;
        }
    }
    void OnTriggerExit(Collider other)
    {
        if (other.gameObject.tag == "Player")
        {
            isPlayerInSight = false;
        }
    }
}
  1. 出于性能原因,我将FindGameObjectWithTag从Update()循环中取出。
  2. 玩家不再监听攻击相反,敌人会向玩家发送伤害。

这样我们就摆脱了静态变量