FPS скрипт управлениия от первого лица

Шутеры от первого лица довольно популярны, особенно если они грамотно сделаны. Однако, если вы только начинаете изучать Unity и хотите сделать что-то наподобие Counter-Strike или вроде того. Могу возникнуть некоторые трудности с управлением персонажа. Заставить объект двигаться, просто, но в нашем случае нужно, чтобы персонаж двигался туда, куда он «смотрит». Конечно, в играх есть еще анимация движения и прочие мелочи, всё это вы уже сами добавите в скрипт, если будет нужно. Нам главное сделать управление движения и прыжок. Впрочем, есть и другой тип игр, где такой простой скрипт подойдет, например: Dear Esther, The Vanishing of Ethan Carter и т.п.


Создаем скрипт PlayerControl

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Rigidbody))]

public class PlayerControl : MonoBehaviour {
	
	public float speed = 1.5f;

	public Transform head;

	public float sensitivity = 5f; // чувствительность мыши
	public float headMinY = -40f; // ограничение угла для головы
	public float headMaxY = 40f;

	public KeyCode jumpButton = KeyCode.Space; // клавиша для прыжка
	public float jumpForce = 10; // сила прыжка
	public float jumpDistance = 1.2f; // расстояние от центра объекта, до поверхности

	private Vector3 direction;
	private float h, v;
	private int layerMask;
	private Rigidbody body;
	private float rotationY;
	
	void Start () 
	{
		body = GetComponent<Rigidbody>();
		body.freezeRotation = true;
		layerMask = 1 << gameObject.layer | 1 << 2;
		layerMask = ~layerMask;
	}
	
	void FixedUpdate()
	{
		body.AddForce(direction * speed, ForceMode.VelocityChange);
		
		// Ограничение скорости, иначе объект будет постоянно ускоряться
		if(Mathf.Abs(body.velocity.x) > speed)
		{
			body.velocity = new Vector3(Mathf.Sign(body.velocity.x) * speed, body.velocity.y, body.velocity.z);
		}
		if(Mathf.Abs(body.velocity.z) > speed)
		{
			body.velocity = new Vector3(body.velocity.x, body.velocity.y, Mathf.Sign(body.velocity.z) * speed);
		}
	}

	bool GetJump() // проверяем, есть ли коллайдер под ногами
	{
		RaycastHit hit;
		Ray ray = new Ray(transform.position, Vector3.down);
		if (Physics.Raycast(ray, out hit, jumpDistance, layerMask))
		{
			return true;
		}
		
		return false;
	}

	void Update () 
	{
		h = Input.GetAxis("Horizontal");
		v = Input.GetAxis("Vertical");

		// управление головой (камерой)
		float rotationX = head.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivity;
		rotationY += Input.GetAxis("Mouse Y") * sensitivity;
		rotationY = Mathf.Clamp (rotationY, headMinY, headMaxY);
		head.localEulerAngles = new Vector3(-rotationY, rotationX, 0);

		// вектор направления движения
		direction = new Vector3(h, 0, v);
		direction = head.TransformDirection(direction);
		direction = new Vector3(direction.x, 0, direction.z);
		
		if(Input.GetKeyDown(jumpButton) && GetJump())
		{
			body.velocity = new Vector2(0, jumpForce);
		}
	}

	void OnDrawGizmosSelected() // подсветка, для визуальной настройки jumpDistance
	{
		Gizmos.color = Color.red;
		Gizmos.DrawRay(transform.position, Vector3.down * jumpDistance);
	}
}

Чтобы всё работало как надо, персонажу нужно придумать и назначить отдельный слой. Это нужно для того, чтобы работал Raycast в скрипте, который определяет возможность прыжка и в тоже время для того, чтобы любой другой Raycast, мог взаимодействовать и игроком.



Всё достаточно просто. Различные детали, каждый сможет настроить под себя, плюс можно еще сделать материал для физики тела, например, чтоб увеличить коэффициент трения или наоборот, изменить массу Rigidbody, ну и прочее. В общем, поэкспериментируйте с настройками.

Скачать пример проекта:

Внимание! Посетители, находящиеся в группе Гости, не могут скачивать файлы.
Тестировалось на: Unity 5.5.0

Комментариев 34

Офлайн
Light,
Тоже интересует прошлогодний вопрос про разворот персонажа вслед за камерой!
Если добавить это

if (Mathf.Abs(v) > 0 || Mathf.Abs(h) > 0) // разворот тела по вектору движения
{
rotate.rotation = Quaternion.Lerp(rotate.rotation, Quaternion.LookRotation(direction), 10 * Time.deltaTime);
}
else // разворот самого игрока
{
Vector3 look = head.transform.TransformDirection(Vector3.forward);
look.y = 0;
rotate.rotation = Quaternion.Lerp(rotate.rotation, Quaternion.LookRotation(look), 10 * Time.deltaTime);
}
приняв rotate за модель персонажа, то он начнет разворачиваться, но камера окажется на затылке! Пробовал внедрить Ваше управление от 3 лица, но там не было подсказки: как отрегулировать камеру таким образом, чтобы она не следила за персонажем не сзади по умолчанию, а находилась спереди (от глаз)
Офлайн
Light 10 мая 2020
Vladecmolodec, всё дело в иерархии, чтобы прочие объекты вращались с камерой согласованно, они должны быть дочерними.
Офлайн
Cherviblo 19 мая 2020
Во время движения персонажа постоянно уносит куда-то в сторону
Офлайн
ObiProm 30 июня 2020
На меня матерятся за 41 ошибку!!!! Чё делать????
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Яндекс.Метрика