Создание игры Hidden object с помощью Unity
Это руководство поможет вам создать собственную игру в жанре hidden object с помощью Unity. Уровень подходит для начинающих пользователей Unity.
Игры в жанре поиск предметов пользуются большой популярностью, могут быть основаны на интересной истории или обычной последовательности локаций для поиска.
На изображении ниже показан пример hidden object, с простой графикой. Цель игры — найти все объекты, перечисленные в текстовом поле внизу, и щелкнуть по ним, чтобы их убрать.

Для работы вам понадобится:
- Unity: для создания игры.
- знание C#.
- Материалы для создания локации (скачать здесь).
- Графические элементы (скачать).
- Звуковые эффекты (скачать).
Если у вас нет Unity. то вы можете загрузить бесплатную персональную версию по ссылке. Также вам потребуется текстовый редактор для работы с исходным кодом. Мы предлагаем использовать Brackets.
Первые шаги
Прежде всего, вам необходимо нарисовать на бумаге предварительную концепцию игры. Таким образом, вы будете иметь визуальное представление о локации и необходимых объектах.
Если вы не обладаете художественными навыками, то проще всего использовать возможности Sweet Home 3D для создания графического контента будущей игры.
Создаем пустую комнату и экспортируем ее в качестве PNG файла:

Также вам необходимо экспортировать несколько предметов интерьера, чтобы комната не выглядела пустой, например:

Теперь вам понадобится редактор изображений, чтобы сделать белые пространства прозрачными; в противном случае у вас будут белые области вокруг ваших объектов в Unity.
Работа с кодом
Запустите Unity и создайте новый проект на вашем диске

Выберите 2D-шаблон:

На вкладке Project ⇒ Assets ⇒ Scenes переименуйте SampleScene в Room1:

На вкладке Project ⇒ Assets создайте 3 новые папки: Backgrounds, Furnitures, Scripts, как показано на изображении ниже.

Добавьте изображение комнаты на вкладку Project ⇒ Assets ⇒ Backgrounds (путем перетаскивания).

То же самое проделайте с мебелью:

Добавьте фон в меню Hierarchy

Нажмите на фоновый объект и в меню Inspector измените значение rder in Layer на -10.
Вам нужно перейти к отрицательным числам, поскольку для текстовых объектов не существует настройки порядка.
Чтобы иметь возможность работать с объектами, которые скрыты, нужно прописать отрицательное значение.

Добавьте предметы мебели и разместите их в нужное место (на свое усмотрение).

Измените параметр Order в настройках слоя для каждого объекта, чтобы установить иерархию в изображении:

Теперь в разделе «Hierarchy» выберите все объекты, которые будут активными.

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

В Box Collider выберите Is Trigger, как показано на изображении ниже.

В данный момент область коллайдера объектов слишком велика и требует правок для каждого из них. Выберите объект (Hierarchy) ⇒ Edit Collider (Inspector) ⇒ измените размер зеленой рамки вокруг объекта.

Теперь вам нужны связанные текстовые объекты. Hierarchy ⇒ Create ⇒ Create Empty:

В конец списка добавляется новый GameObject. Переименуйте его в Blocks_txt.
Inspector⇒ Add Component ⇒ Mesh ⇒ Text Mesh:

Вам также нужно настроить параметры текста. Введите текст для отображения, измените при необходимости шрифт и размер символов.
Установите для Anchor значение Middle Center, как показано на изображении ниже.

Inspector> Transform: поместите текстовый объект в правильное место


Повторите эти действия для каждого объекта,
Теперь перейдем к небольшой части сценария.
В Project ⇒ Scripts создайте сценарий C# (Context menu ⇒ Create ⇒ C# Script) и назовите его ClickControl.

Дважды щелкните его, чтобы войти в редактор и изменить public class на ClickControl.

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

public static string obj_name;
public GameObject obj_txt;
void OnMouseDown()
{
//Link the object and the text
obj_name = gameObject.name;
//Debug.Log (obj_name);
//Destroy the object and the text
Destroy (gameObject);
Destroy (obj_txt);
} Hierarchy ⇒ select all objects. Project ⇒ C# file ⇒ перетащить ⇒ Inspector. Это добавляет сценарий к объектам.

Hierarchy ⇒ выберите объект Blocks.
Hierarchy ⇒ Blocks text ⇒ перетащите Obj_txt в ClickControl (Inspector). Теперь текст связан с объектом.

