Перейти к содержимому

Как создать свой шутер от первого лица

  • автор:

Создание шутера на Unity3D

3D шутер c мультиплеером в Unity / Урок #1 - Начало

3D шутер c мультиплеером в Unity / Урок #1 — Начало

Приступаем к видеокурсу по созданию шутера на Unity. Это будет полноценная 3D игра с возможностью мультиплеера. За курс мы узнаем как сделать шутер в Unity (Unity3D) с возможностью игры по серверу.

Видеоурок

Полезные ссылки:

  1. Официальный сайт Unity ;
Информация про Unity

Unity – это игровой движок, на котором строится большая часть современных игр на разных платформах. Посредством движка реально создавать игры, ориентированные на запуск на компьютерах (Windows, Linux, MacOS), мобильных телефонах, планшетных компьютерах (Android, iOS, Windows Phone) и даже игровых приставках PlayStation, Xbox, Nintendo.

Создание игр на движке Unity невозможно представить без написания дополнительного кода. В Unity поддерживается два языка программирования — JavaScript и C# . Раньше также поддерживался язык Boo, но позже от него отказались.

Вы можете самостоятельно выбрать на каком языке программировать в Unity, так как особого значения это не имеет. Большинство разработчиков дают предпочтение языку C# , так как он более мощный и найти различную документацию намного проще, нежели для языка JavaScript .

В Unity используется встроенные функции, которых нет ни в C#, ни в JavaScript. За счёт этого особо не имеет значения знает вы язык программирования или нет. Тем не менее, мы все же рекомендуем сперва пройти курс по изучению языка C#. Курс представлен на нашем сайте по этой ссылке .

Как сделать шутер на Unity?

Разработка игр на Unity ведется в два этапа:

  • построения дизайна через Unity графический дизайнер;
  • написание скриптов через язык C#.

Мы за курс будем делать стрелялку на Unity с возможностью игры по сети. Для создания своей игры стрелялки необходимо продумать дизайн основных игроков, добавить к ним оружие и продумать систему выстрелов на основе RayCast.

Шутер на Юнити создается столь же просто, как и другие проекты.

План курса

Наша игра не будет иметь потрясающего сюжета или же красивого дизайна, так как нашей задачей является создание всей механики и настройка мультиплеера в игре. Мы построим небольшую карту с игроками, добавим механику передвижения, механику стрельбы и проработаем все классы для создания шутера в Unity3d .

Для реализации мультиплеера мы будем использовать возможности серверов от Unity. Unity предоставляет бесплатный и очень удобный функционал, который можно использовать для подобных целей.

В ходе курса вы не только научитесь создавать шутер с мультиплеером, но также улучшите свои знания и навыки в создании игр на движке Unity.

Как сделать свой собственный шутер от первого лица бесплатно

В те поздние субботние вечера одним из моих самых ярких воспоминаний о моих студенческих днях была игра в сетевую игру DOOM на основе кофеина в инженерной компьютерной лаборатории. Шутеры от первого лица стали важным инструментом в моем репертуаре мероприятий по снижению стресса.

Даже после начала моей первой работы, если бы у меня был тяжелый день на работе, я запускал Quake и запускал несколько раундов — взрывая зверей и существ в забвение. Никогда за миллион лет я не думал, что когда-либо будет возможно создать свои собственные бесплатные шутеры от первого лица, которые будут иметь такой же уровень детализации, эффекты и действия, как эти потрясающие шутеры от первого лица, без глубокого знания компьютера программирование и графический дизайн.

Что ж, настал день, когда любой, кто может указать и щелкнуть, имеет возможность создавать сложные и увлекательные игровые уровни для шутера от первого лица, который настолько прост или подробен, насколько вам нравится. Благодаря удивительному программному обеспечению под названием FPS Creator , теперь вы можете бесплатно создавать свою собственную игру, включающую комнаты, проходы, предметы, уровни и врагов по вашему выбору — это шутер от первого лица в виртуальном мире, который вы можете создавать с нуля без зная одну вещь о компьютерном программировании.

Как сделать свою игру бесплатно

Есть одна важная вещь, которую вы должны знать о бесплатной версии FPS Creator, прежде чем начать, и это то, что хотя вы можете создать свою многоуровневую игру, используя все функции, доступные в полной версии, вы не можете создать автономный исполняемый файл, который вы можете распространять среди своих друзей для игры.

Хотя это является серьезным недостатком, не страшно, если вы собираетесь использовать программное обеспечение так же, как если бы вы использовали программу, подобную SimCity — вы можете создавать свои игровые уровни, а затем сидеть сложа руки и играть в них, нажимая « Test Level» . это все равно что представить свою любимую игру-шутер, создать ее, а затем иметь возможность играть на уровне, о котором ты мечтал.

бесплатные шутеры от первого лица

Область разработки этого программного обеспечения — просто гигантская сетка. В этой сетке вы размещаете коридоры, комнаты, объекты, врагов, предметы и все остальное, что существует в библиотеке объектов программного обеспечения — что довольно обширно. Например, если вы щелкнете по библиотеке сегментов в левой части меню, вы обнаружите набор общих комнат и коридоров, а также несколько наборов, настроенных для определенной темы — научной фантастики и Второй мировой войны.

