Перемещение объекта по вейпоинтам (массив GameObject) - Форум Игроделов
Вт, 04 Фев 2025, 02:49 
 
Приветствую Вас Гость Главная | Регистрация | Вход
Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Перемещение объекта по вейпоинтам (массив GameObject)
DanverДата: Пт, 23 Авг 2013, 18:37 | Сообщение # 1
Нет аватара
 
Сообщений: 3
Награды: 0
Репутация: 0
Статус: Offline
Добрый вечер!
Пытаюсь реализовать перемещение объекта по заданному маршруту с постоянной скоростью, а игрок может нажатием клавиши его остановить. Прыгать персонаж не будет лишь перемещаться да останавливаться. Маршрут будет иметь подъемы и спуски, двигающиеся платформы. Так как с 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
 
СообщениеДобрый вечер!
Пытаюсь реализовать перемещение объекта по заданному маршруту с постоянной скоростью, а игрок может нажатием клавиши его остановить. Прыгать персонаж не будет лишь перемещаться да останавливаться. Маршрут будет иметь подъемы и спуски, двигающиеся платформы. Так как с 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:37
ЛевшаДата: Пт, 23 Авг 2013, 20:00 | Сообщение # 2
Черный Волк
 
Сообщений: 7257
Награды: 30
Репутация: 3313
Статус: Offline
Цитата (Danver)
this.transform.position = Vector3.Slerp(this.transform.position, targetVector.transform.position, Time.deltaTime * speed); // двигаемся к текущей цели-вейпоинту

Эта функция всегда в конце пути будет замедлять движение обьекта, она такая по своей сути - если стартовой точкой служит текущая позиция обьекта
Надо или стартовую точку зафиксировать - напрмер брать позицию предыдущего поинта. Или применять для движения другие методы, например тот - же rigidbody.velosity


X.cor.R (Prologue)
 
Сообщение
Цитата (Danver)
this.transform.position = Vector3.Slerp(this.transform.position, targetVector.transform.position, Time.deltaTime * speed); // двигаемся к текущей цели-вейпоинту

Эта функция всегда в конце пути будет замедлять движение обьекта, она такая по своей сути - если стартовой точкой служит текущая позиция обьекта
Надо или стартовую точку зафиксировать - напрмер брать позицию предыдущего поинта. Или применять для движения другие методы, например тот - же rigidbody.velosity

Автор - Левша
Дата добавления - 23 Авг 2013 в 20:00
DanverДата: Пт, 23 Авг 2013, 23:32 | Сообщение # 3
Нет аватара
 
Сообщений: 3
Награды: 0
Репутация: 0
Статус: Offline
Вообщем, код стал работать лучше, теперь скорость постоянная. Я использовал сохраненное постоянное значение позиции куба для передвижения. А также изменил способ поворота, он стал плавнее. Но вот беда, когда куб достигает последней точки, он вылетает дальше.... Да и если включить в риджиБади гравитацию, то он начинает плясать, не пойму в чем дело...

Код

   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;
    }
      
    if(wayIndex <= pathScript.WayPoints.Length-1)
    {
     if(Vector3.Distance(this.transform.position, targetVector.transform.position) < 1f)   
     {   
      targetVector = pathScript.WayPoints[wayIndex];
      wayIndex++;
      oldPos = this.transform.position;
     }
    }
     var q1 = Quaternion.LookRotation(targetVector.transform.position - this.transform.position);
      
     this.transform.rotation = Quaternion.Slerp(this.transform.rotation, q1,Time.deltaTime);

     this.transform.position += ((targetVector.transform.position - oldPos) * Time.deltaTime * speed);
   }
}


Сообщение отредактировал Danver - Пт, 23 Авг 2013, 23:32
 
СообщениеВообщем, код стал работать лучше, теперь скорость постоянная. Я использовал сохраненное постоянное значение позиции куба для передвижения. А также изменил способ поворота, он стал плавнее. Но вот беда, когда куб достигает последней точки, он вылетает дальше.... Да и если включить в риджиБади гравитацию, то он начинает плясать, не пойму в чем дело...

Код

   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;
    }
      
    if(wayIndex <= pathScript.WayPoints.Length-1)
    {
     if(Vector3.Distance(this.transform.position, targetVector.transform.position) < 1f)   
     {   
      targetVector = pathScript.WayPoints[wayIndex];
      wayIndex++;
      oldPos = this.transform.position;
     }
    }
     var q1 = Quaternion.LookRotation(targetVector.transform.position - this.transform.position);
      
     this.transform.rotation = Quaternion.Slerp(this.transform.rotation, q1,Time.deltaTime);

     this.transform.position += ((targetVector.transform.position - oldPos) * Time.deltaTime * speed);
   }
}

Автор - Danver
Дата добавления - 23 Авг 2013 в 23:32
HunjethДата: Сб, 24 Авг 2013, 10:19 | Сообщение # 4
 
Сообщений: 354
Награды: 1
Репутация: 112
Статус: Offline
пиши тогда в FixedUpdate для rigidbody
 
Сообщениепиши тогда в FixedUpdate для rigidbody

Автор - Hunjeth
Дата добавления - 24 Авг 2013 в 10:19
DanverДата: Вс, 25 Авг 2013, 10:20 | Сообщение # 5
Нет аватара
 
Сообщений: 3
Награды: 0
Репутация: 0
Статус: Offline
Вчера обнаружил один баг... Когда расстояние между двумя вейпоинтами большое, Куб, при достижении второго вейпоинта начинает крутиться вокруг своей оси и отлетает от вейпоинта в сторону... Есть какие идеи по этому поводу?
 
СообщениеВчера обнаружил один баг... Когда расстояние между двумя вейпоинтами большое, Куб, при достижении второго вейпоинта начинает крутиться вокруг своей оси и отлетает от вейпоинта в сторону... Есть какие идеи по этому поводу?

Автор - Danver
Дата добавления - 25 Авг 2013 в 10:20
seamanДата: Вс, 25 Авг 2013, 10:35 | Сообщение # 6
Гуру
 
Сообщений: 1748
Награды: 10
Репутация: 660
Статус: Offline
Зачем Вам ригидбоди, если перемещаете просто двигая позицию? Ну или сделайте его IsKinematic И не надо никаких drag
 
СообщениеЗачем Вам ригидбоди, если перемещаете просто двигая позицию? Ну или сделайте его IsKinematic И не надо никаких drag

Автор - seaman
Дата добавления - 25 Авг 2013 в 10:35
  • Страница 1 из 1
  • 1
Поиск:
Загрузка...

Game Creating CommUnity © 2009 - 2025