Статьи

Совет: пауза, медленное движение и двойное время в Unity

Приостановить игру Unity легко. Есть несколько вещей, о которых вы должны знать, но мы вернемся к ним в конце этого совета. Мы собираемся добавить несколько простых кнопок графического интерфейса для управления временем в базовом проекте Unity.


Давайте посмотрим на конечный результат, к которому мы будем стремиться:

Unity Web Player. Установить сейчас!

Давайте начнем с открытия Unity и создания нового проекта. Возможно, вы захотите добавить анимацию или какое-то действие в процесс, чтобы вы могли увидеть эффект, когда мы нажимаем кнопки. В приведенном примере я просто сделал несколько простых вращающихся кубиков.

Открытие нового проекта приятно и просто. Как только Unity завершит загрузку, если у вас настроено отображение мастера проектов, вы можете нажать вкладку «Создать новый проект» и ввести имя файла. Единство позаботится обо всем остальном. Если окно «Мастер проектов» не открывается при запуске Unity, выберите «Файл»> «Новый проект».

Создание нового проекта Unity

Unity имеет собственную встроенную систему графического интерфейса, которая выходит далеко за рамки этого совета. Давайте просто скажем, что все, что связано с GUI, происходит в функции OnGUI а класс GUI предоставляет целую кучу интересных вещей, таких как кнопка.

Создайте новый скрипт через меню «Активы» — выберите « Активы»> «Создать»> «JavaScript» :

Создание нового скрипта

Ваш новый скрипт должен появиться в окне проекта. Нажмите один раз на сценарий, и он должен выделить, чтобы вы могли переименовать его. Назовите сценарий «PauseScript» и нажмите Enter. Теперь мы хотим начать кодирование, поэтому на этот раз дважды щелкните по нему. Это должно открыть редактор скриптов по умолчанию, в котором уже есть шаблон Unity с шаблоном / кодом по умолчанию. После загрузки редактора сценариев удалите код по умолчанию и замените его следующим кодом:

1
2
3
4
5
6
7
function OnGUI() {
    // show a ‘pause’ button
    if(GUI.Button(Rect(0,0,120,30),»TOGGLE PAUSE»)){
        // call our toggle function
        doPauseToggle();
    }
}

GUI.Button требует Rect (который содержит x, y, ширину и высоту нашей кнопки) и строку для отображения внутри нее. Узнать, была ли нажата кнопка или нет, так же просто, как поместить GUI.Button рисования GUI.Button в оператор if.


Здесь мы ссылаемся на функцию, которую мы собираемся вызвать doPauseToggle() . Это будет простая функция, которая проверяет, приостановлены ли мы или нет, затем выполняет правильное действие. Добавьте следующий код в конец скрипта PauseScript.js, ниже функции OnGUI, которую мы добавили на шаге 2:

01
02
03
04
05
06
07
08
09
10
function doPauseToggle() {
    // here we check to see if we are running at a time scale above 0
    if(Time.timeScale>0){
        // time scale is above zero, so we need to pause the game here
        pauseGame();
    } else {
        // time scale was less than zero, so we unpause the game here
        unPauseGame();
    }
}

Time.timeScale — это то, как мы имеем дело с приостановкой игры. По сути, мы меняем масштаб, по которому проходит время. Когда timeScale 1.0, время в реальном времени. В ноль (0) время приостановлено. Таким образом, в нашей функции doPauseToggle мы просто проверяем, больше ли время, чем ноль, без паузы, если это так, мы вызываем новую pauseGame() . В противном случае вызывается unPauseGame ().


Функции на шаге 3, pauseGame() и unPauseGame() , просто манипулируют значением Time.timeScale с 0 или 1. Добавьте следующий код в конец скрипта PauseScript.js, ниже кода, который мы добавили на шаге 3:

1
2
3
4
5
6
7
function pauseGame () {
    // set scale at which time passes to 0, freezing time(!)
    Time.timeScale=0;
    }function unPauseGame () {
    // set scale at which time passes to 1, running at realtime again
    Time.timeScale=1;
}

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


Ты думаешь, о чем я? Если 0 делает паузу, а 1 делает это, как насчет 0,5? Подумайте время пули!

Во-первых, давайте продолжим и добавим новую кнопку в нашу функцию OnGUI() . Оставьте это в нижней части функции, чуть выше закрывающей скобки.

1
2
3
4
5
// show a ‘slowmo’ button
if(GUI.Button(Rect(0,30,80,30),»SLOWMO»)){
    // call our toggle function
    slowMo();
}

