简体   繁体   English

如何让敌人攻击所有玩家?

[英]How to make enemy attack all the player?

I am building a multiplayer game using unity's survival shooter asset, the player is prefab spawned using network manager in the scene and has tag Player .The enemies are spawned and managed by Enemy Manager that searches for the Player tag and makes enemy target the player,but the enemy only attack the player which is spawned 1st and does not attack the players spawned afterwards.我正在使用 unity 的生存射击游戏资产构建多人游戏,玩家是在场景中使用网络管理器预制生成的,并带有标签Player 。敌人由敌人管理器生成和管理,敌人管理器搜索玩家标签并使敌人瞄准玩家,但是敌人只会攻击第一个生成的玩家,不会攻击之后生成的玩家。

EnemyManager Script敌人管理器脚本

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);
    }
}

Enemy Attack Script敌人攻击脚本

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);
        }
    }
}

Enemy Movement敌人运动

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;
        }
    }
}

Local player Setup Script本地播放器设置脚本

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;
        }

    }

} }

There are couple of problem in your code:您的代码中有几个问题:

  1. You are finding player at AWAKE event (which only runs once at start)您正在AWAKE活动中寻找玩家(在开始时只运行一次)
  2. You are finding player using FindGameObjectWithTag which only returns one object.您正在使用FindGameObjectWithTag寻找玩家,它只返回一个对象。
  3. You are spawning enemy without Network Spawn which will not generate enemy on client.您在没有Network Spawn 的情况下生成敌人,这不会在客户端生成敌人。

Generic solution to your complex problems:复杂问题的通用解决方案:

  1. Make a list of player and Frequently check Players and its count using Invoke repeating.制作玩家列表并使用调用重复经常检查玩家及其计数。 Later, use that list(player list) to attack on player.稍后,使用该列表(玩家列表)攻击玩家。
  2. Find Player using FindGameObjectsWithTag , it will return a list of player.使用FindGameObjectsWithTag查找玩家,它将返回玩家列表。
  3. Use Network Spawn to generate enemy on all clients.使用Network Spawn在所有客户端上生成敌人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM