Создание скриптов
Создадим скрипты CSPlayer, общий скрипт для игроков, и GameManager, главный скрипт для управления игрой. GameManager будет рассмотрен первым.
GameManager: отслеживание и управление игроками
GameManager отслеживает игроков, храня их в словаре (Dictionary). Это эффективнее, чем поиск игроков методом Find, который сильно нагружает программу.
Используем System.Collections.Generic для работы со словарями. Объявляем словарь players как private static:
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
private static Dictionary<string, CSPlayer> players = new Dictionary<string, CSPlayer>();
// ... (остальной код будет добавлен ниже)
}
Методы работы со словарем игроков
Создадим методы для добавления, удаления и получения игроков по ID:
- RegisterPlayer(string neid, CSPlayer player): Регистрирует игрока. Получает ID игрока (neid) и объект игрока (player). Ключ формируется с префиксом "Player ":
public static void RegisterPlayer(string neid, CSPlayer player)
{
const string PlayerIDPrefix = "Player ";
string playerID = PlayerIDPrefix + neid;
player.transform.name = playerID;
players.Add(playerID, player);
}
- UnregisterPlayer(string playerID): Удаляет игрока по ID.
public static void UnregisterPlayer(string playerID)
{
players.Remove(playerID);
}
- GetPlayer(string playerID): Возвращает игрока по ID.
public static CSPlayer GetPlayer(string playerID)
{
return players[playerID];
}
PlayerSetup: автоматическое подключение CSPlayer
В скрипте PlayerSetup добавим автоматическое подключение скрипта CSPlayer:
[RequireComponent(typeof(CSPlayer))]
// ... остальной код PlayerSetup
Перепишем OnStartClient для регистрации игрока в GameManager:
public override void OnStartClient()
{
string neid = GetComponent<NetworkIdentity>().netId.ToString();
CSPlayer player = GetComponent<CSPlayer>();
GameManager.RegisterPlayer(neid, player);
}
В OnDisable удалим игрока из списка GameManager:
public override void OnDisable()
{
GameManager.UnregisterPlayer(transform.name);
}
CSPlayer: получение и обработка урона
В CSPlayer добавим переменные для здоровья и метод обработки урона:
using UnityEngine;
using UnityEngine.Networking;
public class CSPlayer : NetworkBehaviour
{
[SyncVar]
private float maxHealth = 100f;
[SyncVar]
private float currentHealth;
void Awake()
{
currentHealth = maxHealth;
}
[ClientRpc]
public void RpcTakeDamage(float damage)
{
currentHealth -= damage;
Debug.Log($"Player {transform.name} health: {currentHealth}");
}
}
[SyncVar] синхронизирует maxHealth и currentHealth между клиентами. RpcTakeDamage — ClientRpc, вызываемый на всех клиентах для отображения урона.
Интеграция в Unity
Добавим скрипты CSPlayer и GameManager к соответствующим объектам. Сообщения об уроне отображаются на сервере. Создадим сервер и подключимся к нему клиентом. Стрельба по игроку вызовет RpcTakeDamage и уменьшит здоровье.
Мы научились наносить урон, используя синхронизацию данных и обработку событий на сервере и клиентах. Дальнейшие улучшения могут включать обработку смерти и эффекты урона.