Движение камеры по контрольным точкам.

Программирование на Юнити.

Движение камеры по контрольным точкам.

Сообщение Courvee 24 фев 2010, 14:17

Есть некая комната. При нажатии на кнопки, камера должна передвигаться к определенному месту. Каждой кнопке соответствует своя контрольная точка. Есть ли возможность генерировать анимацию камеры в самой Юнити, а не подгружать её из 3д макса (max_sm) . Почему не грузить из 3дмакса? Потому что имеется около 30 контрольных точек, и в любую из них можно перейти из любой же точки. Тоесть 30*30=900 анимаций... к сожалению столько анимаций, пусть и простых я не смогу сделать... Что посоветуете???
Моя специализация: 3D. Моделирую, текстурирую, анимирую.
Аватара пользователя
Courvee
UNIт
 
Сообщения: 91
Зарегистрирован: 19 фев 2010, 08:11
Откуда: Россия, г. Оренбург
  • Сайт
  • ICQ

Re: Движение камеры по контрольным точкам.

Сообщение gnoblin 24 фев 2010, 15:38

Можно без проблем перемещать камеру между точками используя класс Transform.
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Движение камеры по контрольным точкам.

Сообщение Courvee 26 фев 2010, 08:48

Яву я не знаю, разбираюсь с ней по ходу, вместе с движком. Никак не соображу как сдвинуть камеру с текущей точки в нужную мне координату. Нужно именно плавное перемещение... что я не так пишу? :-s

Код: Выделить всё
var x = 1;
var y = 0;
var z = 0;

function Update () {
      transform.Translate (x*Time.deltaTime, y*Time.deltaTime, z*Time.deltaTime, Space.World);
      if (Vector3 < transform.position (x, y, z)) {
         transform.Translate = Vector3 (x, y, z);
      }
   }


Пробовал делать так:

Код: Выделить всё
var x = 1;
var y = 0;
var z = 0;

function Update () {
      transform.position = Vector3 (x, y, z);
      
   }


но при этом камера просто перескакивает, а мне необходимо плавное перемещение...
Моя специализация: 3D. Моделирую, текстурирую, анимирую.
Аватара пользователя
Courvee
UNIт
 
Сообщения: 91
Зарегистрирован: 19 фев 2010, 08:11
Откуда: Россия, г. Оренбург
  • Сайт
  • ICQ

Re: Движение камеры по контрольным точкам.

Сообщение Paul Siberdt 26 фев 2010, 10:30

Если координаты не меняются, двигаться между ними можно простым приращением дельты в функции Lerp:

var vCameraPosition : Vector3 = Vector3.Lerp ( vStartPosition, vEndPosition, moveStatus + Time.deltaTime * speedFactor );

moveStatus должна иметь нулевое значение при начале движения и под завершение получит 1.0.
speedFactor задаст скорость движения.

Данный вариант реализует линейное перемещение. Лучше так двигать якорь камеры, а саму камеру плавно подтягивать к этому жесткому и дерганому объекту :)
Аватара пользователя
Paul Siberdt
Адепт
 
Сообщения: 5317
Зарегистрирован: 20 июн 2009, 21:24
Откуда: Moscow, Russia
Skype: siberdt
  • Сайт

Re: Движение камеры по контрольным точкам.

Сообщение Kann 26 фев 2010, 10:50

Или например так

Код: Выделить всё
var speed =10;
function Update () {
   transform.position = transform.position+Vector3.forward*speed*Time.deltaTime;
}
Kann
Старожил
 
Сообщения: 553
Зарегистрирован: 05 ноя 2009, 14:06

Re: Движение камеры по контрольным точкам.

Сообщение Paul Siberdt 26 фев 2010, 11:02

В примере предыдущего поста, объект будет двигаться не в заданную координату, а в направлении мировой оси +Z

В чем прелесть функции Lerp - не надо считать расстояние между векторами, чтобы убедиться, что пора прекращать движение. Всего делов - проверить значение коэффициента интерполяции.
Аватара пользователя
Paul Siberdt
Адепт
 
Сообщения: 5317
Зарегистрирован: 20 июн 2009, 21:24
Откуда: Moscow, Russia
Skype: siberdt
  • Сайт

Re: Движение камеры по контрольным точкам.

Сообщение Kann 26 фев 2010, 11:38

Ну, смотря какие цели ставить, при желании можно и такое сделать

Код: Выделить всё
var speed =10;
var target:Transform;
function Update () {
   direction = transform.position - target.position;
      direction = target.TransformDirection (direction);
      transform.position = transform.position+direction.normalized *speed*Time.deltaTime;
   transform.LookAt(target);
   }
Kann
Старожил
 
Сообщения: 553
Зарегистрирован: 05 ноя 2009, 14:06

Re: Движение камеры по контрольным точкам.

Сообщение Courvee 26 фев 2010, 13:55

Реализовал Лерпом из примера:

Код: Выделить всё
var start  : Transform;
var end : Transform;
var spd = 6.0;

function Update () {
transform.position = Vector3.Lerp(start.position, end.position, Time.time*spd);
}


