Этот урок описывает реализацию механизма стрельбы в многопользовательском 3D шутере на Unity. Мы создадим скрипты для стрельбы, отслеживания попаданий и синхронизации действий между клиентами и сервером.
Скрипты Weapon и PlayerShoot
К игровому объекту (игроку) добавим скрипт PlayerShoot. Создадим отдельный скрипт Weapon (Оружие) для хранения параметров оружия. PlayerShoot унаследует NetworkBehaviour для работы с сетевыми функциями Unity. Weapon будет сериализуемым ([System.Serializable]) для настройки в редакторе Unity.
Скрипт Weapon
Скрипт Weapon содержит публичные поля:
- public string name: Название оружия (например, «Пистолет»).
- public float damage: Урон (например, 10 единиц).
- public float range: Дальность стрельбы (например, 100 единиц).
Этот скрипт — простая структура данных для хранения характеристик оружия.
Скрипт PlayerShoot
Скрипт PlayerShoot содержит:
- public Weapon weapon: Ссылка на объект типа Weapon.
- private Camera cam: Ссылка на камеру игрока (присваивается в редакторе Unity).
Метод Start:
В Start проверяется наличие камеры. Если cam == null, выводится сообщение Debug.LogError("No Camera"), и скрипт отключается (this.enabled = false).
Метод Update:
В Update обрабатывается нажатие левой кнопки мыши (Input.GetButtonDown("Fire1")). При нажатии:
- Создается переменная RaycastHit hit.
- Выполняется Physics.Raycast для обнаружения коллайдера:
- cam.transform.position: Начальная точка луча.
- cam.transform.forward: Направление луча.
- hit: Переменная для хранения информации о попадании.
- weapon.range: Максимальная дальность луча.
- layerMask: Маска слоев, в которые разрешено попадать.
- Если Physics.Raycast возвращает true, выводится сообщение Debug.Log("Выстрелили и попали в " + hit.collider.name).
Настройка слоев и сетевая синхронизация
Для многопользовательского режима настроим слои для локальных и удаленных игроков. Добавим слои Local Player и Remote Player. В скрипте PlayerSetup назначим слой Local Player локальному игроку и Remote Player — удаленным. Это предотвратит проблемы с двойным выстрелом.
Уникальные имена игроков
Для предотвращения клонирования игроков, каждому игроку присвоим уникальное имя. В PlayerSetup, в методе Start, изменим имя игрового объекта:
transform.name = "Player " + GetComponent<NetworkIdentity>().netId;
Сетевые функции
Для синхронизации создадим сетевую функцию CmdPlayerShoot. Она вызывается на сервере и принимает идентификатор игрока (string _id):
Debug.Log(_id + " выстрелил");
В PlayerShoot добавим функцию Shot, вызываемую на клиенте при выстреле. Если выстрел попадает в игрока, вызывается CmdPlayerShoot.
В этом уроке реализован базовый функционал стрельбы, включая обнаружение попаданий и синхронизацию. Дальнейшая работа будет посвящена добавлению урона, эффектов и других улучшений. Базовая физика стрельбы реализована, и обработка происходит на сервере, обеспечивая целостность игрового процесса.