Unity3D создание лифта с кнопками.

Данный урок описывает основные моменты создания лифта с кнопками управления. Причем расположить кнопки можно как в самом лифте так и за его пределами. В этом и была фишка урока.


Давно хотел описать принцип работы лифта в Unity3D вот решился на это событие. Итак для создания лифта запускаем Unity3d и создаем проект.

    В новый проект лучше добавить элементы управления персонажем чтобы нам не отвлекаться на лишние действия. Для этого нажимаем кнопку Asset packages.

    Ставим галку на против пакета Characters (игрок по русски), это добавит компоненты для управления игроком.

    В целом ничего не измениться даже если Вы установите все галки но после этого ваш проект будет огромным с кучей пока что не нужного барахла. Если это Вас не пугает, делать огромные бесполезные пробные проекты, тогда вперед. Итак все выбрали и запускаем создание нового проекта.

    Ура Unity3D запустился и мы видим прекрасную сцену с одинокой камерой смотрящей в даль.

    Для того чтобы наш будущий игрок мог ходить по полу его нужно создать. Итак добавим на сцену обычный куб который в дальнейшем станет полом для игрока. Для этого выберем пункт GameObject >> Cube

    Кубик создастся размером по всем осям координат в единицу. Для какого то применения данный размер может и подойдет например для Minecraft но нам нужен пол. 
    Для изменения его размеров в инспекторе выставим размеры по ширине X и длине Z объекту например 100 на 100 и увидим как кубик превратился в импровизированный пол. Ура сцена есть.

   

    Далее настроим камере управление чтобы мы могли двигаться по уровню и выполнять какие то действия. Для этого выделим камеру и добавим в ее компоненты систему управления. для этого выберем в меню следующий пункт.

    Данный контроллер очень сложный скрипт позволяющий делать интересные эффекты с персонажем и отвечает он за перемещение, полеты, вращение головой и так далее. Нам достаточно будет того что наша камера будет просто двигаться. Поэтому найдем в параметрах пункт Walk Speed (скорость ходьбы) и выставим ее например в 1 чтобы камера смещалась при ходьбе с этой скоростью. Если будет стоять ноль то мы никуда не двинемся.
    При запуске игры после этих манипуляций можно будет вращать камерой вверх в низ и двигаться по нашему уровню. Итак далее нужно создать лифт. У лифта будет набор органов управления.  

   1) кнопки управления внутри лифта.

   2) кнопка вызова лифта на этаже.

    Первым делом делаем лифт и опишем его поведение. 

   Создаем платформу из кубика которая будет символический лифтом. 

    Далее установим ей размер чтобы она походила на пол лифта. 
    Чтобы лифт отличался и его можно было увидеть на полу. Создадим простой материал и далее присвоим его лифту.

   1) Чтобы создать материал щелкаем мышкой в Assets Store и и выбираем 

   

   2) тащим материал прям на объект сцены который будем раскрашивать 

   3) в полученном материале настраиваем цвет как хочется. Главное чтобы наша площадка выделялась и была видна. 

    Итак теперь опишем поведение данной площадки лифта. Если подумать как работает мотор лифта то можно узнать что у лифта есть всего 3 состояния. 

1) лифт стоит на месте

2) лифт едет вверх

3) лифт едет вниз

    Далее скорость лифта не меняется и она при движении постоянна.

    Итак опишем данный процесс в скрипте C# для этого создаем скрипт на данном языке. Назовем данный скрипт EngineLift (двигатель лифта) .

    Называем созданный скрипт EngineLift.

    Итак объявим 2 переменные одна будет означать направление движения лифта по оси Y 

1) если значение 1 то двигаемся вверх

2) если значение 0 то стоим на месте

3) если значение -1 то двигаться вниз

    Вторая переменная будет скорость движения платформы ( лифта ).

Unity3D переменные для движения лифта

using UnityEngine;

using System.Collections;

public class EngineLift : MonoBehaviour {

    public int 

                SpeedMove = 0,  //скорость движения лифта

                VectorMove = 0; //направление движения

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

}

}

    Чтобы двигать лифт нужно менять координату Y в параметре Transform.position относительно переменной направления умножив ее на скорость и прошедшие секунды. Добавим данное действие в функцию Update()

