Создаем FPS в Unity3D [текст].
Zer0n Дата: Пт, 04 Фев 2011, 13:12 | Сообщение # 1
Сообщений: 880
Награды:
23
Репутация:
516
Статус: Offline
Cоздание шутера от первого лица в Unity3D.
Здравствуйте, дорогие пользователи форума! Сегодня я начинаю серию уроков по созданию шутера от 1 лица (FPS) на движке Unity3D .
Сейчас мы научим FPS Controller приседать. Урок подразумевает, что:
Версия Unity3D – 3.x, автор пользуется 3.1 Базовые знания Unity3D и C#. Уроки ogasod'ы вам в помощь. 1. Подготовка. Нам понадобятся новый проект с импортированными стандартными ассетами и простенькая сцена, подойдет даже простой куб в качестве пола. У меня сцена будет следующей:
Перетащим в сцену
First Person Controller из
Standard Assets/Character Controllers и назовем его
Player (выделяем объект в
Hierarchy и жмем
F2 ).
Внимание: проверьте, чтобы он не пересекался с полом, иначе игрок будет проваливаться сквозь пол! Итог:
Вот и все, приготовления закончились.
2. Сам процесс скриптинга. Давайте создадим новый CSharp скрипт и назовем его
PlayerAddon.cs . Откроем его в редакторе (в моем случае
Visual Studio ).
Начнем! Первым делом сменим имя класса на такое же, как у файла с кодом.
Для начала займемся приседаниями по зажатию кнопки
Ctrl . Делать мы это будем путем уменьшением в высоту коллайдера перса, то есть
Character Controller . За высоту отвечает свойство
Height . По умолчанию равно двум. Давайте сделаем переменную типа
Character Controller для хранения ссылки на него и заодно сделаем переменную, отвечающую за его новую высоту.
Давайте вставим в функцию
Update условие, проверяющее, нажата ли
Ctrl .
Теперь давайте получим ссылку на наш контроллер в функции
Start .
Ну, и наконец-то установим высоту, равную значению переменной newHeight (т.к эта переменная публичная (public), то ее значение можно редактировать в Инспекторе). Делаем это в Update, в нашем условии. И вот еще что, добавим одну private переменную - oldHeight. В нее будем записывать значение высоты в стоячем положении. Код:
Теперь можно сохранить и прицепить скрипт к объекту Player. Установим значение
New Height равному 1.
Он приседает, но вместо вставания падает. Потому, что он находится в земле во время приседа. Приподнимем его. Впишем в Update код:
Готово. Теперь он приседает!
Всем привет, это вторая часть урока. Сегодня мы займемся бегом. Откроем проект из предыдущего урока. Для начала добавим в наш скрипт функцию SetSpeed , принимающую в качестве параметра переменную speed типа int, обозначающую скорость. Для тех, кто в танке, скажу, что объявляем ее в теле класса, после функции Update. Как же мы будем устанавливать скорость? Давайте посмотрим наш объект Player Видите в скрипте Character Motor в разделе Movement три переменные, которые я выделил? Они отвечают за скорость движения вперед, в стороны и назад соответственно - именно они нам и нужны. Создадим переменную для хранения ссылки на CharacterMotor в начале класса. Получим ссылку на наш класс в функции Start. Давайте заполним тело нашей функции. Просто задаем нужным переменным нужное значение.
Сообщение отредактировал Zer0n - Сб, 05 Фев 2011, 19:18
Сообщение Cоздание шутера от первого лица в Unity3D.
Здравствуйте, дорогие пользователи форума! Сегодня я начинаю серию уроков по созданию шутера от 1 лица (FPS) на движке Unity3D .
Сейчас мы научим FPS Controller приседать. Урок подразумевает, что:
Версия Unity3D – 3.x, автор пользуется 3.1 Базовые знания Unity3D и C#. Уроки ogasod'ы вам в помощь. 1. Подготовка. Нам понадобятся новый проект с импортированными стандартными ассетами и простенькая сцена, подойдет даже простой куб в качестве пола. У меня сцена будет следующей:
Перетащим в сцену
First Person Controller из
Standard Assets/Character Controllers и назовем его
Player (выделяем объект в
Hierarchy и жмем
F2 ).
Внимание: проверьте, чтобы он не пересекался с полом, иначе игрок будет проваливаться сквозь пол! Итог:
Вот и все, приготовления закончились.
2. Сам процесс скриптинга. Давайте создадим новый CSharp скрипт и назовем его
PlayerAddon.cs . Откроем его в редакторе (в моем случае
Visual Studio ).
Начнем! Первым делом сменим имя класса на такое же, как у файла с кодом.
Для начала займемся приседаниями по зажатию кнопки
Ctrl . Делать мы это будем путем уменьшением в высоту коллайдера перса, то есть
Character Controller . За высоту отвечает свойство
Height . По умолчанию равно двум. Давайте сделаем переменную типа
Character Controller для хранения ссылки на него и заодно сделаем переменную, отвечающую за его новую высоту.
Давайте вставим в функцию
Update условие, проверяющее, нажата ли
Ctrl .
Теперь давайте получим ссылку на наш контроллер в функции
Start .
Ну, и наконец-то установим высоту, равную значению переменной newHeight (т.к эта переменная публичная (public), то ее значение можно редактировать в Инспекторе). Делаем это в Update, в нашем условии. И вот еще что, добавим одну private переменную - oldHeight. В нее будем записывать значение высоты в стоячем положении. Код:
Теперь можно сохранить и прицепить скрипт к объекту Player. Установим значение
New Height равному 1.
Он приседает, но вместо вставания падает. Потому, что он находится в земле во время приседа. Приподнимем его. Впишем в Update код:
Готово. Теперь он приседает!
Всем привет, это вторая часть урока. Сегодня мы займемся бегом. Откроем проект из предыдущего урока. Для начала добавим в наш скрипт функцию SetSpeed , принимающую в качестве параметра переменную speed типа int, обозначающую скорость. Для тех, кто в танке, скажу, что объявляем ее в теле класса, после функции Update. Как же мы будем устанавливать скорость? Давайте посмотрим наш объект Player Видите в скрипте Character Motor в разделе Movement три переменные, которые я выделил? Они отвечают за скорость движения вперед, в стороны и назад соответственно - именно они нам и нужны. Создадим переменную для хранения ссылки на CharacterMotor в начале класса. Получим ссылку на наш класс в функции Start. Давайте заполним тело нашей функции. Просто задаем нужным переменным нужное значение. Автор - Zer0n Дата добавления - 04 Фев 2011 в 13:12
Max-Hunter Дата: Пн, 04 Июл 2011, 20:46 | Сообщение # 2
Сообщений: 151
Награды:
1
Репутация:
60
Статус: Offline
Не получается бег! 'The type a namespace name 'CharacterMotor' could not be found. Are you missing a using directive or an assembly reference?' Выложите плиз (!)весь(!) скрипт.Возможно не туды вставил
Сообщение Не получается бег! 'The type a namespace name 'CharacterMotor' could not be found. Are you missing a using directive or an assembly reference?' Выложите плиз (!)весь(!) скрипт.Возможно не туды вставил Автор - Max-Hunter Дата добавления - 04 Июл 2011 в 20:46
Shut Дата: Пн, 04 Июл 2011, 23:53 | Сообщение # 3
Сообщений: 608
Награды:
2
Репутация:
258
Статус: Offline
Max-Hunter , у меня все замечательно работало.Quote (Max-Hunter )
Возможно не туды вставил
ТЫ копипастишь?!
Мой тебе совет:переписывай код сам,не копипасть!Если будешь тупо копипастить,далеко не уедешь.
Zer0n , выкладывай код скринами
Где арахисы - там и зима.
Сообщение Max-Hunter , у меня все замечательно работало.Quote (Max-Hunter )
Возможно не туды вставил
ТЫ копипастишь?!
Мой тебе совет:переписывай код сам,не копипасть!Если будешь тупо копипастить,далеко не уедешь.
Zer0n , выкладывай код скринами
Автор - Shut Дата добавления - 04 Июл 2011 в 23:53
Max-Hunter Дата: Сб, 10 Сен 2011, 18:17 | Сообщение # 4
Сообщений: 151
Награды:
1
Репутация:
60
Статус: Offline
Quote (Shut )
ТЫ копипастишь?! wacko Мой тебе совет:переписывай код сам,не копипасть!Если будешь тупо копипастить,далеко не уедешь.
Ээээ....дЫк я ещё не выучил....Если я скопипастить не могу,какое сам пиши! Quote (Shut )
Zer0n, выкладывай код скринами biggrin
Я только за!!!!!!! Всё исправил! Добавлено (10.09.2011, 18:17) --------------------------------------------- Опять не получается сделать...Куда надо впихнуть Code
// устанавливает скорость перса. void SetSpeed(int speed) { }
?
Сообщение отредактировал Max-Hunter - Сб, 10 Сен 2011, 18:21
Сообщение Quote (Shut )
ТЫ копипастишь?! wacko Мой тебе совет:переписывай код сам,не копипасть!Если будешь тупо копипастить,далеко не уедешь.
Ээээ....дЫк я ещё не выучил....Если я скопипастить не могу,какое сам пиши! Quote (Shut )
Zer0n, выкладывай код скринами biggrin
Я только за!!!!!!! Всё исправил! Добавлено (10.09.2011, 18:17) --------------------------------------------- Опять не получается сделать...Куда надо впихнуть Code
// устанавливает скорость перса. void SetSpeed(int speed) { }
?Автор - Max-Hunter Дата добавления - 10 Сен 2011 в 18:17
Zaktan Дата: Сб, 10 Сен 2011, 18:51 | Сообщение # 5
Сообщений: 1022
Награды:
8
Репутация:
349
Статус: Offline
Zer0n , как ты программный код так сделал?
Technology for Home Robotics
Сообщение Zer0n , как ты программный код так сделал?Автор - Zaktan Дата добавления - 10 Сен 2011 в 18:51
Shut Дата: Сб, 10 Сен 2011, 19:02 | Сообщение # 6
Сообщений: 608
Награды:
2
Репутация:
258
Статус: Offline
Evel_Lord_Zaktan , Pastebin.com
Где арахисы - там и зима.
Сообщение Evel_Lord_Zaktan , Pastebin.comАвтор - Shut Дата добавления - 10 Сен 2011 в 19:02
Max-Hunter Дата: Сб, 10 Сен 2011, 20:24 | Сообщение # 7
Сообщений: 151
Награды:
1
Репутация:
60
Статус: Offline
КУКУ РЕБЯТ) ДАК КУДА ЕГО ВСТАВИТЬ?Quote (Zer0n )
Для тех, кто в танке, скажу, что объявляем ее в теле класса, после функции Update.
ВСЁ РАВНО НЕ ПОНЯЛ!Добавлено (10.09.2011, 20:24) ---------------------------------------------
Сообщение КУКУ РЕБЯТ) ДАК КУДА ЕГО ВСТАВИТЬ?Quote (Zer0n )
Для тех, кто в танке, скажу, что объявляем ее в теле класса, после функции Update.
ВСЁ РАВНО НЕ ПОНЯЛ!Добавлено (10.09.2011, 20:24) ---------------------------------------------
Автор - Max-Hunter Дата добавления - 10 Сен 2011 в 20:24
Zer0n Дата: Пн, 12 Сен 2011, 13:57 | Сообщение # 8
Сообщений: 880
Награды:
23
Репутация:
516
Статус: Offline
Code
объявление класса { ... function Update () { } здесь. }
Сообщение Code
объявление класса { ... function Update () { } здесь. }
Автор - Zer0n Дата добавления - 12 Сен 2011 в 13:57
Max-Hunter Дата: Вт, 13 Сен 2011, 16:52 | Сообщение # 9
Сообщений: 151
Награды:
1
Репутация:
60
Статус: Offline
Quote (Zer0n )
объявление класса { ... function Update () { } здесь. }
Но там нет function!!! Там void,и куда бы я не тыкал везде ошибкаДобавлено (13.09.2011, 16:52) --------------------------------------------- Всё,код сделал,но
Quote (Max-Hunter )
'CharacterMotor' could not be found. Are you missing a using directive or an assembly reference?'
Сообщение Quote (Zer0n )
объявление класса { ... function Update () { } здесь. }
Но там нет function!!! Там void,и куда бы я не тыкал везде ошибкаДобавлено (13.09.2011, 16:52) --------------------------------------------- Всё,код сделал,но
Quote (Max-Hunter )
'CharacterMotor' could not be found. Are you missing a using directive or an assembly reference?'
Автор - Max-Hunter Дата добавления - 13 Сен 2011 в 16:52
seaman Дата: Вт, 13 Сен 2011, 19:18 | Сообщение # 10
Гуру
Сообщений: 1748
Награды:
10
Репутация:
660
Статус: Offline
Вот эту строку урока Вы выполнили?: Quote
проект с импортированными стандартными ассетами
Сообщение Вот эту строку урока Вы выполнили?: Quote
проект с импортированными стандартными ассетами
Автор - seaman Дата добавления - 13 Сен 2011 в 19:18
Max-Hunter Дата: Сб, 17 Сен 2011, 15:21 | Сообщение # 11
Сообщений: 151
Награды:
1
Репутация:
60
Статус: Offline
seaman , разумеется))) скрипт CharacterMotor имеется!
Сообщение seaman , разумеется))) скрипт CharacterMotor имеется!Автор - Max-Hunter Дата добавления - 17 Сен 2011 в 15:21
Zer0n Дата: Сб, 17 Сен 2011, 15:52 | Сообщение # 12
Сообщений: 880
Награды:
23
Репутация:
516
Статус: Offline
Max-Hunter , да, надо void, перепутал с JS. Ошибку выдает в Юнити или в редакторе кода?
Сообщение Max-Hunter , да, надо void, перепутал с JS. Ошибку выдает в Юнити или в редакторе кода?Автор - Zer0n Дата добавления - 17 Сен 2011 в 15:52
Max-Hunter Дата: Вс, 18 Сен 2011, 13:01 | Сообщение # 13
Сообщений: 151
Награды:
1
Репутация:
60
Статус: Offline
В юне
Сообщение В юне Автор - Max-Hunter Дата добавления - 18 Сен 2011 в 13:01
Dekterev Дата: Вс, 18 Сен 2011, 14:25 | Сообщение # 14
Сообщений: 1753
Награды:
16
Репутация:
892
Статус: Offline
копипаст хреновый, адназначна...
Поиск | Правила | Новые сообщения
Сообщение копипаст хреновый, адназначна... Автор - Dekterev Дата добавления - 18 Сен 2011 в 14:25
Max-Hunter Дата: Ср, 21 Сен 2011, 13:27 | Сообщение # 15
Сообщений: 151
Награды:
1
Репутация:
60
Статус: Offline
Dekterev , а не можете пожалуйста дать полный скрипт? Мне для изучения.
Сообщение Dekterev , а не можете пожалуйста дать полный скрипт? Мне для изучения.Автор - Max-Hunter Дата добавления - 21 Сен 2011 в 13:27
commandoby Дата: Сб, 14 Апр 2012, 19:43 | Сообщение # 16
Unity 3D Free
Сообщений: 836
Награды:
3
Репутация:
211
Статус: Offline
Если кому надо, я переписал скрипт приседания на UJS: Code
var controller : CharacterController; var oldHeight; var newHeight: float; var newPos; function Start () { controller = GetComponent(CharacterController); oldHeight = controller.height; } function Update() { newPos = new Vector3(transform.position.x, transform.position.y + 0.7f, transform.position.z); if (Input.GetKey(KeyCode.LeftControl)) { controller.height = newHeight; } else { if (Input.GetKeyUp (KeyCode.LeftControl)) { controller.height = oldHeight; transform.position = newPos; } } }
Блог.
Сообщение отредактировал commandoby - Сб, 14 Апр 2012, 19:44
Сообщение Если кому надо, я переписал скрипт приседания на UJS: Code
var controller : CharacterController; var oldHeight; var newHeight: float; var newPos; function Start () { controller = GetComponent(CharacterController); oldHeight = controller.height; } function Update() { newPos = new Vector3(transform.position.x, transform.position.y + 0.7f, transform.position.z); if (Input.GetKey(KeyCode.LeftControl)) { controller.height = newHeight; } else { if (Input.GetKeyUp (KeyCode.LeftControl)) { controller.height = oldHeight; transform.position = newPos; } } }
Автор - commandoby Дата добавления - 14 Апр 2012 в 19:43
seaman Дата: Сб, 14 Апр 2012, 21:20 | Сообщение # 17
Гуру
Сообщений: 1748
Награды:
10
Репутация:
660
Статус: Offline
Я бы написал так: Code
var controller : CharacterController; var oldHeight; function Start () { controller = GetComponent(CharacterController); oldHeight = controller.height; } function Update() { if (Input.GetKey(KeyCode.LeftControl)) controller.height = controller.height / 2; if (Input.GetKeyUp (KeyCode.LeftControl)) { controller.height = oldHeight; transform.position.y = transform.position.y + 0.7f; } }
Сообщение Я бы написал так: Code
var controller : CharacterController; var oldHeight; function Start () { controller = GetComponent(CharacterController); oldHeight = controller.height; } function Update() { if (Input.GetKey(KeyCode.LeftControl)) controller.height = controller.height / 2; if (Input.GetKeyUp (KeyCode.LeftControl)) { controller.height = oldHeight; transform.position.y = transform.position.y + 0.7f; } }
Автор - seaman Дата добавления - 14 Апр 2012 в 21:20
Левша Дата: Сб, 14 Апр 2012, 22:55 | Сообщение # 18
Черный Волк
Сообщений: 7257
Награды:
30
Репутация:
3313
Статус: Offline
Неудачный метод, есть большой шанс при вставании пробить пол и улететь под него или воткнуться в колайдер над головой и застрять.
X.cor.R (Prologue)
Сообщение Неудачный метод, есть большой шанс при вставании пробить пол и улететь под него или воткнуться в колайдер над головой и застрять. Автор - Левша Дата добавления - 14 Апр 2012 в 22:55
commandoby Дата: Сб, 14 Апр 2012, 23:25 | Сообщение # 19
Unity 3D Free
Сообщений: 836
Награды:
3
Репутация:
211
Статус: Offline
В моём случае вероятность пробить пол и улететь - 0%, а пробить потолок - 100%. Я пытался избежать этого путём добавления триггера над головой, но он никак не захотел реагировать на блоки.
Блог.
Сообщение В моём случае вероятность пробить пол и улететь - 0%, а пробить потолок - 100%. Я пытался избежать этого путём добавления триггера над головой, но он никак не захотел реагировать на блоки. Автор - commandoby Дата добавления - 14 Апр 2012 в 23:25
seaman Дата: Вс, 15 Апр 2012, 10:08 | Сообщение # 20
Гуру
Сообщений: 1748
Награды:
10
Репутация:
660
Статус: Offline
Ну я над методом даже не думал. Я просто хотел показать, что то же самое можно записать короче и понятнее. Ну а если думать над методом. Чтобы не пробить головой потолок перед вставанием нужно проверять наличие потолка (RayCast) и соответственно не давать вставать, если он есть. Code
var flagStand = false; function Update() { if(flagStand && !Physics.Raycast (transform.position, Vector2.up, oldheight / 2)) { StandUo(); flagStand = false; } ... if (Input.GetKeyUp (KeyCode.LeftControl) ) { if(!Physics.Raycast (transform.position, Vector2.up, oldheight / 2)) StandUp(); else flagStand = true; } } function StandUp() { controller.height = oldHeight; transform.position.y = transform.position.y + 0.7f; }
Чтобы точно не провалиться под пол нужно при вставании не просто прибавлять 0.7, а рассчитывать позицию посложнее, типа: в Start: Code
dist = oldheight / 4 ; //вообще - (oldheight - controller.height) / 2, но т.к. controller.height == oldheight / 2, то получаем это
в Update: Code
transform.position.y = transform.position.y + dist + 0.01f;
Чтобы не "падать" при приседании, нужно смещать позицию вниз: в Update: Code
transform.position.y = transform.position.y - dist + 0.01f;
Итого нечто такое: Code
var controller : CharacterController; var oldHeight; var flagStand = false; var dist; function Start () { controller = GetComponent(CharacterController); oldHeight = controller.height; dist = oldheight / 4 ; //вообще - (oldheight - controller.height) / 2, но т.к. controller.height == oldheight / 2, то получаем это } function Update() { if(flagStand && !Physics.Raycast (transform.position, Vector2.up, oldheight / 2)) { StandUo(); flagStand = false; } if (Input.GetKey(KeyCode.LeftControl)) Squatting(); if (Input.GetKeyUp (KeyCode.LeftControl) ) { if(!Physics.Raycast (transform.position, Vector2.up, oldheight / 2)) StandUp(); else flagStand = true; } } function StandUp() { controller.height = oldHeight; transform.position.y = transform.position.y + dist + 0.01f } functoin Squatting() { controller.height = controller.height / 2; transform.position.y = transform.position.y - dist + 0.01f; }
Не проверял, мог где-то ошибиться, тем более, что в JS не работаю.Добавлено (15.04.2012, 10:08) --------------------------------------------- Ну ошибка логическая одна есть. При приседании нужно:
Quote
if (Input.GetKey(KeyCode.LeftControl)) { Squatting(); flagStand = false; }
Сообщение Ну я над методом даже не думал. Я просто хотел показать, что то же самое можно записать короче и понятнее. Ну а если думать над методом. Чтобы не пробить головой потолок перед вставанием нужно проверять наличие потолка (RayCast) и соответственно не давать вставать, если он есть. Code
var flagStand = false; function Update() { if(flagStand && !Physics.Raycast (transform.position, Vector2.up, oldheight / 2)) { StandUo(); flagStand = false; } ... if (Input.GetKeyUp (KeyCode.LeftControl) ) { if(!Physics.Raycast (transform.position, Vector2.up, oldheight / 2)) StandUp(); else flagStand = true; } } function StandUp() { controller.height = oldHeight; transform.position.y = transform.position.y + 0.7f; }
Чтобы точно не провалиться под пол нужно при вставании не просто прибавлять 0.7, а рассчитывать позицию посложнее, типа: в Start: Code
dist = oldheight / 4 ; //вообще - (oldheight - controller.height) / 2, но т.к. controller.height == oldheight / 2, то получаем это
в Update: Code
transform.position.y = transform.position.y + dist + 0.01f;
Чтобы не "падать" при приседании, нужно смещать позицию вниз: в Update: Code
transform.position.y = transform.position.y - dist + 0.01f;
Итого нечто такое: Code
var controller : CharacterController; var oldHeight; var flagStand = false; var dist; function Start () { controller = GetComponent(CharacterController); oldHeight = controller.height; dist = oldheight / 4 ; //вообще - (oldheight - controller.height) / 2, но т.к. controller.height == oldheight / 2, то получаем это } function Update() { if(flagStand && !Physics.Raycast (transform.position, Vector2.up, oldheight / 2)) { StandUo(); flagStand = false; } if (Input.GetKey(KeyCode.LeftControl)) Squatting(); if (Input.GetKeyUp (KeyCode.LeftControl) ) { if(!Physics.Raycast (transform.position, Vector2.up, oldheight / 2)) StandUp(); else flagStand = true; } } function StandUp() { controller.height = oldHeight; transform.position.y = transform.position.y + dist + 0.01f } functoin Squatting() { controller.height = controller.height / 2; transform.position.y = transform.position.y - dist + 0.01f; }
Не проверял, мог где-то ошибиться, тем более, что в JS не работаю.Добавлено (15.04.2012, 10:08) --------------------------------------------- Ну ошибка логическая одна есть. При приседании нужно:
Quote
if (Input.GetKey(KeyCode.LeftControl)) { Squatting(); flagStand = false; }
Автор - seaman Дата добавления - 15 Апр 2012 в 10:08