woensdag 30 maart 2016

Unity Basics - How To Create a Dialog Box & Import Text

Link

In mijn spel (zelfde als de inventory) wil ik ook een dialoog systeem maken. Deze tutorial legt uit hoe je dit vanuit een textfile doet.


Wat heb ik er van geleerd?

Een textfile kan je inladen met TextAsset.
Deze textasset kan je dan uitlezen met de text.Split('\n') functie. Dit split de file op bij elke enter. Op die manier kan je verschillende zinnen maken waar de speler dan doorheen kan lezen.

\n betekend nieuwe regel.

Met een currentLine en een endAtLine variable geef je aan op welke regel de text nu is, en op welke hij op moet houden.

FindObjectOfType() kan je gebruiken om een object te vinden met een script welke naam je aangeeft tussen de haakjes.

Wanneer je checkt op een object moet je altijd kijken of het object wel meegestuurd wordt. Dit kan met bijvoorbeeld: if (theText != null)

Door een while loop te gebruiken in een coRoutine kan je een timer maken zonder elke keer de coroutine opnieuw aan te roepen.
Ik deed eerst altijd deze manier:

IEnumerator Timer()
{
    if (timer < 10) 
    { 
       timer++; 
       yield return new waitforseconds(1f);
       startCoroutine(Timer());
     }
}

maar het kan dus ook zo:


IEnumerator Timer()
{
    while (timer < 10)
    {
         yield return new waitforseconds(1f);
         timer++;
    }
}

je kan de letters meten van een string met lineOfText.length en een specefieke letter aangeven met lineOfText[letter];


Wat heb ik er mee gedaan

Je kan naar een poppetje toe lopen en op enter drukken om te praten.









De text wordt geladen uit een text file op basis van de ID van de npc. (npc 1 laad NPC_1.txt)

De text komt letter voor letter in beeld, als een typemachine en kan versneld worden met enter.

Na het gesprek verdwijnt de textbalk weer.

maandag 28 maart 2016

Unity Shader Writing beginner

Link



Waarom deze tutorial?

Deze lijst met tutorials gaan dieper in op het programmeren van shaders. Door deze filmpjes te kijken hoop ik wat meer te leren hierover.


Wat heb ik er van geleerd?

----------------------------------Basics---------------------------------------

De tutorial legt maakt ook de code voor de shaders, deze volg ik helemaal mee, maar ik schrijf alleen de dingen op die ik echt interessant vind (anders komt deze pagina helemaal vol met code).

A shader bepaald wat een matterial kan doen.
Een vertex program werkt op vertex level en kan vertext deformation doen, terwijl fragment programs per fragment(pixel) level werken.

In een shader code zit de naam (geeft aan hoe de shader heet), de properties (dingen die je aan kan passen), subshaders (de shader zelf) hier kan je ook meer van hebben. De pass functie blend verschillende onderdelen tot een shader.

Met CGPROGRAM bepaal je dat unity in GC moet gaan werken.

Structs zijn een soort classes, ze bevatten vooraf bepaalde variables. Zo praten vertex en fragment functions met elkaar.

Een variable in een shader met een _ kan worden aangepast en een variable zonder niet. Zo weet je precies wat je wel en niet kan aanpassen.

Voor CG moet je voor variables 'uniform' zetten zodat je in andere programmas geen errors krijgt. (unity kan zonder).

Wanneer je een positie wil aanmaken moet je er SV_ voorzetten sinds directx11. Dus geen POSITION maar SV_POSITION.

Een pragma is een instructie, het verteld unity waar hij moet kijken. Dit wordt gebruikt voor de vertext en fragment shader.