Unity3D функция движения лифта

using UnityEngine;

using System.Collections;

public class EngineLift : MonoBehaviour {

    public int 

                SpeedMove = 0,  //скорость движения лифта

                VectorMove = 0; //направление движения

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

  //получим текущую позицию лифта

        Vector3 P = this.transform.position;

        //задаем движение относительно оси Y

        P.y = P.y + SpeedMove * VectorMove * Time.deltaTime;

        //меняем координаты лифта на новые 

        this.transform.position = P;

}

}

   Далее сохраняем и тащим наш скрипт на платформу чтобы он начал на ней работать при запуске игры

    Запускаем и прямо во время игры задаем скорость и направление для движения лифта вверх. Всегда обнулив параметр VectorMove мы сможем остановить лифт а если поставить его в -1 то мы его просто заставим опускаться вниз. 

    Итак наш мотор работает поднимает и опускает кабину лифта. Теперь займемся кнопками управления. Что делает кнопка.  Она включается в момент вызова лифта и отключается  в момент когда лифт достиг ее высоты. Таким образом у кнопки есть 2 состояния и один параметр.

1) лифт вызван (кнопка горит) 

2) выключена 

3) Параметр на какой высоте должен остановиться лифт чтобы отключить кнопку.

    Далее лифт не может двигаться бесконечно вверх или вниз поэтому зададим ему ограничения по высоте. Для этого объявим две переменные Max_Y и Min_Y которые будут ограничивать движение нашего лифта вверх и в низ.

Текстовое поле

public class EngineLift : MonoBehaviour {

/***********************************************************/

    //ограничение 

    public float Max_Y=10, //Максимальная высота

                 Min_Y=1;  //минимальная высота

/***********************************************************/

    public int 

                SpeedMove = 0,  //скорость движения лифта

                VectorMove = 0; //направление движения

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

   //получим текущую позицию лифта

        Vector3 P = this.transform.position;

        //задаем движение относительно оси Y

        P.y = P.y + SpeedMove * VectorMove * Time.deltaTime;

/***********************************************************/     

        if (P.y > Min_Y) //проверяем максимальную высоту

            if (P.y < Max_Y) //проверяем минимальную высоту

                this.transform.position = P;//меняем координаты лифта на новые 

/***********************************************************/       

}

}

    Итак создадим кнопку которая в дальнейшем будет управлять движением лифта. Сделаем что то неординарное итак если мы раньше добавляли на сцену куб то теперь добавим на сцену сферу. Чтобы внести разнообразие в наш игровой процесс.

    Итак наша сфера будет принимать 2 состояния которые мы будем менять двумя вариантами первый по щелчку мыши будем включать или отключать вызов лифта. И второе когда лифт будет сам включать и отключать кнопку если он доехал до нее. Для того чтобы отображать эти состояния визуально создадим 2 материала один назовем On второй будет Off

    Создаем 1 материал вызвав контекстное меню в окошке assets store и даем ему имя on

   Выделим данный материал и назначим ему цвет например красный.

   Создаем 2 материал вызвав контекстное меню в окошке assets store и даем ему имя off

    Выделим данный материал и назначим ему цвет например синий.

 

    Отлично далее создадим новый файл скрипта в котором опишем поведение нашей кнопки. Назовем его ButtonKlick и опишем в нем смену состояния кнопки во время щелчка по ней. Опишем в коде массив материалов в котором будут храниться цвета кнопок.

Unity3D массив материалов.

 //список материалов для отображения состояния кнопки

    public Material[] MatOnOff;

    Далее повесим скрипт на кнопку и зададим параметры переменной которая будет хранить изображения состояния кнопки.

    Добавим кнопке переменную которая будет означать в каком она состоянии находиться в текущий момент. Она будет логического типа:

если значение будет true (правда)

значит мы на нее нажали; если значение будет (false) ложь значит мы на нее не нажали. 

    Далее сменим материал во время смены состояния кнопки.