Теперь нам нужна новая функция, чтобы установить временной фактор меньше 1. Прокрутите вниз до нижней части скрипта PauseScript.js и добавьте эту новую функцию:

1
2
3
4
function slowMo () {
    // set scale at which time 5asses to 0.1, running in slowmo
    Time.timeScale=0.1;
}

… тем самым доказывая, что вам не нужно быть Нео для пули в Unity!


Наконец, для развлечения давайте сделаем все немного сумасшедшим, играя в двойное время. Хотя я не видел, чтобы это использовалось в реальной игровой механике, я видел временное масштабирование, чтобы временно запустить эффект частиц — это был эффект огня, и автор хотел, чтобы экран был заполнен огнем быстро, чтобы создать фон его экранного меню к жизни. Он увеличил время на секунду после того, как меню загрузилось и огонь заполнил экран. Затем он сократил время до 1, чтобы пламя двигалось правильно, а все остальное в игре было на постоянной скорости.

Чтобы добавить двойное время, мы будем следовать той же процедуре, что и в шаге 5, добавив новую кнопку, которая вызовет новую функцию. Новая функция просто установит для нашего timeScale значение 2. Найдите функцию OnGUI() в вашем скрипте PauseScript.js и добавьте следующую строку над концом функции и над закрывающей фигурной скобкой } .

1
2
3
4
5
// show a ‘double time’ button
if(GUI.Button(Rect(0,60,120,30),»DOUBLE TIME»)){
    // call our toggle function
    doubleTime();
}

Правильно. У нас есть кнопка, давайте добавим в эту функцию doubleTime ():

1
2
3
4
function doubleTime () {
    // set scale at which time passes to 0.5, running in slowmo
    Time.timeScale=2;
}

Для развлечения попробуйте настроить timeScale до 100 и посмотрите, что произойдет.


Давайте подведем итоги нашего сценария. Вот полный PauseScript.js, на случай, если по пути случится что-то плохое:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
function OnGUI() {
    // show a ‘pause’ button
    if(GUI.Button(Rect(0,0,120,30),»TOGGLE PAUSE»)){
        // call our toggle function
        doPauseToggle();
    }
    // show a ‘slowmo’ button
    if(GUI.Button(Rect(0,30,80,30),»SLOWMO»)){
        // call our toggle function
        slowMo();
    }
    // show a ‘double time’ button
    if(GUI.Button(Rect(0,60,120,30),»DOUBLE TIME»)){
        // call our toggle function
        doubleTime();
    }
}
 
function doPauseToggle() {
    // here we check to see if we are running at a time scale above 0
    if(Time.timeScale>0){
        // time scale is above zero, so we need to pause the game here
        pauseGame();
    } else {
        // time scale was less than zero, so we unpause the game here
        unPauseGame();
    }
}
 
function pauseGame () {
    // set scale at which time passes to 0, freezing time(!)
    Time.timeScale=0;
}
 
function unPauseGame () {
    // set scale at which time passes to 1, running at realtime again
    Time.timeScale=1;
}
 
function slowMo () {
    // set scale at which time passes to 0.1, running in slowmo
    Time.timeScale=0.1;
}
 
function doubleTime () {
    // set scale at which time passes to 0.5, running in slowmo
    Time.timeScale=2;
}

Важно отметить, что Time.timeScale не повлияет на код в функции Update() . Обновление происходит каждый «тик» и происходит за пределами шкалы времени, поэтому, если вам нужно, чтобы что-то происходило во время паузы игры, например, фоновая анимация, место, куда ее нужно поместить, скорее всего, «Обновить». Проверьте документацию Unity для получения дополнительной информации об этом.

Обратите внимание, что если вы измените значение Time.timeScale , любые изменения, связанные со временем, такие как вызовы функции Invoke или таймеры, использующие значения из Time.time, также будут затронуты этим изменением. Если ваша игра работает с удвоенной скоростью, вам придется вдвое сократить скорость ваших действий, основанных на времени (например, если у вас есть гоночная игра с таймером круга, а для Time.timeScale установлено значение 2.0, вам потребуется замедлите таймер круга вдвое, чтобы он точно измерил время).

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

Это оно! Спасибо, что прочитали мой быстрый совет. Поиграйте с Time.timeScale и я с нетерпением жду возможности увидеть интересные эффекты в Time.timeScale Matrix в ваших проектах. Веселитесь, создавая игры!