Работает отлично. Теперь нужно добавить возможность двигаться в разные точки, а не в одну. Я так подозреваю что это можно реализовать через подмену переменной end другим значением. Ушел пробовать..
Моя специализация: 3D. Моделирую, текстурирую, анимирую.
Аватара пользователя
Courvee
UNIт
 
Сообщения: 91
Зарегистрирован: 19 фев 2010, 08:11
Откуда: Россия, г. Оренбург
  • Сайт
  • ICQ

Re: Движение камеры по контрольным точкам.

Сообщение Paul Siberdt 26 фев 2010, 13:59

Да, и не забывайте так же менять точку старта.
Точкой старта становится позиция камеры на момент начала движения в новую точку. Или, как у вас - текущая выбранная позиция камеры из списка.

И разберитесь, что такое Time.time
Как только приложение проживет больше времени, необходимого на перемещение в первую координату, значение коэффициента интерполяции навсегда станет больше 1.0 и ваша камера начнет снова прыгать.

Посмотрите на решение, что я предложил выше и сообразите, что там к чему ;)
Аватара пользователя
Paul Siberdt
Адепт
 
Сообщения: 5317
Зарегистрирован: 20 июн 2009, 21:24
Откуда: Moscow, Russia
Skype: siberdt
  • Сайт

Re: Движение камеры по контрольным точкам.

Сообщение Courvee 26 фев 2010, 14:17

В вашем варианте я всё понял, кроме MoveStatus... можно пояснение по этому поводу?
Аватара пользователя
Courvee
UNIт
 
Сообщения: 91
Зарегистрирован: 19 фев 2010, 08:11
Откуда: Россия, г. Оренбург
  • Сайт
  • ICQ

Re: Движение камеры по контрольным точкам.

Сообщение Paul Siberdt 26 фев 2010, 14:29

moveStatus - это текущее состояние транзишена между точками.

Даже лучше переписать пример на более человеческий:

Код: Выделить всё
var status : float = 0;

