Скрипт движения 2D персонажа

Еще один скрипт управления персонажем, заточенный под 2D физику. В отличии от прочих, здесь имеются некоторые настройки. Возможен выбор осей. Например, если выбрать только ось Х, в этом случаи включается режим как для платформера, персонаж может двигаться по горизонтали и использовать прыжок. Если выбрать оси ХY, тогда скрипт переходит в режим как для скроллера, проще говоря, подходит для управления неким самолетом или вроде того, объект может двигаться не только по горизонтали, но и по вертикали, а та-же самая клавиша, что и в первом варианте, на этот раз выполняет роль ускорителя, то есть добавляет скорости. Кроме того, есть опция отслеживания позиции курсора, чтобы персонаж смотрел на него.

Создаем новый C# скрипт Player2DControl, со следующим содержанием:

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Rigidbody2D))]

public class Player2DControl : MonoBehaviour {

	public enum ProjectAxis {onlyX = 0, xAndY = 1};
	public ProjectAxis projectAxis = ProjectAxis.onlyX;
	public float speed = 150;
	public float addForce = 7;
	public bool lookAtCursor;
	public KeyCode leftButton = KeyCode.A;
	public KeyCode rightButton = KeyCode.D;
	public KeyCode upButton = KeyCode.W;
	public KeyCode downButton = KeyCode.S;
	public KeyCode addForceButton = KeyCode.Space;
	public bool isFacingRight = true;
	private Vector3 direction;
	private float vertical;
	private float horizontal;
	private Rigidbody2D body;
	private float rotationY;
	private bool jump;

	void Start () 
	{
		body = GetComponent<Rigidbody2D>();
		body.fixedAngle = true;

		if(projectAxis == ProjectAxis.xAndY) 
		{
			body.gravityScale = 0;
			body.drag = 10;
		}
	}

	void OnCollisionStay2D(Collision2D coll) 
	{
		if(coll.transform.tag == "Ground")
		{
			body.drag = 10;
			jump = true;
		}
	}
	
	void OnCollisionExit2D(Collision2D coll) 
	{
		if(coll.transform.tag == "Ground")
		{
			body.drag = 0;
			jump = false;
		}
	}
	
	void FixedUpdate()
	{
		body.AddForce(direction * body.mass * speed);

		if(Mathf.Abs(body.velocity.x) > speed/100f)
		{
			body.velocity = new Vector2(Mathf.Sign(body.velocity.x) * speed/100f, body.velocity.y);
		}

		if(projectAxis == ProjectAxis.xAndY)
		{
			if(Mathf.Abs(body.velocity.y) > speed/100f)
			{
				body.velocity = new Vector2(body.velocity.x, Mathf.Sign(body.velocity.y) * speed/100f);
			}
		}
		else
		{
			if(Input.GetKey(addForceButton) && jump)
			{
				body.velocity = new Vector2(0, addForce);
			}
		}
	}

	void Flip()
	{
		if(projectAxis == ProjectAxis.onlyX)
		{
			isFacingRight = !isFacingRight;
			Vector3 theScale = transform.localScale;
			theScale.x *= -1;
			transform.localScale = theScale;
		}
	}
	
	void Update () 
	{
		if(lookAtCursor)
		{
			Vector3 lookPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.z));
			lookPos = lookPos - transform.position;
			float angle  = Mathf.Atan2(lookPos.y, lookPos.x) * Mathf.Rad2Deg;
			transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
		}

		if(Input.GetKey(upButton)) vertical = 1;
		else if(Input.GetKey(downButton)) vertical = -1; else vertical = 0;

		if(Input.GetKey(leftButton)) horizontal = -1;
		else if(Input.GetKey(rightButton)) horizontal = 1; else horizontal = 0;

		if(projectAxis == ProjectAxis.onlyX) 
		{
			direction = new Vector2(horizontal, 0); 
		}
		else 
		{
			if(Input.GetKeyDown(addForceButton)) speed += addForce; else if(Input.GetKeyUp(addForceButton)) speed -= addForce;
			direction = new Vector2(horizontal, vertical);
		}

		if(horizontal > 0 && !isFacingRight) Flip(); else if(horizontal < 0 && isFacingRight) Flip();
	}
}

speed - скорость движения, как не странно.

