如何让敌人攻击所有玩家



我正在使用 Unity 的生存射击游戏资源构建一个多人游戏,玩家是使用场景中的网络管理器生成的预制件,并具有标记播放器。敌人由敌人管理器生成和管理,该管理器搜索玩家标签并使敌人成为玩家的目标,但敌人只攻击生成第一个的玩家,不会攻击之后生成的玩家

敌人管理器脚本

public class EnemyManager : MonoBehaviour
{
    PlayerHealth playerHealth;       // Reference to the player's heatlh.
    public GameObject enemy;                // The enemy prefab to be spawned.
    public float spawnTime = 3f;            // How long between each spawn.
    public Transform[] spawnPoints;         // An array of the spawn points this enemy can spawn from.

    void Start ()
    {
        // Call the Spawn function after a delay of the spawnTime and then continue to call after the same amount of time.
        playerHealth = GameObject.FindWithTag("Player").GetComponent<PlayerHealth>();
        InvokeRepeating ("Spawn", spawnTime, spawnTime);
    }

    void Spawn ()
    {
        // If the player has no health left...
        if(playerHealth.currentHealth <= 0f)
        {
            // ... exit the function.
            return;
        }
        // Find a random index between zero and one less than the number of spawn points.
        int spawnPointIndex = Random.Range (0, spawnPoints.Length);
        // Create an instance of the enemy prefab at the randomly selected spawn point's position and rotation.
        Instantiate (enemy, spawnPoints[spawnPointIndex].position, spawnPoints[spawnPointIndex].rotation);
    }
}

敌人攻击脚本

public class EnemyAttack : MonoBehaviour
{
    public float timeBetweenAttacks = 0.5f;     // The time in seconds between each attack.
    public int attackDamage = 10;               // The amount of health taken away per attack.

    Animator anim;                              // Reference to the animator component.
    GameObject player;                          // Reference to the player GameObject.
    PlayerHealth playerHealth;                  // Reference to the player's health.
    EnemyHealth enemyHealth;                    // Reference to this enemy's health.
    bool playerInRange;                         // Whether player is within the trigger collider and can be attacked.
    float timer;                                // Timer for counting up to the next attack.

    void Awake ()
    {
        // Setting up the references.
        player = GameObject.FindGameObjectWithTag ("Player");
        playerHealth = player.GetComponent <PlayerHealth> ();
        enemyHealth = GetComponent<EnemyHealth>();
        anim = GetComponent <Animator> ();
    }

    void OnTriggerEnter (Collider other)
    {
        // If the entering collider is the player...
        if(other.gameObject == player)
        {
            // ... the player is in range.
            playerInRange = true;
        }
    }

    void OnTriggerExit (Collider other)
    {
        // If the exiting collider is the player...
        if(other.gameObject == player)
        {
            // ... the player is no longer in range.
            playerInRange = false;
        }
    }

    void Update ()
    {
        // Add the time since Update was last called to the timer.
        timer += Time.deltaTime;
        // If the timer exceeds the time between attacks, the player is in range and this enemy is alive...
        if(timer >= timeBetweenAttacks && playerInRange && enemyHealth.currentHealth > 0)
        {
            // ... attack.
            Attack ();
        }
        // If the player has zero or less health...
        if(playerHealth.currentHealth <= 0)
        {
            // ... tell the animator the player is dead.
            anim.SetTrigger ("PlayerDead");
        }
    }

    void Attack ()
    {
        // Reset the timer.
        timer = 0f;
        // If the player has health to lose...
        if(playerHealth.currentHealth > 0)
        {
            // ... damage the player.
            playerHealth.TakeDamage (attackDamage);
        }
    }
}

敌人运动

public class EnemyMovement : MonoBehaviour
{
    Transform player;               // Reference to the player's position.
    PlayerHealth playerHealth;      // Reference to the player's health.
    EnemyHealth enemyHealth;        // Reference to this enemy's health.
    NavMeshAgent nav;
    void Awake ()
    {
        // Set up the references.
        player = GameObject.FindGameObjectWithTag ("Player").transform;
        playerHealth = player.GetComponent<PlayerHealth>();
        enemyHealth = GetComponent <EnemyHealth> ();
        nav = GetComponent <NavMeshAgent> ();
    }

    void Update ()
    {
        // If the enemy and the player have health left...
        if(enemyHealth.currentHealth > 0 && playerHealth.currentHealth > 0)
        {
            // ... set the destination of the nav mesh agent to the player.
            nav.SetDestination (player.position);
        }
        // Otherwise...
        else
        {
            // ... disable the nav mesh agent.
            nav.enabled = false;
        }
    }
}

本地播放器设置脚本

public class LocalPlayerSetup : NetworkBehaviour {
    void Start()
    {
        GameObject.FindGameObjectWithTag ("EnemyManager").SetActiveRecursively (true);
        if (isLocalPlayer) {
            GameObject.FindGameObjectWithTag ("MainCamera").GetComponent<CameraFollow> ().enabled = true;
            GetComponent<PlayerMovement> ().enabled = true;
            GetComponentInChildren<PlayerShooting> ().enabled = true;
        }
    }

}

你的代码中有几个问题:

  1. 您正在 AWAKE 事件中找到玩家(该事件仅在开始(
  2. 您正在使用FindGameObjectWithTag查找播放器,其中只有返回一个对象。
  3. 你正在生成没有网络生成的敌人,这不会 在客户端上生成敌人。

复杂问题的通用解决方案:

  1. 列出玩家列表,并使用调用重复频繁检查玩家及其计数。稍后,使用该列表(玩家列表(攻击玩家。
  2. 使用FindGameObjectsWithTag查找玩家,它将返回玩家列表。
  3. 使用网络生成在所有客户端上生成敌人。

最新更新