Programozás alapjai
Olyan része a kódnak, amit nem hajt végre a számítógép. Általuk extra információkat tudunk a kódhoz rendelni a kódot olvasó programozó számára.
Változókat arra használunk, hogy valamilyen adatot (objektumot) tároljunk bennük. Egy változó és a benne tárolt adat mindig egy konkrét információt reprezentál.
Minden változónak van egy neve, ami segít beazonosítani, mit reprezentál az adott változó. A változót mindig a programozó nevezi el és később ezen a néven keresztül tudunk hivatkozni a változóra.
A statikusan típusos nyelveknél (mint a C#) a változóknak van egy típusa is, ami meghatározza, hogy milyen értékeket tarthatunk benne.
Az erősen típusos nyelvekben, így a C#-ban is a típusok vagy más néven adattípusok határozzák meg, hogy egy adat mit reprezentál és milyen értékeket vehet fel.
Változóknak, függvények visszatérési értének és paramétereinek mindig meg kell határozni a típusát.
Egy eldöntendő, kérdésre adható választ tartalmazó adat. Két lehetséges értéke a true (igaz) és a false (hamis).
Egy számábrázolási mód a számítástechnikában, ahol tizedes tört számokat tudunk eltárolni fix bitszámon úgy, hogy a tizedes pont pozíciója nem kötött.
C#-ban a float
, double
és a decimal lebegőpontos típusok. A float
32 biten, míg a double
64 biten ábrázol számokat binárisan, a decimal
pedig 128 biten decimálisan.
A lebegőpontos számok nagy pontossággal tudnak számokat ábrázolni a 0 közelében és ahogy egyre nő a bennük tárolt érték úgy csökken a pontosság.
Egy művelet, amit a számítógép végre tud hajtani. Egy programot egy vagy több utasítás sorozata alkotja.
Top level statement-ek olyan utasítások, amik nem saját definiálású típusokon belül (osztályok, struktúrák, statikus osztályok…) helyezkednek el, hanem egy fájl gyökerében.
A .NET 6-tól felfelé a C# támogat Top level statement-eket. Az egész projektben csak egy file lehet, amiben utasítások vagy függvények állnak magukban.
Ez a program belépési pontja.
Ugyanez metódusokra is igaz. Azok is csak típusdefiníciókon belül létezhetnek, és szintén kivétel ez alól a Top level statement-eket tartalmazó fájl.
Bármi, aminek az eredménye egy meghatározott típusú adat. Például:
int típusú kifejezések: 2, 45, 12 + 33, 22 * (23 - 5), Mathf.Abs(-6) * 45
bool típusú kifejezések: true, false, 4 > 66, !(a % 10 < 2) $$ (a >= 0)
Kifejezés lehet például egy konstans érték, egy változó, egy műveletsorozat, vagy egy metódus végrehajtás és a fentiek minden kombinációja.
Egy vezérlési szerkezet felelős azért, hogy megmondja, hogy összetevőit milyen sorrendben hajtsa végre a számítógép és, hogy bizonyos összetevőket végrehajtson-e egyáltalán.
A vezérlési szerkezetek összetevői lehetnek utasítások és egyéb vezérlési szerkezetek is.
3 vezérlési szerkezet létezik:
Egy vezérlési szerkezet, amiben az összetevők (utasítások vagy egyéb vezérlési szerkezetek) egymás után sorrendben hajtódnak végre.
Egy vezérlési szerkezet, amiben egy vagy több feltétel határozza meg azt, hogy milyen összetevőket (utasításokat vagy egyéb vezérlési szerkezeteket) hajtson végre a számítógép.
Egy elágazás esetén a program végrehajtása több ágra szakad, amelyek közül csak egyet hajtunk végre.
Az elágazásoknak egy feltétel esetén lehet 1 vagy 2 ága, viszont több ágra is felbonthatunk egy elágazást újabb feltételekkel.
Egy vezérlési szerkezet, aminek összetevőit (utasításokat vagy egyéb vezérlési szerkezeteket) egymás után többször is le tudnak futni.
A ciklus akkor ér véget, amikor annak feltétele hamissá válik.
Egy nyitó és egy záró kapcsos zárójel közti részt C#-ben kódblokknak vagy egyszerűen blokknak nevezzük.
Egy önnállóan végrehajtható kódrészlet. Egy metódust egyszer kell megírni és utána a kód bármely pontjából meghívható amikor is a metódusban lévő kód végrehajtódik.
Egy metódusnak lehetnek bemenő paraméterei és visszatérése.
Olyan metódus ami rendelkezik visszatéréssel, azaz a típusa nem void.
Visszatérés nélküli azaz void típusú metódus.
Egy olyan típust, ami egyéb belső elemeket tartalmazhat.
Egy összetett típus magába foglalja, hogy milyen belső adatokból épül fel (változók formájában), valamint a rajta végezhető műveleteket (metódusok formájában).
Pl.: Egy (2D vektor-t) leíró Vector2D típus tartalmazza
- az x ás y float típusú változókat.
- a vektorösszeadás és -kivonás műveleteket leíró függvényeket (többek közt).
(A programozási koncepciót, ami szerint szorosan összefüggő adatokat és a rajtuk végezhető műveleteket egy helyen tartjuk enkapszulációnak vagy egységbe zárásnak nevezik és az Objektum Orientált programozás egyik alappillére.)
Egy összetett típus definiálásánál egy általános leírást, egy vázlatot adunk meg. Ezen definíció után, példányokat azaz konkrét objektumokat tudunk belőle létrehozni.
C#-ban 2 kategóriája létezik az összetett típusoknak:
- Referenciatípus: Class / Oszály (és Record / Rekord)
- Referenciatípus: Struct / Struktúra
Egy referencia-típusként működő összetett típus.
Egy érték-típusként működő összetett típus.
Egy referencia-típusként működő összetett típus. Fő különlegessége egy osztályhoz képest, hogy az egyenlőségvizsgálat érték (és nem referencia) alapon működik.
A C#-ban érték és referencia típusok léteznek. A referencia típusú értékek mindig az adott objektumra mutató referencián keresztül kerülnek átadásra.
int someInteger = 3; // Az int egy érték típus, ezért
int someOtherInteger = someInteger; // itt készül egy új másolat az objetumból,
someOtherInteger = 999; // Ha az egyik változó értékén módosítunk,
// annak semmi hatása nincs a másikra.
Console.WriteLine(someInteger); // Kiírja: 3
A C#-ban érték és referencia típusok léteznek. A referencia típusú értékek mindig az adott objektumra mutató referencián keresztül kerülnek átadásra.
int[] someArray = {1, 2, 3}; // Minden tömb referencia típus, ezért
int[] someOtherArray = someArray; // itt nem készül egy új másolat a tömbből,
// hanem mindkét változó ugyanarra
// az objektumra fog hivatkozni.
someOtherArray [1] = 999; // Ha az egyik változó értékén módosítunk,
// a másik-ban is megtörténik a változás.
Console.WriteLine(someArray[1]); // Kiírja: 999
A programozásban minden konkrét, létező adatatot egy objektum reprezentál.
Objektumot létrehozni bármilyen típusból lehet. Pl.:
Primitívek: Az 5 egy int, a “Hello!” pedig egy string típusú objektum.
Összetett adattípusok: A new Vektor2(1.3f, 0.5f) egy string Vector2 objektum.
Egy objektumra szoktak úgy is hivatkozni, mint egy típus egy példánya
Az informatikában redundanciának nevezzük agy adatt többszörös eltárolását.
Ha a kódunkban redundancia van azzal növeljük a valószínűségét, hogy inkonzisztens állapotba kerül a szoftverünk, azaz több adat, ami ugyanazt az információt takarja más értéket vesz fel.
Redundáns kód hibás és nehezen debug-olható viselkedéshez vezet.
Olyan változó, amit egy osztályon belül, de metóduson kívül hozunk létre. Egy field és annak értéke az osztály egy példányáról árul el valami információt.
Az egy objektum aktuális állaptát, a field-jeinek összessége reprezentálja.
(Nem csak osztályoknak lehet field-je, hanem más összetett típusoknak is: Struct, Record)
Olyan tagja egy összetett típusnak, ami egy adat lekérdezésére és/vagy beállítására használatos.
Egy property egy getter-ből (lekérdező metódusból) és egy setter-ből (beállító metódusból) áll vagy csak a kettő közül az egyikből.
A property tehát gyakorlatilag egy vagy kettő metódus ám használata a típuson kívülről egy field-hez hasonlít.
A tagok olyan “alkatrészei”, egy összetett típusnak (osztály/struktúra), amik a típus egy példányához tartoznak. Ezek lehetnek :
- Field-ek, amik egy objektum belső állapotát tárolják,
- Metódusok, amik műveleteket végrehajtanak az objektummal
- *Property**-k, amik biztonságos és jól szabályozható hozzáférést biztosítanak az objektum belső állapotához.
Egy adatszerkezet, ami egy fix hosszú felsorolását tartalmazza egy adott típusú adatnak.
Bármilyen típusból lehet tömböt létrehozni.
Csak a tömb maga nevesített, annak egyes elemei az indexük (sorszámuk) szerint érhetők el.
A tömbhöz hasonlóan olyan adatszerkezet, ami egy felsorolását tartalmazza egy adott típusú adatnak.
Fő különbsége a tömbhöz képest, hogy rugalmasabb felépítésű: Könnyen bővíthető és csökkenthető a mérete.
Az attribútumok lehetőséget biztosítanak arra, hogy olyan programozási elemeket, mint típusok, mezők és metódusok, stb. kiegészítő információkkal ruházzunk fel.
Főleg arra a célra lettek az attribútumok megalkotva, hogy kiegészítsék a C# nyel funkcionalitását olyan keretrendszerek számára, mint a Unity, ami hozzá tud férni ezekhez a kiegészítő információkhoz és működését ehhez mérten tudja módosítani.
Egy attribútumnak mindig adott, hogy miféle programozási elemek-hez rendelhető.
Névterekkel tudjuk a teljes kódbázisunkat logikailag elkülönülő modulokra bontani.
Minden osztály vagy bármi egyéb típus definíció egy névtér része.
Azt hogy az adott kód mely névtér része lesz, a namespace
kulcsszó jelzi. Ha a névteret nem definiáljuk, az adott programozási elem a globális névtér része lesz.
Ha egy másik névtér elemeit használni szeretnénk (saját és a globális névtéren kívül), akkor a usig
kulcsszóval ezt jeleznünk kell a C# fájl elején.
A szerializáció az a folyamat, amikor egy programozási objektumból nyelv- és platformfüggetlen adatot készítünk.
Ezt a szerializált adatott aztán többek között elmenthetjük fájlba vagy továbbíthatjuk hálózaton keresztül.
A szerializált adatokat később deszerializálás során lehet visszaállítani az eredeti formájukra, azaz programozási nyelvek objektumaivá.
Egy művelet lépésről lépésre pontosan meghatározott leírása.
A programozás során algoritmusokat ültetünk a gyakorlatba és valósítjuk meg őket egy adott programozási nyelv által.
Szkriptnek azokat az apró programrészeket nevezzük, amik egy nagyobb programrendszerbe épülnek be.
A Unity szkriptnyelve a C#, amivel úgy nevezett MonoBehavour
szkripteket építhetünk be szoftverünkbe.
Az IDE-k speciális szövegszerkesztő eszközök, amik kifejezetten programok forráskódjának szerkesztésére specializálódnak.
IDE-k számtalan hasznos, a fejlesztők munkáját nagyban megkönnyítő funkcióval rendelkeznek, mint automatikus kódformázás, kódszínezés, kódkiegészítés, refaktorálás, fordítási idejű hiba detektálás, valós idejű debug-olás, és még sok más…
A C# és Unity kódhoz leggyakrabban használt IDE-k :
- Visual Studio: A Microsoft terméke, akár a C# nyelv és a .NET keretrendszer maga.) Támogatott operációs rendszerek: Windows, Mac (Visual Studio for Mac)
- Visual Studio Code: (Nem összekeverendő a Visual Studio-val. Külön szoftver.) Szintén a Microsoft terméke, de pehelysúlyúbb, moduláris. (Windows, Mac, Linux)
- JetBrains Rider: Fizetős szoftver, sok extra hasznos funkcióval. (Windows, Mac, Linux)
Egy verziókezelő szoftver elsődleges feladata, hogy nyomon kövesse egy projekt mappa tartalmának változásait egy számítógépen és ezen változásokat megfelelő parancsok hatására szinkronizálja egy szerveren tárolt verzióval.
Segítségével nagy csapat tud egyszerre dolgozni egy projekten több számítógépről.
Egy VCS egyszerre tárolja nem csak a legújabb de minden korábbi “mentett” állapotát egy projektnek. Mindezt úgy teszi, hogy mindig csak az változtatott fájlokat tárolja el a rendszer, ezáltal egy projekt mérete nem duzzad hamar túlzottan nagyra.
Ezáltal egy VCS lehetővé teszi a fejlesztőknek, hogy a projekt bármely verziójára visszaálljanak valamint, hogy könnyen nyomon kövessék és összehasonlítsák a kód változásait.
A legnépszerűbb VCS-ek a Unity játékfejlesztéshez:
- Git
- Plastic
- SVN
Egy gyakran előforduló programozási problémára adott, általános, bevett és újrafelhasználható, megoldás.
Ezen megoldások általában nem kötődnek szorosan egy fejlesztési keretrendszerhez, azaz valamelyest platform és nyelvfüggetlenek.
A minták általában osztályok és objektumok közötti kapcsolatokat és műveleteket írnak le azok nevesítése, részletes specifikációja, és konkrét implementációja nélkül.
A osztály függ egy másik B osztálytól, ha A osztály kódja bármi módon hivatkozik B osztályra, például változó lekérdezésen, függvényhíváson vagy bármi egyéb módon keresztül.
Tehát ha törölnénk B osztályt akkor A osztályon belül fordítási idejű hibák jelennének meg. Fordítva ez nem igaz.
Ezt más néven úgy mondjuk, hogy A osztály ismeri B-t.
Lehetséges, hogy A és B kölcsönösen függnek egymástól.
Számítógépes grafika, játékfejlesztés és Game Design
A videojáték olyan számítógépes program, amely használatának célja maga a használattal járó élmény.
A játékmotor olyan fejlesztői keretrendszer és programozói könyvtár egyben, ami kifejezetten videojátékok és egyéb dinamikus 2 és 3D-s szoftverek elkészítéséhez szükséges megoldásokat foglal magába.
- A fejlesztői keretrendszer egy szoftveres környezet, ami hátteret biztosít új szoftverek fejlesztéséhez.
- A programozói könyvtár (vagy kicsikét félrevezető elnevezéssel függvénykönyvtár) egy adag előre megírt programkód, olyan programozói elemekkel, amiket a fejlesztő fel tud használni saját programjai elkészítéséhez.
A pixel- vagy rasztergrafikus kép egy négyzetrács, amelyen belül minden négyzet (ritkább esetben téglalap) egy színt vesz fel.
Ezen egy négyzetét a négyzetrácsnak képpontnak vagy pixelnek hívjuk.
Azt a folyamatot, amikor egy számítógépes modellről vagy jelenetről egy virtuális kamera pixelgrafikus vagy más néven rasztergrafikus képet készít, renderelésnek vagy képszintézisnek nevezzük.
Ha a képeket folytonosan meg is jelenítjük gyors egymásutánban, akár egy filmet, valós idejű vagy “real-time” renderelésről beszélünk.
Annak a mértékegység nélküli mérőszáma, hogy egy másodperc alatt, hány teljes pixelgrafikus vagy más néven rasztergrafikus kép renderelése készült el.
2D grafikában pixelgrafikus képeket jelenítünk meg egymás mellett és halmozva rétegekben. Ebből áll össze a játékvilág. Ezeket a képeket sprite-oknak nevezzük.
A sprite és a kép fogalma abban tér el, hogy a sprite szó magában hordozza, mire használjuk a képet:
A sprite-ok különbontható eleme egy nagyobb 2D kompozíciónak.
Egy sprite-ot sok mindenre használhatunk. Megjeleníthet környezeti elemet, gyűjthető jutalmat, ellenfelet és a játékos karaktert is.
Egy mesh egy sarokpontja. Minden vertex-nek van egy pozíciója a 3D térben, amit egy (x,y,z) koordinátákkal írunk le. Ezen kívül sok kiegészítő információt is rehdelhetünk egy vertex-hez. Pl.:
- Az adott pontban a normálvektor iránya
- Textúrakordináták: Ezeket U és V betűkkel jelöljük (az x,y,z már foglalt), ezért leggyakrabban uv koordinátákként hivatkozunk rájuk. (Mivel egy materialhoz több textúra is tartozhat, ezért egy vertexhez több UV koordináta is tartozhat)
- Nyers színadat: Ha nem használunk textúrát. (Ez elég ritka.)
Egy textúra egy pontjának meghatározására szolgáló számpár. A számpár egy 2D koordináta, melyen az U nevet viseli a vízszintes és V nevet a függőleges tengely.
A koordinátarendszerben minden tengely 0 és 1 közt értelmezett: U = 0: textúra bal oldala, U = 1: textúra jobb oldala, V = 0: textúra alja, V = 1: textúra teteje.
Egy háromszögön belüli pozíció meghatározására szolgáló számhármas, ami a háromszög egyes csúcsaitól való arányos távolságot adja meg. Ezek alapján egyértelműen meghatározható egy pont.
Egy material egy file, ami meghatározza hogyan mézzen ki a 3D objektum felülete és hogy pontosan hogyan verje vissza a fényt.
A material gyakorlatilag egy shader program és annak egy adott beállításának összessége.
A játékok objektumainak renderelésének módját egy apró, a videokártyán futó szoftver, a shader program írja le. Egy adott objektumon használt shader határozza meg, hogy az adott Mesht hogyan jeleníti meg a renderer. Mennyire tükröződjön a felület? Mennyire erősen érvényesüljön az árnyék és milyen színnel? Ilyen és ehhez hasonló kérdésekre a shader ad választ.
Olyan technika a számítógépes grafikában a pixelgrafikus képek éleinek simításához használható.
Az antialiasing különösen 3D játékok esetében tudja nagyban javítani a látványt.
Unity fejlesztés alapjai
Kiindulópont a Unity munkához.
A szoftver ami összefogja a Unity projektjeinket és a telepített Unity Editor verziókat.
Az "Unity Editor" az a grafikus fejlesztői környezet, amelyet a Unity motorhoz készítettek. Ez a szoftver eszköz biztosítja a játékfejlesztőknek azt a felületet, amelyen keresztül létrehozhatják, szerkeszthetik és tesztelhetik a játékuk. Ezen szoftverben zajlik a Unity-vel készült szoftver fejlesztése.
Az "Unity Runtime" az a rész a Unity fejlesztői ökoszisztémában, amely felelős az elkészült játék futtatásáért. A Unity Editor-ral elkészített játékot a Runtime futtatja valós időben különböző platformokon, legyen az számítógép, mobil eszköz vagy játékkonzol.
Egy Unity szoftver virtuális világának legnagyobb egysége a jelenet. Ezen jelenetek a játék egy logikailag jól körül határolt szeletét foglalják magába, például külön jelenetet készíthetünk a főbb menüknek és különböző játékmódoknak, vagy a játék pályáinak.
Egy jelenet vagy Scene tetszőleges számú GameObject-et foglal magába, amik a virtuális világ létezőit reprezentálják, (fizikai objektumok, kamera, fények…). Emellett a Scene általános fényelésre vonatkozó beállításokat is magába foglal.
Minden jelenet egy külön fájlban tárolódik, aminek kiterjesztése .unity (Pl.: SampleScene.unity). Egy Unity projektben tetszőleges számú jelenetfájlt hozhatunk létre.
Egyszerre legalább egy jelenet mindig betöltött állapotban van. A Unity program futása közben válthatunk a jelenetek közt, vagy akár additív módon a korábbi mellé újakat is betölthetünk. Ez utóbbi esetben az összes betöltött Scene objektumai egyszerre élnek a játékban.
Bármilyen entitás, ami jelen van egy Unity Scene-ben, az egy GameObject. GameObject-ek bármit reprezentálhatnak a játékban. Az, hogy milyen tulajdonságaik és viselkedése van egy adott GameObject-nek, azt a komponensei határozzák meg. Egy GameObject tetszőleges számú és típusú komponenst tartalmazhat.
Viselkedéssel és tulajdonságokkal ruháznak fel GameObject-eket. Minden komponens egy szeparált viselkedést vagy funkcionalitást ír le, amikhez változatos beállítások tartoznak. A komponensei és azok beállításai határozzák meg, mire való egy GameObject.
Amikor a Unity Editor-on belül Play mode-ba válthatunk, amikor a jelenetet/játékot egy belső játékablakban indíthatjuk el, és tesztelhetjük. Ez segíti a fejlesztőket abban, hogy gyorsan ellenőrizzék a játék működését anélkül, hogy folyamatosan le kellene fordítani és futtatni a projektet.
Ennek párja, az editor, azaz szerkesztő mód, amikor a játék nem fut, a MonoBechaviour üzenetmetódusok nagy része (pl.: Start()
, Update()
) nem fut le, fizikai motor nem működik és az objektumok nem interaktálnak egymással.
Olyan osztályok, amik példányai komponensként hozzáadhatók GameObject-ekhez.
Ezen szkripek az elsődleges eszközeink, ahhoz, hogy kódból manipuláljuk a játékunk futását.
using UnityEngine;
class MyClassName : MonoBehaviour { ... }
(A MonoBehaviour osztály a UnityEngine névtér része, ezért a használatához a file elején a using
kulcsszóval jelezni kell, hogy használni szeretnénk a névteret.)
Amikor egy MonoBehaviour osztályt írunk, akkor adhatunk hozzá speciális, előre meghatározott nevű és paraméterezésű metódusokat. Ezeket a Unity automatikusan meghívja (lefuttatja / végrehajtja) egyszer vagy többször bizonyos események hatására. Ez minden egyes komponens példányra megtörténik, ami betöltött Scene-ben szerepel és be van kapcsolva.
Az ilyen metódusokat nevezzük MonoBehaviour üzenet- vagy eseménymetódusoknak, mivel általuk küld a Unity üzenetet a kódunk felé egy esemény megtörténtéről.
Példák:
void Start() { /* A komponens létrejöttekor fut le Play módbab */ }
void Update() { /* Minden képfrissítés előtt fut le Play módbab */ }
Update()
method / metódusOlyan MonoBehaviour üzenetmetódus, ami minden képernyőfrissítés előtt fut le automatikusan play mód alatt.
LateUpdate()
method / metódusOlyan MonoBehaviour üzenetmetódus, ami minden képernyőfrissítés előtt de az Update metódus végrehajtása után fut le automatikusan a play mód alatt.
Minden komponens példány Update metódusa garantáltan lefut az előtt, hogy az első LateUpdate lefutna.
Start()
method / metódusOlyan MonoBehaviour üzenetmetódus, ami minden komponens létrejöttekor fut le egyszer.
Awake()
method / metódusOlyan MonoBehaviour üzenetmetódus, ami a Start()
-hoz hasonlóan minden komponens létrejöttekor fut le egyszer. A különbség a start-hoz képest, hogy az egyszerre létrejött objektumok mindegyikének lefut az Awake()
eljárása, mielőtt az első Start()
-ot meghívná a Unity.
(Javasolt a kizárólag az adott komponenst érintő beállításkódot Awake()
-ben végezni, míg a kommunikációt egyéb komponensekkel a Start()
-ban. Ha ezt betartjuk, akkor biztosak lehetünk benne, hogy egy komponens már beállított állapotban, lesz, amikor metódushíváson keresztül kommunikálni szeretnénk vele.)
OnEnable()
, OnDisable()
methods / metódusokOlyan MonoBehaviour üzenetmetódus, amik egy objektum be- és kikapcsolásánál futnak le. Ez pontosan a következőt jelenti:
Az OnEnable()
lefut…
- Közvetlenül az
Awake()
után, ha létrejött a GameObject. - Ha a komponens enabled property-jét
false
-bóltrue
-ba állítjuk. - Ha a GameObject aktívvá válik a hierarchiában.
Még pontosabban akkor, ha a fenti feltételek közül mindegyik teljesül.
Tehát, ha olyan állapotba kerül a komponens, amikor a GameObject aktív ÉS a komponens is bekapcsolt.
Az OnDisable()
lefut…
- Közvetlenül az
OnDestroy()
előtt, ha törlődik a GameObject. - Ha a komponens enabled property-jét
true
-bólfalse
-ba állítjuk. - Ha a GameObject inaktívvá válik a hierarchiában.
Még pontosabban akkor, ha a fenti feltételek közül legalább egy teljesül.
Tehát, ha olyan állapotba kerül a komponens, amikor a GameObject inaktív VAGY a komponens kikapcsolt.
OnDestroy()
method / metódusOlyan MonoBehaviour üzenetmetódus, ami egy objektum törlése előtt fut le.
A layer (réteg) egy beállítás, amit egy GameObject-hez tudunk rendelni.
Minden Unity GameObject-nek kötelezően van egy és csakis egy layer-e. Egy Unity projektben maximum 32 Layer-t definiálhatunk.
A prefab egy file, ami egy GameObject-et reprezentál gyerekeivel, komponenseivel és beállításaival együtt.
A prefabok lehetővé teszik a fejlesztők számára a játék elemeinek előre elkészített, újrahasznosítható változatainak létrehozását és használatát.
Egy prefab beágyazott, ha egy másik prefab-on belül helyezkedik el, annak részeként van elmentve. Ez a prefab technikailag nem különbözik semmiben a hagyományos prefabtól, önmagában, önálló elemként is használható.
A nested prefabok lehetővé teszik a játékfejlesztők számára, hogy adatduplikáció nélkül hozzanak létre összetett elemeket, megegyező kisebb modulokból, azáltal hogy a kisebb egységeket kiemelik külön prefab fájlba.
A prefab variáns egy olyan előre elkészített, újrahasznosítható változata egy másik Unity prefab-nak, amely többnyire ugyanazokat az alapokat használja mint az eredeti, de bizonyos tulajdonságai felülírtak.
A prefab variánsok lehetővé teszik a játékfejlesztők számára, hogy különböző változatokat hozzanak létre egy prefab-ból amellett, hogy megőrzik az eredeti GameObject tulajdonságainak és belső szerkezetének nagy részét.
Matematika
A Descartes-koordináta-rendszer egy matematikai és geometriai rendszer, amit René Descartes, a francia filozófus és matematikus dolgozott ki.
Lényege, hogy a koordináta-rendszer 2D vagy 3D (vagy bárhány dimenziós) térben kijelöl:
- Egy sepeciális pont: Az origót, koordináta-rendszer “középpontját”
- Tengelyeket, azaz olyan egyeneseket, amik merőlegesek egymással és érintik az origót.
- Egy-egy számegyenest minden tengelyen, aminek a 0 pontja az origóban van. Ez a számegyenes pozitív és negatív iránnyal látja el a tengelyeket.
Ezután a tér minden pontja egyértelműen megfeleltethető egy számpárnak (2D) számhármasnak (3D) (vagy általánosan bárhány dimenziós számsorozatnak).
Irányított szakasz (egy nyíl), ami leírható 2D térben 2 számmal, 3D térben pedig 3-mal. Ezen számok azt adják meg, hogy mekkora elmozdulása van ennek az irányított szakasznak a Descartes koordináta rendszerben az egyes tengelyek mentén.
(Természetesen a vektorok is kiterjeszthetők bármekkora magasabb dimenzióra is, de a grafikában általában ezek nem érdekelnek minket.)
A vektor magában nem tartalmazza azt, hogy hol van a térben a kiindulópontja vagy a vége, csak az irányát és a hosszát.
Vektor abszolút értékén a vektor hosszát értjük, azaz a helyvektor origótól vett távolságát.
Olyan vektor, aminek kiindulópontját az origóhoz tesszük. Ekkor a vektor vége egy pontra mutat a Descartes koordináta rendszerben, aminek értéke (számsorozata) megegyezik a pont koordinátájával.
A helyvektor gyakorlatilag csak egy módja annak, hogy mentálisan összekössük a vektor és a térbeli pont fogalmát.
Pontosan 1 egység hosszúságú vektor.
Az a pontosan 1 egység hosszú vektor, azaz egységvektor, amit arra használunk, hogy egy irányt leírjunk.
Ha A irányvektort szorzunk egy float típusú B skalárral, akkor az így kapott vektor az eredeti A irányvektor irányába fog mutatni és pontosan B hosszúságú lesz.
Ez azt jelenti, hogy bármilyen fizikai vektormennyiség vektormennyiség (sebesség, gyorsulás, erő…) előállítható tehát egy irányvektor és a mennyiségméretet leíró szám.
A sebességvektor az a vektor, ami leírja egy mozgásnak mind az irányát, mind a mértékét (hosszát) egy adott pillanatra.
Ha a sebességvektor állandó, akkor egy másodperc alatt pontosan a vektornyival kerülne odébb a mozgatott objektum.
Ez a vektor időben folyamatosan változhat. A sebesség mértéke a vektor hosszával egyenlő. Ezen sebesség mértékegysége (Unity hossz egység/másodperc)-ben értendő.
Egy 3D felület vagy 2D görbe normálvektora a felületre vagy görbére merőleges vektor. A normálvektor hossza általában 1 (, de ez definíciótól függő). Ha a felületnek van elülső és hátulsó oldala, akkor a Normál vektor kifelé a elülső oldal irányába mutat.
Fizika
A klasszikus mechanika a fizikának azon ága, ami a fizikai testek mozgását és a rajtuk ható erők hatását vizsgálja.
A kinematika a mechanika azon részterülete, ami pusztán a testek mozgásával foglalkozik.
Ezzel szemben a dinamika számításba veszi a fizikai objektumok tömegét is. A dinamika a testeken ható erők tudománya függetlenül attól, hogy ezen erők mozgást eredményeznek-e.
Az idő alapvető fizikai mennység, amely jelölésére az szimbólumot használjuk.
Unity-ben az idő mindig másodpercben vagyis szekundumban () értendő.
Az út alapvető fizikai mennyiség, amely térbeli távolságot jelöl.
Unity-ben az útra mindig egy absztrakt mértékegységben értendő. Mi, azaz a fejlesztők döntjük el, hogy miként kezeljük ezt a mértéket, méterként, kilométerként vagy bármi egyébként.
Legtöbb esetben javasolt a SI út alapmértéket a métet () használni.
Jelölésére az szimbólumot használjuk.
(A másodpercből (mint időmértékből), és választott út és tömeg mértékegységekből kapjuk meg az egyéb leszármazott fizikai mennyiségek egységét is.)
Olyan fizikai mennyiség, amit két információ jellemez, az irány és nagyság.
Egy vektormennyiség eltárolható egy vektorban, hiszen annak is van iránya és nagysága.
Vektormennyiség, ami ez egységnyi idő alatt megtett elmozdulást adja meg.
(Az angol velocity fogalmat általában akkor szoktuk használni ha sebességvektorról beszélünk, a speed fogalmat, akkor hogyha a vektor abszolútértékéről, azaz irány nélküli hosszáról beszélünk.)
Unity fizikában a gyorsulásnak nincs megszabott mértékegysége, de legtöbb esetben javasolt a SI tömeg alapmértéket a méter per szekundumot () használni.
Jelölésére az szimbólumot használjuk.
Vektormennyiség, ami ez egységnyi idő alatti sebességváltozást adja meg.
Unity fizikában a gyorsulásnak nincs megszabott mértékegysége, de legtöbb esetben javasolt a SI tömeg alapmértéket a méter per szekundum négyzetet () használni.
Jelölésére az szimbólumot használjuk.
Egy test tehetetlenségének mértéke.
Minél nagyobb egy test tömege, annál nagyobb erő kell ahhoz, hogy módosítsuk sebességét.
Unity fizikában a tömegnek nincs megszabott mértékegysége, de legtöbb esetben javasolt a SI tömeg alapmértéket a kilogrammgot () használni.
Jelölésére az szimbólumot használjuk.
(A másodpercből (mint időmértékből), és választott út és tömeg mértékegységekből kapjuk meg az egyéb leszármazott fizikai mennyiségek egységét is.)
Vektormennyiség, ami egy test sebességének és tömegének szorzatával kapható meg.
Unity fizikában a gyorsulásnak nincs megszabott mértékegysége, de legtöbb esetben javasolt a SI tömeg alapmértéket a kilogramm-szor méter per szekundumot () használni.
Jelölésére az szimbólumot használjuk.
Az erő a gyorsulás és a tömeg szorzatávl meghatározott fizikai mennység.
Unity fizikában a tömegnek nincs megszabott mértékegysége, de legtöbb esetben javasolt a SI tömeg alapmértéket a Newton () használni.
Jelölésére az szimbólumot használjuk.
…
…
…
…
…
…
…
…
Olyan komponens, amivel egy merev test reprezentáló, amin a 3D vagy 2D fizikai szimuláció részét képezi.
…
Olyan komponens, ami fizikai alakkal ruházza fel a 3D és 2D GameObjectet. Ezen az alakon fizikai szimuláció alkalmazható, ha Rigidbody-t is adunk hozzá.
Olyan 3D és 2D fizikai alakzatok, amik nem tudnak ütközni semmivel, da ha egyéb testekkel érnek össze, akkor arról egy üzenetet kap a MonoBehaviour komponens kód egy üzenetmetódus formájában.
Ahhoz, hogy egy GameObject Trigger-ként viselkedjen, kell legyen egy Collider-e, amin be kell jelölni, a Trigger beállítást.
A 3D és 2D Rigidbodykat köt össze, fejt rájuk ki erőt és korlátozza mozgásukat.
Egy dinamikus Rigidbody sleep, azaz alvó módban van, ha nyugvó helyzetbe kerül. Utána a fizikai motor nem alkalmaz rajta szimulációt addig, amíg nem ütközik valamivel vagy valami új erőhatás nem éri. Az alvó mód egy optimalizációs eszköz, ami jelen van a 2D és 3D fizikában egyaránt.
A Physics Material egy olyan fájl a Unity játékfejlesztői környezetben, amely egy 3D Collider-hez vagy Rigidbody-hoz csatolva lehetővé teszi a olyan fizikai tulajdonságok beállítását a játékobjektumok közötti ütközéseknél, mint súrlódás és rugalmasság.
A Physics Material-nak 2D változata is létezik: Physics Material2D
Az a művelet, amikor egy adott pontból, egy adott irányba egy virtuális sugarat lövünk ki és megkapjuk, hogy ezen sugár milyen fizikai Collider-t talált el és hol.
A Raycast-ot véggezhetjük 2D-ben és 3D-ben is.
Egyszerre lekérhetjük a legközelebbit találatot, de akár többet is.
FixedUpdate()
metódusOlyan MonoBehaviour üzenetmetódus, ami minden képernyőfrissítés előtt fut le automatikusan a play mód alatt.
OnTrigger…()
metódusokOlyan MonoBehaviour üzenetmetódusok, amik bizonyos trigger-események hatására futnak le. A két kapcsolatba lépő Collider közül legalább az egyik Trigger kell, hogy legyen.
OnTriggerEnter()
: Két 3D Collider egymásba ért.OnTriggerStay()
: Amígy két 3D Collider fedésben van egymással, addig minden FixedUpdate() után meghívódik.OnTriggerExit()
: Két korábban átfedésben lévő 3D Collider eltávolodott.OnTriggerEnter2D()
: AzOnTriggerEnter()
2D verziója.OnTriggerStay2D()
: AzOnTriggerStay()
2D verziója.OnTriggerExit2D()
: AzOnTriggerExit()
2D verziója.
A két kapcsolat balépő Collider közül bármely GameObject összes MonoBehaviour komponenseire meghívódnak a Trigger üzenetmetódusok.
OnCollider…()
metódusokOlyan MonoBehaviour üzenetmetódusok, amik bizonyos collider azaz ütközés-események hatására futnak le. A két kapcsolatba lépő Collider közül egyik sem lehet Trigger.
OnColliderEnter()
: Két 3D Collider egymáshoz ért.OnColliderStay()
: Amígy két 3D Collider egymáshoz ér, addig mindenFixedUpdate()
után meghívódik.OnColliderExit
: Két korábban egymáshoz érő 3D Collider eltávolodott.OnColliderEnter2D()
: AzOnColliderEnter()
2D verziója.OnColliderStay2D()
: AzOnColliderStay()
2D verziója.OnColliderExit2D()
: AzOnColliderExit()
2D verziója.
A két kapcsolat balépő Collider közül bármely GameObject összes MonoBehaviour komponenseire meghívódnak a Collider üzenetmetódusok.
Verziókezelés
A Repository egy projektet reprezentál a verziókövető rendszerben. A Repository nem egy az aktuális állapotát tárolja a projektnek, hanem minden “elmentett” állapotának összességét. Bármikor vissza lehet állni ezen állapotok közül bármelyik korábbira.
Ha egy Repository-t klónozunk, azzal egy lokális verziót készítünk a projektből a saját gépünkre. amely időnként szinkronizálni kell a szerveren lévő repository-val a Push és a Pull műveletekkel.
…
…
…
…
…
…