бесплатные шутеры от первого лица

Все, что вам нужно сделать, чтобы построить свои уровни, — это дважды щелкнуть мышью по вашему выбору, а затем поместить их в сетку так, как вы этого хотите. Нажмите «R», чтобы повернуть ориентацию на 90 градусов. Если вы не знаете, что делать, просто нажмите « Справка » и откройте руководство.

Руководство для этого программного обеспечения на самом деле является очень хорошо написанным документом, который чрезвычайно полезен, если вы застряли. Тем не менее, шансы довольно хорошие, у вас не возникнет никаких проблем — кривая обучения для этого приложения дизайна не очень крутая.

сделайте свои бесплатные шутеры от первого лица

Конечно, ни одна шутер от первого лица не обходится без врагов. Враги находятся в библиотеке « Сущность », которая также содержит мебель и другие предметы, которые вы поместите в комнаты. Не забывайте нажимать на предметы и складывать оружие и боеприпасы, чтобы ваш персонаж мог подобрать их, или вы обнаружите, что пытаетесь пройти опасный игровой уровень без каких-либо средств защиты!

бесплатные шутеры от первого лица

Дизайн игры не может быть проще, чем этот. Это просто вопрос выбора нужных объектов и размещения их в сетке в правильной ориентации. Здесь я создал очень маленький уровень со стартовой прихожей, комнатой с безоружным ИИ-персонажем, а затем еще одну прихожую с врагом, ожидающим прямо за углом.

как сделать бесплатные шутеры от первого лица

Когда вы закончите создание и сохранение уровня, просто нажмите « Тестовый уровень » — и после того, как программа закончит рендеринг всех ваших объектов, предметов, врагов и других элементов вашего дизайна, вы окажетесь в середине из опасного виртуального мира, который вы создали. Ваша миссия, если вы решите принять это, — пройти через это живым.

Как сделать свой собственный шутер от первого лица бесплатно fpsfree6

Здесь вы можете увидеть мой первый коридор, где я положил оружие (узи) и достаточно патронов, чтобы начать. Сразу за отверстием находится комната, а затем угрожающий коридор справа, освещенный только красными огнями.

Как сделать свой собственный шутер от первого лица бесплатно fpsfree7

Выйдя за угол, я замечаю своего безобидного (я думаю) персонажа ИИ. Я заглядываю за угол, а он не двигается. Подойдя ближе к нему, он присел на землю … этот парень не сделает муху больно. Я заметил, что в углу комнаты я создал лестницу, которая поднимается до потолка без отверстий — упс! Лестница и верхние уровни требуют некоторого привыкания, но создание коридоров и комнат совсем несложно.

Когда я направился вниз по освещенному красным коридору, я осторожно двинулся, поскольку знал, что поставил врага за угол — злобного вида научно-фантастического персонажа-врага с автоматом. Конечно же, как только я вышел за угол, она последовала за мной и начала стрелять.

шутер от первого лица

Реализм атаки был приличным. После каждого удара брызги крови были, а в стенах и полу остались пулевые отверстия, как и немного крови от боя. Реализм этой игры распространяется не только на стрельбу и кровь. Проходя уровень, вы заметите звуковые эффекты и атмосферу, которые вы ожидаете от профессиональных шутеров от первого лица.

Вы можете слышать ваши шаги, когда вы идете, ваше оружие стреляет и перезаряжается звучит реалистично, и поведение врагов в атаке довольно агрессивно, но с достаточной паузой, так что если вы будете достаточно быстры, вы сможете убрать их до того, как тебя убьют.

Хотите сделать свои собственные бесплатные шутеры от первого лица? Загрузите копию FPS Creator сегодня, сделайте это и дайте нам знать, что вы думаете в разделе комментариев ниже.

Как создать шутер от первого лица с поддержкой ИИ в Unity

Шутер от первого лица (FPS) — это поджанр игр-шутеров, в которых игроком управляют от первого лица.

Чтобы создать игру FPS в Unity, нам понадобится контроллер игрока, набор предметов (в данном случае оружия) и враги.

Шаг 1. Создайте контроллер проигрывателя

Здесь мы создадим контроллер, который будет использоваться нашим плеером.

  • Создайте новый игровой объект (Game Object -> Create Empty) и назовите его. «Player»
  • Создайте новую капсулу (Игровой объект -> 3D-объект -> Капсула) и переместите ее внутрь объекта «Player».
  • Удалите компонент Capsule Collider из Capsule и измените его положение на (0, 1, 0).
  • Переместите основную камеру внутри объекта «Player» и измените ее положение на (0, 1.64, 0).
  • Создайте новый скрипт, назовите его «SC_CharacterController» и вставьте в него приведенный ниже код:

SC_CharacterController.cs

