Скриптинг
Скриптинг необходимая составляющая всех игр. Даже самые простые игры нуждаются в скриптах для реакции на действия игрока и организации событий геймплея. Кроме того, скрипты могут быть использованы для создания графических эффектов, управления физическим поведением объектов или реализации пользовательской ИИ системы для персонажей игры. Эти небольшие части кода работают сообща, чтобы делать самые разные вещи: от перемещения персонажа по экрану до отслеживания вашего инвентаря. Разработчики игр пишут сценарии в Unity на C#, мощном объектно-ориентированном языке программирования, разработанном Microsoft около 2000 года. С тех пор он стал одним из самых популярных языков программирования. Команда Unity выбрала C # в качестве основного языка программирования, потому что он хорошо документирован, прост в изучении и достаточно гибок. В основе Unity лежит хорошо документированный API, с которым могут взаимодействовать скрипты.
Движок поддерживает несколько популярных языков программирования, так что вам не придется учить новый язык с нуля. Нужно только выбрать один из языков, которыми уже владеете, «прокачать» его и можно начинать экспериментировать. Одни из самых популярных это C#, C++ и JavaScript.
Создание и использование скриптов.
В отличие от большинства других ресурсов, сценарии обычно создаются непосредственно в Unity. Вы можете создать новый сценарий из меню "Создать" в левом верхнем углу панели проекта или выбрав Assets > Create > C# Script в главном меню.
Новый скрипт будет создан в папке, которую вы выбрали в панели Project. Имя нового скрипта будет выделено, предлагая вам ввести новое имя.
Структура файла скрипта.
Скрипт взаимодействует с внутренними механизмами Unity за счет создания класса, наследованного от встроенного класса, называемого MonoBehaviour. Вы можете думать о классе как о своего рода плане для создания нового типа компонента, который может быть прикреплен к игровому объекту. Каждый раз, когда вы присоединяете скриптовый компонент к игровому объекту, создается новый экземпляр объекта, определенный планом. Имя класса берется из имени, которое вы указали при создании файла. Имя класса и имя файла должны быть одинаковыми, для того, чтобы скриптовый компонент мог быть присоединен к игровому объекту.
Основные вещи, достойные внимания, это две функции, определенные внутри класса. Функция Update - это место для размещения кода, который будет обрабатывать обновление кадра для игрового объекта. Это может быть движение, срабатывание действий и ответная реакция на ввод пользователя, в основном всё, что должно быть обработано с течением времени во игровом процессе. Чтобы позволить функции Update выполнять свою работу, часто бывает полезно инициализировать переменные, считать свойства и осуществить связь с другими игровыми объектами до того, как будут совершены какие-либо действия. Функция Start будет вызвана Unity до начала игрового процесса (т.е. до первого вызова функции Update), и это идеальное место для выполнения инициализации.
Заметка для опытных программистов: вы можете быть удивлены, что инициализация объекта выполняется не в функции-конструкторе. Это потому, что создание объектов обрабатывается редактором и происходит не в начале игрового процесса, как вы могли бы ожидать. Если вы попытаетесь определить конструктор для скриптового компонента, он будет мешать нормальной работе Unity и может вызвать серьезные проблемы с проектом.

Редактор кода скрипта.
По умолчанию в Unity используется редактор кода Micosoft Visual Studio. Можно использовать и другие редакторы кода, но как показывает практика VStudio идеально подходит для написания скриптов в Unity, одни из преимуществ использования VStudio:
  • Среда содержит множество инструментов, которые очень хорошо работают на C#.
  • Наличие бесплатной версии — Community Edition.
  • Community содержит все что нужно для независимого разработчика.
  • Самое эффективное ПО для разработки на любой платформе, включая .Net и C#.
  • Возможность хранения данных в облаке.

Все языки, с которыми работает Unity, являются объектно-ориентированными языками сценариев. Как и любой язык, языки сценариев имеют синтаксис и основные компоненты, такие как переменные, функции и классы. Ниже приведен базовый сценарий в Unity с сообщением журнала.
Как вы можете заменить, существуют переменные(Variabless), функции(Function) и классы(Classes).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HelloWorld : MonoBehaviour
{
//Variables
//Functions
//Classes

// Start is called before the first frame update
void Start()
{
Debug.Log("Hello World");
}

// Update is called once per frame
void Update()
{

}
}

Сценарии.

1. Переменные.