Unity3D переменная состояния кнопки

  //список материалов для отображения состояния кнопки

   public Material[] MatOnOff;

    //переменная обозначения нажатия кнопки 

   public bool ON=false; //по умолчанию отключена

   void ChangeON() 

    {

        //присваиваем переключателю обратный вид

        ON = !ON;

    }

   void OnMouseDown() 

    {

        ChangeON();

    }

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

        //получаем параметр материала

        Renderer rend = GetComponent();

       //если материал загружен в скрипт

        if(MatOnOff.Length>0)

       //меняем цвет материала в зависимости от того нажата кнопка или нет

        if(ON)

        rend.material = MatOnOff[1];

        else

        rend.material = MatOnOff[0];

           

}

   

    Кнопка будет хранить в себе координату в какой точке она ждет лифт (по сути координаты этажа куда нужно попасть чтобы погасить кнопку). Потом мы будем эту координату использовать при определении куда нужно ехать лифту. Итак добавляем это значение (переменную) нашей кнопке.

Unity3D координаты этажа кнопки

 //координата этажа кнопки

    public float VY = 0;

     Теперь чтобы кнопки у нас были одинаковые создадим в Assets контейнер (prefab)

 и разместим в нем нашу настроенную кнопку, просто перетащив его из окна Hitrarhy сферу в созданный префаб.

    Итак теперь мы готовы описать логику вызова лифта на нужный нам этаж.
   Для этого на сцене разместим 3 кнопки. В каждой кнопке укажем координаты этажа на который нужно подняться лифту.
 Button button1 button2
 

 

 

    Теперь мы можем описать алгоритм движения лифта на указанную высоту проходя вызванные кнопки. Создаем скрипт MoveLift. 

   Для текущей задачи добавим в код одну кнопку и ссылку на платформу лифта которой будем управлять с помощью этой кнопки.

Текстовое поле

   //список кнопок лифта

   public GameObject ButtonLift;

   //лифт которым будем управлять

   public GameObject Lift;

    По идее, данный код можно будет повесить на весь лифт, например на стену лифта или на его основную панель управления. Главное чтобы при старте игры он фигурировал в ней. Я повешу его на камеру. Но нужно понимать что это не принципиально где он будет расположен.

    Итак попробуем описать сначала запуск движения лифта на основе первой самой нижней кнопки. Для этого в скрипт добавим 2 переменные. Первая переменная будет ссылка на кнопку лифта которая должна управлять платформой, вторая переменная будет ссылка на платформу.

Unity3D кнопка управления лифтом

 //список кнопок лифта

   public GameObject ButtonLift;

 //лифт которым будем управлять   

   public GameObject Lift;

    Следующим шагом опишем поведение лифта в виде функции MoveLifts

Текстовое поле

 void MoveLifts() 

    {

       //получаем данные о кнопке

        ButtonKlick S = ButtonLift.GetComponent();

        EngineLift Engine = Lift.GetComponent();

       //получаем значение кнопки

        if (S.ON)

        {

           //если кнопка включена то получаем направление в какую сторону двигать лифт

            //получаем текущее положение лифта

            float PozaLift = Lift.transform.position.y;

           //получаем направление лифта

            float Direct = S.VY - PozaLift;

            //округлим координату чтобы не париться с дробями и точными значениями 

            Direct = Mathf.Round(Direct);

           //значит направление вверх

            if (Direct > 0)

            {

                Engine.VectorMove = 1; //задаем лифту направление вверх

            }

            if (Direct < 0)

            {

                Engine.VectorMove = -1;//задаем направление лифт в низ

            }

           //значит мы доехали

            if (Direct == 0)

            {

               //если мы достигли нужно высоты то

                S.ON = false; //отключаем кнопку

                Engine.VectorMove = 0; //останавливаем лифт

            }

        }

        else 

        {

           //если кнопка отключена то останавливаем движение лифта

            S.ON = false;//отключаем кнопку

            Engine.VectorMove = 0;//останавливаем лифт

        }

    }

    Добавляем вызов функции управления в функцию Update

Текстовое поле

// обновление при каждом новой перерисовки экрана