using UnityEngine; [RequireComponent(typeof(CharacterController))] public class SC_CharacterController : MonoBehaviour < public float speed = 7.5f; public float jumpSpeed = 8.0f; public float gravity = 20.0f; public Camera playerCamera; public float lookSpeed = 2.0f; public float lookXLimit = 45.0f; CharacterController characterController; Vector3 moveDirection = Vector3.zero; Vector2 rotation = Vector2.zero; [HideInInspector] public bool canMove = true; void Start() < characterController = GetComponent(); rotation.y = transform.eulerAngles.y; > void Update() < if (characterController.isGrounded) < // We are grounded, so recalculate move direction based on axes Vector3 forward = transform.TransformDirection(Vector3.forward); Vector3 right = transform.TransformDirection(Vector3.right); float curSpeedX = canMove ? speed * Input.GetAxis("Vertical") : 0; float curSpeedY = canMove ? speed * Input.GetAxis("Horizontal") : 0; moveDirection = (forward * curSpeedX) + (right * curSpeedY); if (Input.GetButton("Jump") && canMove) < moveDirection.y = jumpSpeed; >> // Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below // when the moveDirection is multiplied by deltaTime). This is because gravity should be applied // as an acceleration (ms^-2) moveDirection.y -= gravity * Time.deltaTime; // Move the controller characterController.Move(moveDirection * Time.deltaTime); // Player and Camera rotation if (canMove) < rotation.y += Input.GetAxis("Mouse X") * lookSpeed; rotation.x += -Input.GetAxis("Mouse Y") * lookSpeed; rotation.x = Mathf.Clamp(rotation.x, -lookXLimit, lookXLimit); playerCamera.transform.localRotation = Quaternion.Euler(rotation.x, 0, 0); transform.eulerAngles = new Vector2(0, rotation.y); >> >
  • Прикрепите скрипт SC_CharacterController к объекту «Player» (вы заметите, что он также добавил еще один компонент под названием «Контроллер символов», изменив его центральное значение на (0, 1, 0))
  • Назначьте основную камеру переменной Player Camera в SC_CharacterController.

Контроллер Player теперь готов:

Шаг 2: Создайте систему оружия

Система оружия игрока будет состоять из трех компонентов: менеджера оружия, сценария оружия и сценария пули.

  • Создайте новый скрипт, назовите его «SC_WeaponManager» и вставьте в него приведенный ниже код:

SC_WeaponManager.cs

using UnityEngine; public class SC_WeaponManager : MonoBehaviour < public Camera playerCamera; public SC_Weapon primaryWeapon; public SC_Weapon secondaryWeapon; [HideInInspector] public SC_Weapon selectedWeapon; // Start is called before the first frame update void Start() < //At the start we enable the primary weapon and disable the secondary primaryWeapon.ActivateWeapon(true); secondaryWeapon.ActivateWeapon(false); selectedWeapon = primaryWeapon; primaryWeapon.manager = this; secondaryWeapon.manager = this; >// Update is called once per frame void Update() < //Select secondary weapon when pressing 1 if (Input.GetKeyDown(KeyCode.Alpha1)) < primaryWeapon.ActivateWeapon(false); secondaryWeapon.ActivateWeapon(true); selectedWeapon = secondaryWeapon; >//Select primary weapon when pressing 2 if (Input.GetKeyDown(KeyCode.Alpha2)) < primaryWeapon.ActivateWeapon(true); secondaryWeapon.ActivateWeapon(false); selectedWeapon = primaryWeapon; >> >
  • Создайте новый скрипт, назовите его «SC_Weapon» и вставьте в него приведенный ниже код:

SC_Weapon.cs

using System.Collections; using UnityEngine; [RequireComponent(typeof(AudioSource))] public class SC_Weapon : MonoBehaviour < public bool singleFire = false; public float fireRate = 0.1f; public GameObject bulletPrefab; public Transform firePoint; public int bulletsPerMagazine = 30; public float timeToReload = 1.5f; public float weaponDamage = 15; //How much damage should this weapon deal public AudioClip fireAudio; public AudioClip reloadAudio; [HideInInspector] public SC_WeaponManager manager; float nextFireTime = 0; bool canFire = true; int bulletsPerMagazineDefault = 0; AudioSource audioSource; // Start is called before the first frame update void Start() < bulletsPerMagazineDefault = bulletsPerMagazine; audioSource = GetComponent(); audioSource.playOnAwake = false; //Make sound 3D audioSource.spatialBlend = 1f; > // Update is called once per frame void Update() < if (Input.GetMouseButtonDown(0) && singleFire) < Fire(); >if (Input.GetMouseButton(0) && !singleFire) < Fire(); >if (Input.GetKeyDown(KeyCode.R) && canFire) < StartCoroutine(Reload()); >> void Fire() < if (canFire) < if (Time.time >nextFireTime) < nextFireTime = Time.time + fireRate; if (bulletsPerMagazine >0) < //Point fire point at the current center of Camera Vector3 firePointPointerPosition = manager.playerCamera.transform.position + manager.playerCamera.transform.forward * 100; RaycastHit hit; if (Physics.Raycast(manager.playerCamera.transform.position, manager.playerCamera.transform.forward, out hit, 100)) < firePointPointerPosition = hit.point; >firePoint.LookAt(firePointPointerPosition); //Fire GameObject bulletObject = Instantiate(bulletPrefab, firePoint.position, firePoint.rotation); SC_Bullet bullet = bulletObject.GetComponent(); //Set bullet damage according to weapon damage value bullet.SetDamage(weaponDamage); bulletsPerMagazine--; audioSource.clip = fireAudio; audioSource.Play(); > else < StartCoroutine(Reload()); >> > > IEnumerator Reload() < canFire = false; audioSource.clip = reloadAudio; audioSource.Play(); yield return new WaitForSeconds(timeToReload); bulletsPerMagazine = bulletsPerMagazineDefault; canFire = true; >//Called from SC_WeaponManager public void ActivateWeapon(bool activate) < StopAllCoroutines(); canFire = true; gameObject.SetActive(activate); >>
  • Создайте новый скрипт, назовите его «SC_Bullet» и вставьте в него приведенный ниже код:

SC_Bullet.cs

using System.Collections; using UnityEngine; public class SC_Bullet : MonoBehaviour < public float bulletSpeed = 345; public float hitForce = 50f; public float destroyAfter = 3.5f; float currentTime = 0; Vector3 newPos; Vector3 oldPos; bool hasHit = false; float damagePoints; // Start is called before the first frame update IEnumerator Start() < newPos = transform.position; oldPos = newPos; while (currentTime < destroyAfter && !hasHit) < Vector3 velocity = transform.forward * bulletSpeed; newPos += velocity * Time.deltaTime; Vector3 direction = newPos - oldPos; float distance = direction.magnitude; RaycastHit hit; // Check if we hit anything on the way if (Physics.Raycast(oldPos, direction, out hit, distance)) < if (hit.rigidbody != null) < hit.rigidbody.AddForce(direction * hitForce); IEntity npc = hit.transform.GetComponent(); if (npc != null) < //Apply damage to NPC npc.ApplyDamage(damagePoints); >> newPos = hit.point; //Adjust new position StartCoroutine(DestroyBullet()); > currentTime += Time.deltaTime; yield return new WaitForFixedUpdate(); transform.position = newPos; oldPos = newPos; > if (!hasHit) < StartCoroutine(DestroyBullet()); >> IEnumerator DestroyBullet() < hasHit = true; yield return new WaitForSeconds(0.5f); Destroy(gameObject); >//Set how much damage this bullet will deal public void SetDamage(float points) < damagePoints = points; >>

Теперь вы заметите, что сценарий SC_Bullet содержит некоторые ошибки. Это потому, что нам осталось сделать последнее — определить интерфейс IEntity.

Интерфейсы в C# полезны, когда вам нужно убедиться, что в скрипте, который их использует, реализованы определенные методы.

Интерфейс IEntity будет иметь один метод ApplyDamage, который позже будет использоваться для нанесения урона врагам и нашему игроку.

  • Создайте новый скрипт, назовите его «SC_InterfaceManager» и вставьте в него приведенный ниже код:

SC_InterfaceManager.cs

//Entity interafce interface IEntity

Настройка менеджера оружия

Менеджер оружия — это объект, который будет находиться под объектом «Основная камера» и содержать все оружие.

  • Создайте новый GameObject и назовите его. «WeaponManager»
  • Переместите WeaponManager внутри основной камеры игрока и измените его положение на (0, 0, 0).
  • Прикрепите скрипт SC_WeaponManager к «WeaponManager»
  • Назначьте основную камеру переменной Player Camera в SC_WeaponManager.

Настройка винтовки

  • Перетащите модель оружия на сцену (или просто создайте куб и растяните его, если у вас еще нет модели).
  • Масштабируйте модель так, чтобы ее размер соответствовал размеру Player Capsule.

В моем случае я буду использовать изготовленную на заказ модель винтовки (BERGARA BA13):

БЕРГАРА BA13

  • Создайте новый GameObject и назовите его «Rifle», затем переместите в него модель винтовки.
  • Переместите объект «Rifle» внутрь объекта «WeaponManager» и поместите его перед камерой следующим образом:

Исправьте проблему с отсечением камеры в Unity.

Чтобы исправить отсечение объекта, просто измените ближнюю плоскость отсечения камеры на что-нибудь меньшее (в моем случае я установил ее на 0,15):

БЕРГАРА BA13

  • Прикрепите скрипт SC_Weapon к объекту винтовки (вы заметите, что он также добавил компонент Audio Source, он необходим для воспроизведения звука стрельбы и перезарядки).

Как видите, SC_Weapon можно назначить 4 переменные. Вы можете сразу назначить переменные Fire audio и Reload audio, если в вашем проекте есть подходящие аудиоклипы.

Переменная Bullet Prefab будет объяснена позже в этом уроке.

На данный момент мы просто назначим переменную Fire point:

  • Создайте новый GameObject, переименуйте его в «FirePoint» и переместите внутрь объекта Rifle. Поместите его прямо перед бочкой или немного внутри, вот так:

  • Назначьте FirePoint Transform переменной Fire point в SC_Weapon.
  • Назначьте винтовку переменной вторичного оружия в скрипте SC_WeaponManager.

Настройка пистолета-пулемета

  • Дублируйте объект «Винтовка» и переименуйте его в «Пистолет-пулемет».
  • Замените внутри него модель пистолета на другую модель (В моем случае я буду использовать кастомную модель TAVOR X95)

ТАВОР X95

  • Переместите преобразование Fire Point, пока оно не будет соответствовать новой модели.

