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

时间:2017-02-11 03:41:26

标签: c# unity3d multiplayer

我正在使用团结生存射击游戏资产构建多人游戏,玩家使用网络管理器在场景中生成预制件并标记玩家。敌人由敌人生成和管理搜索玩家标记并让敌人瞄准玩家的经理,但敌人只攻击第一个产生的玩家并且不会攻击后来产生的玩家。

EnemyManager脚本

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 个答案:

答案 0 :(得分:0)

您的代码中存在几个问题:

  1. 您正在AWAKE事件中找到玩家(仅在该事件中运行一次) 启动)
  2. 您只能使用 FindGameObjectWithTag 找到玩家 返回一个对象。
  3. 你是在没有Network Spawn的情况下产生敌人的     在客户端产生敌人。
  4. 解决复杂问题的通用解决方案:

    1. 制作播放器列表,并使用Invoke重复频繁查看播放器及其计数。之后,使用该列表(玩家列表)攻击玩家。
    2. 使用FindGameObjectsWithTag查找播放器,它将返回播放器列表。
    3. 使用Network Spawn在所有客户端上生成敌人。