Свяжите все объекты с текстом и протестируйте результат.
Расширение геймплея
Чтобы игрок не халтурил и не кликал по всей локации, пытаясь «на ощупь» найти загаданные предметы, целесообразно ввести за это штраф.
Вам потребуется новый скрипт C #.
Назовите его ClickTrack.

Добавьте этот скрипт в GameObject и выберете спальню, как показано на изображении ниже:

Добавьте новый GameObject для текстового поля и дочерний GameObject для самого текста:

Добавьте папку Sounds в Assets и добавьте звуковой файл в эту папку.

Замените код ClickTrack следующим содержимым:
public static int TotalClick = 0;
public KeyCode MouseClick;
public AudioClip bcgMusic;
public GameObject myGameObject;
void Start()
{
myGameObject.SetActive(false);
}
void Update()
{
if (Input.GetKeyDown (MouseClick))
{
TotalClick += 1;
}
if (TotalClick >= 5)
{
TotalClick = 0;
AudioSource.PlayClipAtPoint(bcgMusic, transform.position);
StartCoroutine(Wait5Sec());
}
}
IEnumerator Wait5Sec()
{
myGameObject.SetActive(true);
yield return new WaitForSeconds(5.0f);
myGameObject.SetActive(false);
} В коде, созданном в предыдущей главе (ClickControl), нам нужно повторно инициализировать счетчик при щелчке по объекту. После MouseDown добавьте следующую строку:
ClickTrack.TotalClick = 0;
Теперь вам нужно назначить значения для переменных, определенных в скрипте. В GameObject в разделе Click Track (Script) выполните следующие действия:
установите значение Mouse Click на Mouse 0
перетащите звуковой файл в Bcg Music
перетащите Wait_Box в My Game Object

Анимация объектов
Если объект найден правильно, вы можете воспроизвести небольшую анимацию поверх исяезающего текста.
В иерархии создайте Particle System, как показано на рисунке:

В меню Inspector настройте частицы по своему усмотрению, например, так
В Project> Assets создайте новую папку с именем Prefab. Перетащите вашу систему частиц в Prefab и удалите gameObject из Hierarchy:

Частицы должны срабатывать при нажатии на gameObject. Для этоо вам нужно изменить скрипт ClickControl.
Откройте скрипт и добавьте следующее:
public Transform MyPartSys;
И добавьте в OnMouseDown следующее:
Instantiate(MyPartSys, obj_txt.transform.position, MyPartSys.rotation);
Вернувшись в Unity, выберите все удаляемые gameObject и добавьте префаб частиц в My Part Sys под частью скрипта в меню Inspector, как показано на изображении ниже:

Создание кнопки помощи
Если игрок застрянет, неплохо будет ему как-нибудь помочь.
Для этого вам нужно создать кнопку «Помощь».
Для начала добавьте в Иерархию изображение шара, Hint_btn, и мерцание hintSparkles:

Теперь создайте новый скрипт C # HintButton:

В скрипте HintButton добавьте следующие переменные:
public float myAlpha = 0; public float colortimer = 0; public static string hintready = "n"; public static string hintused = "n"; public GameObject MyPartSys;
В Start добавьте следующий скрипт:
GetComponent<SpriteRenderer>().color = new Color(0, 0, 0, myAlpha); MyPartSys.gameObject.SetActive(false);
Также необходимо добавить еще один скрипт в раздел Update:
colortimer += Time.deltaTime;
if (( colortimer >= .5) && (myAlpha < 1))
{
myAlpha += 0.05f;
colortimer = 0;
}
GetComponent<SpriteRenderer>().color = new Color(1,1,1, myAlpha);
if (myAlpha >= 1)
{
hintready = "y";
MyPartSys.gameObject.SetActive(true);
} Вам также необходимо повторно инициализировать все значения после события в виде нажатия мыши. Для этого следующим шагом добавьте этот код:
private void OnMouseDown()
{
if (hintready == "y")
{
hintused = "y";
myAlpha = 0;
GetComponent<SpriteRenderer>().color = new Color(0, 0, 0, myAlpha);
MyPartSys.gameObject.SetActive(false);
}
} Добавляем скрипт в Hint_btn.
Добавьте hintSparkles к кнопке Hint Button (Script) ⇒ My Part Sys, как показано ниже:

Теперь вам нужно сделать код для выделения объектов после того, как игрок нажмет кнопку подсказки. Этот код необходимо добавить в сценарий ClickControl, который мы использовали в предыдущей главе.
Добавьте эту переменную в скрипт ClickControl:
public int randNumb = 0;
Теперь добавьте код код в раздел Update:
if (HintButton.hintused == "y")
{
randNumb = Random.Range(1, 12);
if ((gameObject.name == "br1_alarm") && (randNumb == 1))
{
GetComponent<SpriteRenderer>().color = new Color(1, 0, 0);
HintButton.hintused = "n";
}
if ((gameObject.name == "br1_blocks") && (randNumb == 2))
{
GetComponent<SpriteRenderer>().color = new Color(1, 0, 0);
HintButton.hintused = "n";
}
if ((gameObject.name == "br1_flowers") && (randNumb == 3))
{
GetComponent<SpriteRenderer>().color = new Color(1, 0, 0);
HintButton.hintused = "n";
}
if ((gameObject.name == "br1_framered") && (randNumb == 4))
{
GetComponent<SpriteRenderer>().color = new Color(1, 0, 0);
HintButton.hintused = "n";
}
if ((gameObject.name == "br1_lamp") && (randNumb == 5))
{
GetComponent<SpriteRenderer>().color = new Color(1, 0, 0);
HintButton.hintused = "n";
}
if ((gameObject.name == "br1_laptop") && (randNumb == 6))
{
GetComponent<SpriteRenderer>().color = new Color(1, 0, 0);
HintButton.hintused = "n";
}
if ((gameObject.name == "br1_plane") && (randNumb == 7))
{
GetComponent<SpriteRenderer>().color = new Color(1, 0, 0);
HintButton.hintused = "n";
}
if ((gameObject.name == "br1_plant") && (randNumb == 8))
{
GetComponent<SpriteRenderer>().color = new Color(1, 0, 0);
HintButton.hintused = "n";
}
if ((gameObject.name == "br1_plant2") && (randNumb == 9))
{
GetComponent<SpriteRenderer>().color = new Color(1, 0, 0);
HintButton.hintused = "n";
}
if ((gameObject.name == "br1_tower") && (randNumb == 10))
{
GetComponent<SpriteRenderer>().color = new Color(1, 0, 0);
HintButton.hintused = "n";
}
if ((gameObject.name == "br1_train") && (randNumb == 11))
{
GetComponent<SpriteRenderer>().color = new Color(1, 0, 0);
HintButton.hintused = "n";
}
} Нажмите » Play», чтобы проверить как работает игра!
Несколько слов о дизайне уровней
Создавать уровни и предметы на локации можно не только с помощью сторонних программ, но и вручную.
1. Стадия проектирования:
Смысл состоит в том, чтобы построить сцену из 3D-моделей, а затем визуализировать линейную графику.

На самом деле на это нужно меньше времени, чем кажется на первый взгляд. Пример, как получить макеты:
Стол для рулетки: Мы ищем в Google «бесплатная 3D модель рулетки» и выбираем подходящий рисунок. Колесо расположено очень близко к камере, поэтому нужны хорошие детали.
Некоторые элементы можно бесплатно скачать тут. Находим подходящий стул и добавляем детали самостоятельно.
Стол для блэкджека слева позаимствован из другой игры и немного отредактирован.
Фон комнаты моделируется вручную. Вы можете видеть, что это тоже очень простые геометрические формы.

Затем нужно вручную расскрасить все элементы локации и добавить тени.
На этом этап проектирования завершен.

2. Этап арт-обработки
Теперь нужно визуализировать 3D-изображение и переделать его в 2D.

Работа с 3D состоит из двух основных этапов: наложение текстуры и освещение. На этапе наложения текстуры вы потратите большую часть времени на поиск подходящих текстур.
Наиболее важные работы, которые необходимо выполнить на этом этапе:
- Добавьте больше источников света, чтобы сделать освещение сцены более насыщенным;
- Примените используемый мазок кисти ко всем продметам, чтобы рисунок больше походил на картину.
3. Размещение объектов для поиска
Последний этап включает в себя размещение объектов для поиска.
Далее вы можете использовать приемы, описанные в предыдущих разделах этой статьи.







Я хочу сделать игру
Как успехи?