Настройка объекта Weapon Fire Point в Unity.

  • Назначьте пистолет-пулемет переменной основного оружия в скрипте SC_WeaponManager.

Настройка префаба Bullet

Префаб пули будет генерироваться в зависимости от скорострельности оружия и будет использовать Raycast, чтобы определить, попало ли оно во что-нибудь и нанесло ли оно урон.

  • Создайте новый GameObject и назовите его. «Bullet»
  • Добавьте к нему компонент Trail Renderer и измените его переменную Time на 0,1.
  • Установите для кривой ширины меньшее значение (например, начало 0,1, конец 0), чтобы добавить заостренный след.
  • Создайте новый материал, назовите его Bullet_trail_material и измените его шейдер на Particles/Additive.
  • Назначьте вновь созданный материал средству Trail Renderer.
  • Измените цвет средства визуализации следа на другой (например, начало: ярко-оранжевый, конец: темно-оранжевый).

  • Сохраните объект Bullet в Prefab и удалите его со сцены.
  • Назначьте недавно созданный префаб (перетащите его из представления «Проект») переменной префаба винтовки и пули-пулемета.

Оружие теперь готово.

Шаг 3: Создайте вражеский ИИ

Врагами будут простые кубы, которые будут следовать за игроком и атаковать, как только они подойдут достаточно близко. Они будут атаковать волнами, причем с каждой волной придется уничтожить все больше врагов.

Настройка ИИ противника

Ниже я создал 2 варианта Куба (левый предназначен для живого экземпляра, а правый будет создан после убийства врага):

  • Добавьте компонент Rigidbody как в мертвые, так и в живые экземпляры.
  • Сохраните мертвый экземпляр в Prefab и удалите его из сцены.

Теперь живому экземпляру понадобится еще пара компонентов, чтобы иметь возможность перемещаться по игровому уровню и наносить игроку урон.

  • Создайте новый скрипт и назовите его «SC_NPCEnemy», затем вставьте в него приведенный ниже код:

SC_NPCEnemy.cs

using UnityEngine; using UnityEngine.AI; [RequireComponent(typeof(NavMeshAgent))] public class SC_NPCEnemy : MonoBehaviour, IEntity < public float attackDistance = 3f; public float movementSpeed = 4f; public float npcHP = 100; //How much damage will npc deal to the player public float npcDamage = 5; public float attackRate = 0.5f; public Transform firePoint; public GameObject npcDeadPrefab; [HideInInspector] public Transform playerTransform; [HideInInspector] public SC_EnemySpawner es; NavMeshAgent agent; float nextAttackTime = 0; // Start is called before the first frame update void Start() < agent = GetComponent(); agent.stoppingDistance = attackDistance; agent.speed = movementSpeed; //Set Rigidbody to Kinematic to prevent hit register bug if (GetComponent()) < GetComponent().isKinematic = true; > > // Update is called once per frame void Update() < if (agent.remainingDistance - attackDistance < 0.01f) < if(Time.time >nextAttackTime) < nextAttackTime = Time.time + attackRate; //Attack RaycastHit hit; if(Physics.Raycast(firePoint.position, firePoint.forward, out hit, attackDistance)) < if (hit.transform.CompareTag("Player")) < Debug.DrawLine(firePoint.position, firePoint.position + firePoint.forward * attackDistance, Color.cyan); IEntity player = hit.transform.GetComponent(); player.ApplyDamage(npcDamage); > > > > //Move towardst he player agent.destination = playerTransform.position; //Always look at player transform.LookAt(new Vector3(playerTransform.transform.position.x, transform.position.y, playerTransform.position.z)); > public void ApplyDamage(float points) < npcHP -= points; if(npcHP <= 0) < //Destroy the NPC GameObject npcDead = Instantiate(npcDeadPrefab, transform.position, transform.rotation); //Slightly bounce the npc dead prefab up npcDead.GetComponent().velocity = (-(playerTransform.position - transform.position).normalized * 8) + new Vector3(0, 5, 0); Destroy(npcDead, 10); es.EnemyEliminated(this); Destroy(gameObject); > > >
  • Создайте новый скрипт, назовите его «SC_EnemySpawner» и вставьте в него приведенный ниже код:

SC_EnemySpawner.cs