Содержат значения и ссылки на объекты и начинаются со строчной буквы. Когда мы объявляем переменные, существует несколько типов видимости, но два наиболее важных из них являются общедоступными и частными. Если вы создадите сценарий с приведенным выше текстом в редакторе кода, а затем вернетесь в Unity и назначите сценарий GameObject, вы увидите, что можете получить доступ и увидеть переменную gameObject1, объявленную в инспекторе как общедоступную, но вы не можете увидеть закрытую. И это потому, что то, что определено как “частное”, может быть доступно только в этом конкретном сценарии, в этом конкретном классе.
public class HelloWorld : MonoBehaviour
{
public GameObject gameObject1;
private GameObject gameObject2;
}
2. Классы.

Классы - это способ структурирования кода для объединения переменных и функций вместе для создания шаблона, определяющего свойства объекта.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HelloWorld : MonoBehaviour
{
public GameObject gameObject1;
private GameObject gameObject2;

// Start is called before the first frame update
void Start()
{
Display();
}

// Update is called once per frame
void Update()
{

}

void Display()
{
Debug.Log("Hello World");
}
}
3. Функции.

Функции - это наборы кода, которые сравнивают эти переменные и управляют ими. Функции начинаются с заглавной буквы. Сценарии управляют переменными с помощью функций. Существует ряд функций, которые автоматически запускаются внутри Unity.
// Вызывается при загрузке скрипта
private void Awake() {}

// Вызывается каждый раз, когда объект активен
private void OnEnable() {}

// Вызывается в кадре, когда скрипт активен
private void Start() {}

// Вызывается один раз за кадр
private void Update() {}

// Вызывается каждый кадр после обновления
private void LateUpdate() {}

// Вызывается каждый фиксированный временной шаг
private void FixedUpdate() {}

// Вызывается, когда средство визуализации видимо любой камерой
private void OnBecameVisible() {}

// Вызывается, когда средство визуализации больше не отображается ни одной камерой
private void OnBecameInvisible() {}

// Позволяет рисовать вещицы в режиме просмотра сцены
private void OnDrawGizmos() {}

// Вызывается несколько раз за кадр в ответ на события графического интерфейса
private void OnGUI() {}

// Вызывается в конце кадра при обнаружении паузы
private void OnApplicationPause() {}

// Вызывается каждый раз, когда объект отключен
private void OnDisable() {}

// Вызывается только ранее активным GameObject, который был уничтожен
private void OnDestroy() {}
Awake вызывается только один раз, когда создается экземпляр игрового объекта с этим компонентом. Если игровой объект неактивен, он не будет вызываться до тех пор, пока не станет активным.

Start будет вызван, если игровой объект активен, но только если компонент включен.

Update вызывается один раз за кадр. Здесь вы помещаете код для определения логики, которая работает непрерывно, например анимации, искусственного интеллекта и других частей игры, которые необходимо постоянно обновлять.
4. GameObject Manipulation.

Вы можете вносить изменения в свойства компонентов с помощью Inspector. Например, изменения значений положения Transform Component приведут к изменению положения игрового объекта. Аналогично, вы можете изменить цвет материала визуализатора или массу твердого тела с соответствующим эффектом на внешний вид или поведение игрового объекта. Сценарии также предназначены для изменения свойств компонентов для управления игровыми объектами.
// Создайте игровой объект
Instantiate(GameObject prefab);
Instantiate(GameObject prefab, Transform parent);
Instantiate(GameObject prefab, Vector3 position, Quaternion rotation);

// На Практике
Instantiate(bullet);
Instantiate(bullet, bulletSpawn.transform);
Instantiate(bullet, Vector3.zero, Quaternion.identity);
Instantiate(bullet, new Vector3(0, 0, 10), bullet.transform.rotation);

// Уничтожить игровой объект
Destroy(gameObject);
// Finding GameObjects
GameObject myObj = GameObject.Find("NAME IN HIERARCHY");
GameObject myObj = GameObject.FindWithTag("TAG");

// Доступ к Компонентам
Example myComponent = GetComponent<Example>();
AudioSource audioSource = GetComponent<AudioSource>();
Rigidbody rgbd = GetComponent<Rigidbody>();
5. Input System.

Используйте этот класс для считывания осей, настроенных в обычном игровом вводе, и для доступа к данным мультитач/акселерометра на мобильных устройствах. Для считывания оси используйте ввод.Получите ось с одной из следующих осей по умолчанию: “Горизонтальная” и “Вертикальная” отображаются на джойстике, A, W, S, D и клавиши со стрелками. "Mouse X" и "Mouse Y" сопоставлены с дельтой мыши. "Fire1", "Fire2", "Fire3" сопоставляются клавишам Ctrl, Alt, Cmd и трем кнопкам мыши или джойстика.
if (Input.GetKeyDown(KeyCode.Space)) {
Debug.Log("Space key was Pressed");
}
if (Input.GetKeyUp(KeyCode.W)) {
Debug.Log("W key was Released");
}
if (Input.GetKey(KeyCode.UpArrow)) {
Debug.Log("Up Arrow key is being held down");
}

