Движение камеры за персонажем [2D платформер]

Сегодня напишем скрипт, который предназначен для того, чтобы камера следовала за объектом. Прежде всего, данный скрипт заточен под платформер, где игрок управляет неким персонажем. Например, как в игре Mario и подобные, важно то, что персонаж должен перемещаться влево или вправо, по оси икс. Камера будет плавно двигаться вслед за объектом, а также определять в какую сторону в данный момент движется объект. Это нужно, чтобы добавить смещение по иксу, то есть, если персонаж смотрит допустим вправо, то камера будет сдвинута немного вправо и вверх, если добавлено смещение по вертикали.

Чтож, создаем скрипт CameraFollow2D:

using UnityEngine;
using System.Collections;

public class CameraFollow2D : MonoBehaviour {

	public float damping = 1.5f;
	public Vector2 offset = new Vector2(2f, 1f);
	public bool faceLeft;
	private Transform player;
	private int lastX;

	void Start ()
	{
		offset = new Vector2(Mathf.Abs(offset.x), offset.y);
		FindPlayer(faceLeft);
	}

	public void FindPlayer(bool playerFaceLeft)
	{
		player = GameObject.FindGameObjectWithTag("Player").transform;
		lastX = Mathf.RoundToInt(player.position.x);
		if(playerFaceLeft)
		{
			transform.position = new Vector3(player.position.x - offset.x, player.position.y + offset.y, transform.position.z);
		}
		else
		{
			transform.position = new Vector3(player.position.x + offset.x, player.position.y + offset.y, transform.position.z);
		}
	}

	void Update () 
	{
		if(player)
		{
			int currentX = Mathf.RoundToInt(player.position.x);
			if(currentX > lastX) faceLeft = false; else if(currentX < lastX) faceLeft = true;
			lastX = Mathf.RoundToInt(player.position.x);

			Vector3 target;
			if(faceLeft)
			{
				target = new Vector3(player.position.x - offset.x, player.position.y + offset.y, transform.position.z);
			}
			else
			{
				target = new Vector3(player.position.x + offset.x, player.position.y + offset.y, transform.position.z);
			}
			Vector3 currentPosition = Vector3.Lerp(transform.position, target, damping * Time.deltaTime);
			transform.position = currentPosition;
		}
	}
}

damping - регулируем плавность движения камеры.
offset - добавить смещение по вертикали и горизонтали.
faceLeft - если изначально персонаж "смотрит" влево, ставим галочку.



Чтобы всё работало, тот объект, которым управляет игрок, должен иметь стандартный тег Player. Стоит обратить внимание на функцию FindPlayer, к ней нужно обращаться каждый раз, когда используется респаун объекта, кроме того, учитывается и то, в какую сторону "смотрит" объект по умолчанию, например, FindPlayer(true), если "смотрит" влево. Здесь важно понимать, что суть не в том, куда смотрит персонаж во время перемещения, а то, в какую сторону движется объект, влево или вправо. Если вы хотите жесткую привязку, относительно лица, тогда надо удалить все строки с обработкой переменных lastX и currentX. А переменную faceLeft сделать статической:

public static bool faceLeft;

И изменять ее, через скрипт управления персонажа.

Допустим, вот так:

if(Input.GetKey(KeyCode.A))
{
	CameraFollow2D.faceLeft = true;
}

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

Офлайн
_2
_2 8 августа 2015
Огромное спасибо за статью, правда временами бывает очень странный "баг" (или фича, просто я криворук), если персонаж очень быстро бежит то камера за ним не успевает и начинает дергаться, увеличение damping помогает, но если мне нужно добавить offset (допустим чтобы камера бежала впереди персонажа) во время его разворота героя камера так же резко разворачивается следом и плавность полностью теряется.
Офлайн
Light 8 августа 2015
Цитата: _2
камера так же резко разворачивается следом и плавность полностью теряется

Чтобы сохранить плавность после разворота, нужно делать сброс damping.

Например так:

Объявить пару переменных:

private float damp_tmp;
private bool f_tmp;

В функцию Start добавить:

damp_tmp = damping;


Затем в Update после строки:

lastX = Mathf.RoundToInt(player.position.x);

Добавить:

bool f = faceLeft;
if(f != f_tmp) damping = 1;
damping = Mathf.Lerp(damping, damp_tmp, 1.5f * Time.deltaTime);
f_tmp = faceLeft;

Тогда при смене направления, будет делаться сброс - затем возврат.
Офлайн
krav 14 октября 2015
У меня на 5Unityне работает почемуто
Офлайн
Light 14 октября 2015
Цитата: krav
У меня на 5Unityне работает почемуто

Может потому, что не найден объект с тегом Player.
Офлайн
А если вместо faceLeft использовать facingRight из скрипта персонажа?Или обращение к другому скрипту в Update чревато нагрузками?
Офлайн
Light 6 ноября 2016
Федор Николаев, если это просто запрос состояния переменной типа bool, то ничего страшного с нагрузками не случится.
Офлайн
Как добавить скрипт?
Почему НИ ОДИн сайт не показывает детально как создать, как назвать, как перенести, как вствить в спрайт и в какой, какие ошибки могут быть
Офлайн
Light 12 ноября 2016
Цитата: VeryNoobOfCodesAndEnglish
Как добавить скрипт?

Есть куча других примеров, тоже про движение камеры и уже собраны в пакет, качай и смотри.
Офлайн
dianismult 23 ноября 2017
Помогите разобраться, не могу понять ошибку. Повесил скрипт на камеру все вроде работает хорошо, но стоит в аниматоре поиграться с настройками и при запуске проекта камера выдает зеленый фон солид, и канвас gui. А после весь редактор крашится. Движение вправо и лево сделано через развоорот по оси y 0 и 180 соответственно. Я заметил что при движении влево начинает плыть координата z персонажа. И чем дальше влево тем страшнее цифра. Отключаю скрипт камеры и ошибок нет. Все работает хорошо. В чем беда всю голову сломал.
Офлайн
Light 23 ноября 2017
dianismult, надо смотреть проект, кинь в личку...
Офлайн
dianismult 23 ноября 2017
Light,
Проект слишком большой, не смогу прислать. Нашел почему скачит координата z, в моем случае я указал у объекта player ее в ручную равной -1, теперь нет странных чисел с кучей знаков после запятой. И понял почему камера при старте отображает солид. Скрипт не менял, почему то судя по координатам камера съезжает на вектор офсет относительно нулевой координаты, т.е. от точки отчета сцены а не объекта player. Не могу сообразить как исправить ситуацию.
Офлайн
occuidem 7 марта 2020
как сделать, чтобы камера не сдвигалась по y?
Офлайн
Light 10 марта 2020
occuidem, перед строкой transform.position = currentPosition; добавить currentPosition.y = transform.position.y;
Офлайн
l1pton 9 апреля 2020
когда персонаж двигается влево, то камера двигается влево за ним, но смещается ещк вниз а половину, как пофисить можно7
Офлайн
Light 10 апреля 2020
l1pton, offset подкрутить.
Офлайн
TikTak 31 августа 2020
Здравствуйте , почему камера при скрипте наблюдает не за объектом а ниже или левее его, там где серый кружочек при нажати на объект, просьба помочь.
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Яндекс.Метрика