using UnityEngine; using UnityEngine.SceneManagement; public class SC_EnemySpawner : MonoBehaviour < public GameObject enemyPrefab; public SC_DamageReceiver player; public Texture crosshairTexture; public float spawnInterval = 2; //Spawn new enemy each n seconds public int enemiesPerWave = 5; //How many enemies per wave public Transform[] spawnPoints; float nextSpawnTime = 0; int waveNumber = 1; bool waitingForWave = true; float newWaveTimer = 0; int enemiesToEliminate; //How many enemies we already eliminated in the current wave int enemiesEliminated = 0; int totalEnemiesSpawned = 0; // Start is called before the first frame update void Start() < //Lock cursor Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; //Wait 10 seconds for new wave to start newWaveTimer = 10; waitingForWave = true; >// Update is called once per frame void Update() < if (waitingForWave) < if(newWaveTimer >= 0) < newWaveTimer -= Time.deltaTime; >else < //Initialize new wave enemiesToEliminate = waveNumber * enemiesPerWave; enemiesEliminated = 0; totalEnemiesSpawned = 0; waitingForWave = false; >> else < if(Time.time >nextSpawnTime) < nextSpawnTime = Time.time + spawnInterval; //Spawn enemy if(totalEnemiesSpawned < enemiesToEliminate) < Transform randomPoint = spawnPoints[Random.Range(0, spawnPoints.Length - 1)]; GameObject enemy = Instantiate(enemyPrefab, randomPoint.position, Quaternion.identity); SC_NPCEnemy npc = enemy.GetComponent(); npc.playerTransform = player.transform; npc.es = this; totalEnemiesSpawned++; > > > if (player.playerHP > > void OnGUI() < GUI.Box(new Rect(10, Screen.height - 35, 100, 25), ((int)player.playerHP).ToString() + " HP"); GUI.Box(new Rect(Screen.width / 2 - 35, Screen.height - 35, 70, 25), player.weaponManager.selectedWeapon.bulletsPerMagazine.ToString()); if(player.playerHP else < GUI.DrawTexture(new Rect(Screen.width / 2 - 3, Screen.height / 2 - 3, 6, 6), crosshairTexture); >GUI.Box(new Rect(Screen.width / 2 - 50, 10, 100, 25), (enemiesToEliminate - enemiesEliminated).ToString()); if (waitingForWave) < GUI.Box(new Rect(Screen.width / 2 - 125, Screen.height / 4 - 12, 250, 25), "Waiting for Wave " + waveNumber.ToString() + " (" + ((int)newWaveTimer).ToString() + " seconds left. )"); >> public void EnemyEliminated(SC_NPCEnemy enemy) < enemiesEliminated++; if(enemiesToEliminate - enemiesEliminated > >
  • Создайте новый скрипт, назовите его «SC_DamageReceiver» и вставьте в него приведенный ниже код:

SC_DamageReceiver.cs

using UnityEngine; public class SC_DamageReceiver : MonoBehaviour, IEntity < //This script will keep track of player HP public float playerHP = 100; public SC_CharacterController playerController; public SC_WeaponManager weaponManager; public void ApplyDamage(float points) < playerHP -= points; if(playerHP > >
  • Прикрепите сценарий SC_NPCEnemy к живому экземпляру врага (вы заметите, что в него добавлен еще один компонент, называемый NavMesh Agent, который необходим для навигации по NavMesh)
  • Назначьте недавно созданный префаб мертвого экземпляра переменной Npc Dead Prefab.
  • Для Fire Point создайте новый GameObject, переместите его внутрь экземпляра живого врага и поместите немного впереди экземпляра, затем назначьте его переменной Fire Point:

  • Наконец, сохраните живой экземпляр в Prefab и удалите его из сцены.

Настройка генератора врагов

Теперь перейдем к SC_EnemySpawner. Этот скрипт будет порождать врагов волнами, а также отображать на экране некоторую информацию пользовательского интерфейса, например, здоровье игрока, текущие боеприпасы, количество врагов, оставшихся в текущей волне и т. д.

  • Создайте новый GameObject и назовите его. «_EnemySpawner»
  • Прикрепите к нему скрипт SC_EnemySpawner
  • Назначьте вновь созданный ИИ врага переменной Enemy Prefab.
  • Назначьте текстуру ниже переменной текстуры перекрестия.

  • Создайте пару новых игровых объектов и разместите их вокруг сцены, а затем назначьте их массиву точек появления.

Вы заметите, что осталось назначить еще одну переменную — переменную Player.

  • Прикрепите скрипт SC_DamageReceiver к экземпляру Player.
  • Измените тег экземпляра Player на «Player»
  • Назначьте переменные Player Controller и Weapon Manager в SC_DamageReceiver.

  • Назначьте экземпляр Player переменной Player в SC_EnemySpawner.

И, наконец, нам нужно запечь NavMesh в нашей сцене, чтобы вражеский ИИ мог перемещаться.

Кроме того, не забудьте пометить каждый статический объект на сцене как Navigation Static перед запеканием NavMesh:

  • Перейдите в окно NavMesh (Окно -> AI -> Навигация), щелкните вкладку «Выпечка», затем нажмите кнопку «Выпечка». После того, как NavMesh запечется, он должен выглядеть примерно так:

Теперь пришло время нажать Play и протестировать:

Sharp Coder Видео проигрыватель

Все работает так, как ожидалось!

Unity помогает Madfinger концентрироваться на впечатлениях игроков на мобильных устройствах в Shadowgun War Games

Этот разработанный чешской студией шутер от первого лица использует готовые решения Unity для разработки, хостинга игры, подбора игроков и голосовой коммуникации.

MADFINGER Games: пример использования Unity

Как вам удалось организовать плавный выпуск нового крупного дополнения к сюжетной игровой франшизе? Unity и MADFINGER Games объединили усилия 10 лет назад, когда обе компании были намного меньше и только выходили на рынок мобильных игр. Ситуация сильно изменилась, но наши отношения прочны как никогда и затрагивают ключевые операции всего жизненного цикла игры.