Een fallback shader wordt gedaan, als er geen andere shader te vinden is. (het is handig om deze even weg te halen als je aan programmeren bent, anders zie je niet of je iets fout hebt gedaan.

----------------------------------Lighting---------------------------------------

De belichting wordt berekend door een aantal vectors:
* Light direction (waar komt het licht vandaan)
* View direction (van waar kijkt de camera)
* Normal direction (de kant waar de normals opstaan)
* Reflected direction (de tegenovergestelde kant van het licht)
* Halfway vector (halverwege de camera en het licht)

Met een dot-product kan je een calculatie tussen twee punten berekenen.
Een dot-product geeft de waarde tussen -1 en 1 als de eerste vector dichter bij de tweede komt.
Met _WorldSPaceLightPos0 kan je de directie van het licht bepalen uit unity.
Met normalize maak je een getal tussen 0 en 1. Handig voor dotproducts.

Met Tags kan je het programma specialde dingen vertellen. Zoals wat voor soort licht je gebruikt. (LightMode = ForwardBase) (moet voor CGPROGRAM)
Door een MAX te gebruiken zorg je ervoor dat een variable niet onder/boven een bepaald getal komt.

Unity heeft een ingebouwde variable genaamd: UNITY_LIGHTMODEL_AMBIENT, dit is een float4 kleur dat door je project is aangegeven. Deze kan je gebruiken om de schaduw van je object wat lichter te maken.

Specular shading pakt de bestaande lambertian shader en voegt daar specular highlight aan toe. De specular hightlight is een punt van light dat volgt halverwege tussen de kijkrichting en de licht-richting.

Met reflect(-lightDirection,normalDirection) calculeer je de reflectie vector.
Met dot(reflect(-lightDirection,normalDirection),viewDirection) krijg je het punt waar het licht moet komen.
Met de pow functie kan je de specular highlight naar een power krijgen zodat je controle krijgt over de intensiteit.

Je moet natuurlijk wel een camera hebben om de direction te meten.

Een vertext lighting met specular is veel lichter dan een fragment lighting maar minder mooi.

Rim lighting is het kleine beetje rand belichting dat je om silhouetten ziet. Het maakt een randje van licht om het object heen, gebaseert op de kijkrichting en daarna word het gemaskeerd met de licht richting.

De saturate function klamt tussen 0 en 1. Het wordt dus nooit groter dan 1 of kleiner dan 0.

Tags { Lightmode = "Forwardbase" } zegt unity dat dit het primaire licht is in de scene.
Tags { Lightmode = "ForwardAdd" } zegt unity dat dit de rest van de lichten zijn.
Blend one one zegt hoe alles gemixt wordt. Dit kan op basis van:
* Zero (niets)
* SrcColor (Source kleur)
* SrcAlpha (Source doorzichtigheid)
* DstColor (Destination kleur)
* DstAlpha (Destination doorzichtigheid)
* OneMinusSrcsColor (een min Source kleur)
* OneMinusSrcsAlpha (een min Source alpha)
* OneMinusDstColor (een min Destination alpha)
* OneMinusDistAlpha (een min Afstand alpha)

Voor een blend copieer je de hele pass en zet je inplaats van Tags { Lightmode = "ForwardBase" }, Tags { Lightmode = "ForwardAdd" }  neer. Dat geeft dus aan wat er moet gebeuren met ander licht.

Conditional statements zijn erg zwaar dus gebruik lerps.

----------------------------------Textures---------------------------------------

In de property geef je met _MainText ("Diffuse Texture",2D) = "White" aan dat je een texture wil ontvangen, maar als dat niet zo is het programma wit mag gebruiken.

Dan moet je de textures 'sample-en' Dat doe je door uniform sampler2D_MainTex: en uniform float4 _MainTex_ST te gebruiken. Dit geeft de controle over hoe groot en wat de offset is van de texture.

In de code bereken je eerst de plaats van de texture, beinvloed door de grootte en offset die de gebruiker heeft aangegeven in de inspector (scale en offset) en daarna komt licht en ambient kleur er bij.

Alle belichting technieken die eerder uitgelegd zijn, zijn ook te gebruiken in combinatie met de texture. Dan heb je dus inplaats van een kleur met belichting, een texture met belichting.

met #pragma exclude renders flash zorgt ervoor dat de shader niet ge-renderd wordt op beplaalde renderers, in dit geval: Flash.

Om realistishe textures te maken (dus er uit zien alsof de texture uitsteekt) moet je normal maps gebruiken. Een normal is de richting dat een vextex staat. Een normal map draait de normals voor elke fragment (pixel) om de illusie van diepte te creeren.

Om normals te draaien heb je een normal direction, een tangent normal en een bi-normal/co-tangent direction nodig.

Unity slaat normal maps op in de alpha en green channels om ruimte te besparen.

Een normal map moet net als een texture ge-sampled worden. Zodat de gebruiker een plaatje kan inladen.

Een normal map zit in de alpha channel en geeft dus waardes van 0 tot 1. Omdat we een waarde van -1 tot 1 willen voor de normals doen we deze maal 2 en dan -1.

De upacknormal functie zit in unity ingebouwd, maar dit kan je beter handmatig doen aangezien de unity manier meer geheugen verbruikt.

Om nog meer textures toe te voegen dan diffuse en normal textures is best gemakkelijk.

Om een specular map toe te voegen hoe je alleen maar de specular reflectie die je al gemaakt hebt te vermenigvuldigen met de specular texture (die je nog wel moet aanmaken op de zelfde manier als je andere textures hebt toegevoegd.)

Met een emission map kan je bepaalde texture uitlichten (ook als de scene compleet donker is)


----------------------------------Optimizing---------------------------------------

Het filmpje liet een aantal errors zien en hoe je ze moet oplossen. Het leek me onzinnig om deze allemaal hier neer te zetten.

Wanneer je een calculatie vaak gebruikt kan je hem ook in een variable stoppen om sneller te zijn.maar alleen als je hem vaker dan 1 keer wil berekenen.

Aan de andere kant, wanneer je een variable aanmaakt die je maar een keer gebruikt kan je de calculaties in de zelfde zin maken, inplaats van een tijdelijke variable aan te maken voor elk ding wat je wilt berekenen.

Elke variable dat een float is kan je ook veranderen naar een half of fixed om ruimte te besparen. Kijk of de variable boven de 2 komt dan gebruik je half.

donderdag 24 maart 2016

Inventory system tutorial

Link naar de tutorial


https://www.youtube.com/watch?v=ZW6RCKVnqT4

Waarom deze tutorial?

Ik ben bezig met een kleine rpg game. Om een inventory te kunnen maken is erg handig.

Wat heb ik er van geleerd?

Met een horizontal layout group kan je bepalen hoeveel er maximaal in een bepaald gebied mag. Handig om text binnen de randen te houden.
Met een canvas group geef je aan of het object ook interacteble moet zijn (zoals de tooltip, deze hoeft niet interactive te zijn).
Een grid layout group zorgt ervoor dat alle object die als child in dit object komen zich netjes orderen in een grid.
Met een json DLL kan je bestanden inlezen van .json formaat. Dit heb ik nu gebruikt voor mijn inventory items op te slaan.

Alle items uit de json file worden dan omgezet naar variables zodat unity ze kan uitlezen.

Door een interface te gebruiken van IBeginDragHandler etc kan je gemakkelijk drag en drop regelen. Je krijgt dan gewoon een void waarmee je verschillende acties kan aangeven. Hiervoor moet je wel eventsystems namespace includen.

Je kan gewoon html opmaak gebruiken om text op te maken.

Wat heb ik er mee gedaan?


Ik heb deze tutorial helemaal mee gevolgd en ge-implementeerd in mijn spel!