Привет, Хабр!

Сегодня вечером у меня появилось свободное время и в процессе бесполезного путешествия по просторам своего ноутбука обнаружил установленную Unity3d, до которой так и не дошли руки.
Ну и решил что-нибудь простое намутить.

Для начала откроем Unity и создадим проект (3D).

Приступим?


Заходим в меню GameObject>3D Object>Cube и получаем куб

image

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

image

Добавляем еще 1 куб и даем ему имя player. Привязываем камеру к «игроку»

image


Нажимаем Add Component>Physics>Rigidbody

image


В окне Rigidbody ставим галочку Use Gravity.

Если нажать на кнопку Play, то мы увидим падающий куб на пластину

Создаем лабиринт


Создаем новый куб и делаем из него подобие стены

image

Дублируем стены и создаем из них лабиринт. Точку финиша украсим выпирающей плитой.
image

Добавляем цвета


image

Самое время кодить


Создаем новый C# скрипт, который называем playerActions

image

Открываем его.

Объявляем переменные


public GameObject player;
public int speed;
public int rotationSpeed;

Функция Start()



player = (GameObject)this.gameObject;

Функция Update()


Следующие строки позволят нашему «герою» перемещаться вперед-назад


if (Input.GetKey (KeyCode.W)) {
	player.transform.position += transform.forward * speed * Time.deltaTime;
}
if (Input.GetKey (KeyCode.S)) {
	player.transform.position -= transform.forward * speed * Time.deltaTime;
}

Для поворота героя используем эти строки


if (Input.GetKey (KeyCode.D)) {
	player.transform.Rotate (Vector3.up * rotationSpeed*Time.deltaTime);
}
if (Input.GetKey (KeyCode.A)) {
	player.transform.Rotate (Vector3.down * rotationSpeed*Time.deltaTime);
}

Функция OnGUI()


Когда дойдем до финиша надо бы сказать мол все, прошли лабиринт и выйти из игры.