Создать потрясающую мобильную игру с использованием готовых технологий и услуг поддержки Unity.
Team members

Около 75 человек, работающих в Unity, включая программистов, художников, аниматоров, дизайнеров и тестировщиков.

Более 100 сотрудников. Брно, Чехия.

Студия Madfinger Games

MADFINGER Games team

Этот независимый разработчик не прячется в тени

Since 2010, the fiercely independent Madfinger’s mandate has been “to build the best mobile games.” And the 100-member team is doing just that. In 2019, they won the award for the Most Beautiful Game on Google Play for Shadowgun Legends. With 260 million downloads across eight games, their loyal player base loves the distinctive Madfinger touch on titles like Shadowgun: DeadZone, Dead Trigger, and UNKILLED.

With the recently launched Shadowgun War Games – a console-quality, mobile multiplayer first-person shooter (FPS) – there are heroes like Sara, Jet, Revenant, Willow and Slade, for all types and levels of players, ranging from non-competitive solo to hardcore 5v5. Madfinger built and launched the game with Unity’s real-time 3D content-creation platform, tapped Multiplay for game hosting, and will soon integrate Vivox for in-game voice comms.

Результаты

  • Fast prototyping, iteration, and optimization thanks to a wide range of Unity developer tools
  • Easy multiplatform (Android, iOS) builds due to one code base
  • Seamless game server hosting with Multiplay’s proven technology, battle-tested at scale
  • Sub-second matching of players to servers with the new Beta Matchmaker
  • Quick integration of voice comms courtesy of Vivox

Смотрите: интервью с MADFINGER Games

In this interview, Madfinger CEO and cofounder Marek Rabas talks to Unity about the challenges his team faces and how they solve them with Unity’s suite of multiplayer tools.

  • Создавая игры, а не движки
  • Помощь многим командам разработчиков
  • Нет лагу, читерам и P2P
  • Плавный запуск, бесшовное масштабирование
  • Better player engagement with better matchmaking
  • Даем игрокам голос с Vivox
  • Что теперь ждать от Madfinger?

Интерфейс редактора Unity

Создавая игры, а не движки

Madfinger — дружная студия с конкурентным подходом — ценит свой небольшой, но эффективный размер, позволяющий противостоять огромным конкурентам — и даже боссам — в мобильном мире. И это отношение определяет их технические решения.

«Мы просто не можем позволить себе выделить 10 человек для работы над движком и еще 10 над другими внутренними инструментами. Нам нужно отдавать все наши силы дизайну игры и созданию превосходной графики, которая является нашей сильной стороной, — говорит Мирослав Ондрус, технический директор Madfinger.

— Лет 20 назад, когда я начал создавать игры, было мало сторонних движков, поэтому нам с друзьями приходилось создавать и поддерживать собственный. Но сейчас Unity обладает всеми нужными функциями и поддержкой, которую осуществляет команда из более 1000 инженеров, что позволяет нам сконцентрироваться на разработке игр, а не на расходующих время создании и обслуживании движка».

Лучиано Алибранди, главный операционный директор и действующий директор по маркетингу соглашается: «10 лет назад мы нашли друг друга в нужный момент, когда Unity и Madfinger росли. Нас сплотила идеальная комбинация навыков с обеих сторон и правильного момента, что породило очень долгие отношения, позволяющие нам концентрироваться на том, что мы делаем лучше всего — создании отличных игр».

Команда разработчиков Madfinger Games

Помощь многим командам разработчиков

So, once a new title gets greenlit, how does Madfinger begin fleshing out its latest game ideas?

“We like ProBuilder a lot – it’s a powerful tool for prototyping new levels and assets within Unity. We use it to build our scenes quickly and iterate on them across teams. We also like to use it for grey-boxing all the levels. This is handy because we can do all our work in Unity and don’t have to use another third-party software tool.”

Ondrus also likes Unity’s Animation editor, especially the updated version of Key manipulation in Curves mode. His animators build their work in Autodesk’s MotionBuilder, and once they import their clips they can select and manipulate several keys at once to, for example, scale curves horizontally (to change the time placement) or vertically (to change the value). It’s a small feature but it really speeds up their workflow.

Another feature they like a lot is baked lighting mode, which provides two important benefits according to Ondrus, “It lets us create great atmosphere in our games without any cost to performance.”

Ever mindful of how high-fidelity graphics run on player devices, Ondrus says, “We’re hyper-aware of the battery cost on mobile, so consequently we heavily optimize performance. To do that we use Unity tools, including the Profiler, which helps us look for unnecessary allocations and render calls, and to optimize our code in general.” They also tap the Frame Debugger and Occlusion Culling to ensure the builds are tight and the game lands just right on whatever device you’re playing on.

Ondrus mentions one other popular Unity feature. “For me, Unity’s multiplatform capabilities simplify things quite a bit. We can build an entire game on one code base and not have to worry about which mobile device it’s going to run on. With Unity, it’s really easy – it’s just a switch in the settings and the runtime version is output for the target platform.”

Разработка уровня Shadowgun War Games в редакторе Unity

Нет лагу, читерам и P2P

