
Приветствую! В данной статье мы научимся реализовывать передвижение 3D персонажа в то место, где был произведён клик мыши. В одной из предыдущих статей мы уже научились это делать на примере 2D объекта. Поэтому так же рекомендуем для ознакомления гайд под названием «Как передвинуть 2D объект в место клика мыши», поскольку данная реализация для 2D и 3D игр существенно отличается. Ну а мы приступим к делу.
Для начала подготовим нашу сцену. Первым делом с помощью окна Hierarchy создадим новый игровой объект(3D Object - Plane), на котором мы будем перемещаться, и назовём его Ground. Так же заранее создайте новый тег Ground, и присвойте его к данному объекту. Он нужен для нашего будущего скрипта.
Далее создайте ещё один игровой объект (3D Object - Cube), и назовите его Player. Он будет являться вашим персонажем, который будет передвигаться по земле. Должно получится примерно так.

Теперь перейдём к самому интересному, к написанию скриптов. Создйте C# скрипт и назовите его Move. Заранее присвойте его к объекту вашего персонажа Player, и впишите в данный скрипт следующее содержимое:
using UnityEngine;
public class Player2 : MonoBehaviour
{
public float speed;
public Vector3 target;
public bool isMoving = false;
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit placeInfo;
if (Physics.Raycast(ray, out placeInfo))
{
if(placeInfo.collider.CompareTag("Ground"))
{
target = new Vector3(placeInfo.point.x, transform.position.y, placeInfo.point.z);
isMoving = true;
}
}
}
if (isMoving == true)
{
transform.LookAt(target);
transform.Translate(new Vector3(0, 0, speed * Time.deltaTime));
if (Vector3.Distance(target, transform.position) < 0.01)
{
isMoving = false;
}
}
}
}
Предлагаю разобрать данный код:
- В строке #5 создали переменную speed, в которой хранится информация о скорости перемещения нашего персонажа.
- В строке #6 создана переменная target, в которой будут храниться координаты той точки, куда кликнул игрок, и куда должен перемещаться персонаж.
- В строке #7 создана переменная isMoving, которая хранит информацию о том, нужно ли перемещать нашего персонажа к указанной точке, или нет. True - нужно, false - нет.
Теперь перейдём к разбору метода Update():
- В строке #11 с помощью метода GetMouseButtonDown() мы определяем, была ли кликнула левая кнопка мыши. Если да, то с помощью mousePosition определяем позицию курсора на экране, а потом с помощью ScreenPointToRay получаем луч, идущий от камеры через точку экрана.
- Далее в строке #16 с помощью Physics.Raycast мы выпускаем луч для нахождения координат мирового пространства, чтобы определить, в какую же позицию был произведён клик мыши. И если объект, на котором находится данная координата имеет тег Ground, то в переменную target эти координаты сохраняем. На этом этапе мы получили в переменную target те координаты, куда должен следовать наш персонаж. Ну а в следующей строке мы в переменную isMoving записали значение true, чтобы указать, что необходимо начать движение персонажа.
- В строке #26 мы проверяем, если isMoving равняется true, то мы сначала с помощью метода LookAt() разворачиваем нашего персонажа в то направление, куда необходимо идти, а только потом осуществляем его передвижение с помощью метода Translate().
- Ну а в строке #30 с помощью метода Distance() мы проверяем, если наш игрок дошёл до указанной точки, то прекращаем движение объекта, установив в переменную isMoving значение false.
На этом всё. Но бывают случаи, когда нам необходимо, чтобы персонаж оббегал препятствия, которые попадаются на его пути. И для этих целей нужно использовать NavMesh. В нашей недавней стетье под названием «Поиск пути и обход препятствий с помощью NavMesh» мы подробно это разбирали, поэтому советуем так же ознакомится и с данным материалом.
Если гайд был полезен, буду рад лайкам. Так же оставляйте свои вопросы в комментариях.


Почему у вас имя скрипта "Move", а в коде "Player2"?