скрипт для движения персонажа через wasd юнити 3 д
Правильная реализация передвижения персонажа
Почему один обьект проходит сквозь другой хотя у меня есть коллайдеры на обоих обьектах?
Почему мой персонаж во время движения проходит сквозь другой обьект, а потом его откидывает назад?
Как реализовать передвижение персонажа в Unity3d правильно?
Почему так часто используется передвижение через transform.position и почему это неправильно?
Почему мой персонаж движется с разной скоростью если проседает FPS?
Почему двигать персонажа через смену transform.position неправильно?
Как сделать прыжок от пола, но так что бы персонаж не мог бесконечно взлетать
Почему когда платформа движется, персонаж стоящий на платформе остается на месте?
Почему пуля не всегда наносит урон?
Все эти вопросы, фактически, являются одним единым вопросом, который слишком уж часто встречается у начинающих.
Заодно создал тэг unity3d-faq
1 ответ 1
Перед прочтением важно знать
Хоть я здесь и разбираю в т.ч. нефизическое движение, я настоятельно рекомендую использовать ФИЗИЧЕСКОЕ движение. И переходить на нефизическое только в исключительных ситуациях.
Я буду использовать здесь 2 термина: «телепортация» и «плавное движение». В моем понимании:
Есть люди у которых мнение отличается.
Учтите, что все что написано ниже упирается в верхние значения терминов, а не эти.
Двигать обьекты в игровых движках можно следующими способами:
используя физический движок (движение обусловленное физической моделью игрового движка)
Движение реализуемое через CharacterController (здесь пока что не рассматривается т.к. новички в его сторону вообще не смотрят, может, позже распишу)
Новички очень часто использую телепортацию на каждом кадре, что есть критически неправильным подходом. Потом на SO появляются кучи клонов вопросов вроде «почему персонажа дергает возле стены?» или «почему он проходит сквозь стену?» или «почему пуля не всегда наносит урон?» и подобные.
Нужно запомнить всего одно правило: Двигать/поворачивать через присвоение transform.position / transform.rotation нельзя. Это порождает проблемы. В любом случае это вам вылезет боком.
Пример правильной реализации движения:
( на примере обьекта-шара )
в отличии от пестрящих дичью форумов, в т.ч. сервисе вопросов/ответов от юнити. Там в таких темах слишком часто пишут ответы те люди, которые понятия не имеют о правильном подходе.
Связанные с темой понятия:
Если обьект не обладает физическими свойствами (не имеет RigidBody) эти параметры и методы можно использовать для НЕфизического передвижения.
Например поворот камеры.
Или крутящийся куб на небосводе.
Мы не получим дергающуюся картинку при проседании кадров если сделаем НЕФИЗИЧЕСКОЕ движение правильно:
мы присваиваем в новую позицию:
Про физические свойства движения.
мы разово задаем вектор скачка. Только 1 долю секунды. Но он будет изменятся во времени автоматически равномерно уменьшаясь под силой тяжения. Пока не станет нулевым (верхняя точка прыжка), а потом не пойдет в минус по Y (падение), а потом не упадет на землю и не отскочит от нее (снова плюс по Y ) и так до полной остановки физической скорости обьекта на земле.
Если девайс с игрой сильно загружен, вызов методов Update() / FixedUpdate() тоже может просесть в скорости. И если в физике это учтено и без нас, то сейчас мы делаем НЕ физическое движение и именно по-этому это нужно учитывать добавлением даного множителя.
Но и без использования даного множителя у нас не появится проблем с провалами сквозь стены. Это просто фикс скорости.
Пример простой но хорошей НЕФИЗИЧЕСКОЙ реализации кода движения на примере персонажа.
Если в прошлом примере мы двигали шар, то было допустимо его толкать используя физ.модель. То есть мы использовали AddForce() для этих целей.
Давайте актуализируем этот код под даного персонажа. Мы заменим физический толчек обьекта на не-физическое, но ПЛАВНОЕ перемещение обьекта в пространстве:
С этим кодом мы получим такой результат:
С такой реализацией у нас не будет проблем вроде скачков скорости на проседании или повышении количества FPS, проваливаний, дерганости, прохождения сквозь стены или других неожиданностей.
Так же можно добавить анимацию бега на нашего персонажа (ну если бы это был не куб).
Но как же реализация на физике?
Да, можно подобное реализовать и на физике.
Наша прошлая версия скрипта имела несколько недостатков. А именно:
Давайте поместим на наш куб CapsuleCollider (минимальное торможение из-за силы трения) и заблочим в rigidBody rotateX и rotateZ (что б наш персонаж не падал на бок).
А потом нацепим на него вот этот скрипт:
Вы видите эту плавность, как будто человек бежит, останавливается, бежит в другую сторону? Красота!
А теперь вернитесь к прошлой гифке и присмотритесь. Движение совсем не такое 🙂 Там как буд-то рукой двигают шахматную фигуру по доске.
Ну и описанные выше баги поведения были пофикшены с такой реализацией.
Можно добавить еще физический материал нашему персонажу и откоректировать его поведение.
Вообще улучшать реализацию можно до бесконечности. Но, думаю, основные проблемы СПОСОБОВ ПЕРЕДВИЖЕНИЯ с которыми вы столкнетесь, я затронул 🙂
Оптимально использовать именно передвижение на базе физики.
Пытайтесь использовать исключительно физическое передвижение.
Реализация нестандартной физики движений.
Одним из моих любимейших примеров нестандартной физики движения является игра Ori and the Blind Forest
Такое перемещение/такие прыжки невозможно сделать на основе стандартной физики. Вероятнее всего, это делалось через физическое перемещение + костыли для получения нужных эфектов которые противоречат стандартной физике.
Сначала разрабатываются концепты движения. Они делаются в любом видеоредакторе с примитивными фигурами. Вот пример (если станет недоступным искать можно по Ori and the blind forest Enemy Concepts ) :
Обратите внимание на то, то здесь прорисовано не только перемещение обьекта, но и его вытягивания/сжатия. Изменения формы во время любого взаимодействия с внешним миром. В т.ч. выстрелы так же влияют на форму. А так же что указываются радиусы опознавания главного героя каждым отдельным врагом.
Костыли для каждого персонажа/врага свои собственные. Это делается что бы каждый из них обладал своей уникальной физикой. Сделать это на общей физике навряд ли возможно.
Движение реализовано «правильно» но предмет все равно пролетает сквозь стену
ДАЖЕ если вы реализовали физическое передвижение вашего персонажа, все равно может случится такое, что просчет CollisionDetect может проходить с ошибками. Такое бывает.
Для таких случаев есть настройки отвечающие за обработку CollisionDetect в настройках самого RigidBody.
Желательно такого не делать т.к. это негативно сказывается на производительности. Чем на большем количестве обьектов вы меняете эти настройки, тем более вероятно что вы делаете какую-то дичь, которую делать совсем не нужно. Считайте это спасательным кругом, а не панацеей. А если вы так будете делать, то рано или поздно вы прийдете на SO с вопросом почему игра тормозит, вас попросят показать код и ничего не найдут просто потому, что проблема тормозов не в коде. И намучаетесь вы с оптимизациями ой как сильно.
Скрипт для движения персонажа через wasd юнити 3 д
Вот небольшой скрипт который позволяет двигать персонажем с помощью клавиатуры. Закинула на сцену три кнопки, для кнопки верх при событии onclick выполняется метод Jump. А как сделать так чтобы персонаж двигался влево и вправо при нажатии на кнопки?
using UnityEngine;
using System.Collections;
public class Character : MonoBehaviour
<
private float speed = 5.0F;
private float jumpForce = 10.0F;
public float score = 0;
public float key = 0;
private bool isGrounded = false;
private Rigidbody2D rb;
private Animator animator;
private SpriteRenderer sprite;
public void FixedUpdate()
<
CheckGround();
if (Mathf.Abs(direction.x) > 0.1)
transform.position = Vector3.MoveTowards(transform.position, transform.position + direction, speed * Time.fixedDeltaTime);
>
private void Update()
<
if (isGrounded)
animator.SetInteger(«State», 0);
if (Input.GetButton(«Horizontal»))
Run();
else
direction = Vector3.zero;
if (Input.GetKeyDown(KeyCode.UpArrow)) Jump();
>
public void Run()
<
direction = transform.right * Input.GetAxis(«Horizontal»);
sprite.flipX = direction.x 1;
if (!isGrounded)
animator.SetInteger(«State», 2);
>
>
Re: Движение персонажа при нажатии на кнопки.
Re: Движение персонажа при нажатии на кнопки.
Re: Движение персонажа при нажатии на кнопки.
Re: Движение персонажа при нажатии на кнопки.
public class PointerListener : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
<
bool _pressed = false ;
public void OnPointerDown ( PointerEventData eventData )
<
_pressed = true ;
>
public void OnPointerUp ( PointerEventData eventData )
<
_pressed = false ;
>
Re: Движение персонажа при нажатии на кнопки.
public class PointerListener : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
<
bool _pressed = false ;
public void OnPointerDown ( PointerEventData eventData )
<
_pressed = true ;
>
public void OnPointerUp ( PointerEventData eventData )
<
_pressed = false ;
>
Re: Движение персонажа при нажатии на кнопки.
Скрипт для движения персонажа через wasd юнити 3 д
Уже порядочное время читаю форум, потихоньку пишу сам в , но не могу сделать простое перемещение npc. Пробовал
NPC великолепно передвигаются по ровным поверхностям, по воздуху, но подняться на небольшой склон не в состоянии. Что я не так делаю?
Re: Перемещение NPC
Re: Перемещение NPC
Re: Перемещение NPC
Re: Перемещение NPC
У меня же ни в какую. Либо отлетает от поверхности с нереальной скоростью, либо крадётся ещё медленнее, чем раньше. При этом шар как-то странно дёргается, нервничает, походу.
В обоих случаях перемещает правильно, но очень быстро. Пробовал MobSpeed ставить и 1, и 0.001, всё равно.
Не хочется прибегать к извращению в виде увеличения размеров сцены.
Существуют ли другие способы перемещения?
Re: Перемещение NPC
Закройте тему, пожалуйста.
Re: Перемещение NPC
Использование чарКонтроллера само собой подразумевает такое движение:
Достаточно было открыть скриптРеференсы в хелпе, забить в поиск слово CharacterController и посмотреть пример использования.
Re: Перемещение NPC
Я не использовал CharacterController.
Сделал через rigidbody.AddForce.
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Скрипт для движения персонажа через wasd юнити 3 д
Может уже поднимался такой вопрос, но поиск результатов не дал, может не те слова писал.
Собственно помогите дописать скрипт управления, наверняка уже кто-то писал такой.
Нужно управление персонажем и камерой как в обычной ММО.
Скрипт для камеры:
using UnityEngine ;
using System.Collections ;
[ AddComponentMenu ( «Camera-Control/Mouse Orbit with zoom» ) ]
public class MyMousLook : MonoBehaviour <
//Ссылка на отслеживаемый объект
public Transform target ;
//коэффициенты скорости по осям X Y
public float xSpeed = 12.0f ;
public float ySpeed = 12.0f ;
//Скорость скрола
public float scrollSpeed = 10.0f ;
//Максимальное и минимальное расстояние до камеры
public float zoomMin = 1.0f ;
public float zoomMax = 30.0f ;
//Текущее расстояние док камеры
public float distance = 15 ;
public float Ypos ;
// позиция камеры
public Vector3 position ;
public static Vector3 positionCamera ; //Для передачи в скрипт управления персом
//Зажата ли правая кнопка
public bool isActivated ;
//для отслеживания позиции курсора по осям
float x = 0.0f ;
float y = 0.0f ;
// Выполняется после полного обновления сцены
void LateUpdate ( ) <
if ( Input. GetMouseButtonDown ( 1 ) ) <
isActivated = true ;
>
if ( Input. GetMouseButtonUp ( 1 ) ) <
isActivated = false ;
>
public static float ZoomLimit ( float angle, float min, float max )
<
if ( angle min )
angle = min ;
if ( angle > max )
angle = max ;
return Mathf. Clamp ( angle, min, max ) ;
>
>
Заготовка для персонажа:
///
/// Move player.
/// Управление мышью персонажем
/// Вешается на персонажа
///
using UnityEngine ;
using System.Collections ;
public class MovePlayer : MonoBehaviour
<
private GameObject Player ;
public MyMousLook Char ;
// Переменные для управления мышью
public float stopStart = 1.5f ;
public float speed = 5f ;
public float rotationSpeed = 1200f ;
public float heightPlayer = 1f ;
private float mag, angleToTarget ;
private Ray ray ;
private RaycastHit hit ;
private Vector3 dir ;
private Vector3 target = new Vector3 ( ) ;
private Vector3 lastTarget = new Vector3 ( ) ;
// Анимации
public AnimationClip a_Idle ;
public float a_IdleSpeed = 1 ;
public AnimationClip a_Walk ;
public float a_WalkSpeed = 1 ;
public AnimationClip a_Run ;
public float a_RunSpeed = 2 ;
private bool walk ;
private bool _run ;
//———————-
private float LastClick = 0f ; //Время последнего клика
private float doubleClickDelay = 0.3f ; //Длительность двойного клика
if ( _run ) <
animation. CrossFade ( a_Run. name ) ;
>
else <
animation. CrossFade ( a_Walk. name ) ;
>
>
else if ( Input. GetKey ( KeyCode. D ) || Input. GetKey ( KeyCode. RightArrow ) )
< //на лево
//transform.Rotate(MyMousLook.positionCamera * rotationSpeed * Time.deltaTime);
//transform.rotation = Quaternion.identity;
if ( _run ) <
animation. CrossFade ( a_Run. name ) ;
>
else <
animation. CrossFade ( a_Walk. name ) ;
>
if ( gap doubleClickDelay ) <
LastClick = Time. time ;
>
Собственно всё.
Заранее спасибо за помощь.
Как научить персонажа двигаться в Unity 2D и 3D
Привет, друзья! Давайте начнем обучение созданию игр на Unity (Юнити). Мы публикуем уроки Юнити бесплатно, чтобы вы смогли познакомиться с этой средой и узнать, как устроен язык программирования C# (Си Шарп). В этом уроке разберем как сделать управление персонажем и прыжки в 2D- и 3D-проекте.
Управление персонажем в 3D
Создаем скрипт и даем ему название на английском языке.
Управление персонажем в 2D
Для работы потребуется два спрайта — для персонажа и для земли. Перемещаем персонажа и землю на сцену. С помощью клавиш CTRL+D дублируем землю.
Создаем пустой объект. И в него перемещаем все объекты земли.
Персонажу добавляем физику и коллайдер и так же настраиваем границы коллайдера.
Создаем скрипт на C#
Теперь отражаем наш спрайт в зависимости от того, в какую сторону движется наш персонаж. Условием If проверяем. Если нажали клавишу для перемещения вправо, а персонаж направлен влево, то поворачиваем спрайт вправо. С else if — обратная ситуация.
И теперь сама функция Flip. В ней мы отражаем спрайт по оси X и задаем размеры, чтобы из-за отражения не исказились размеры спрайта.
Сохраняем скрипт и перемещаем его на персонажа. Запускаем Юнити и проверяем.
В школе “Пиксель” мы ведем полный курс обучения Unity 3D для детей и подростков. Изучая наши уроки Си Шарп, вы быстро освоите азы программирования и научитесь создавать свои игры.