Как сделать счетчик в юнити
Unity3d. Уроки от Unity 3D Student (B13-B16)
Предыдущие уроки вы можете найти по следующим ссылкам:
Уроки B01-B03
Уроки B04-B08
Уроки B09-B12
PS: Так же исправленны некоторые ошибки в предыдущих уроках, большое спасибо хабравчанинам ufomesh и MikhailS.
Базовый Урок 13 — Определение столкновений с триггером
В уроке рассказывается, как определить столкновения между невидимыми для игрока объектами, используя неосязаемые «триггер коллайдеры» (trigger colliders).
Если вы хотите определить столкновения, но не ходите, чтоб столкнувшийся объект остановился, вам требуется использовать триггер (trigger)
Триггеры позволяют вам определить, где именно расположен объект на сцене (во время запуска приложения).
На нашей сцене имеется куб («box» с rigidbody), который падает на синюю платформу («platform»).
Естественно платформа останавливает куб, поскольку среди ее компонентов присутствует box collider.
У компонента box collider есть чекбокc Is Trigger. Если включить
его и запустить сцену снова, то куб провалиться через платформу.
Таким образом мы можем создавать столкновения, которые не должны быть видны пользователю. Например, отключим компонент Mesh Renderer у нашей платформы. Мы по прежнему видем зеленый контур объекта, если выделим его в Hierarchy View.
Если мы нажмем play, то куб провалиться через нивидимую платформу, но пока мы не можем ничего узнать о произошедшем.
Создадим скрипт, назовем его Trigger и добавим в тело класса следующий код
Добавим скрипт к платформе. Теперь, как тольку куб пройдет сквозь платформу, вы увидете сообщение «Box went through!» в консоли.
Базовый Урок 14 — GUI текст и счетчики
В уроке рассказывается, как отобразить информацию о счетчике на экран используя компонент GUI Text
Чтобы отображать текстовую информацию на экран воспользуемся элементом GUI Text.
Добавим его на сцену — Game Object->Create Other->GUI Text.
Так же, обратите внимание, чтоб у камеры был включен компонент GUILayer.
Текст можно редактировать напрямую через редактор (поле Text).
Но мы воспользуемся скриптом для этого. Добавим скрипт (GUITextExample). Код будем писать в метод Update():
Если зайти в стравку о параметре guiText.text, то увидите следующие:
var text: String
Description
The text to display.
То есть, при передачи параметра мы должны быть уверены что передаем string.
Теперь если запустить игру, то текст поменяется.
Попробуем отобразить счетчик. В класс добавим переменную-счетчик (Counter) и немного подправим код в методе Update().
В итоге Unity выдаст ошибку:
Нам требуется привести переменную типа int к типу string.
Это можно сделать многими способами. Вот некоторые из них:
Воспользуемся последним способом, только вместо пустой строки напишем текст:
Жмем play и наблюдаем как увеличивается значения переменной-счетчика.
Мы так же можем изменить шрифт текста, если у вас в проекте есть дополнительный шрифт (font).
Чтоб поменять шрифт, достаточно перетащить его в соответствующие поле компонента GUIText (Font).
Тут же можно поменять другие параметры, такие как размер (font size), выравнивание (alignment) и некоторые другие.
Базовый Урок 15 — Добавление компонентов с помощью скриптов
В уроке рассказывается, как добавить компонент к объекту используя скрипты и быть увереным, что мы их добавили только однажды.
Для того, чтобы добавить компонент в run-time воспользуемся скриптами.
В нашем примере у нас снова есть платформа («platform») и ящик(«box» с rigidbody) который на нее падает.
Попробуем добивать компонент к платформе, как только ящик упадёт на неё.
Добавим скрипт addComp В класс добивим следующий код:
Скрипт добавим к ящику. Жмем play и видим — как только ящик падает на платформа, она тоже начнёт падать.
Но в консоле вы увидите предупреждение:
Мы получили это сообщение, поскольку пытаемся добавить компонент Rigidbody каждый раз, когда ящик сталкивается с платформой, то есть — мы добавляем его более одного раза. Чтоб этого не происходило, нам нужно добавить проверку и добавлять компонент, только в случае его отсутствия. Добавим в OnCollisionEnter() еще одно условие:
Теперь запустим приложение и убедимся, что в консоли отсутствует предупреждение.
Базовый Урок 16 — Переключение между сцен
В уроке рассказывается, как написать скрипт, для переключения между сценами в проекте Unity.
Для полноценной работы с Unity нужно уметь переключаться между различными сценами, для загрузки разных уровней, меню и другого контента. Для этого воспользуемся методом LoadLevel() класса Application.
В нашем примере есть 2е сцены. Первая («Level») — с кубом и плоскостью («floor»), на которую куб падает.Вторая («gameover») — с зеленым фотон и GUI Text’ом — «YOU WIN!»
Добавим скрипт (LoadLevel) со следующим кодом:
Жмем play. В итоге в консоли появилась ошибка:
Дело в том, что когда мы работаем с классом Application, мы должны указывать в настройках сборки (Build Settings) все сцены, которые хотим загружать в итоговом приложении. Перейдем в настройки сборки File->Build Settings и перетащим сцены Level и gameover из Project View в верхнее поле Buil Settings
Немного подредактируем наш скрипт так, чтоб мы могли указывать имя уровня из окна редактора, таким образом мы делаем наш скрипт более «гибким».
В окне редактора, на против соответствующего поля компонента, напишем название сцены, которую хотим загрузить.
Как создать счетчик времени с помощью C# в Unity 3D
Я хотел бы создать счетчик времени для моей игры Unity 3D.
Я уже пробовал использовать Time.time, но я не могу сбросить таймер, не сбросив всю игру. timeSinceLevelLoad тоже не работает для меня, потому что требуется перезагрузка уровня.
Я пытался использовать Time.deltaTime внутри FixedUpdate, но чувствую, что время еще не пришло. Причина, по которой я не могу перезагрузить игру или уровень, заключается в том, что я сделал состояние своей машины только одной сценой:
Так что вся моя игра проходит в одной сцене. Эта функция используется для перезапуска игры с помощью GameStates.INGAME:
Мой вопрос заключается в следующем: как я могу создать прогрессивный счетчик времени, который я могу сбросить без необходимости перезагрузки игры, сцены или уровня?
3 ответа
У меня есть вопросы с Unity 3d: как вы получаете текущее положение мыши на объекте Canvas в Unity 3D? В настоящее время я пытаюсь создать трекер мыши на Unity 3D, поэтому, если вы переместите мышь на холст, под мышью появится небольшой текст, показывающий текущее положение мыши.
Вы можете использовать закрытую переменную для отслеживания времени.
Вы можете установить или сбросить этот поплавок, когда вам это нужно.
Тогда вы можете просто проверить, когда прошло время.
В вашем коде замените код, который запускает ваш счетчик:
И код, который остановит это:
Похожие вопросы:
Есть ли команда в игровом движке Unity 3D с C#, чтобы заставить код ждать, прежде чем что-то произойдет? Вот пример: void Start () < //(wait code here) Connect(); >
Я начинаю изучать разработку игр с использованием unity 3d для android. Я скачал пробную версию unity 3.3. Я прошел через несколько уроков. У меня есть один вопрос, на который нет ответа. В обычных.
В настоящее время я разрабатываю приложение с первоначальной целью получения в режиме реального времени модели окружения 3D с помощью устройства Kinect. Эта информация позже будет использована для.
У меня есть вопросы с Unity 3d: как вы получаете текущее положение мыши на объекте Canvas в Unity 3D? В настоящее время я пытаюсь создать трекер мыши на Unity 3D, поэтому, если вы переместите мышь.
Я застрял на проблеме сценариев c# в Unity, которую хотел бы решить. Это то, чего я хочу достичь: Введите имя на InputField Получение символов из поля ввода Для каждого символа: установите 3D.
Я экспериментирую с Google Cardboard в Unity 3D, чтобы создать базовую игру VR. У меня возникли проблемы с выяснением, какой сборный блок является стереоскопической картонной камерой. Я нашел.
Я уже целую вечность ищу, как сделать стратегическую камеру в реальном времени для Unity в 2D. Я имею в виду, что вы должны управлять камерой с помощью W, A, S, D, и где бы я ни смотрел, это только.
Я начал изучать разработку игр с использованием Unity, и есть одна вещь, которую я не смог полностью понять. Я наткнулся на сайт Sketch Fab и заметил этот классный рынок с моделями 3D, и мне было.
Как сделать счетчик в юнити
using UnityEngine ;
using System.Collections ;
public class TimerLesson : MonoBehaviour <
public int xs, ys, ;
public int xm, ym ;
//do not edit
public int timersecond ;
public float secondgametime = 0 ;
public float secondgametimereset = 0 ;
public float minedgametime = 0 ;
public float minegametimereset = 0 ;
//up game timer translate in second
secondgametime += Time. deltaTime ;
if ( secondgametime >= 2.5 ) <
timersecond += 1 ;
>
if ( secondgametime >= 2.5 ) <
secondgametime = secondgametimereset ;
>
//up second time translate into minutes
if ( timersecond >= 60 ) <
minedgametime += 1 ;
timersecond = 0 ;
>
if ( minedgametime >= 60 ) <
minedgametime = minegametimereset ;
>
>
стартовые числа для счётчика
public int timersecond;
public float secondgametime = 0;
public float secondgametimereset = 0;
public float minedgametime = 0;
public float minegametimereset = 0;
Рассчитываем счётчик для минут
Вывод Чисел на экран, причём числа не будут плясать по экрану,на разных по размеру экранам, а будут фиксироваться.
Дальше вешаем скрипт на камеру, в инспекторе скрипта пишем координаты GUI 700,10 и 670,10 или же свои
Вывод числа не как в Unity таймере 1.343453 а культурные целые числа
Так же хочу отметить что если написать вместо апдейт, фиксапдейт, то скрипт на ос андроид будет работать немного точнее
версия 2 с подробным описанием в более оптемизированном скрипте
По этой ссылке скачивайте Asset и импортируете его в Unity
https://yadi.sk/d/X56YqD3JeoToL
Дальше откройте проект, он называется LessonTimer
Заходим папку скрипт и отрываем файл под названием TimerEmult
И так что мы видим
Поскольку описание в скрипте есть я не буду сильно на этом останавливаться..
Дальше вешаем наш скрипт на камеру
Запускаем и видим что отсчёт идёт
Дальше нам к примеру надо сделать что бы секунды и минуты начинали отчёт с 20 секунд 30 минут
Идём в Inspector
Пишем на против поля Timersecond 10, а на против поля Minedgametime 30
запускаем и видим отсчёт в секундах начался с 10 секунд, а отчёт минут с 30 минут.
Собственно сам скрипт кому лень скачивать)))
Делаем простую игру с кнопками, ящиками и дверями на Unity
Unity бесподобна для быстрого прототипирования игр. Если у вас появилась идея какой-то новой игровой механики, с Unity её можно реализовать и протестировать в кратчайшие сроки. Под катом я расскажу как можно сделать несложную головоломку используя только стандартные компоненты и не залезая в графические редакторы. По ходу статьи я продемонстрирую пару трюков игрового дизайна, а в конце немного расскажу об эстетике, динамике и механике.
Для самых нетерпеливых по ссылкам ниже находится готовый прототип.
Онлайн версия
Скомпилированная версия для Windows [Зеркало]
Что мы собираемся делать? Двумерную головоломку с колобком в роли главного героя, который может двигать ящики, которые могут нажимать кнопки, которые могут открывать двери, за которыми скрывается выход из уровня, который построил я. Или вы, у нас же здесь туториал как-никак.
Подразумевается, что вы уже успели скачать Unity и поигрались немного в редакторе. Нет? Сейчас самое время, я подожду.
Грубый набросок
Я соврал, я не буду ждать. Создаём пустой проект без лишних пакетов и выбираем схему расположения окошек на свой вкус, я буду использовать Tall. Добавляем в иерархию сферу, перетаскиваем на неё главную камеру. Теперь камера будет следовать за нашей сферой, если она вдруг захочет погулять. Переименовываем сферу в «Player», перетаскиваем в Project, теперь у нас есть prefab, который мы можем использовать в любых новых сценах, если таковые будут. Не забывайте проверять координаты префабов при создании и использовании, если мы хотим делать игрушку в двух измерениях, то третья ось должна быть выставлена в ноль для всех взаимодействующих объектов.
Добавим на сцену кубик, назовём его «Wall» и перетащим в Assets. Одинокая кубическая стена рядом со сферическим колобком не очень-то впечатляет, да? Три поля Scale в инспекторе позволят нам вытягивать стенку, а комбинация клавиш Ctrl+D создаст её копию. В Unity есть много других полезных горячих клавиш, например зажатый Ctrl ограничивает перемещение объектов единичными интервалами, а клавиша V позволит тягать объект за вершины, и они будут липнуть к вершинам других объектов. Замечательно, не правда ли? И вы всё ещё пишете свой движок? Ну-ну.
Сообразите что-нибудь похожее на комнату, сохраните сцену, нажмите Play и полюбуйтесь своим творением пару минут. Хорошие гейм-дизайнеры называют это тестированием. Чего-то не хватает, да? Хмм. Возможно, если я полюбуюсь ещё немного, то…
Скрипты и физика
Нам нужно больше движения и цвета! Хотя, если ваше суровое детство было наполнено бетонными игрушками, то можно оставить всё как есть. Для всех остальных пришло время скриптов. Я буду приводить примеры на C#, но можно писать и на JS или Boo. На самом деле выбирать последние два смысла не имеет, они были добавлены в Юнити скорее как довесок, меньше поддерживаются, хуже расширяются и для них сложнее найти примеры. Особенно ужасен Boo, который по сути является unpythonic Python. Мерзость. Виват, питонисты!
Создаём C# Script, называем его «PlayerController», перетаскиваем на префаб Player и открываем с помощью Visual Studio любимого редактора. Сперва нужно потереть лишний мусор, оставим только нужное.
Функция Update вызывается в каждом кадре, что очень удобно для реализации движения, внутри неё мы и будем размещать код. Нажатия кнопок игроком можно получить с помощью класса Input. В комплекте с Unity идут замечательные настройки ввода, достаточно написать Input.GetAxis(«Horizontal») и мы уже знаем нажал ли игрок на клавиатуре стрелку вправо или влево. Если у игрока подключён геймпад, то он может управлять и с него, нам даже не надо писать лишний код.
Функция AddForce имеет несколько интересных вариантов приложения силы, но для начала нам хватит и значений по умолчанию.
Готово! Сохраняем, жмём Play, тестируем.
Эээм, знаете, мне это напомнило тот момент из фильма Inception, где мужик бешено вращал глазами и катился кубарем то по стене, то по потолку. Наверное так он себя чувствовал.
Нам нужно запретить вращение и передвижение по оси Z. Выделяем префаб, смотрим на компонент Rigidbody и видим раздел Constraints. Оставляем неотмеченными только первые две галочки X и Y, остальные четыре включаем. Чуть выше снимаем галочку Use Gravity и прописываем Drag равный четырём (в разделе об эстетике я расскажу зачем это было сделано). Тестируем ещё раз.
Оно шевелится и не вертится! Ура! Но делает это слишком медленно. Добавим одну переменную к нашему скрипту и задействуем её в формуле нашего движения. Весь код будет в итоге выглядеть так:
Заметили как в инспекторе появилось новое поле Acceleration у нашего скрипта? Эффектно, да? Вбиваем в поле тридцатку или что-нибудь на ваш вкус и проверяем в действии.
Материалы и коллайдеры
Пора уже сделать какую-нибудь кнопку, чтобы было на что нажимать. Дублируем префаб Wall и переименовываем его в «Button». В инспекторе у коллайдера ставим галочку Is Trigger. Это развоплотит нашу кнопку и заставит другие объекты проходить сквозь неё. Создаём скрипт «Button» и вешаем на кнопку.
У коллайдеров-триггеров есть события OnTriggerEnter и OnTriggerExit, которые вызываются всякий раз, когда что-то пересекает область триггера. На самом деле это не совсем так, ибо есть множество разных объектов и физический движок обрабатывает не все столкновения, подробнее читайте здесь.
Для начала просто проверим как работают триггеры. Напишем что-нибудь в консольку Unity. Функция Debug.Log очень полезная, кроме текста она также умеет печатать разные игровые объекты.
Класс Color может принимать кроме тройки RGB ещё и альфу, но у нас стоит обычный диффузный шейдер, поэтому она для нас не важна. Тестируем!
Если вы ещё не сделали это, то настала пора прибраться в нашем проекте, иначе мы заблудимся в мешанине префабов и скриптов. Например создадим папку «Levels» для хранения сцен, «Prefabs» для складирования заготовок, «Materials» для материалов и «Scripts» для скриптов, а потом рассортируем накопившееся богатство по папочкам.
Знаете, а ведь наша кнопка до сих пор не похожа на кнопку! Давайте её сплющим и заставим продавливаться под колобком. Выберите кнопку в иерархии, сделайте её толщиной в 0.3 единицы и положите на пол, т. е. выставьте координату Z в 0.35. Видите в инспекторе наверху три удобных кнопочки «Select», «Revert» и «Apply»? С помощью них можно взаимодействовать с префабом прямо на месте. Нажмите Apply и все кнопки отныне будут плоские и лежачие.
Для реализации программной анимации мы будет использовать класс Transform. У него есть свойство localPosition, которое позволит нам двигать кнопку:
Этот код нажмёт кнопку. В целом это выглядит так:
Двери, ящики и магниты
Теперь, когда у нас есть полнофункциональная кнопка, можно заставить её что-нибудь делать. Склонируем префаб стенки, назовём его «Door», создадим красненький материал «Door Mat», повесим его куда нужно и закинем свежеиспечённую дверь на сцену. Для того, чтобы как-то воздействовать на дверь, нам нужно иметь ссылку на её объект, поэтому создадим у кнопки новую переменную.
GameObject это класс, в который заворачиваются все-все-все объекты на сцене, а значит у них у всех есть функция SetActive, которая представлена в инспекторе галочкой в левом верхнем углу. Если вы ещё пользуетесь Unity третьей версии, то вам придётся воспользоваться альтернативами. С помощью свойства активности можно прятать объекты не удаляя их. Они как бы пропадают со сцены и их коллайдеры перестают участвовать в расчётах. Прям то, что надо для двери. Приводим код к следующему виду:
Выбираем кнопку на сцене, перетаскиваем дверь из иерархии на появившееся поле в свойствах скрипта кнопки. Проверяем код в действии.
Наезд колобком на кнопку автомагически растворяет дверь и возвращает её на место после разъезда. Но какой толк нам от кнопки, которая постоянно выключается и запирает нам дверь? Настал час ящиков! Копируем префаб стенки, называем его «Box», добавляем к нему Rigidbody, не забываем проделать те же самые операции, что и с Player’ом, а затем кидаем его на сцену.
Как вы наверное заметили, толкать ящик не очень-то удобно. Кроме того, если он застрянет в углу комнаты, то достать его будет невозможно. Как вариант, мы можем сделать зоны-телепорты по углам комнаты, которые будут перемещать все попавшие в них ящики, но это немного мудрёно. Добавим в PlayerController магнит, который будет притягивать все близлежащие ящики. Функция Input.GetButton в отличие от Input.GetButtonDown будет возвращать true до тех пор, пока нажата запрашиваемая кнопка. То, что нам нужно.
Как мы будем находить ящики? Вариантов множество, например, мы можем прицепить к Player’у ещё один коллайдер и регистрировать OnTriggerEnter или OnTriggerStay, но тогда нужно будет решать проблему раннего реагирования триггера кнопки. Помните ту ссылку на матрицу с разными коллайдерами? Вот-вот. К тому же магнит должен работать только по нажатию кнопки, в остальное время он не нужен. Поэтому мы будем вручную проверять столкновения с помощью Physics.OverlapSphere. Transform.position даст нам координаты центра колобка. Поищем объекты поблизости:
Поищем объекты, практически касающиеся колобка.
Нашли объект в большой сфере, проверили его наличие в малой сфере, проверили метку, двинули к себе. Немного математики с векторами, ничего сложного для тех, кто не прогуливал школу.
Ящик всё равно нас немного толкает, не не будем сейчас на этом заморачиваться, в движении всё равно это не мешает.
Внимательные читатели давно уже заметили один баг кнопки. Внимательные и усердные его уже исправили. Какой же это баг?
Если в поле коллайдера попадает два объекта, а потом один объект уходит по своим делам, то срабатывает лишнее выключение кнопки. Что делать? Нам нужно считать количество колобков и ящиков в области коллайдера и выключать кнопку, когда рядом никого нет, а включать при любом количестве тех и других. К сожалению, в Unity нет списка текущих столкновений. Очень жаль. Возможно, у разработчиков ещё не дошли до этого руки. В любом случае это решается парой строчек кода. Мы можем сделать свой список и складывать в него все приходящие объекты, вынимать все уходящие, а состояние кнопки менять в Update.
Lertmind предложил вместо списка использовать счётчик. Этот способ однозначно изящнее, но старый код оставляю выше для примера, как не надо делать.
Сцены, частицы и шейдеры
У нас есть игровой персонаж, стены, кнопка и дверь, но за ней ничего не скрывается. Пора уже сделать перемещение между уровнями.
Дублируем префаб стенки, переименовываем в «Finish», меняем метку на одноимённую, превращаем коллайдер в триггер. Создадим материал «Finish Mat» с манящим голубеньким цветом и повесим на финиш.
Вся семья в сборе. Но как-то не очень маняще и слишком похоже на стенку. И на дверь. И на кубик. На помощь приходят шейдеры! Сейчас у нас для всех материалов используется обычный матовый диффузный шейдер. В свойствах материала выберем для финиша Transparent/Specular. Этот шейдер будет учитывать альфу цвета и отсвечивать вторым цветом, который мы укажем. Поставим у голубенького альфу в половину, а отблеск сделаем белым. Тестируем.
Осталось заставить финиш перемещать игрока на следующий уровень. Для управления сценами в Unity есть несколько полезных функций и переменных. Application.loadedLevel покажет нам текущий уровень, Application.levelCount покажет их количество, а Application.LoadLevel загрузит желаемый. Кроме того, нам нужно указать в Build Settings все сцены, в которые мы хотим попасть. Создадим новый скрипт «Finish», повесим на префаб и напишем внутри следующее:
Мы проверяем, что на финиш попал игрок, а потом перемещаемся на следующий или первый уровень. Дегустируем наш новый полнофункциональный финиш.
Эстетика, динамика и механика
Вот наш прототип и готов. Мы теперь можем нажимать на кнопки, открывать двери и переходить с уровня на уровень. Если мы хотим только протестировать новую механику, то этого достаточно. Но если мы хотим сделать прототип игры, то нужно думать ещё об эстетике и динамике. Возможно вы не часто слышали эти термины в применении к играм. Если вкратце, то механика — это какое-то взаимодействие пользователя с игровым миром. Кнопка, которую может нажать пользователь, чтобы открыть дверь, это одна механика. Ящики, которые тоже могут нажимать кнопки — другая. Механики взаимодействуют друг с другом и создают динамику игры. Игрок нашёл ящик, дотащил до кнопки, открыл дверь, перешёл на другой уровень. Эстетика — это ощущение от игры. Бывало ли у вас в какой-нибудь стрелялке чувство, что вы действительно нажимаете курок? Приятная отдача, анимация, звук — всё это влияет на эстетику стрельбы. На эстетику игры в целом влияет множество факторов, от скорости загрузки до сюжета. Кропотливая работа над эстетикой отличает игры-однодневки от игр, которые помнят.
Посмотрим на наше творение. Самая часто используемая механика — передвижение. Давайте внимательно посмотрим всё ли у неё в порядке. Открываем код.
Если приглядеться, то видно, что по диагоналям наш вектор длиннее, а значит больше и прилагаемая сила. Можно исправить это нормализовав вектор:
А можно это не исправлять. Особенности игрового движка тоже могут быть частью эстетики. Quake 3 без распрыжек был бы совсем другим. Именно знание тонкостей механики отличает новичков от летающих демонов-убийц профессиональных игроков. Но тонкости не должны вредить удобству, именно поэтому мы ранее поменяли Drag у Rigidbody игрока на четвёрку. Такое трение заставляет колобка останавливаться быстро, но не сразу. А большое ускорение даёт чувство контроля. В идеале, старт тоже должен происходить не сразу, это пригодилось бы для точных манёвров. Эти маленькие детали механики влияют на общую эстетику.
Вглядываемся сильнее и замечаем, что… Видите? Нет? Скомпилируйте проект и поставьте настройки на минимум. Здорово колобок летает, правда? Да так шустро, что пролетает коллайдеры насквозь. Это всё из-за функции Update в скрипте управления, которая выполняется в каждом кадре. Если игра ускоряется в два раза, то и все силы прикладываются в два раза чаще. Для решения этой проблемы можно просто поменять Update на FixedUpdate, который не зависит от частоты кадров, а обноляется по таймеру. Если бы для движения использовался не Rigidbody, а Transform, то проще было бы отвязать перемещение от FPS с помощью Time.deltaTime.
Камера даёт игроку возможность заглянуть в игровой мир, поэтому от её ракурса и поведения тоже немало зависит. Сейчас наша камера просто болтается воздушным шариком над главным героем, но если её немного наклонить, то нам будет легче воспринимать уровень, появится ощущение перспективы. Или мы можем наоборот поменять камеру на ортогональную, тогда всё будет абсолютно плоское.
Внешний вид игры тоже имеет большое значение. Под внешним видом я подразумеваю не количество полигонов в кадре. Помните, игры это искусство. Какие вещи важны в смежных видах искусства? Стилистика, цвет, свет, тень. Попробуйте найти интересное сочетание цветов здесь или соберите свой набор здесь. Посмотрите например на Proun. Эта игра выполнена в духе супрематизма, так близкого хабру. Можно попробовать скопировать некоторые цветовые решения, но без текстур и колдовства с шейдерами получится не так красиво. Нетерпеливые уже посмотрели результат моей попытки по ссылкам наверху, а внимательные читатели могут увидеть их ещё раз в конце статьи.
Суть этого раздела в следующем: даже если вы делаете только прототип игры, сразу стоит подумать о том, что вы хотите сказать будущему игроку, какие чувства в нём вызвать. Это справедливо для всех видов искусств. Сделать минимальный набросок стилистики совсем не сложно, и это окупится в первую очередь для вас, вам будет легче выбрать дальнейшее направление.
Заключение
С помощью примитивных кубиков и пары капель цвета, можно изготовить вполне сносный прототип, в который (по моему скромному мнению) будет приятно играть. Используя Unity это сделать совсем не сложно, но нельзя забывать зачем вам это всё нужно.