addForce - если выбран режим Оnly X, будет использовано для прыжка, при нажатии соответствующий клавиши. Во втором режиме, значение addForce будет прибавлено к speed, тем самым придавая ускорение.

lookAtCursor - отслеживание позиции курсора, персонаж будет вращаться по оси Z. Важно помнить, что лицом считается ось Х.

isFacingRight - если на старте сцены персонаж смотрит вправо, то надо ставить true.

При движении только по горизонтали, разворот персонажа осуществляется через функцию Flip. Так же, чтобы прыжок был возможен, все объекты по которым возможно передвижение, как бы земля/поверхность, у всех них должен быть тег Ground.

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

Офлайн
krav 14 октября 2015
Помогите , у меня не работает прыжок!Что можна сделать?
Офлайн
Light 14 октября 2015
Цитата: krav
Помогите , у меня не работает прыжок!Что можна сделать?

Тег Ground установлен на объектах по которым ходит персонаж?
Офлайн
alsn_5 2 марта 2016
есть одна проблема. при удерживании клавши движения в сторону/прыжка персонаж прилипает к стене/потолку, если достигает ее/его. как это лечится? попытался ограничить, разрешив движении только, если прикрепленный к игроку объект groundCheck касается земли, но тогда персонаж может зависнуть, если ударится той частью тела, где граундчека нет. помогите
Офлайн
Light 2 марта 2016
alsn_5,
Это надо настраивать физику, использовать эффекторы, или например сделать физический 2д материал, поставить все значения на ноль, и прицепить его к коллайдеру стены, тогда ничего застревать не будет.
Офлайн
Почему при отпускании клавиши ходьбы игрок ещё немного продолжает двигаться?
Офлайн
Light 22 мая 2016
Цитата: Руслан
Почему при отпускании клавиши ходьбы игрок ещё немного продолжает двигаться?

Надо настроить физику, чтобы не скользил как утюг на льду. Просто добавить физ. материал в коллайдер персонажа и отрегулировать параметр трения, до нужного результата.
Офлайн
Light,
Спасибо!
Офлайн
MxKame 14 июня 2016
Извините, я новичок и поэтому еще не разобрался.
У меня есть проблема, весь интернет обыскал, как сделать так, чтобы на определенную кнопу проигрывался спрайт.
У меня есть спрайты ходьбы и ожидания, но я не знаю как сделать чтобы они проигрывались при ходьбе! Помогите
Офлайн
Light 15 июня 2016
MxKame, по этому вопросу будет публикация.
Офлайн
maxler 15 октября 2016
Подскажите я создал кнопку для управления персонажем. У элемента "Кнопка" есть возможность выбора функций из скрипта. Как вынести переменные в глобальные чтобы была возможность привязать действие к кнопке на экране
Офлайн
Light 17 октября 2016
maxler, чтобы функция стала доступной, она должна быть публичной, типа public void.
Офлайн
Здравствуйте уважаемые знатоки кодов, зарегистрировался только ради того чтобы спросить о проблеме. Я так понял, чтобы спрайт ходил по земле, у земли должен быть тэг. Как присвоить тэг? Вот: https://yadi.sk/i/RkhP38unySbWN
Спрайт просто летит сквозь землю. https://yadi.sk/i/HYFpWqK8ySbpQ
Офлайн
Цитата: VeryNoobOfCodesAndEnglish
Здравствуйте уважаемые знатоки кодов, зарегистрировался только ради того чтобы спросить о проблеме. Я так понял, чтобы спрайт ходил по земле, у земли должен быть тэг. Как присвоить тэг? Вот: https://yadi.sk/i/RkhP38unySbWN
Спрайт просто летит сквозь землю. https://yadi.sk/i/HYFpWqK8ySbpQ

Спасибо, разобрался. Надо было добавить не 3D коллайдер к земле а 2D и убрать риджидбади с камеры
Офлайн
KaKTyS_76Rus 8 октября 2017
Дайте ссылку на то как сделать чтобы анимация ходьбы отображалась когда я двигаюсь.
Офлайн
Light 9 октября 2017
KaKTyS_76Rus, в юнити есть стандартные ассеты Assets -> Import Package -> 2D там есть анимированный 2д перс, где можно посмотреть как у него сделана анимация.
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Дешевый хостинг
  • Яндекс.Метрика