Контроллер игрока в жанрах RTS и MOBA для Unity
В видеоиграх термин RTS означает стратегию в реальном времени.
Отличие RTS от обычных шутеров от первого/третьего лица заключается в том, что управление персонажами осуществляется с помощью указателя мыши, а не обычных кнопок W, A, S и D.
Игроку предоставляется обзор поля боя с возможностью отдавать приказы войскам, не управляя ими напрямую. Примерами игр RTS являются Warcraft, Starcraft, Cossacks и т. д.
С другой стороны, MOBA означает Multiplayer Online Battle Arena, это несколько новый поджанр игр RTS, в которых игрок управляет только одним персонажем вместо многих.
Примерами таких игр являются League of Legends и Dota 2.
В этом уроке я покажу, как создать контроллер в стиле RTS/MOBA в Unity.
Шаг 1: Давайте создадим необходимые скрипты.
Это руководство довольно простое, так как для него требуется только один скрипт.
RTSPlayerController.cs
//You are free to use this script in Free or Commercial projects
//sharpcoderblog.com @2018
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(NavMeshAgent))]
public class RTSPlayerController : MonoBehaviour
{
public Camera playerCamera;
public Vector3 cameraOffset;
public GameObject targetIndicatorPrefab;
NavMeshAgent agent;
GameObject targetObject;
// Use this for initialization
void Start()
{
agent = GetComponent<NavMeshAgent>();
//Instantiate click target prefab
if (targetIndicatorPrefab)
{
targetObject = Instantiate(targetIndicatorPrefab, Vector3.zero, Quaternion.identity) as GameObject;
targetObject.SetActive(false);
}
}
// Update is called once per frame
void Update()
{
#if (UNITY_ANDROID || UNITY_IOS || UNITY_WP8 || UNITY_WP8_1) && !UNITY_EDITOR
//Handle mobile touch input
for (var i = 0; i < Input.touchCount; ++i)
{
Touch touch = Input.GetTouch(i);
if (touch.phase == TouchPhase.Began)
{
MoveToTarget(touch.position);
}
}
#else
//Handle mouse input
if (Input.GetKeyDown(KeyCode.Mouse0))
{
MoveToTarget(Input.mousePosition);
}
#endif
//Camera follow
playerCamera.transform.position = Vector3.Lerp(playerCamera.transform.position, transform.position + cameraOffset, Time.deltaTime * 7.4f);
playerCamera.transform.LookAt(transform);
}
void MoveToTarget(Vector2 posOnScreen)
{
//print("Move To: " + new Vector2(posOnScreen.x, Screen.height - posOnScreen.y));
Ray screenRay = playerCamera.ScreenPointToRay(posOnScreen);
RaycastHit hit;
if (Physics.Raycast(screenRay, out hit, 75))
{
agent.destination = hit.point;
//Show marker where we clicked
if (targetObject)
{
targetObject.transform.position = agent.destination;
targetObject.SetActive(true);
}
}
}
}
Шаг 2
Теперь давайте настроим контроллер игрока и игровой уровень.
- Создайте новый GameObject и назовите его 'RTSPlayer'
- Прикрепите к нему скрипт RTSPlayerController.cs (ПРИМЕЧАНИЕ. После присоединения он автоматически добавит еще один компонент с именем NavMeshAgent, этот компонент понадобится позже)
- Добавьте тело игрока (в моем случае я буду использовать простую капсулу с кубом, но вы можете добавить модель игрока, если она у вас есть). Уменьшите его до нужного размера.
- Переместите модель игрока внутри игрового объекта 'RTSPlayer' (ПРИМЕЧАНИЕ. Перед созданием родительского объекта убедитесь, что 'RTSPlayer' расположен внизу модели игрока)
- Выберите 'RTSPlayer' и в NavMeshAgent настройте радиус и высоту, пока они не будут соответствовать модели игрока.
- Далее нужно создать целевой индикатор prefab. Это простой GameObject с квадратом, который будет указывать, где мы нажали на карте.
Вы можете использовать текстуру ниже:
- И наконец, выберите 'RTSPlayer' и назначьте все необходимые переменные в скрипте RTSPlayerController:
Камера игрока — понятно, это может быть любая камера.
Camera Offset - насколько далеко должна находиться камера от игрока
Target Indicator Prefab — только что созданный префаб.
В режиме игры вы заметите, что нажатие на карту не заставляет игрока двигаться. Это потому, что нам осталось сделать последнее: запечь Навигационную сетку (Navmesh):
- Выделите все объекты, являющиеся частью карты, и отметьте их как статичные:
- Перейдите в Окно -> AI -> Навигация.
- На вкладке «Выпечка» измените значения «Радиус агента» и «Высота агента» (они должны соответствовать значениям из NavMeshAgent), затем нажмите «Выпечка».
- После завершения запекания вы увидите сетку с голубоватым контуром, обозначающую зону, по которой можно ходить.
ПРИМЕЧАНИЕ. Чтобы игрок не мог ходить по холмам, вернитесь на вкладку «Запекание» и уменьшите угол максимального уклона, а затем повторно запекайте навигационную сетку.
Намного лучше!
Наконец, вернитесь в режим игры и щелкните левой кнопкой мыши где-нибудь на карте.
Теперь игрок должен двигаться к цели, избегая препятствий:
Совет: настройте значение скорости, угловой скорости и ускорения в NavMeshagent в соответствии с вашими потребностями.