void Update () {

         MoveLifts(); //проверяем состояние кнопки

}

    Итак запустим  проект и посмотрим что получилось. Как видим задав кнопке значение высоты мы заставляем платформу ехать в направлении этого значения пока лифт не достигнет его. Как только лифт достиг желанной точки он останавливается и отключает кнопку.

    Следующим шагом нам нужно будет перебрать все кнопки по очереди о которых будет наш скрипт и направить нашу импровизированную платформу по тем кнопкам которые включены. Причем как известно лифт останавливается в указанном месте на какое то время и потом едет далее.  Для этого мы добавим задержку времени.

    Итак модифицируем нашу переменную которая является ссылкой на кнопку и сделаем из нее массив кнопок. Для этого изменим строку 

Unyti3d меняем эту строку

   //список кнопок лифта

   public GameObject ButtonLift;

    На строку:

Текстовое поле

 //список кнопок лифта

   public GameObject [ ] ButtonLift;

    Отлично теперь мы будет знать не об одной кнопке а о всех которые есть на сцене и должны управлять лифтом.

Теперь модифицируем функцию движения лифта для этого создадим локальную переменную в виде параметра функции чтобы в нее передавать выбранную кнопку. А далее добавим вторую переменную которая будет возвращать нам результат движения лифта если он едет то будет false если он стоит то будет true это позволит понять что нужно проверить следующую кнопку лифта. 

Unity3D модифицируем функцию управления лифтом MoveLifts

//функция будет возвращать ложь в тот момент когда кнопка будет включена

   bool MoveLifts(GameObject ButtonL) //передаем в функцию ссылку на кнопку лифта

    {

        //получаем данные о кнопке

        ButtonKlick S = ButtonL.GetComponent();

        //получаем информацию о движении лифта

        EngineLift Engine = Lift.GetComponent();

        //получаем значение кнопки

        if (S.ON)

        {

            //если кнопка включена то получаем направление в какую сторону двигать лифт

            //получаем текущее положение лифта

            float PozaLift = Lift.transform.position.y;

            //получаем направление лифта

            float Direct = S.VY - PozaLift;

            //округлим координату чтобы не париться с дробями и точными значениями 

            Direct = Mathf.Round(Direct);

            //значит направление вверх

            if (Direct > 0)

            {

                Engine.VectorMove = 1; //задаем лифту направление вверх

            }

            if (Direct < 0)

            {

                Engine.VectorMove = -1;//задаем направление лифут в низ

            }

            //значит мы доехали

            if (Direct == 0)

            {

                //если мы достигли нужно высоты то

                S.ON = false; //отключаем кнопку

                Engine.VectorMove = 0; //останавливаем лифт

            }

        }

        else 

        {

            //если кнопка отключена то останавливаем движение лифта

            S.ON = false;//отключаем кнопку

            Engine.VectorMove = 0;//останавливаем лифт

        }

       return S.ON; //возвращаем состояние кнопки

    }

    Теперь в функции Update выполним следующий процесс. Будем в цикле перебирать кнопки лифта. Находим первую включенную кнопку лифта и запускаем процесс движения к ней. Далее когда наша функция достигает этой кнопки ищем следующую включенную кнопку и двигаемся к ней. И так далее пока кнопки включенные кнопки не закончатся. Если все кнопки выключены то лифт будет стоять на месте бездельничать.

Unity3D функция Update движение лифта по нажатию на кнопки

// обновление при каждом новой перерисовки экрана

void Update () {

     

        //перебираем все кнопки из массива кнопок

       foreach (GameObject B in ButtonLift)

        {

                //выбираем кнопку в массиве и двигаемся к ней

                if (MoveLifts(B))

                {

                   //если кнопка все еще включена то не ищем следующий блок

                   break

                }

        }

}

    Далее в настройках скрипта добавим все ссылки на кнопки которые у нас находятся на сцене. 

    Итак запускаем проект и проверяем как лиф будет перемещаться при нажатых кнопках.

   

    Проект данного урока можно скачать по ссылке 

Чтобы увидеть уровень нужно открыть карту с именем lift которая расположена в Assets данного проекта


327 0 850 3
3
2015-07-12
Отличный урок - Спасибо! И отдельное спасибо за C#
2015-07-13
[quote=lostframe] Отличный урок - Спасибо! И отдельное спасибо за C# [/quote]
Очень рад) что понравился урок. 
2016-07-24
да.... хоть кто-то по человечески просветил данную тему ! )) если и есть официальный тутор по этой теме, то этот ни чуть не уступает. спасибо автору !!
RENDER.RU