/* Кнопка input расположенная в разделе Edit >> Project Settings >> Input */
if (Input.GetButtonDown("ButtonName")) {
Debug.Log("Button was pressed");
}
if (Input.GetButtonUp("ButtonName")) {
Debug.Log("Button was released");
}
if (Input.GetButton("ButtonName")) {
Debug.Log("Button is being held down");
}
6. Вектор.

Векторы - это фундаментальная математическая концепция, которая позволяет описать направление и величину. В играх и приложениях векторы часто используются для описания некоторых фундаментальных свойств, таких как положение персонажа, скорость, с которой что-то движется, или расстояние между двумя объектами. Векторы могут быть выражены в нескольких измерениях, и Unity предоставляет классы Vector2, Vector3 и Vector4 для работы с 2D, 3D и 4D векторами.
X = Left/Right Y = Up/Down Z = Forward/Back
Vector3.right /* (1, 0, 0) */ Vector2.right /* (1, 0) */
Vector3.left /* (-1, 0, 0) */ Vector2.left /* (-1, 0) */
Vector3.up /* (0, 1, 0) */ Vector2.up /* (0, 1) */
Vector3.down /* (0, -1, 0) */ Vector2.down /* (0, -1) */
Vector3.forward /* (0, 0, 1) */
Vector3.back /* (0, 0, -1) */
Vector3.zero /* (0, 0, 0) */ Vector2.zero /* (0, 0) */
Vector3.one /* (1, 1, 1) */ Vector2.one /* (1, 1) */
float length = myVector.magnitude /* Length of this Vector */
myVector.normalized /* Сохраняет направление, но уменьшает длину до 1 */
7. Time

Класс времени Unity предоставляет ряд важных базовых свойств, которые позволяют вам работать со значениями, связанными со временем, в вашем проекте.
  • Time.time возвращает количество времени с момента начала воспроизведения вашего проекта.
  • Time.deltaTime возвращает время, прошедшее с момента завершения последнего кадра.
  • Time.timeScale представляет скорость, с которой проходит время.
// Время в секундах с момента начала игры
float timeSinceStartOfGame = Time.time;

// Масштаб, в котором проходит время
float currentTimeScale = Time.timeScale;

// Время паузы
Time.timeScale = 0;

// Время в секундах, необходимое для завершения последнего кадра
// Использовать с Update() и LateUpdate()
float timePassedSinceLastFrame = Time.deltaTime;

// Интервал в секундах, с которым выполняется обновление физики и фиксированной частоты кадров и используется с FixedUpdate()
float physicsInterval = Time.fixedDeltaTime;

8. Физические события (Physics Events).

Unity помогает вам моделировать физику в вашем проекте, чтобы убедиться, что объекты правильно ускоряются и реагируют на столкновения, гравитацию и различные другие силы.
/* Оба объекта должны иметь коллайдер, а один объект должен иметь твердое тело, чтобы эти события работали */
private void OnCollisionEnter(Collision hit) {
Debug.Log(gameObject.name + " hits " + hit.gameObject.name);
}
private void OnCollisionStay(Collision hit) {
Debug.Log(gameObject.name + " is hitting " + hit.gameObject.name);
}
private void OnCollisionExit(Collision hit) {
Debug.Log(gameObject.name + " stopped hitting " + hit.gameObject.name);
}

// Триггер должен быть проверен на одном из коллайдеров
private void OnTriggerEnter(Collider hit) {
Debug.Log(gameObject.name + " just hit " + hit.name);
}
private void OnTriggerStay(Collider hit) {
Debug.Log(gameObject.name + " is hitting " + hit.name);
}
private void OnTriggerExit(Collider hit) {
Debug.Log(gameObject.name + " stopped hitting " + hit.name);
}

// Для 2D-коллайдеров
private void OnCollisionEnter2D(Collision2D hit) { }
private void OnCollisionStay2D(Collision2D hit) { }
private void OnCollisionExit2D(Collision2D hit) { }
private void OnTriggerEnter2D(Collider2D hit) { }
private void OnTriggerStay2D(Collider2D hit) { }
private void OnTriggerExit2D(Collider2D hit) { }

// Ray casting to detect the collision
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100)){
Debug.DrawLine(ray.origin, hit.point);
Debug.Log("Hit: " + hit.collider.name);
}
9. Rendering materials.