function AnyFunction() {
....
status += Time.deltaTime * speedFactor;
vCameraPosition = Vector3.Lerp ( start , end, status );


Чем сильнее status отклоняется от 0.0 к 1.0, тем дальше камера переползает от start к end.
Дельта времени гарантирует прирост этого самого отклонениея в каждом кадре.

Ситуация status >= 1 означает, что камера доползла до новой точки и можно прекращать движение.
Для этого проще ввести бульку.

Общий алгоритм такой:
- если нам надо двигать камеру, ставим новые start и end, status = 0.0, onMove = true
- если onMove == true, добавляем к status временную дельту и смещаем камеру Лерпом согласно нового status, а если status >= 1.0, ставим onMove = false.
Аватара пользователя
Paul Siberdt
Адепт
 
Сообщения: 5317
Зарегистрирован: 20 июн 2009, 21:24
Откуда: Moscow, Russia
Skype: siberdt
  • Сайт

Re: Движение камеры по контрольным точкам.

Сообщение Serge 26 фев 2010, 16:14

Я делаю таким образом:
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class TestCameraMove : MonoBehaviour
{

    public Vector3 distance1;  // коорд. перемещения    
    public Vector3 distance2;  // коорд. перемещения
    public float timeLerp = 3f; // время за кот. нужно сделать перемещение    

    // вспомогательные переменые
    Vector3 mPosition;
    Vector3 oldPosition;
    float speed;
    float oldTime = 0f;    

    bool dvi1, dvi2, dvi3, dvi4, dvi5, dvi6;    
   
    void Start()
    {
        mPosition = oldPosition = transform.position;
        oldTime = Time.time;
        dvi1 = true;
    }
   
    void Update()
    {
        if (dvi1)
        {
            if (mPosition != distance1)
            {
                speed = (Time.time - oldTime) / timeLerp;
                mPosition = Vector3.Lerp(oldPosition, distance1, speed);
                transform.position = mPosition;
            }
            else
            {
                dvi1 = false;                
                mPosition = oldPosition = transform.position;
                timeLerp = 14;
                oldTime = Time.time;
                dvi2 = true;
            }
        }

        if (dvi2)
        {
            if (mPosition != distance2)
            {
                speed = (Time.time - oldTime) / timeLerp;
                mPosition = Vector3.Lerp(oldPosition, distance2, speed);
                transform.position = mPosition;
            }
            else
            {
                dvi2 = false;                
            }
        }
    }
}
 


Здесь у меня главным является время перемещения, а не скорость. Но мне не нравится вариант повторения кода в зависимости от количества движений. Лучшего пока ничего не придумал. :(
О, сколько нам открытий чудных Готовят просвещенья дух И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель.
Аватара пользователя
Serge
UNIверсал
 
Сообщения: 476
Зарегистрирован: 20 мар 2009, 15:53
Откуда: Сибирь г. Омск
  • Сайт
  • ICQ

Re: Движение камеры по контрольным точкам.

Сообщение ][@FF 01 май 2011, 16:56

ммм, попробовал немного переделать ваш код чтобы можно было не повторять куски кода, но он не работает и не понимаю почему.

Синтаксис:
Используется csharp
    public GUIStyle ExcursionStyle;//стиль окна с кнопкой
    float ExcursionWindowX;
    float ExcursionWindowY;
    public GUIStyle ExcursionBtnStyle;

    bool ExcursionBool;//при тру запускаем код в апдейте
    string ThisRoom;//проверяем в какой мы сейчас комнате (я поставил по умолчанию при старте что в 1, в будущем можно передавать параметр комнат)

Vector3[] MarkPosition; //массив точек, заместо Vector3 distance1,distance1;
float[] BetweenTime; //заместо float timeLerp (можно ставить разные значения времени между участками)
bool[] dvi; //заместо dvi1, dvi2,dvi3...
GameObject MainCamGG;//камера ГГ(собсна это мы и есть = ))

bool OneTime;// переключатель для того чтобы камера начинала двигаться не от того положения где мы были при старте сцены, а с первой указанной нами точки

float speed;// так и остался

    void Start ()
    {
        oldTime = Time.time;
        OneTime = true;
        MainCamGG = GameObject.Find("MainCam");
        ThisRoom = "1";
    }

    void OnGUI()//окно
    {
        GUI.Window(9, new Rect(0, 0, ExcursionWindowX, ExcursionWindowY), ExcursionWindow, "", ExcursionStyle);
    }
   
    void ExcursionWindow(int windowID)
    {
        GUI.BringWindowToFront(9);
        ExcursionWindowX = 59;
        ExcursionWindowY = 49;

        //кнопка при нажатии на которую запускаем код в апдейте
        if (GUI.Button(new Rect(0, 0, ExcursionWindowX, ExcursionWindowY), "", ExcursionBtnStyle))
        {
            ExcursionBool = true;
        }
    }


    void Update ()
    {
        if (ExcursionBool)//запускаем код
        {
            if (ThisRoom == "1")//если комната первая
            {
                NumMark = 7;//7 точек в комнате
                Vector3[] MarkPosition = new Vector3[NumMark]; // 7 точек в комнате
                float[] BetweenTime = new float[NumMark - 1];//6 временных интервалов
                bool[] dvi = new bool[NumMark - 1];//6 булевых переменных

                MarkPosition[0] = new Vector3(32.37901f, 1.922392f, 1.876713f);//первое положение
                BetweenTime[0] = 20;//время между 0 и 1 точками
                MarkPosition[1] = new Vector3(13.17782f, 1.922392f, 19.61474f);
                BetweenTime[1] = 20;
                MarkPosition[2] = new Vector3(-15.90358f, 1.922392f, 12.12216f);
                BetweenTime[2] = 20;
                MarkPosition[3] = new Vector3(-23.59447f, 1.922392f, -5.401195f);
                BetweenTime[3] = 20;
                MarkPosition[4] = new Vector3(-8.763806f, 1.922392f, -29.94238f);
                BetweenTime[4] = 20;
                MarkPosition[5] = new Vector3(17.4964f, 1.922392f, -22.29062f);
                BetweenTime[5] = 20;
                MarkPosition[6] = new Vector3(32.63352f, 1.922392f, -11.34174f);

                MainCamGG.transform.position = MarkPosition[0];//переносим камеру в 0 точку

                if (OneTime)
                {
                    mPosition = oldPosition = MarkPosition[0];
                    dvi[0] = true;
                    OneTime = false;
                }
               
                //наш цикл за место кусков кода, он не работает не понимаю почему, мозгов не хватает наверно = )
                for (int i = 0; i < NumMark - 1; i++)
                {
                    if (dvi[i])
                    {
                        if (mPosition != MarkPosition[i+1])
                        {
                            speed = (Time.time - oldTime) / BetweenTime[i];
                            mPosition = Vector3.Lerp(oldPosition, MarkPosition[i+1], speed);
                            MainCamGG.transform.position = mPosition;
                            //yield return new WaitForSeconds(BetweenTime[i]);
                        }
                        else
                        {
                            if (i + 1 == NumMark)
                            {
                                dvi[i] = false;
                                ExcursionBool = false;
                            }
                            else
                            {
                                dvi[i] = false;
                                mPosition = oldPosition = MarkPosition[i + 1];
                                oldTime = Time.time;
                                dvi[i + 1] = true;
                            }
                        }
                    }
                }
                //---------------------------
            }
        }
        }


буду очень рад если объясните где я сделал ошибку в цикле, и правильно ли вообще делать такой цикл, может стоит сделать через While,
так же наверно стоит поставить ожидание по времени между точками
Аватара пользователя
][@FF
UNIт
 
Сообщения: 62
Зарегистрирован: 24 фев 2011, 20:02
  • ICQ

Re: Движение камеры по контрольным точкам.

Сообщение ][@FF 02 май 2011, 12:02

решение выложил
viewtopic.php?f=18&t=4265
Аватара пользователя
][@FF
UNIт
 
Сообщения: 62
Зарегистрирован: 24 фев 2011, 20:02
  • ICQ


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8