Scripting
Scripting is an essential ingredient in all applications you make in Unity. Most applications need scripts A piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary to respond to input from the player and to arrange for events in the gameplay to happen when they should. Beyond that, scripts can be used to create graphical effects, control the physical behaviour of objects or even implement a custom AI system for characters in the game.
This section explains the main concepts that apply to scripting in Unity.
Plug-ins A set of code created outside of Unity that creates functionality in Unity. There are two kinds of plug-ins you can use in Unity: Managed plug-ins (managed .NET assemblies created with tools like Visual Studio) and Native plug-ins (platform-specific native code libraries). More info
See in Glossary
Related pages
See the Unity Learn website’s Scripting section for tutorials on how to use scripting in Unity.
The Knowledge Base Editor section has troubleshooting, guidance on interpreting C# Compiler Errors and tips and tricks.
Coding in C# in Unity for beginners
You want to start learning to code in Unity so you can get going on your first game, but you don’t know where to begin. We get the struggle. Here’s a breakdown of the scripting elements in Unity and some learning material that you can use to go through more advanced projects like «Space Shooter». This should get you covered in the following areas: the very basics of coding, like variables, functions and classes, and how to use them.
Scripting tells our GameObjects how to behave; it’s the scripts and components attached to the GameObjects, and how they interact with each other, that creates your gameplay. Now, scripting in Unity is different from pure programming. If you’ve done some pure programming, e.g. you created a running app, you should realize that in Unity you don’t need to create the code that runs the application, because Unity does it for you. Instead, you focus on the gameplay in your scripts.
Unity runs in a big loop. It reads all of the data that’s in a game scene. For example, it reads through the lights, the meshes, what the behaviors are, and it processes all of this information for you.
If you think about television, where, for example in North America, you have 29.5 frame/sec, Unity needs to do the same thing. It’s running single discrete frames, one after another. You direct Unity with the instructions that you write in your scripts, and Unity executes them frame after frame as fast as it can.
Achieving a high frame rate means not only your game will look more fluid, but your scripts will also be executed more often, making controls more responsive.
A script must be attached to a GameObject in the scene in order to be called by Unity. Scripts are written in a special language that Unity can understand. And, it’s through this language that we can talk to the engine and give it our instructions.
The language that’s used in Unity is called C# (pronounced C-sharp). All the languages that Unity operates with are object-oriented scripting languages. Like any language, scripting languages have syntax, or parts of speech, and the primary parts are called variables, functions, and classes.
If you’re using a version of Unity until 2017.3, you’ll notice that it has a text editor called MonoDevelop: it can help us complete our code, it’ll let us know if we’re writing a wrong piece of code, and allows us to take shortcuts. Starting with 2018.1, you can also use Visual Studio for Unity Community, or other text editors such as Visual Studio, Notepad, or Sublime text.
Here’s a script with some sample code in it (based on the Coding in Unity for the Absolute Beginner tutorial):
As you can see, there are variables, functions, and classes.
Variables hold values and references to objects (you can see objects as “bigger” variables). They’re like a box that holds something for us to use. Variables start with a lowercase letter.
Functions are collections of code that compare and manipulate these variables. Functions start with an uppercase letter. We organise code in functions so that they can be easily reused multiple times in different parts of the program.
Classes are a way to structure code to wrap collections of variables and functions together to create a template that defines the properties of an object.
Scripting is primarily comparing these objects and their current states and values. It’s based on logic determining an outcome or resolution.
In Unity, the scripts start by laying out the tools that you need at the top, and this is usually by declaring variables. You can see the declared variables here with the visibility keyword “public” or «private» at the front, followed by a type, and a name.
When we’re declaring your variables there are several visibility types, but the two most important ones are public and private.
If you create a script with the above text in your code editor and then come back to Unity and assign the script to a GameObject, you’ll see that you can access and see the light variable declared as public in the Inspector, but you can’t see the private one. And that’s because what’s defined as “private” can only be accessed within this particular script, within this particular class.
If you make this public, then it’s accessible to other scripts and other classes, and can be changed in the Inspector from the Unity editor. So, that means other people can access it and change its value.
There are many reasons to choose between private or public. Private variables allow your code to be cleaner, since you know that the value of those variables can be changed only inside that class. This makes debugging and maintaining the code easier.
If you choose “public” , and you experience an issue, you need to look inside your whole codebase in order to track the source because any other object has access to that variable. However, if you want objects to communicate between themselves you need some variables (or functions) to be public.
Another important aspect of variables is the type. A type defines what kind of value is the variable holding in memory, e.g. it can be a number, text, or more complex types, like the ones in the image below: Transform, Light and Demo Script in the image below are in fact references to Components. Unity needs to know what type of object it is so that it knows how to handle it.
Another important thing about variables is the name. The main thing that you need to remember about naming variables is that it can’t start with a number, and it can’t contain spaces. Therefore, there’s a style of writing the names. In C#, the naming convention is camelCase: you start with a lowercase letter and add words, without spaces, starting with a capital letter, e.g. «myLight».
When Unity compiles the script, it makes public variables visible in the editor. See the image below from the inspector.
Scripts manipulate the variables by using functions. There are a number of functions that run automatically inside Unity. See below:
Awake is called only once when the GameObject with that component is instantiated. If a GameObject is inactive, then it will not be called until it is made active. However, Awake is called even if the GameObject is active but the component is not enabled (with the little checkbox next to its name). You can use Awake to initialize all the variables that you need to assign a value to.
Start – like Awake, Start will be called if a GameObject is active, but only if the component is enabled. For more information on the differences with Awake, see this video.
Update is called once per frame. This is where you put code to define the logic that runs continuously, like animations, AI, and other parts of the game that have to be constantly updated.
FixedUpdate is when you want to do physics work.
As you can see, there’s Fixed Update and Update and in our Scripting tutorials section, you can learn how to effect changes every frame with the Update and FixedUpdate functions, and their differences.
LateUpdate is a function that’s similar to Update, but LateUpdate is called at the end of the frame. Unity will look at all of the game objects, find all of the Updates, and call the LateUpdates. This is good for things like the camera. Let’s say you want to move a character in your game. And then he’s bumped into by another character and ends up in a different position. If we move the camera at the same time as the character, there would be a jiggle, and the camera wouldn’t be where it needs to be. So, basically, it’s a second loop that comes in very handy.
When writing a function, remember that functions start with the returned type of the function at the beginning, followed by the name of the function, and then the parameters in the parentheses (if any). Function names start with a capital letter and the body of the function goes between the curly brackets. Here’s an example on how to write a function:
How do we call this function?
Functions can do calculations and then return a value. You can ask a function to do something, process the information, then return an answer. If you use the type «void», then they are not returning anything.
Classes are collections of these variables and functions. For example, this script is a class:
Bear in mind that the class name must match the file name of the C# script for it to work. And then to be attached to a GameObject, it has to derive from another class called MonoBehaviour which is automatically put there for you when you first create a script. Classes can also be public or private.
In Unity, if you create a custom class, like in the example below, you have to ask it to serialize it. This means that it will be converted into simple data that Unity can look at in the inspector. When you do that, it’ll see that you have the class will appear in the inspector.
Variables, functions, and classes are just the basics of starting with coding in Unity. Check out the Learn section, you can find a bunch of useful scripting tutorials that will help you go learn about programming from scratch, then progress to create detailed code for your projects.
Разработка с Unity: Часть 1 редактор Unity
Разработка приложения или игры требует от разработчика знания доступных инструментов и умения ими пользоваться. В данной статье описаны основы работы с редактором Unity. Статья ориентирована на начинающих разработчиков, но, возможно, опытные разработчики найдут для себя что-то новое.
Редактор Unity
Редактор Unity — программный инструмент, который используется для создания 2D и 3D игр, приложений.
Графическая и программная часть редактора периодически обновляются разработчиками, но общие черты графического интерфейса пользователя, функционал и подход к разработке сохраняются.
Окно «Scene»
В окне «Scene» отображается сцена — виртуальный мир, создаваемый пользователем. Пользователь может выбирать, перемещать и редактировать объекты на сцене. На сцену добавляются игровые объекты такие, как персонажи, свет, эффекты, камеры, декорации.
Для управления камерой редактора и смены вида существует несколько методов:
Управление стрелками
При помощи стрелок можно перемещать камеру в четырех направлениях.
Стрелка вверх перемещает камеру вперед, стрелка вниз — назад. Стрелки вправо и влево перемещают камеру вправо и влево соответственно.
Управление мышью и клавиатурой
Наиболее часто применяется.
Окно «Project»
В окне «Project» отображаются все файлы и папки, которые используются в проекте. Через окно «Project» пользователь может создавать, редактировать, открывать, переименовывать, копировать и удалять файлы.
Откроется окно проводника, где выбираются файлы для добавления в проект.
Файлы в проект возможно добавить перетаскиванием из проводника в окно «Project».
Окно «Hierarchy»
В окне «Hierarchy» отображаются все объекты, расположенные на сцене. Через окно «Hierarchy» пользователь может выбирать, удалять, копировать, переименовывать, сортировать и объединять в группы объекты на сцене.
Добавление объектов на сцену
Группировка объектов и Parenting
Игровые объекты можно группировать. Объект может содержать другие объекты, которые наследуют его свойства такие, как положение в пространстве, вращение и масштаб. При перемещении, вращении или масштабировании объекта, стоящего выше по иерархии, все дочерние объекты буду изменены.
Для связывания объектов необходимо в окне «Hierarchy» перенести один объект на другой, при этом переносимый объект становится дочерним. Для примера создана сфера, которая помещена в дочерние объекты куба. При перемещении куба сфера перемещалась вместе с ним.
Окно «Inspector»
В окне «Inspector» отображаются все свойства выбранного объекта. Пользователь может просматривать и редактировать параметры объектов на сцене, компонентов, материалов и файлов в проекте.
На рисунке 7 окно пустое. Для отображения свойств необходимо выбрать объект. Был выбран ранее добавленный в проект текстовый документ «TestFile.txt». В окне «Inspector» отобразилась информация о файле и его содержимое.
Редактирование окон
Редактор Unity позволяет имеет возможность гибкой настройки интерфейса. Пользователь может изменять размеры, ориентацию и положение окон, прикреплять их к панелям, создавать вкладки.
Сохранение и загрузка настроек окон
Пользователь может сохранить и загрузить расположение и параметры окон при помощи выпадающего списка «Select editor layout», находящегося в правом верхнем углу редактора.
Открытие окон
В верхней панели во вкладке «Window» пользователь может выбрать окно, которое необходимо открыть. Для примера было добавлено окно «Inspector»
Разворачивание окон
Пользователь может развернуть окно на всю область редактора, для этого необходимо открыть панель параметров окна и выбрать пункт «Maximize». Аналогичным образом окно возвращается к прежнему размеру.
Name already in use
Unity3d-Handbook / general.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
Базовый класс для всех объектов в Unity.
Базовый класс для всего что содержит в себе любой игровой объект(GameObject)
Порядок наследования: Component -> Object
Базовый класс для всех объектов на сценах Unity.
Порядок наследования: GameObject -> Object
Базовый класс, от которого наследуются все скрипты.
Порядок наследования: MonoBehavior -> Behavior -> Component -> Object
Класс MonoBehavior имеет ряд функций «сообщений», которые вызываются при определенных условиях. Пример функций: Start(), Update()
Флажок выключающий MonoBehavior в любом скрипте предотвращает выполнение функций:
Start(), Awake(), Update(), FixedUpdate(), OnGUI()
Наследование в C#
Синтаксис наследование: public class ChildClass : ParentClass
Полиморфизм в С#
- Во время выполнения объекты производного класса могут обрабатываться как объекты базового класса
- Базовые классы могут определять и реализовывать виртуальные методы, а производные классы — переопределять их:
Внутри производного класса можно получить доступ к методам базового через base Пример:
Интерфейсы могут включить в класс поведение из нескольких источников.
Интерфейс содержит только сигнатуры методов, свойств, событий или индексаторов.
Отладка в Unity
Самый простой способ отладки, использовать класс Debug, который выводит сообщения в консоли редактора:
Переопределение метода ToString()
Визуальная отладка осуществляется с помощью класса Gizmo и метода MonoBehavior.OnDrawGizmos()
Регистрация ошибок в текстовый файл
Профайлер Unity помогает вам оптимизировать вашу игру. Он сообщает вам о том, как много времени тратится в различных областях вашей игры.
Функция получающая компонент объекта по его типу.
Функция получает несколько компонентов по типу
Функции Find и FindWithTag
Поиск объектов в сцене. Первый ищет по имени объекта, второй по тегу. Второй способ быстрее!
Функция сравнения тегов CompareTag
Функция сравнения двух объектов GetInstanceID
Расстояние между двумя объектами
Поиск объектов определенного типа
Не использовать в Update()
Проверка препятствий между объектами
Присоединение одного объекта к другому с помощью Transform
Работа с кадрами в Unity
Для работы с кадрами имеются три основных вида событий в любом классе MonoBehavior.
- Update()
- FixecUpdate()
- LateUpdate()
Вызывается один раз для каждого кадра в каждом активном компоненте каждого активного объекта. Update соответствует понятию кадра в Unity. Используется для событий ввода: клавиатура, мышь. Очередность обработки Update не определена. Нельзя утверждать, что Update Х будет вызван раньше чем Update Y и наоборот.
Не привязано к кадрам. Может вызываться несколько раз в кадре. Вызывается регулярно и нормированно, через фиксированные интервалы времени. Используется для эмуляции физических характеристик объектов(св-ва компонента RigidBody)
Вызывается в каждом кадре как и Update, но только после событий Update и FixedUpdate. Используется для изменения положения камеры, т.к. положение объекта уже было изменено в Update
Вызывается один раз в первом кадре, где игровой объект становится активным.
Вызывается один раз, всегда при создании объекта, всегда перед функцией Start
Два важных правила в работе с кадрами
- Важно рационально относиться к Update и любым другим регулярным вызываемым событиям, связанным с кадрами. Они должны содержать только самый необходимый код. Серьезно уменьшить нагрузку на функции Update поможет событийное программирование.
- Движение должно основываться на времени. То есть нужно писать код для реализации движений и изменений так, чтобы вне зависимости от частоты кадров они выглядели одинаково у всех игроков.Для этого используется переменная Time.deltaTime
transform.localPosition += transform.forward * Speed * Time.deltaTime;
По умолчанию объекты не могут существовать вне сцены, которой они принадлежат, они уничтожаются при смене активной сцены.
Чтобы перенести объект из сцены в сцену, необходимо его сохранять. Одним из способов сохранения является функция DontDestroyOnLoad: DontDestroyOnLoad(gameObject);
При этом также будут сохраняться все дочерние объекты и любые ресурсы которые использует сохраняемый объект. Также может возникнуть проблема дублирования объектов, т.к. данная функция переносит копию объекта.
Синглтоны и статические переменные
Синглтоны это классы у которых может существовать только один экземпляр. Такие классы используются в Unity для переноса данных из сцены в сцену. Пример реализации синглтона GameManager:
Событийное программирование в Unity
Используется для значительного увеличения производительности, заместо постоянного использования функции Update
Два варианта реализации логики врага
- Через функцию Update :
- Событийная реализация логики врага :
Система управления событиями EventManager
Для подобной системы нам нужен произвольный класс управления EventManager, который позволит объектам получать уведомления о конкретных событиях. Эта система основана на трех основных идеях:
- EventListener: «получатель событий» применимо к любому объекту, который должен получать уведомления о событии, даже если это событие связано с ним самим. Всякий раз, когда объект ожидает, что ему сообщат о событии, он становится получателем.
- EventPoster: объект, который обнаруживает, что произошло событие, после чего он должен уведомить всех получателей, или разместить объявление о событии. Требуется, чтобы объект инициировал события на глобальном уровне.
- EventManager: синглтон, который сохраняется при переходе между уровнями и доступен глобально. Связывает получателей с отправителями. Принимает уведомления о событиях, и сразу же передает их нужным получателям в форме события.
Должен быть зарегистрирован в EventManager в качестве получателя одного или более конкретных событий. Необходимо создать интерфейс, из которого мы будем обращаться ко всем объектам получателей.
Интерфейс в C# является подходящим кандидатом для создания объектов получателей.
С помощью интерфейса Listener, от которого будут произведены все объекты, каждый объект получает возможность стать получателем события.
Простой интерфейс Listener :
С помощью интерфейса IListener мы можем сделать получателем любой объект, используя только наследование класса, то есть любой объект может объявить себя получателем и получать события:
EventManager(класс диспетчер синглтон)
Обязанностью диспетчера является вызов событий у получателей, когда события действительно происходят. Этот класс, будучи неуничтожаемым синглтоном, будет подключаться к пустому игровому объекту в сцене и непосредственно доступен для всех других объектов через статическое свойство.
Для получения уведомлений о событии (любом событии) получатель должен зарегистрироваться в экземпляре синглтона EventManager. Обычно это делается при первой же возможности, например в функции Start. Не используйте для этого функцию Awake, потому что она зарезервирована для внутренней инициализации объектов, а не для операций, которые выходят за пределы текущего объекта, для смены состояний и настройки других объектов. Регистрация получателя событий:
После регистрации получателей одного или более событий объекты могут затем уведомить синглтон EventManager об обнаруженном событии:
Наконец, после отправки уведомления о событии, все подписавшиеся на него получатели будут автоматически уведомлены синглтоном EventManager. В частности, объект EventManager вызовет функцию OnEvent каждого получателя, давая возможность обработать событие и среагировать в случае необходимости:
Директивы #region и #endregion для свертывания кода
Они добавляют в исходный код организацию и структурность, не затрагивая его сущности и не влияя на его выполнение.
Альтернативный способ, основанный на делегировании
Можно прочитать в книге Алон Торн — Искусство создания сценариев в Unity стр. 155
События класса MonoBehavior
Класс содержит широкий спектр событий, которые вызываются автоматически при определенных условиях. Эти функции, или события, начинаются с префикса On и включают например такие события, как:
- OnGUI
- OnMouseEnter
- OnMouseDown
- OnParticleCollision
OnMouseEnter, OnMouseDown и OnMouseExit регистрируют события не только для мыши, но и для сеносорной панели. Вызов этих событий определяется коллайдером объекта, события вызываются при нахождении курсора мыши в пределах его объекта. Ни одно из событий мыши не срабатывает для объектов, не имеющих коллайдера.
OnApplicationQuit посылается всем объектам сцены перед завершением игры, но до уничтожения сцены и ее содержимого. Если игра тестируется в редакторе, событие вызывается при остановке воспроизведения.
- Важно!OnApplicationQuit не вызывается на устройствах, работающих под управлением iOS, т.к. приложения часто не закрываются, а приостанавливаются, позволяя позже возобновить работу с того же места.
OnApplicationFocus передается всем объектам в сцене, когда окно игры теряет фокус, например когда оно деактивируется при переключении на другую программу. Это событие может быть значительным событием для игр, особенно для многопользовательских, где действия и события в общем мире продолжаются, даже если один или несколько игроков не принимают в игре участия.
OnApplicationPause является неоднозначным событием, потому что понятие паузеы в Unity четко не определено. При вызове данного метода все действия и события в игре полностью приостанавливаются. В этом состоянии нет течения времени, и ничто не может двигаться. Это событие будет вызываться, только если сброшен флаг Run In Background во вкладке Player Settings в группе Resolution.
- В iOS событие OnApplicationPause будет вызываться всякий раз, когда приложение сворачивается или переносится на задний план.
Более верно не полагаться на событие OnApplicationPause при реализации собственной паузы. Лучше использовать переменную Time.timeScale или создать более полноценную систему, которая сможет сама выбирать, какие элементы приостанавливать.
Определение видимости объекта
Самым простым способом определения видимости или невидимости объекта являются два события:
- OnBecameVisible
- OnBecameInvisible Оба автоматически вызываются для любого объекта с компонентом отображения, таким как MeshRenderer или SkinnedMeshRenderer.
Пример:
- Видимость здесь означает, что объект попал в поле зрения камеры, но он может быть перекрыт другими объектами, находящимися ближе к камере.
- Событие относится ко всем камерам, а не к конкретной. Тобишь срабатывает на любой камере.
- Обе функции отслеживают также видимость камеры сцены.
Видимость для конкретной камеры
Для определения видимости для конкретной камеры используется событие OnWillRenderObject. Это событие вызывается регулярно, один раз в каждом кадре для каждой камеры, для которой виден объект. Проверка заслонения другими объектами не применяется. С помощью свойства Camera.current можно получить ссылку на камеру, для которой объект в настояее время виден.
Визуализации изображений в 2D играх
В двухмерных играх графика отображается напрямую. Поэтому желательно сохранить ее стандартные размеры, пиксель в пиксель. Такой вид визуализации называется безупречным, потому каждый пиксель в текстуре выводится на экран без изменений. Но реализация его требует особого подхода.
- Для отображения 1 игровой еденицы в 1 пиксель значение в поле Size во вкладке Camera должно быть равно половине вертикального разрешения дисплея.
То есть, если игра будет запущена в окне с разрешением 1024х768, поле Size должно содержать значение 364, потому что 768 / 2 = 364.
Если пользователь имеет возможность изменять размер окна игры или разрешение, необходимо обновить размер камеры программно:
- Обратите внимание на переменную PixelToWorldUnits, определяющую масштаб ортографического размера в соответствии с полем Pixel To Units импортированной текстуры спрайтов. Это гарантирует, что спрайты отобразятся с правильными размерами при выводе на экран. Это вызвано необходимостью масштабировать все спрайты в соответствии с этим значением для отображения пикселей текстуры в мировые еденицы измерения.
Вывод изображения с камеры и постобработка
Камеры и обхекты Unity предоставляют широкие возможности управдения отображением сцены. Все связанные с этим вопросы называются постобработкой. Они включают в себя эффекты размытия, регулировки цвета, эффект рыбьего глаза и т.д.