Это определения того, как должна отображаться поверхность, включая ссылки на используемые текстуры, информацию о плитках, цветовые оттенки и многое другое. Доступные параметры для материала зависят от того, какой шейдер используется в материале.
[SerializeField] Material material;
[SerializeField] Texture2D texture;
[SerializeField] Color color = Color.red;

// Запуск вызывается перед первым обновлением кадра
void Start() {
MeshRenderer meshRenderer = GetComponent<MeshRenderer>();
// Изменение материала, текстуры, цвета и шейдера во время выполнения
meshRenderer.material = material;
meshRenderer.material.mainTexture = texture;
meshRenderer.material.color = color;
meshRenderer.material.SetColor("_Color", Color.blue);
meshRenderer.material.EnableKeyword("_EMISSION");
meshRenderer.material.SetColor("_EmissionColor", Color.yellow);
meshRenderer.material.shader = Shader.Find("Standard (Specular setup)");
}
10. Освещение.

Освещение в Unity работает, приближаясь к тому, как свет ведет себя в реальном мире. Unity использует подробные модели работы света для более реалистичного результата или упрощенные модели для более стилизованного результата.
[SerializeField] LightType lightType = LightType.Directional;
Light lightComp = null;

// Запуск вызывается перед первым обновлением кадра
void Start() {
GameObject lightGameObject = new GameObject("The Light");
lightComp = lightGameObject.AddComponent<Light>();
lightComp.color = Color.blue;
lightComp.type = lightType;
lightGameObject.transform.position = new Vector3(0, 5, 0);
}

void Update() {
if (Input.GetKey(KeyCode.UpArrow)) lightComp.GetComponent<Light>().enabled = true;
if (Input.GetKey(KeyCode.DownArrow)) lightComp.GetComponent<Light>().enabled = false;
}

11. Coroutine.

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

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

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

Однако важно помнить, что сопрограммы не являются потоками. Синхронные операции, выполняемые в сопрограмме, все еще выполняются в основном потоке. Если вы хотите сократить количество процессорного времени, затрачиваемого на основной поток, так же важно избегать блокирования операций в сопрограммах, как и в любом другом коде скрипта. Если вы хотите использовать многопоточный код в Unity, рассмотрите систему заданий C#.

Лучше всего использовать сопрограммы, если вам нужно выполнять длительные асинхронные операции, такие как ожидание передачи HTTP, загрузки ресурсов или завершения ввода-вывода файлов.
// Создайте сопрограмму
private IEnumerator CountSeconds(int count = 10)
{
for (int i = 0; i <= count; i++) {
Debug.Log(i + " second(s) have passed");
yield return new WaitForSeconds(1.0f);
}
}

// Вызовите сопрограмму
StartCoroutine(CountSeconds());
StartCoroutine(CountSeconds(10));

// Сохраните и вызовите сопрограмму из переменной
private IEnumerator countSecondsCoroutine;

countSecondsCoroutine = CountSeconds();
StartCoroutine(countSecondsCoroutine);

// Остановка сохраненной сопрограммы
StopCoroutine(countSecondsCoroutine);

// Типы возвращаемых сопрограмм
// Ожидает следующего вызова функции Update()
yield return null;
// Ожидает следующего вызова FixedUpdate()
yield return new WaitForFixedUpdate();
// Ждет, пока не будет выполнено все, что этот кадр
yield return new WaitForEndOfFrame();
// Ожидает игровое временя в секундах
yield return new WaitForSeconds(float seconds);
// Ожидает, пока не будет выполнено пользовательское условие
yield return new WaitUntil(() => MY_CONDITION);
// Ожидает веб-запроса
yield return new WWW("MY/WEB/REQUEST");
// Ожидает завершения другой сопрограммы
yield return StartCoroutine("MY_COROUTINE");
12. Анимация.

В Unity 3D есть несколько отличных инструментов для обработки анимации. Unity вызывает контроллеры аниматора для управления тем, какие анимации воспроизводить и когда их воспроизводить. Компонент анимации используется для воспроизведения анимации. Вы можете назначить анимационные клипы компоненту анимации и управлять воспроизведением из своего сценария.
[SerializeField] GameObject cube;

cube.GetComponent<Animator>().enabled = true;
cube.GetComponent<Animator>().SetTrigger("Enable");
cube.GetComponent<Animator>().ResetTrigger("Enable");
cube.GetComponent<Animator>().SetInteger("animId", 1);
© Курсовой проект Виноградова Александра
Группа ВС-1
Рыбинский авиационный колледж
Социальные сети
This site was made on Tilda — a website builder that helps to create a website without any code
Create a website