if (player.transform.position.z >= 0.99 && player.transform.position.z <= 1.75 &&  player.transform.position.x <= -1.1 && transform.position.x>=-1.49) {
if (GUI.Button (new Rect (200, 200, 800, 400), "You are win!\nExit"))
	{Application.Quit ();}
	ime.timeScale = 0;

Ну вот и все


Почти все готово, осталось только перетащить наш скрипт на «героя»!
Запускаем. Проверяем. Ничего не работает?

Правильно, мы ведь забыли задать значение переменным speed и rotationSpeed!

Вводим значения и запускаем

image


Добавляем аудио-дорожку Game Object>Audio>Audio Source и привязываем к игроку. В поле AudioClip переносим музыку.

Сохраняем нашу сцену.

Сборка


Заходим в меню File>Build and Settings. Добавляем нашу сцену, выбираем платформу и собираем.

Итог


github

Комментарии (21)


  1. suharik
    29.01.2018 16:02

    Класс. Осталось добавить текстуры на стены. Немного кубодверей. Кубооружие, затем кубоврагов. Или наоборот — кубоврагов, затем кубооружие. Кубоаптечки и кубобоеприпасы, чтобы не оказаться запертым в кубоуглу кубоврагом. Загримировать пластину под куболифт.
    Получим Spear of Destiny.


    1. Power911
      29.01.2018 19:56
      +1

      зачем? сразу релиз в стим


    1. heximal
      30.01.2018 19:24

      Похоже, именно в такой последовательности создавался Майнкрафт)


  1. AkshinM
    29.01.2018 17:10

    вместо изображений написано слово «image». автор пофикси


  1. V1tol
    29.01.2018 17:14

    Движение куба в видео очень напомнило скринсейвер «Лабиринт»

    Видео


  1. necyberwolf
    29.01.2018 17:51

    Разве не лучше передвигать кубик с помощью Rigidbody ради избежания проблем с коллайдерами?
    Плюс в Update лучше оставить только проверку на нажатие кнопок, когда как само перемещение поместить в FixedUpdate для того, чтобы не надо было умножать на Time.DeltaTime.


    1. AgentFire
      31.01.2018 12:40

      движение объектов в FixedUpdate? а вы, сударь, ломатель стереотипов.


  1. sergeymolchanovsky
    29.01.2018 19:32

    Так, ребят, давайте не будем парня огорчать, он старался.
    Я в 12 лет тоже подобные «туториалы» писал, по Blitz Бэйсику, и отправлял на бывший тогда популярным форум GamesAnatomy. Все с чего-то начинали :)


  1. savostin
    29.01.2018 19:37

    На Javascript как-то плавнее получается.


  1. Tutanhomon
    30.01.2018 14:54

    Люто минусую!
    1. Ригидбоди и движение трансформом — хлясь по рукам!
    2. player = (GameObject)this.gameObject; — ШТА??
    3. player.transform.position — где кеширование? (мусор и вызовы GC — привет!)

    Какая плавность, вы чего?
    Молчу уже про выравнивания и паблик переменные.


    1. dipspb
      30.01.2018 17:11

      Ничего, что парень впервые в руки взял C# и unity? Естественно, от матёрого девелопера и даже джуниора я сам такое нахрен не приму. Но тут совсем молодняк. За конкретику — однозначно спасибо. Но минусовать какой смысл? Чем ему это поможет?


      1. Tutanhomon
        30.01.2018 18:41

        А какой смысл выкладывать в качестве пособия то, в чем сам некомпетентен? То что взял Юнити в руки — молодец. Но это не повод для статьи на хабре.


        1. dipspb
          30.01.2018 18:56

          Хабр это сборник пособий?! Или место где делятся опытом? Ну вот такой его первый опыт.


          1. Tutanhomon
            30.01.2018 18:59

            Ну вот я считаю что этот опыт для других скорее вреден, чем полезен. А автор пускай сначала почитает хотя бы Мануал


      1. Tutanhomon
        30.01.2018 18:50

        А минусовать нужно для того, чтобы меньше людей читало подобные «туториалы». Их и в интернете полно, примерно такого же качества. Для того голосование за статью и введено, чтобы объективно выводить вверх то, что действительно интересно и полезно, и опускать вещи нулевой полезности.


        1. dipspb
          30.01.2018 19:00

          Это для вас полезность статьи нулевая. А для любого новичка, который ещё ни разу такого не попробовал, она может быть полезной вполне. Хотя бы тем, что покажет: «Чувак, смотри… Ты тоже можешь! Хабр это не только место для снобов-профи, попробуй тоже — у тебя получится!»


    1. Neongrey
      01.02.2018 00:03

      А можете мне пояснить ваш пункт 1?


      1. Tutanhomon
        01.02.2018 12:15

        Конечно. Наличие ригидбоди указывает движку что объект подвержен воздействию физики. А это значит, что двигать его можно исключительно средствами физики и исключительно в FixedUpdate. Если вы делаете все вручную это заставляет физику делать перерасчеты всего и вся, из-за того что физические движок не понимает какого вообще происходит, и это дает приличные просадки производительности. Крмое того, на игроке еще и коллайдер висит без галочки isTrigger, а это значит что физика думает что этот коллайдер статичен (принадлежит к миру) и перерасчитывает ВСЕ готовые расчеты коллизий для статических коллайдеров. Все это написано в справке по юнити большими жирными буквами.


        1. Tutanhomon
          01.02.2018 12:31

          Насчет коллайдера я, кстати, неправ. Статический он был бы без ригидбоди, вот тогда бы его было очень больно двигать.


    1. cry_san
      01.02.2018 03:24

      Приведите свой код


    1. lgorSL
      01.02.2018 11:51

      player.transform.position — где кеширование? (мусор и вызовы GC — привет!)

      in Unity5 we also cache the transform component on the c# side, so there should no longer be a performance reason to cache the transform component yourself.
      Нашёл здесь: https://blogs.unity3d.com/2014/06/23/unity5-api-changes-automatic-script-updating/


      Вот тут люди сравнили ручное кеширование с его отсутствием — разница незначительная.


      Если transform выглядит как поле у gameObject, а position — как поле у transform, откуда новичку знать, что там что-то создаётся?


      И вообще, этот код написан для примера — он должен быть максимально простым и коротким. Если в примере переменные вместо публичных станут приватными, а код разрастётся из-за выравнивания и стремления спасти GC от страшной напасти в виде 50 новых объектов в секунду, повысится ли его понятность?