Деякі дизайнерські рішення, прийняті в Defold, відрізняються від іншого програмного забезпечення, і це може зайняти деякий час, щоб добре поговорити про те, як і чому речі складаються так, як вони є. Щоб правильно зрозуміти, як керує і надає доступ до ігрових ресурсів Defold, прочитайте цей документ, посібник із адресації та інструкцію з передачі повідомлень.
Деякі або багато речей тут можуть бути незнайомі та важко зрозуміти на перший погляд, але не хвилюйтеся. Займайтеся своїм часом, експериментуйте з редактором та двигуном та повертайтеся до документації, коли виникають проблеми.Ігрові об'єкти
Ігрові об'єкти є простими об'єктами, кожна з яких має окрему тривалість життя під час виконання вашої гри. Ігрові об'єкти зазвичай обладнані візуальним чи звуковим представленням (наприклад, звуковим або спрайтовим компонентом). Вони також можуть бути обладнані поведінкою через компоненти скриптів. Ігрові об'єкти, таким чином, є окремою справою з спрацьовування,
моделей або звуків, оскільки вони є контейнерами для цих різних компонентів. Ви створюєте ігрові об'єкти та розміщуєте їх у колекціях у редакторі або динамічно створюєте їх під час виконання заводів.
Існує два різні способи створення графічних об'єктів у редакторі:
Створіть файл об'єкта гри, а потім створіть екземпляр цього файлу в колекції.
Створіть в місці екземпляр об'єкта гри в колекції.
Давайте розглянемо різницю між цими.
Прототипи та зразки
Коли ви створюєте файл game object , ви створюєте схему або прототип для об'єкта гри. Цей прототип може бути зразом для одного або декількох об'єктів гри.
Хороша річ із цією моделлю полягає в тому, що якщо ви зміните файл об'єкта гри, то ви змінюєте прототип, так що будь-який екземпляр, який використовує файл як його проект, негайно зміниться.
Дитячі об'єкти гри
Давайте розглянемо справу, яка може здатися властивою спочатку. Додати екземпляр "my_gameobject" цього прототипу до колекції, а потім створити інший об'єкт гри "серце" на місці (клацніть правою кнопкою миші та оберіть Add Game Object) з деяким компонентом. Нарешті, зробити "серцем" дитину "my_gameobject", перетягнувши його на нього.
Тепер у вас є колекція, яка виглядає так:
Ви можете припустити, що, перетягнувши об'єкт "серце" на "my_gameobject", ви зміните файл "my_gameobject.go", але це не так. Ефект операції полягає в тому, що екземпляр об'єкта ігрового об'єкта "my_gameobject" отримує дитину, яка додається до неї. Елемент ігрового об'єкта має два окремих властивості для його прототипу та його дітей.
Коли ви додаєте дітей до екземпляру об'єкту гри, ви додаєте об'єкт до власності дітей - ви не торкаєтеся прототипу.
Якщо ви відкриваєте колекцію в текстовому редакторі, клацнувши правою кнопкою миші та вибравши «Відкрити за допомогою ▸ редактора тексту», ви можете перевірити структуру даних об'єкта гри:
name: "default"
instances {
id: "my_gameobject"
prototype: "/a_simple_test/my_gameobject.go"
children: "heart"
...
}
scale_along_z: 0
embedded_instances {
id: "heart"
data: "embedded_components {\n id: \"sprite\"\n type: \"sprite\"\n data: \"tile_set: \\\"/cards_example/cards_sprites.atlas\\\"\\ndefault_animation: \\\"heart\\\"\\nmaterial: \\\"/builtins/materials/sprite.material\\\"\\nblend_mode: BLEND_MODE_ALPHA\\n\"\n position {\n x: 0.0\n y: 0.0\n z: 0.0\n }\n rotation {\n x: 0.0\n y: 0.0\n z: 0.0\n w: 1.0\n }\n}\n"
...
}
Ви можете чітко бачити, що екземпляр об'єкта ігрового процесу має прототип властивості, який встановлений у об'єктний файл гри. У неї є ще одне майно дітей, які вказують "серце" як єдину дитину. Ігровий об'єкт "серце" інший. Оскільки це об'єкт гри in_place, не заснований на прототипі,
він вказаний в embedded_instances, і всі його дані зберігаються безпосередньо у файлі збірки.
Окрім чіткого розмежування між прототипами і екземплярами ігрових об'єктів при роботі з ними в редакторі, слід також взяти час, щоб уважно вивчити, як ігрові об'єкти ідентифікуються з фіксованим ідентифікатором під час виконання, і як і чому ідентифікатор не впливає дитина Документ, що проходить повідомлення, детально пояснює це. Message passing documentation l.
На цьому етапі ви можете запитати себе: "Що робити, якщо я створюю об'єктний файл гри з ігровим об'єктом і дитиною, а потім видаляє дитину після того, як виставив об'єкт у колекцію?" Відповідь - це просто, що ви не можете. Ігровий об'єктний файл є орієнтиром для одного об'єкту гри. Доцільно лише додати дітей до екземплярів об'єктів гри
або під час створення в редакторі шляхом редагування колекції, або під час виконання через:
msg.post("my_object", "set_parent", { parent_id = go.get_id("my_parent") })
Компоненти
Компоненти використовуються для надання конкретних виразів та / або функцій для об'єктів гри. Вони не живуть власним життям, але повинні міститися всередині ігрових об'єктів. Існує два різні способи створення нових компонентів у редакторі:
Створіть файл компонентного типу, а потім створіть екземпляр цього компонента всередині об'єкта гри.
Створіть на місці екземпляр компонента в об'єкті гри.
У будь-якому з цих випадків ви створюєте компоненти певного типу. Відкриття цього компонента в редакторі викликає специфічний редактор компонентів типу, який дозволяє маніпулювати компонентом таким чином, який має сенс для типу.
У попередньому розділі ви побачили, як редактор зберігає вбудовані компоненти в об'єкті гри, хоча властивість embedded_components. Якщо ми замість цього виберемо примірник компонента з посиланням на файл, дані виглядають так:
embedded_instances {
id: "heart2"
data: "components {\n id: \"sprite\"\n component: \"/a_simple_test/my_heart.sprite\"\n position {\n x: 0.0\n y: 0.0\n z: 0.0\n }\n rotation {\n x: 0.0\n y: 0.0\n z: 0.0\n w: 1.0\n }\n}\n"
...
}
Специфічні компоненти даних зберігаються у файлі компонентів, на які посилається властивість компонента.
Найпоширеніший тип компонент, ймовірно, є компонентом сценарію, який ви використовуєте для створення поведінки. Неважко забувати, що між компонентом сценарію та об'єктом гри є чітка межа. Наприклад,
такий стиль передачі повідомлень є загальним:
msg.post("my_object", "my_message", { my_data = 1 }})
Тут ми надішлемо власне повідомлення на об'єкт гри "my_object". Це зазвичай працює, але не рекомендується. По-перше, оскільки надсилання повідомлень до об'єкта гри передає повідомлення всім, що містить компоненти, ви створюєте непотрібні накладні витрати. По-друге, ви навіть можете порушити поведінку об'єкта гри. Припустимо, наприклад,
що об'єкт гри містить кілька компонентів скриптів, які всі прослуховують повідомлення "my_message", і вони не призначені для запуску одночасно. Рекомендований спосіб адресації повідомлень, натомість, повинен бути максимально конкретним, і це вимагає збереження різниці між об'єктом і компонентом гри.
msg.post("my_object#script", "my_message", { my_data = 1 })
Власні властивості компонентів
Компоненти мають певні властивості типу, які в той чи інший спосіб змінювали компонент. Це може бути ширина і висота спрієстрованого компонента або прапор, що диктує, чи звуковий компонент повинен петляти свій звук чи ні під час відтворення. Сценарні компоненти, навпаки, дозволяють вказати спеціальні властивості для будь-яких цілей.
У сценарії ви визначаєте компонент сценарію, просто додаючи його визначення до файлу сценарію:
-- self.health will be automatically set to 100 by default. You can change
-- the init value for any instance containing the script component in the editor.
go.property("health", 100)
function on_message(self, message_id, message, sender)
-- Now we can access the property as "self.health"
...
end
Детальне пояснення того, як властивості скрипту працюють, і як вони можуть бути використані, знаходиться в документації властивостей сценарію. Ви визначаєте властивості сценарію - це тип властивості екземпляра, пов'язаний із компонентом сценарію. Defold зберігає їх у файлі як загальну властивість компонентів. Якщо об'єкт гри встановлений з прототипу,
властивість separate_properties до об'єкта об'єкта, що містить властивості сценарію (і в майбутньому, можливо, і інші властивості компоненту):
component_properties {
id: "script"
properties {
id: "my_property"
value: "4712.0"
type: PROPERTY_TYPE_NUMBER
}
}
І навпаки, у об'єкті вбудованої гри будь-які властивості компоненту явно виражаються як властивість властивості у файлі збірки:
data: "components {\n"
" id: \"some_script\"\n"
" component: \"/a_simple_test/my_thing.script\"\n"
" position {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" }\n"
" rotation {\n"
" x: 0.0\n"
" y: 0.0\n"
" z: 0.0\n"
" w: 1.0\n"
" }\n"
" properties {\n"
" id: \"my_property\"\n"
" value: \"4713.0\"\n"
" type: PROPERTY_TYPE_NUMBER\n"
" }\n"
"}\n"
Колекції
Колекції - це механізм Defold для створення шаблонів, або те, що в інших движках називається "prefabs". Колекції - це структури дерев, що містять ігрові об'єкти та інші колекції. Колекція завжди зберігається у файлі та вводиться в гру в один з двох способів:
Або на час створення, помістивши колекцію в іншу колекцію в редакторі.
Під час виконання динамічно завантажує всі ресурси, зібрані в колекції через колекційну проксі (докладніше див. Документацію про проксі колекції).
Колекції, розміщені в редакторі, не можуть бути змінені. Наприклад, ви не можете додавати дітей до ігрових об'єктів, які є частиною розміщеної колекції. Чому ви не можете це зробити, це стає зрозумілим, коли ви дивитеся на дані, які зберігаються для екземпляру збору.
Дані для містяться об'єктів ігор знаходяться у файлі зіставлення my_collection.collection, і це не те, що ви редагуєте.
Хоча ви не можете змінювати вміст екземпляра колекції, не редагуючи файл колекційного коду,
редактор дозволяє змінювати значення властивостей, такі як властивості скрипту, які пов'язані з компонентами колекції.
collection_instances {
id: "my_collection"
collection: "/a_simple_test/my_collection.collection"
position {
x: -172.74739
y: 149.61157
z: 0.0
}
rotation {
x: 0.0
y: 0.0
z: 0.0
w: 1.0
}
scale: 1.0
instance_properties {
id: "my_gameobject"
properties {
id: "script"
properties {
id: "my_property"
value: "4717.0"
type: PROPERTY_TYPE_NUMBER
}
}
}
}
Ієрархії від батьків і дітей
Під час редагування файлу збірки ви можете створювати ієрархії об'єктів гри, щоб один або декілька об'єктів гри були дітьми для об'єкта батьківського гри. Ієрархії батьків-дитина об'єкта є динамічним відношенням, що впливає на те, як об'єкти реагують на перетворення. Будь-яке перетворення (рух,
обертання або масштабування), що застосовується до об'єкта, у свою чергу буде застосовано до дітей об'єкту.
Можна також змінити батьків об'єкта під час виконання, відправивши set_parentmessages.
local parent = go.get_id("some_object")
msg.post(".", "set_parent", { parent_id = parent })
Загальне непорозуміння полягає в тому, що місце ігрового об'єкта в ієрархії збірників підключено до цієї ієрархії батьків-дитина під час виконання. Але це дві абсолютно різні речі. Ієрархія батьків-дитина динамічно змінює графік сцени, що дозволяє об'єкти бути візуально прив'язаними один до одного.
Місце, яке об'єкт гри в ієрархії збірки диктує його ідентифікатор. Цей ідентифікатор статичний протягом усього терміну дії об'єкта і ніколи не зміниться
.
Немає коментарів:
Дописати коментар
Kоментарі неуkраїнсьkою видалятимуться