Добрый вечер! Пытаюсь реализовать перемещение объекта по заданному маршруту с постоянной скоростью, а игрок может нажатием клавиши его остановить. Прыгать персонаж не будет лишь перемещаться да останавливаться. Маршрут будет иметь подъемы и спуски, двигающиеся платформы. Так как с ANTARES и кривыми у меня не сложилось, решил попробовать сделать сам. Вот что пока получилось:
1. Имеем Объект Path (GameObject) с набором пустых GameObject - вейпоинтов, а также скриптом с массивом этих вейпоинтов.
Код
using UnityEngine; using System.Collections;
public class MyPath : MonoBehaviour { public GameObject[] WayPoints;
// Use this for initialization void Start () {
}
// Update is called once per frame void Update () {
} }
2. Имеем объект Cube - куб, у которого есть коллайдер, риджидбади с отключенной гравитацией, а также собственно двигающий скрипт.
Код
using UnityEngine; using System.Collections;
public class PlayerControllerPath : MonoBehaviour { public GameObject Path; // ссылка на объект путь с вложенными вейпоинтами PathMover pathScript; // ссылка на скрипт-объект в объекте Path public GameObject targetVector; // текущая цель-вейпоинт public int wayIndex; // текущий номер элемента в массиве вейпоинтов объекта Path public float speed; // скорость
// Use this for initialization void Start () { wayIndex = 0; pathScript = Path.GetComponent<PathMover>(); targetVector = pathScript.WayPoints[wayIndex]; // получаем первую цель-вейпоинт }
// Update is called once per frame void Update () { if(Input.GetKey(KeyCode.Space)) // если нажат пробел то полностью останавливаем объект Cube { speed = 0; this.rigidbody.drag = 20; } else // если нет, то задаем постоянную скорость { speed = 2f; this.rigidbody.drag = 0; }
if(wayIndex <= pathScript.WayPoints.Length-1) // если в пределах размера массива { if(Vector3.Distance(this.transform.position, targetVector.transform.position) < 1f) // и мы возле текущей цель-вейпоинта { targetVector = pathScript.WayPoints[wayIndex]; // выставляем новую цель-вейпоинт wayIndex++; // увеличиваем индекс массива вейпоинтов объекта Path } }
this.transform.LookAt(targetVector.transform.position); // смотрим на текущую цель-вейпоинт this.transform.position = Vector3.Slerp(this.transform.position, targetVector.transform.position, Time.deltaTime * speed); // двигаемся к текущей цели-вейпоинту } }
Скрипт набросан быстро и он рабочий, но почему то объект Cube при приближении к цели-вейпоинту замедляется. И так при приближении к каждому последующему вейпоинту. По идее персонаж должен двигаться с постоянной скоростью от вейпоинта к вейпоинту. Желательно чтобы его путь не был угловатым, но тут уж наверное просто нужно увеличить количество вейпоинтов чтобы он был более плавным.
Буду очень благодарен за любые полезные советы!
Сообщение отредактировал Danver - Пт, 23 Авг 2013, 18:38
Эта функция всегда в конце пути будет замедлять движение обьекта, она такая по своей сути - если стартовой точкой служит текущая позиция обьекта Надо или стартовую точку зафиксировать - напрмер брать позицию предыдущего поинта. Или применять для движения другие методы, например тот - же rigidbody.velosity X.cor.R (Prologue)
Вообщем, код стал работать лучше, теперь скорость постоянная. Я использовал сохраненное постоянное значение позиции куба для передвижения. А также изменил способ поворота, он стал плавнее. Но вот беда, когда куб достигает последней точки, он вылетает дальше.... Да и если включить в риджиБади гравитацию, то он начинает плясать, не пойму в чем дело...
Код
public int wayIndex; public float speed; private Vector3 oldPos;
// Use this for initialization void Start () { oldPos = this.transform.position; wayIndex = 0; pathScript = Path.GetComponent<PathMover>(); targetVector = pathScript.WayPoints[wayIndex]; }
// Update is called once per frame void Update () { if(Input.GetKey(KeyCode.Space)) { speed = 0; this.rigidbody.drag = 20; } else { speed = 0.5f; this.rigidbody.drag = 0; }
Вчера обнаружил один баг... Когда расстояние между двумя вейпоинтами большое, Куб, при достижении второго вейпоинта начинает крутиться вокруг своей оси и отлетает от вейпоинта в сторону... Есть какие идеи по этому поводу?