如何让所有玩家受到敌人的攻击?
问题描述:
我正在构建一个使用团结的生存射击游戏资产的多人游戏,玩家使用网络管理员在场景中产生并具有标签玩家。敌人由敌人管理器产生和管理,搜索玩家标签和使敌人瞄准玩家,但敌人只攻击第一代产生的玩家,而不会攻击之后产生的玩家。如何让所有玩家受到敌人的攻击?
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;
}
}
}
答
有几个问题,你的代码:
- 您在AWAKE事件寻找播放器(仅在 开始运行一次)
- 正在查找的玩家正在使用FindGameObjectWithTag其中只有 返回一个对象。
- 你在没有Network Spawn的情况下会产生敌人,而不会在敌人身上产生敌人 。
通用解决您的复杂问题:
- 让玩家的列表,并经常检查使用调用重复播放器和计数。稍后,使用该列表(玩家列表)来攻击玩家。
- 使用FindGameObjectsWithTag查找玩家,它会返回一个玩家列表。
- 使用Network Spawn在所有客户身上产生敌人。
+0
我明白了你的观点,但是我怎样才能在我的代码上实现它们? –
您的代码片段不会显示脚本,显示敌人如何决定要攻击哪个玩家。但是,一般来说,敌人需要检查所有玩家并决定攻击哪一个,最常见的是选择哪一个最接近。 – Abion47
没有敌人只是攻击玩家第一次spawned.please检查现在添加了敌人的攻击和移动脚本 –
目标是通过调用'GameObject.FindGameObjectWithTag'设置的,它只返回一个对象。你可以使用'GameObject.FindGameObjectsWithTag'获得所有玩家,然后你可以遍历它们来找到最接近的玩家。 (这假设所有的玩家实体都有''玩家''标签。) – Abion47