How and where a studio hosts its new game is a perennial question, with options available right across the spectrum, from 100% bare metal servers to fully in the cloud. Each of these options has technical and financial advantages as well as drawbacks. With an eye to the future, Madfinger decided early that for a competitive first-person shooter (FPS) like Shadowgun War Games, peer-to-peer (P2P) wasn’t going to cut it. They needed dedicated servers to guarantee a smooth, lag-free experience.

For Vladimir Zadrazil (“Zadr”), Madfinger’s lead programmer, it was a simple choice. “Our ambition with War Games is to deliver a fun yet highly competitive experience, so lag, cheating, and long queues are unacceptable. Thankfully, with Multiplay’s multi-cloud, scalable solution we’re able to give our players a consistent experience, regardless of device or location. The only thing we can’t promise is that you’ll win!”

With Madfinger’s ambition to make the new game an eSports favorite, dedicated servers were a must, as they can prevent one player from gaining an unfair advantage over an opponent. “With P2P there’s more risk of cheating due to one device being the host. With dedicated servers we can put anti-cheat measures in place and, if necessary, take down a server with ease. It gives us more control,” says Zadr.

Сцена Madfinger Games

Плавный запуск, бесшовное масштабирование

As any studio will tell you, new game launches are always fraught with unknowns, such as approximately how many players will join and from where. However, when Shadowgun War Games went live, server scaling went smoothly. “Thanks to Multiplay, there was never an issue of running out of server capacity. As word got out and players started to download and play the game en masse, we were able to scale with ease. This meant no players were left waiting for a game, which is so important for us,” says Ondrus.

According to Zadr, latency is one of the top issues that determine good or bad gameplay experience. “That’s why we decided to collaborate with Multiplay on networking. And it’s a win-win strategy because they helped us focus on making games, while we gave them feedback on their tech, so they can make the product better for everyone, not just for us.”

Ondrus also calls out Unity’s support as a key to their comfort level, “The communication is super fast and super smooth. For example, I recently asked a question in our Slack channel and someone in San Francisco replied and helped me, which was amazing because he was many time zones away! We have excellent cooperation from Unity.”

Онлайн-шутер от первого лица Shadowgun War Games

Better player engagement with better matchmaking

В многопользовательских играх правильный и быстрый подбор соперников крайне важен для приятной игры. «Мы хотим обеспечить игрокам наилучшие впечатления, и они начинаются с ваших соперников. Мы хотим, чтобы игроки попадали в игру быстро и играли с другими игроками их уровня, иначе они просто закроют приложение и никогда к нему не вернутся», — говорит Zadr.

Ондрус рассказывает, что они создавали дизайн процесса подбора игроков во время разработки Shadowgun War Games. «Это было до того, как мы узнали о разработке Unity собственного масштабируемого Matchmaker Service, поэтому и не рассматривали сторонние инструменты. Но когда мы об этом прознали, сразу же выбрали его. И все что нам оставалось сделать — это настроить наши функции, что было довольно просто».

До того как игрок присоединяется к матчу, клиент игры (например, телефон игрока) оценивает качество связи с международными дата-центрами Multiplay относительно качества услуг. Данные о качестве услуг, настройки матча и параметры игрока собираются серверно-авторитарным сервисом лобби Madfinger, чтобы предотвратить жульничество, и передаются в сервис подбора игроков. Сервис подбора выполняет заданные Madfinger функции и ищет соревновательные игры с быстрым подключением. И все это происходит за считанные секунды.

Сервис подбора Multiplay полностью интегрирован в многооблачный масштабатор, а значит игрокам будут подобраны не только правильные противники, но и на правильных серверах.

Сцена Madfinger Games Shadowgun War Games

Даем игрокам голос с Vivox

For today’s multiplayer games, live communication during campaigns and battles is key to outcomes. Voice comms are one of the most important factors to player experience because they let players get more organized by discussing what they want to do and how to do it, adding a lot to their experience.

Madfinger first integrated Vivox into Shadowgun Legends, and it was a simple process. They spent just two days with Unity’s Vivox SDK, which is the expected implementation time. “We ran into a few small issues on our side but in general it was a super easy, painless process,” says Ondrus. Now Vivox hosts and manages all the voice comms for the game, and Madfinger is planning to integrate it into Shadowgun War Games very soon.

This means the Madfinger team can speed up their development process and focus on player engagement. “Having the Vivox team available 24/7 is a blessing. Rather than stressing over an outage in one region or some bug or another, we can speak to the Vivox guys and it gets fixed,” added Ondrus.

To round out their in-game comms strategy, players can also communicate with emojis, and Madfinger is planning to implement text messaging soon.

Сцена шутера от первого лица Shadowgun War Games

Что теперь ждать от Madfinger?

“We’re really excited about the launch of Shadowgun War Games, as we believe this game will work across the board, from solo players to the most competitive team gamers,” says Ondrus. “And as our player base grows, we’ll definitely start thinking about eSports,” which is not surprising to learn. After all, this ambitious studio has always punched well above its weight in the mobile-gaming arena.

Watch Madfinger’s presentation at Unite Copenhagen to get the behind-the-scenes scoop on how they’re using Multiplay and Vivox for game hosting, matchmaking, and voice comms.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *